diff --git a/tamer/src/asg/graph.rs b/tamer/src/asg/graph.rs index c1941bbb..89476300 100644 --- a/tamer/src/asg/graph.rs +++ b/tamer/src/asg/graph.rs @@ -598,7 +598,7 @@ mod test { let sym = "symext".intern(); let src = Source::default(); - let kind = IdentKind::Class(Dim::from_u8(3)); + let kind = IdentKind::Class(Dim::Matrix); let node = sut.declare_extern(sym, kind.clone(), src.clone())?; let resrc = Source { diff --git a/tamer/src/asg/ident.rs b/tamer/src/asg/ident.rs index cdffe766..67204a22 100644 --- a/tamer/src/asg/ident.rs +++ b/tamer/src/asg/ident.rs @@ -19,7 +19,7 @@ //! Identifiers (a type of [object][super::object::IdentObject]). -use crate::obj::xmlo::{SymAttrs, SymDtype, SymType}; +use crate::obj::xmlo::{Dim as XmloDim, SymAttrs, SymDtype, SymType}; use crate::sym::{st, GlobalSymbolResolve, SymbolId}; use std::convert::TryFrom; use std::error::Error; @@ -245,14 +245,14 @@ impl TryFrom<&SymAttrs> for IdentKind { Ok($to) }; ($to:expr, dim) => { - Ok($to(Dim(attrs.dim.ok_or(Self::Error::MissingDim)? as u8))) + Ok($to(attrs.dim.ok_or(Self::Error::MissingDim)?.into())) }; ($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)? as u8), + attrs.dim.ok_or(Self::Error::MissingDim)?.into(), attrs.dtype.ok_or(Self::Error::MissingDtype)?, )) }; @@ -309,64 +309,46 @@ impl Error for IdentKindError { } } -/// Identifier dimensions. +/// Value dimensionality. /// -/// This determines the number of subscripts needed to access a scalar +/// This indicates 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`. -#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)] -pub struct Dim(u8); - -impl Dim { - pub fn from_u8(value: u8) -> Self { - // We don't expect to format a value this large. - // In practice, it should never exceed 2. - assert!(value < 10, "Dim value cannot exceed 9"); - - Self(value) - } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u8)] +pub enum Dim { + Scalar = 0, + Vector = 1, + Matrix = 2, } -/// Underlying datatype of identifier. -/// -/// TODO: This will always be 0≤n≤9, so let's introduce a newtype for it. -impl AsRef for Dim { - fn as_ref(&self) -> &str { - match self.0 { - 0 => &"0", - 1 => &"1", - 2 => &"2", - 3 => &"3", - 4 => &"4", - 5 => &"5", - 6 => &"6", - 7 => &"7", - 8 => &"8", - 9 => &"9", - _ => unreachable!(), +// These are clearly the same thing, +// but it's not worth sharing them until a natural shared abstraction +// arises. +impl From for Dim { + fn from(dim: XmloDim) -> Self { + match dim { + XmloDim::Scalar => Dim::Scalar, + XmloDim::Vector => Dim::Vector, + XmloDim::Matrix => Dim::Matrix, } } } impl From for u8 { fn from(dim: Dim) -> Self { - dim.0 + dim as u8 } } impl From for SymbolId { fn from(dim: Dim) -> Self { - st::decimal1(dim.0).as_sym() + st::decimal1(dim as u8).as_sym() } } impl std::fmt::Display for Dim { fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result { - (self.0).fmt(fmt) + (*self as u8).fmt(fmt) } } @@ -379,23 +361,6 @@ mod test { use crate::obj::xmlo::Dim as XmloDim; use std::convert::TryInto; - #[test] - fn dim_from_u8() { - let n = 5u8; - - assert_eq!(Dim(n), Dim::from_u8(n)); - } - - #[test] - fn dim_to_str() { - // we'll just test high and low - let low: &str = Dim(0).as_ref(); - let high: &str = Dim(9).as_ref(); - - assert_eq!("0", low); - assert_eq!("9", high); - } - macro_rules! test_kind { ($name:ident, $src:expr => $dest:expr) => { #[test] @@ -417,7 +382,7 @@ mod test { let dim = XmloDim::Vector; assert_eq!( - Ok($dest(Dim(dim.into()))), + Ok($dest(Dim::Vector)), SymAttrs { ty: Some($src), dim: Some(dim), @@ -470,7 +435,7 @@ mod test { let dtype = SymDtype::Float; assert_eq!( - Ok($dest(Dim(dim.into()), dtype)), + Ok($dest(Dim::Vector, dtype)), SymAttrs { ty: Some($src), dim: Some(dim), diff --git a/tamer/src/asg/object.rs b/tamer/src/asg/object.rs index 373cab0a..4cc23aa4 100644 --- a/tamer/src/asg/object.rs +++ b/tamer/src/asg/object.rs @@ -688,7 +688,7 @@ mod test { #[test] fn ident_object_kind() { let sym: SymbolId = "sym".intern(); - let kind = IdentKind::Class(Dim::from_u8(5)); + let kind = IdentKind::Class(Dim::Matrix); assert_eq!(None, IdentObject::Missing(sym).kind()); @@ -872,7 +872,7 @@ mod test { #[test] fn ident_object() { let sym: SymbolId = "extern".intern(); - let kind = IdentKind::Class(Dim::from_u8(1)); + let kind = IdentKind::Class(Dim::Vector); let src = Source { desc: Some("extern".into()), ..Default::default() @@ -887,7 +887,7 @@ mod test { #[test] fn resolved_on_extern() { let sym: SymbolId = "extern resolved".intern(); - let kind = IdentKind::Class(Dim::from_u8(1)); + let kind = IdentKind::Class(Dim::Vector); let pkg_name: SymbolId = "pkg/name".intern(); let src = Source { pkg_name: Some(pkg_name), @@ -951,7 +951,7 @@ mod test { #[test] fn redeclare_compatible_resolves() { let sym: SymbolId = "extern_re_pre".intern(); - let kind = IdentKind::Class(Dim::from_u8(2)); + let kind = IdentKind::Class(Dim::Matrix); let src = Source { desc: Some("okay".into()), ..Default::default() @@ -969,7 +969,7 @@ mod test { #[test] fn redeclare_compatible_resolves_post() { let sym: SymbolId = "extern_re_post".intern(); - let kind = IdentKind::Class(Dim::from_u8(1)); + let kind = IdentKind::Class(Dim::Vector); let src = Source { desc: Some("okay".into()), ..Default::default() @@ -986,7 +986,7 @@ mod test { #[test] fn redeclare_another_extern() { let sym: SymbolId = "extern_extern".intern(); - let kind = IdentKind::Class(Dim::from_u8(0)); + let kind = IdentKind::Class(Dim::Scalar); let src_first = Source { desc: Some("first src".into()), ..Default::default() @@ -1009,7 +1009,7 @@ mod test { #[test] fn redeclare_post_incompatible_kind() { let sym: SymbolId = "extern_re_bad_post".intern(); - let kind = IdentKind::Class(Dim::from_u8(2)); + let kind = IdentKind::Class(Dim::Matrix); let src = Source { desc: Some("bad kind".into()), ..Default::default() @@ -1053,7 +1053,7 @@ mod test { #[test] fn redeclare_pre_incompatible_kind() { let sym: SymbolId = "extern_re_bad_pre".intern(); - let kind_given = IdentKind::Class(Dim::from_u8(1)); + let kind_given = IdentKind::Class(Dim::Vector); let src = Source { desc: Some("bad kind".into()), ..Default::default() @@ -1259,7 +1259,7 @@ mod test { // This isn't the purpose of the test, but we want to make // sure that the non-virtual override error occurs before // the kind error. - let bad_kind = IdentKind::Cgen(Dim::from_u8(1)); + let bad_kind = IdentKind::Cgen(Dim::Vector); let result = non_virt .clone() @@ -1312,7 +1312,7 @@ mod test { ..Default::default() }; - let bad_kind = IdentKind::Cgen(Dim::from_u8(1)); + let bad_kind = IdentKind::Cgen(Dim::Vector); let result = virt .clone() .resolve(bad_kind.clone(), over_src.clone()) @@ -1488,7 +1488,7 @@ mod test { ..Default::default() }; - let bad_kind = IdentKind::Cgen(Dim::from_u8(1)); + let bad_kind = IdentKind::Cgen(Dim::Vector); let result = virt_frag .clone() .resolve(bad_kind.clone(), over_src.clone()) diff --git a/tamer/src/ld/xmle/lower.rs b/tamer/src/ld/xmle/lower.rs index 39c821e8..bb1150e0 100644 --- a/tamer/src/ld/xmle/lower.rs +++ b/tamer/src/ld/xmle/lower.rs @@ -632,7 +632,7 @@ mod test { let sym3_node = asg .declare( sym3, - IdentKind::Func(Dim::default(), SymDtype::Empty), + IdentKind::Func(Dim::Scalar, SymDtype::Empty), Source { virtual_: true, ..Default::default() @@ -674,7 +674,7 @@ mod test { let sym1_node = asg .declare( sym1, - IdentKind::Func(Dim::default(), SymDtype::Empty), + IdentKind::Func(Dim::Scalar, SymDtype::Empty), Source { virtual_: true, ..Default::default() @@ -696,7 +696,7 @@ mod test { let sym3_node = asg .declare( sym3, - IdentKind::Func(Dim::default(), SymDtype::Empty), + IdentKind::Func(Dim::Scalar, SymDtype::Empty), Source { virtual_: true, ..Default::default() @@ -737,7 +737,7 @@ mod test { let sym_node = asg .declare( sym, - IdentKind::Func(Dim::default(), SymDtype::Empty), + IdentKind::Func(Dim::Scalar, SymDtype::Empty), Source { virtual_: true, ..Default::default() @@ -747,7 +747,7 @@ mod test { asg.declare( dep, - IdentKind::Func(Dim::default(), SymDtype::Empty), + IdentKind::Func(Dim::Scalar, SymDtype::Empty), Source { virtual_: true, ..Default::default() @@ -795,7 +795,7 @@ mod test { let sym2_node = asg .declare( sym2, - IdentKind::Func(Dim::default(), SymDtype::Empty), + IdentKind::Func(Dim::Scalar, SymDtype::Empty), Source { virtual_: true, ..Default::default() diff --git a/tamer/src/ld/xmle/section.rs b/tamer/src/ld/xmle/section.rs index f571f02c..1f60c814 100644 --- a/tamer/src/ld/xmle/section.rs +++ b/tamer/src/ld/xmle/section.rs @@ -288,7 +288,7 @@ mod test { let a = IdentObject::IdentFragment( "a".intern(), - IdentKind::Const(Dim::from_u8(0), SymDtype::Integer), + IdentKind::Const(Dim::Scalar, SymDtype::Integer), Default::default(), "fraga".intern(), ); @@ -327,19 +327,19 @@ mod test { let cgen = IdentObject::Ident( "cgen".intern(), - IdentKind::Cgen(Dim::from_u8(1)), + IdentKind::Cgen(Dim::Vector), Default::default(), ); let gen = IdentObject::Ident( "gen".intern(), - IdentKind::Gen(Dim::from_u8(1), SymDtype::Integer), + IdentKind::Gen(Dim::Vector, SymDtype::Integer), Default::default(), ); let lparam = IdentObject::Ident( "lparam".intern(), - IdentKind::Lparam(Dim::from_u8(1), SymDtype::Integer), + IdentKind::Lparam(Dim::Vector, SymDtype::Integer), Default::default(), ); @@ -434,13 +434,13 @@ mod test { let mut sut = Sections::new(); add_syms!(sut, { - cgen: IdentKind::Cgen(Dim::from_u8(1)), - class: IdentKind::Class(Dim::from_u8(2)), - const_: IdentKind::Const(Dim::from_u8(0), SymDtype::Boolean), - func: IdentKind::Func(Dim::from_u8(1), SymDtype::Integer), - gen: IdentKind::Gen(Dim::from_u8(1), SymDtype::Boolean), - lparam: IdentKind::Lparam(Dim::from_u8(2), SymDtype::Float), - param: IdentKind::Param(Dim::from_u8(0), SymDtype::Integer), + cgen: IdentKind::Cgen(Dim::Scalar), + class: IdentKind::Class(Dim::Matrix), + const_: IdentKind::Const(Dim::Scalar, SymDtype::Boolean), + func: IdentKind::Func(Dim::Vector, SymDtype::Integer), + gen: IdentKind::Gen(Dim::Vector, SymDtype::Boolean), + lparam: IdentKind::Lparam(Dim::Matrix, SymDtype::Float), + param: IdentKind::Param(Dim::Scalar, SymDtype::Integer), rate: IdentKind::Rate(SymDtype::Integer), tpl: IdentKind::Tpl, ty: IdentKind::Type(SymDtype::Integer), diff --git a/tamer/src/ld/xmle/xir/test.rs b/tamer/src/ld/xmle/xir/test.rs index 74ee46e5..8b24bf58 100644 --- a/tamer/src/ld/xmle/xir/test.rs +++ b/tamer/src/ld/xmle/xir/test.rs @@ -80,7 +80,7 @@ fn test_writes_deps() -> TestResult { let objs = [ IdentObject::Ident( "cgentest".intern(), - IdentKind::Cgen(Dim::from_u8(1)), + IdentKind::Cgen(Dim::Vector), Source { yields: Some("yieldsValue".intern()), parent: Some("cparent".intern()), @@ -91,32 +91,32 @@ fn test_writes_deps() -> TestResult { ), IdentObject::Ident( "classtest".intern(), - IdentKind::Class(Dim::from_u8(2)), + IdentKind::Class(Dim::Matrix), Default::default(), ), IdentObject::Ident( "consttest".intern(), - IdentKind::Const(Dim::from_u8(0), SymDtype::Boolean), + IdentKind::Const(Dim::Scalar, SymDtype::Boolean), Default::default(), ), IdentObject::Ident( "functest".intern(), - IdentKind::Func(Dim::from_u8(1), SymDtype::Integer), + IdentKind::Func(Dim::Matrix, SymDtype::Integer), Default::default(), ), IdentObject::Ident( "gentest".intern(), - IdentKind::Gen(Dim::from_u8(1), SymDtype::Boolean), + IdentKind::Gen(Dim::Matrix, SymDtype::Boolean), Default::default(), ), IdentObject::Ident( "lparamtest".intern(), - IdentKind::Gen(Dim::from_u8(2), SymDtype::Float), + IdentKind::Gen(Dim::Matrix, SymDtype::Float), Default::default(), ), IdentObject::Ident( "paramtest".intern(), - IdentKind::Gen(Dim::from_u8(0), SymDtype::Integer), + IdentKind::Gen(Dim::Scalar, SymDtype::Integer), Default::default(), ), IdentObject::Ident( @@ -484,4 +484,4 @@ macro_rules! test_exec_sec { test_exec_sec!(test_map_exec, QN_L_MAP_EXEC, IdentKind::Map); test_exec_sec!(test_retmap_exec, QN_L_RETMAP_EXEC, IdentKind::RetMap); test_exec_sec!(test_static, QN_L_STATIC, IdentKind::Worksheet); -test_exec_sec!(test_exec, QN_L_EXEC, IdentKind::Class(Dim::from_u8(1))); +test_exec_sec!(test_exec, QN_L_EXEC, IdentKind::Class(Dim::Vector));