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-10863main
parent
279ddc79d7
commit
c0fa89222e
|
@ -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),
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue