tamer: obj::xmlo::ir::Dim: New enum

This replaces u8 and will be used for the new XmloReader.

Previously I wasn't sure what direction TAMER was going to go in with
regards to dimensionality, but I do not expect that higher dimensions will
be supported, and if they are, they'd very likely compile down to lower ones
and create an illusion of higher-dimensionality.

Whatever the future holds, it's not used today, and I'd rather these types
be correct.

ASG needs changing too, but one step at a time.

DEV-10863
main
Mike Gerwitz 2022-03-25 13:38:38 -04:00
parent 279ddc79d7
commit c0fa89222e
6 changed files with 57 additions and 47 deletions

View File

@ -236,14 +236,14 @@ impl TryFrom<&SymAttrs> for IdentKind {
Ok($to)
};
($to:expr, dim) => {
Ok($to(Dim(attrs.dim.ok_or(Self::Error::MissingDim)?)))
Ok($to(Dim(attrs.dim.ok_or(Self::Error::MissingDim)? as u8)))
};
($to:expr, dtype) => {
Ok($to(attrs.dtype.ok_or(Self::Error::MissingDtype)?))
};
($to:expr, dim, dtype) => {
Ok($to(
Dim(attrs.dim.ok_or(Self::Error::MissingDim)?),
Dim(attrs.dim.ok_or(Self::Error::MissingDim)? as u8),
attrs.dtype.ok_or(Self::Error::MissingDtype)?,
))
};
@ -367,6 +367,7 @@ pub type DataType = SymDtype;
#[cfg(test)]
mod test {
use super::*;
use crate::obj::xmlo::Dim as XmloDim;
use std::convert::TryInto;
#[test]
@ -404,10 +405,10 @@ mod test {
($name:ident, $src:expr => $dest:expr, dim) => {
#[test]
fn $name() {
let dim = 1;
let dim = XmloDim::Vector;
assert_eq!(
Ok($dest(Dim(dim))),
Ok($dest(Dim(dim.into()))),
SymAttrs {
ty: Some($src),
dim: Some(dim),
@ -456,11 +457,11 @@ mod test {
($name:ident, $src:expr => $dest:expr, dim, dtype) => {
#[test]
fn $name() {
let dim = 1;
let dim = XmloDim::Vector;
let dtype = SymDtype::Float;
assert_eq!(
Ok($dest(Dim(dim), dtype)),
Ok($dest(Dim(dim.into()), dtype)),
SymAttrs {
ty: Some($src),
dim: Some(dim),

View File

@ -31,6 +31,24 @@ use crate::sym::{st, GlobalSymbolResolve, SymbolId};
use std::convert::TryFrom;
use std::result::Result;
/// Value dimensionality.
///
/// This indicates the number of subscripts needed to access a scalar
/// value.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum Dim {
Scalar = 0,
Vector = 1,
Matrix = 2,
}
impl Into<u8> for Dim {
fn into(self) -> u8 {
self as u8
}
}
/// Symbol attributes.
///
/// This is a subset of all available attributes available on the
@ -60,15 +78,7 @@ pub struct SymAttrs {
pub ty: Option<SymType>,
/// Number of dimensions.
///
/// This determines the number of subscripts needed to access a scalar
/// value.
/// A value of `0` indicates a scalar;
/// a value of `1` indicates a vector;
/// a value of `2` indicates a matrix;
/// and a value of `n` indicates a multi-dimensional array of
/// depth `n`.
pub dim: Option<u8>,
pub dim: Option<Dim>,
/// Type of underlying data.
///

View File

@ -81,5 +81,5 @@ mod reader;
pub use asg_builder::{AsgBuilder, AsgBuilderState};
pub use error::XmloError;
pub use ir::{SymAttrs, SymDtype, SymType};
pub use ir::{Dim, SymAttrs, SymDtype, SymType};
pub use reader::{XmloEvent, XmloReader};

View File

@ -49,6 +49,7 @@
use super::super::{SymAttrs, SymType};
use super::{XmloError, XmloEvent, XmloResult};
use crate::obj::xmlo::Dim;
use crate::sym::{GlobalSymbolInternUnchecked, GlobalSymbolResolve, SymbolId};
#[cfg(test)]
use crate::test::quick_xml::MockBytesStart as BytesStart;
@ -357,7 +358,7 @@ where
}
b"dim" => {
sym_attrs.dim = Some(Self::dim_to_u8(&attr.value)?);
sym_attrs.dim = Some(Self::char_to_dim(&attr.value)?);
}
b"dtype" => {
@ -594,23 +595,16 @@ where
Ok(XmloEvent::Fragment(id, text))
}
/// Convert single-character `@dim` to a [`u8`].
///
/// Errors
/// ======
/// - [`XmloError::InvalidDim`] if first character is not an ASCII
/// digit,
/// or if there is more than one character.
fn dim_to_u8(value: &[u8]) -> XmloResult<u8> {
// Technically this could allow for incorrect inputs (we only take
// the first character)
if value.len() > 1 || !value[0].is_ascii_digit() {
return Err(XmloError::InvalidDim(unsafe {
/// Convert single-character `@dim` to a [`Dim`].
fn char_to_dim(value: &[u8]) -> XmloResult<Dim> {
match value {
[b'0'] => Ok(Dim::Scalar),
[b'1'] => Ok(Dim::Vector),
[b'2'] => Ok(Dim::Matrix),
_ => Err(XmloError::InvalidDim(unsafe {
String::from_utf8_unchecked(value.to_vec())
}));
})),
}
Ok(value[0] - b'0')
}
}

View File

@ -446,7 +446,7 @@ xmlo_tests! {
XmloEvent::SymDecl(
"sym-nonempty".intern(),
SymAttrs {
dim: Some(2),
dim: Some(Dim::Matrix),
pkg_name: Some("pkg/name".intern()),
..Default::default()
},
@ -696,12 +696,12 @@ sym_tests! {
}
dim_0: [dim="0"] => SymAttrs {
dim: Some(0),
dim: Some(Dim::Scalar),
..Default::default()
}
dim_1: [dim="1"] => SymAttrs {
dim: Some(1),
dim: Some(Dim::Vector),
..Default::default()
}
@ -769,7 +769,7 @@ sym_tests! {
// see macro for src relpath
src: Some("foo".intern()),
ty: Some(SymType::Class),
dim: Some(1),
dim: Some(Dim::Vector),
dtype: Some(SymDtype::Float),
extern_: true,
..Default::default()

View File

@ -217,18 +217,23 @@ where
(NodeExpected(stack), tok) => Self::parse_node(stack, tok),
(AttrExpected(stack, sa), tok) => match sa.parse_token(tok).into() {
(Transition(sa), Ok(Incomplete)) => {
Transition(AttrExpected(stack, sa)).incomplete()
(AttrExpected(stack, sa), tok) => {
match sa.parse_token(tok).into() {
(Transition(sa), Ok(Incomplete)) => {
Transition(AttrExpected(stack, sa)).incomplete()
}
(Transition(sa), Ok(Obj(attr))) => {
Transition(AttrExpected(stack, sa))
.with(Object::Attr(attr))
}
(_, Ok(Dead(lookahead))) => {
Self::parse_node(stack, lookahead)
}
(Transition(sa), Err(x)) => {
Transition(AttrExpected(stack, sa)).err(x)
}
}
(Transition(sa), Ok(Obj(attr))) => {
Transition(AttrExpected(stack, sa)).with(Object::Attr(attr))
}
(_, Ok(Dead(lookahead))) => Self::parse_node(stack, lookahead),
(Transition(sa), Err(x)) => {
Transition(AttrExpected(stack, sa)).err(x)
}
},
}
(Done, tok) => Transition(Done).dead(tok),
}