tamer: Move Dim and {Sym=>}Dtype into num module

A previous commit mentioned that there's not a place for `Dim`, and
duplicated it between `asg` and `xmlo`.  Well, `Dtype` is also needed in
both, and so here's a home for now.

`Dtype` has always been an inappropriate detail for the system and will one
day be removed entirely in favor of higher-level types; the machine
representation is up to the compiler to decide.

DEV-11864
main
Mike Gerwitz 2022-05-19 10:09:49 -04:00
parent b2a79e930b
commit 07d2ec1ffb
15 changed files with 183 additions and 197 deletions

View File

@ -22,9 +22,10 @@
extern crate tamer;
extern crate test;
use tamer::num::Dtype;
use test::Bencher;
use tamer::asg::{DataType, DefaultAsg, IdentKind, Source};
use tamer::asg::{DefaultAsg, IdentKind, Source};
use tamer::ld::xmle::{lower::sort, Sections};
use tamer::sym::{GlobalSymbolIntern, SymbolId};
@ -44,7 +45,7 @@ fn sort_1_with_1_000_existing_supernode(bench: &mut Bencher) {
.map(|sym| {
sut.declare(
*sym,
IdentKind::Rate(DataType::Integer),
IdentKind::Rate(Dtype::Integer),
Source::default(),
)
.unwrap()
@ -75,7 +76,7 @@ fn sort_1_with_1_000_existing_one_edge_per_node_one_path(bench: &mut Bencher) {
.map(|sym| {
sut.declare(
*sym,
IdentKind::Rate(DataType::Integer),
IdentKind::Rate(Dtype::Integer),
Source::default(),
)
.unwrap()

View File

@ -444,7 +444,7 @@ impl From<ObjectRef> for NodeIndex {
mod test {
use super::super::error::AsgError;
use super::*;
use crate::asg::Dim;
use crate::num::Dim;
use crate::sym::GlobalSymbolIntern;
use std::assert_matches::assert_matches;

View File

@ -19,8 +19,10 @@
//! Identifiers (a type of [object][super::object::IdentObject]).
use crate::obj::xmlo::SymDtype;
use crate::sym::{st, GlobalSymbolResolve, SymbolId};
use crate::{
num::{Dim, Dtype},
sym::{st, GlobalSymbolResolve, SymbolId},
};
/// Types of identifiers.
///
@ -46,21 +48,21 @@ pub enum IdentKind {
Class(Dim),
/// Constant value.
Const(Dim, DataType),
Const(Dim, Dtype),
/// Re-usable encapsulated expression.
///
/// Functions are nothing more than expressions that can be re-used with
/// dynamic values at runtime.
/// See also [`Lparam`][IdentKind::Lparam].
Func(Dim, DataType),
Func(Dim, Dtype),
/// Generating calculation.
///
/// Generators are associated with iterative expressions,
/// such as sums and products.
/// They always have a parent [`Rate`][IdentKind::Rate].
Gen(Dim, DataType),
Gen(Dim, Dtype),
/// Local (non-global) parameter.
///
@ -71,13 +73,13 @@ pub enum IdentKind {
///
/// This is not to be confused with the global
/// [`Param`][IdentKind::Param].
Lparam(Dim, DataType),
Lparam(Dim, Dtype),
/// Global parameter.
///
/// These parameters serve as inputs to the system.
/// Input values are bound using [`Map`][IdentKind::Map].
Param(Dim, DataType),
Param(Dim, Dtype),
/// Scalar result of a named calculation.
///
@ -86,7 +88,7 @@ pub enum IdentKind {
/// This represents a named expression that yields a scalar value.
///
/// This serves as a parent to [`Gen`][IdentKind::Gen].
Rate(DataType),
Rate(Dtype),
/// Template definition.
///
@ -100,8 +102,8 @@ pub enum IdentKind {
/// The only types typically defined are enums and unions of enums.
/// The type itself has no runtime value,
/// but each of the enum variants have an associated value of type
/// [`DataType`].
Type(DataType),
/// [`Dtype`].
Type(Dtype),
/// Input map head (meta identifier generated by compiler for each input
/// map).
@ -189,10 +191,10 @@ impl std::fmt::Display for IdentKind {
match self {
Self::Cgen(dim) => {
write!(fmt, "{}[{}; {}]", name, DataType::Boolean, dim)
write!(fmt, "{}[{}; {}]", name, Dtype::Boolean, dim)
}
Self::Class(dim) => {
write!(fmt, "{}[{}; {}]", name, DataType::Boolean, dim)
write!(fmt, "{}[{}; {}]", name, Dtype::Boolean, dim)
}
Self::Const(dim, dtype) => {
write!(fmt, "{}[{}; {}]", name, dtype, dim)
@ -215,36 +217,3 @@ impl std::fmt::Display for IdentKind {
}
}
}
/// 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 From<Dim> for u8 {
fn from(dim: Dim) -> Self {
dim as u8
}
}
impl From<Dim> for SymbolId {
fn from(dim: Dim) -> Self {
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 as u8).fmt(fmt)
}
}
/// Underlying datatype of identifier.
pub type DataType = SymDtype;

View File

@ -198,7 +198,7 @@ mod object;
pub use error::AsgError;
pub use graph::{Asg, AsgResult, IndexType, ObjectRef};
pub use ident::{DataType, Dim, IdentKind};
pub use ident::IdentKind;
pub use object::{
FragmentText, IdentObject, Source, TransitionError, TransitionResult,
UnresolvedError,

View File

@ -652,8 +652,8 @@ impl From<SymAttrs> for Source {
#[cfg(test)]
mod test {
use super::super::ident::Dim;
use super::*;
use crate::num::Dim;
use crate::sym::{GlobalSymbolIntern, SymbolId};
// Note that IdentObject has no variants capable of None

View File

@ -169,9 +169,9 @@ impl std::error::Error for SortError {
mod test {
use super::*;
use crate::{
asg::{Dim, FragmentText, IdentObject, Source},
asg::{FragmentText, IdentObject, Source},
ld::xmle::{section::PushResult, Sections},
obj::xmlo::SymDtype,
num::{Dim, Dtype},
sym::GlobalSymbolIntern,
};
@ -632,7 +632,7 @@ mod test {
let sym3_node = asg
.declare(
sym3,
IdentKind::Func(Dim::Scalar, SymDtype::Empty),
IdentKind::Func(Dim::Scalar, Dtype::Empty),
Source {
virtual_: true,
..Default::default()
@ -674,7 +674,7 @@ mod test {
let sym1_node = asg
.declare(
sym1,
IdentKind::Func(Dim::Scalar, SymDtype::Empty),
IdentKind::Func(Dim::Scalar, Dtype::Empty),
Source {
virtual_: true,
..Default::default()
@ -696,7 +696,7 @@ mod test {
let sym3_node = asg
.declare(
sym3,
IdentKind::Func(Dim::Scalar, SymDtype::Empty),
IdentKind::Func(Dim::Scalar, Dtype::Empty),
Source {
virtual_: true,
..Default::default()
@ -737,7 +737,7 @@ mod test {
let sym_node = asg
.declare(
sym,
IdentKind::Func(Dim::Scalar, SymDtype::Empty),
IdentKind::Func(Dim::Scalar, Dtype::Empty),
Source {
virtual_: true,
..Default::default()
@ -747,7 +747,7 @@ mod test {
asg.declare(
dep,
IdentKind::Func(Dim::Scalar, SymDtype::Empty),
IdentKind::Func(Dim::Scalar, Dtype::Empty),
Source {
virtual_: true,
..Default::default()
@ -795,7 +795,7 @@ mod test {
let sym2_node = asg
.declare(
sym2,
IdentKind::Func(Dim::Scalar, SymDtype::Empty),
IdentKind::Func(Dim::Scalar, Dtype::Empty),
Source {
virtual_: true,
..Default::default()

View File

@ -264,8 +264,8 @@ impl std::fmt::Display for SectionsError {
#[cfg(test)]
mod test {
use super::*;
use crate::asg::{Dim, IdentKind, IdentObject, Source};
use crate::obj::xmlo::SymDtype;
use crate::asg::{IdentKind, IdentObject, Source};
use crate::num::{Dim, Dtype};
use crate::sym::GlobalSymbolIntern;
type Sut<'a> = Sections<'a>;
@ -288,7 +288,7 @@ mod test {
let a = IdentObject::IdentFragment(
"a".intern(),
IdentKind::Const(Dim::Scalar, SymDtype::Integer),
IdentKind::Const(Dim::Scalar, Dtype::Integer),
Default::default(),
"fraga".intern(),
);
@ -333,13 +333,13 @@ mod test {
let gen = IdentObject::Ident(
"gen".intern(),
IdentKind::Gen(Dim::Vector, SymDtype::Integer),
IdentKind::Gen(Dim::Vector, Dtype::Integer),
Default::default(),
);
let lparam = IdentObject::Ident(
"lparam".intern(),
IdentKind::Lparam(Dim::Vector, SymDtype::Integer),
IdentKind::Lparam(Dim::Vector, Dtype::Integer),
Default::default(),
);
@ -436,14 +436,14 @@ mod test {
add_syms!(sut, {
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),
const_: IdentKind::Const(Dim::Scalar, Dtype::Boolean),
func: IdentKind::Func(Dim::Vector, Dtype::Integer),
gen: IdentKind::Gen(Dim::Vector, Dtype::Boolean),
lparam: IdentKind::Lparam(Dim::Matrix, Dtype::Float),
param: IdentKind::Param(Dim::Scalar, Dtype::Integer),
rate: IdentKind::Rate(Dtype::Integer),
tpl: IdentKind::Tpl,
ty: IdentKind::Type(SymDtype::Integer),
ty: IdentKind::Type(Dtype::Integer),
maphead: IdentKind::MapHead,
map: IdentKind::Map,
maptail: IdentKind::MapTail,

View File

@ -20,11 +20,11 @@
use super::*;
use crate::ld::xmle::section::PushResult;
use crate::ld::xmle::Sections;
use crate::obj::xmlo::SymDtype;
use crate::num::{Dim, Dtype};
use crate::sym::{GlobalSymbolIntern, GlobalSymbolResolve};
use crate::xir::tree::merge_attr_fragments;
use crate::{
asg::{Dim, IdentKind, Source},
asg::{IdentKind, Source},
xir::{
pred::{not, open},
tree::parser_from,
@ -96,32 +96,32 @@ fn test_writes_deps() -> TestResult {
),
IdentObject::Ident(
"consttest".intern(),
IdentKind::Const(Dim::Scalar, SymDtype::Boolean),
IdentKind::Const(Dim::Scalar, Dtype::Boolean),
Default::default(),
),
IdentObject::Ident(
"functest".intern(),
IdentKind::Func(Dim::Matrix, SymDtype::Integer),
IdentKind::Func(Dim::Matrix, Dtype::Integer),
Default::default(),
),
IdentObject::Ident(
"gentest".intern(),
IdentKind::Gen(Dim::Matrix, SymDtype::Boolean),
IdentKind::Gen(Dim::Matrix, Dtype::Boolean),
Default::default(),
),
IdentObject::Ident(
"lparamtest".intern(),
IdentKind::Gen(Dim::Matrix, SymDtype::Float),
IdentKind::Gen(Dim::Matrix, Dtype::Float),
Default::default(),
),
IdentObject::Ident(
"paramtest".intern(),
IdentKind::Gen(Dim::Scalar, SymDtype::Integer),
IdentKind::Gen(Dim::Scalar, Dtype::Integer),
Default::default(),
),
IdentObject::Ident(
"ratetest".intern(),
IdentKind::Rate(SymDtype::Integer),
IdentKind::Rate(Dtype::Integer),
Default::default(),
),
IdentObject::Ident(
@ -131,7 +131,7 @@ fn test_writes_deps() -> TestResult {
),
IdentObject::Ident(
"typetest".intern(),
IdentKind::Type(SymDtype::Integer),
IdentKind::Type(Dtype::Integer),
Default::default(),
),
IdentObject::Ident(

View File

@ -85,6 +85,7 @@ pub mod diagnose;
pub mod fs;
pub mod iter;
pub mod ld;
pub mod num;
pub mod obj;
pub mod parse;
pub mod span;

92
tamer/src/num.rs 100644
View File

@ -0,0 +1,92 @@
// General numberic types for TAMER
//
// Copyright (C) 2014-2022 Ryan Specialty Group, LLC.
//
// This file is part of TAME.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//! General numeric types used throughout the system.
use crate::sym::{st, SymbolId};
/// Value dimensionality.
///
/// This indicates the number of subscripts needed to access a scalar
/// value.
/// This the value
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum Dim {
Scalar = 0,
Vector = 1,
Matrix = 2,
}
impl From<Dim> for u8 {
fn from(dim: Dim) -> Self {
dim as u8
}
}
impl From<Dim> for SymbolId {
fn from(dim: Dim) -> Self {
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 as u8).fmt(fmt)
}
}
/// Machine representation of scalar data.
///
/// _NB: This was not enforced by the XSLT-based compiler._
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum Dtype {
/// {⊥,} = {0,1} ⊂ ℤ
Boolean,
///
Integer,
///
Float,
/// ∅
Empty,
}
impl Dtype {
pub fn as_sym(&self) -> SymbolId {
match self {
Dtype::Boolean => st::L_BOOLEAN,
Dtype::Integer => st::L_INTEGER,
Dtype::Float => st::L_FLOAT,
Dtype::Empty => st::L_EMPTY,
}
.as_sym()
}
}
impl Into<SymbolId> for Dtype {
fn into(self) -> SymbolId {
self.as_sym()
}
}
impl std::fmt::Display for Dtype {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(fmt, "{}", self.as_sym())
}
}

View File

@ -39,10 +39,12 @@
use super::{
reader::{XmloResult, XmloToken},
Dim, SymAttrs, SymType, XmloError,
SymAttrs, SymType, XmloError,
};
use crate::{
asg::{Asg, AsgError, IdentKind, Source},
sym::SymbolId,
};
use crate::asg::{Asg, AsgError, Dim as AsgDim, IdentKind, Source};
use crate::sym::SymbolId;
use std::convert::TryInto;
use std::error::Error;
use std::fmt::Display;
@ -350,14 +352,14 @@ impl TryFrom<&SymAttrs> for IdentKind {
Ok($to)
};
($to:expr, dim) => {
Ok($to(attrs.dim.ok_or(Self::Error::MissingDim)?.into()))
Ok($to(attrs.dim.ok_or(Self::Error::MissingDim)?))
};
($to:expr, dtype) => {
Ok($to(attrs.dtype.ok_or(Self::Error::MissingDtype)?))
};
($to:expr, dim, dtype) => {
Ok($to(
attrs.dim.ok_or(Self::Error::MissingDim)?.into(),
attrs.dim.ok_or(Self::Error::MissingDim)?,
attrs.dtype.ok_or(Self::Error::MissingDtype)?,
))
};
@ -414,25 +416,13 @@ impl Error for IdentKindError {
}
}
// These are clearly the same thing,
// but it's not worth sharing them until a natural shared abstraction
// arises.
impl From<Dim> for AsgDim {
fn from(dim: Dim) -> Self {
match dim {
Dim::Scalar => AsgDim::Scalar,
Dim::Vector => AsgDim::Vector,
Dim::Matrix => AsgDim::Matrix,
}
}
}
// These tests are coupled with BaseAsg, which is not ideal.
#[cfg(test)]
mod test {
use super::*;
use crate::asg::{DefaultAsg, FragmentText, IdentKind, IdentObject};
use crate::obj::xmlo::{SymAttrs, SymDtype, SymType};
use crate::num::{Dim, Dtype};
use crate::obj::xmlo::{SymAttrs, SymType};
use crate::span::{DUMMY_SPAN, UNKNOWN_SPAN};
use crate::sym::GlobalSymbolIntern;
use std::collections::hash_map::RandomState;
@ -982,7 +972,7 @@ mod test {
let dim = Dim::Vector;
assert_eq!(
Ok($dest(AsgDim::Vector)),
Ok($dest(Dim::Vector)),
SymAttrs {
ty: Some($src),
dim: Some(dim),
@ -1005,7 +995,7 @@ mod test {
($name:ident, $src:expr => $dest:expr, dtype) => {
#[test]
fn $name() {
let dtype = SymDtype::Float;
let dtype = Dtype::Float;
assert_eq!(
Ok($dest(dtype)),
@ -1032,10 +1022,10 @@ mod test {
#[test]
fn $name() {
let dim = Dim::Vector;
let dtype = SymDtype::Float;
let dtype = Dtype::Float;
assert_eq!(
Ok($dest(AsgDim::Vector, dtype)),
Ok($dest(Dim::Vector, dtype)),
SymAttrs {
ty: Some($src),
dim: Some(dim),

View File

@ -27,28 +27,11 @@
//! This IR should be converted into a higher-level IR quickly,
//! especially considering that it will be going away in the future.
use crate::sym::{st, GlobalSymbolResolve, SymbolId};
use crate::num::{Dim, Dtype};
use crate::sym::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
@ -85,7 +68,7 @@ pub struct SymAttrs {
/// This is not a primitive,
/// and mostly represents whether or not floating point computations
/// will take place.
pub dtype: Option<SymDtype>,
pub dtype: Option<Dtype>,
/// Whether the symbol's location will be determined at link-time.
///
@ -237,62 +220,19 @@ impl TryFrom<&[u8]> for SymType {
}
}
/// Underlying datatype.
///
/// This is the type of scalar data stored within the given symbol.
///
/// *NB:* This was _not enforced_ by the XSLT-based compiler.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum SymDtype {
/// {⊥,} = {0,1} ⊂ ℤ
Boolean,
///
Integer,
///
Float,
/// ∅
Empty,
}
impl SymDtype {
pub fn as_sym(&self) -> SymbolId {
match self {
SymDtype::Boolean => st::L_BOOLEAN,
SymDtype::Integer => st::L_INTEGER,
SymDtype::Float => st::L_FLOAT,
SymDtype::Empty => st::L_EMPTY,
}
.as_sym()
}
}
impl Into<SymbolId> for SymDtype {
fn into(self) -> SymbolId {
self.as_sym()
}
}
// TODO: Remove after xmle writer is removed
impl AsRef<str> for SymDtype {
/// Produce `xmlo`-compatible representation.
fn as_ref(&self) -> &str {
self.as_sym().lookup_str()
}
}
impl TryFrom<&[u8]> for SymDtype {
impl TryFrom<&[u8]> for Dtype {
type Error = String;
/// Determine data type from source `preproc:sym/@dtype`.
///
/// This raises source `xmlo` data into this IR.
/// See [`crate::obj::xmlo::XmloReader`].
fn try_from(value: &[u8]) -> Result<SymDtype, Self::Error> {
fn try_from(value: &[u8]) -> Result<Dtype, Self::Error> {
match value {
b"boolean" => Ok(SymDtype::Boolean),
b"integer" => Ok(SymDtype::Integer),
b"float" => Ok(SymDtype::Float),
b"empty" => Ok(SymDtype::Empty),
b"boolean" => Ok(Dtype::Boolean),
b"integer" => Ok(Dtype::Integer),
b"float" => Ok(Dtype::Float),
b"empty" => Ok(Dtype::Empty),
_ => Err(format!(
"unknown symbol dtype `{}`",
String::from_utf8(value.to_vec())
@ -302,12 +242,6 @@ impl TryFrom<&[u8]> for SymDtype {
}
}
impl std::fmt::Display for SymDtype {
fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(fmt, "{}", self.as_sym().lookup_str())
}
}
#[cfg(test)]
mod test {
use super::*;
@ -330,15 +264,12 @@ mod test {
#[test]
fn symdtype_from_u8() {
assert_eq!(
Ok(SymDtype::Integer),
SymDtype::try_from(b"integer" as &[u8])
);
assert_eq!(Ok(Dtype::Integer), Dtype::try_from(b"integer" as &[u8]));
}
#[test]
fn symdtype_failure_from_unknown_u8() {
match SymDtype::try_from(b"unknownd" as &[u8]) {
match Dtype::try_from(b"unknownd" as &[u8]) {
Err(s) => assert!(s.contains("unknownd")),
bad => panic!("expected error: {:?}", bad),
}
@ -346,7 +277,7 @@ mod test {
#[test]
fn symdtype_as_str() {
let boolean: &str = SymDtype::Boolean.as_ref();
let boolean = Dtype::Boolean.to_string();
assert_eq!("boolean", boolean);
}
}

View File

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

View File

@ -19,7 +19,8 @@
use super::{SymAttrs, XmloError};
use crate::{
obj::xmlo::{Dim, SymDtype, SymType},
num::{Dim, Dtype},
obj::xmlo::SymType,
parse::{
self, EmptyContext, NoContext, ParseState, Transition,
TransitionResult, Transitionable,
@ -470,14 +471,14 @@ impl SymtableState {
}
/// Parse a `preproc:sym/@dtype` attribute.
fn parse_dtype(value: SymbolId) -> Option<SymDtype> {
fn parse_dtype(value: SymbolId) -> Option<Dtype> {
use raw::*;
match value {
L_BOOLEAN => Some(SymDtype::Boolean),
L_INTEGER => Some(SymDtype::Integer),
L_FLOAT => Some(SymDtype::Float),
L_EMPTY => Some(SymDtype::Empty),
L_BOOLEAN => Some(Dtype::Boolean),
L_INTEGER => Some(Dtype::Integer),
L_FLOAT => Some(Dtype::Float),
L_EMPTY => Some(Dtype::Empty),
_ => None,
}
}

View File

@ -22,7 +22,8 @@ use std::assert_matches::assert_matches;
use super::*;
use crate::{
convert::ExpectInto,
obj::xmlo::{SymDtype, SymType},
num::Dtype,
obj::xmlo::SymType,
parse::{ParseError, ParseState, Parsed},
span::{Span, DUMMY_SPAN},
sym::GlobalSymbolIntern,
@ -243,22 +244,22 @@ symtable_tests! {
)
dtyboolean: [dtype="boolean"] => Ok(SymAttrs {
dtype: Some(SymDtype::Boolean),
dtype: Some(Dtype::Boolean),
..Default::default()
})
dtyinteger: [dtype="integer"] => Ok(SymAttrs {
dtype: Some(SymDtype::Integer),
dtype: Some(Dtype::Integer),
..Default::default()
})
dtyfloat: [dtype="float"] => Ok(SymAttrs {
dtype: Some(SymDtype::Float),
dtype: Some(Dtype::Float),
..Default::default()
})
dtyempty: [dtype="empty"] => Ok(SymAttrs {
dtype: Some(SymDtype::Empty),
dtype: Some(Dtype::Empty),
..Default::default()
})
@ -311,7 +312,7 @@ symtable_tests! {
src: Some("foo".intern()),
ty: Some(SymType::Class),
dim: Some(Dim::Vector),
dtype: Some(SymDtype::Float),
dtype: Some(Dtype::Float),
extern_: true,
..Default::default()
})