1use crate::*;
2
3#[derive(Clone, Debug, PartialEq, Eq, Hash)]
6pub enum Kind {
7 Any,
8 None,
9 Atom(u64, String),
10 Empty,
11 Enum(u64, String),
12 Id,
15 Index,
16 Map(Box<Kind>,Box<Kind>),
17 Matrix(Box<Kind>,Vec<usize>),
18 Option(Box<Kind>),
19 Record((Vec<(String,Kind)>)),
20 Reference(Box<Kind>),
21 Scalar(u64),
22 Set(Box<Kind>,Option<usize>),
23 Table(Vec<(String,Kind)>,usize),
24 Tuple(Vec<Kind>),
25 Kind(Box<Kind>),
26}
27
28impl Kind {
29
30 #[cfg(feature = "kind_annotation")]
31 pub fn to_value(&self, kinds: &KindTable) -> MResult<Value> {
32 let value_kind = self.to_value_kind(kinds)?;
33 Ok(Value::Kind(value_kind))
34 }
35
36 #[cfg(feature = "kind_annotation")]
37 pub fn to_value_kind(&self, kinds: &KindTable) -> MResult<ValueKind> {
38 match self {
39 Kind::Kind(kind) => {
40 let val_knd = kind.to_value_kind(kinds)?;
41 Ok(ValueKind::Kind(Box::new(val_knd)))
42 },
43 Kind::None => Ok(ValueKind::None),
44 Kind::Any => Ok(ValueKind::Any),
45 Kind::Empty => Ok(ValueKind::Empty),
46 Kind::Atom(id, name) => Ok(ValueKind::Atom(*id, name.clone())),
47 Kind::Enum(id, name) => Ok(ValueKind::Enum(*id, name.clone())),
48 Kind::Id => Ok(ValueKind::Id),
49 Kind::Index => Ok(ValueKind::Index),
50 Kind::Map(keys, vals) => {
51 let key_knd = keys.to_value_kind(kinds)?;
52 let val_knd = vals.to_value_kind(kinds)?;
53 Ok(ValueKind::Map(Box::new(key_knd), Box::new(val_knd)))
54 },
55 Kind::Matrix(knd, size) => {
56 let val_knd = knd.to_value_kind(kinds)?;
57 Ok(ValueKind::Matrix(Box::new(val_knd), size.clone()))
58 },
59 Kind::Option(knd) => {
60 let val_knd = knd.to_value_kind(kinds)?;
61 Ok(ValueKind::Option(Box::new(val_knd)))
62 },
63 Kind::Record(elements) => {
64 let val_knds: Vec<(String, ValueKind)> = elements.iter()
65 .map(|(id, k)| k.to_value_kind(kinds).map(|kind| (id.clone(), kind)))
66 .collect::<MResult<_>>()?;
67 Ok(ValueKind::Record(val_knds))
68 },
69 Kind::Reference(kind) => {
70 let val_knd = kind.to_value_kind(kinds)?;
71 Ok(ValueKind::Reference(Box::new(val_knd)))
72 },
73 Kind::Scalar(id) => {
74 match kinds.get(id).cloned() {
75 Some(val_knd) => Ok(val_knd),
76 None => Err(
77 MechError::new(
78 UndefinedKindError { kind_id: *id },
79 None,
80 )
81 .with_compiler_loc()
82 ),
83 }
84 },
85 Kind::Set(kind, size) => {
86 let val_knd = kind.to_value_kind(kinds)?;
87 Ok(ValueKind::Set(Box::new(val_knd), *size))
88 },
89 Kind::Table(elements, size) => {
90 let val_knds: Vec<(String, ValueKind)> = elements.iter()
91 .map(|(id, k)| k.to_value_kind(kinds).map(|kind| (id.clone(), kind)))
92 .collect::<MResult<_>>()?;
93 Ok(ValueKind::Table(val_knds, *size))
94 },
95 Kind::Tuple(elements) => {
96 let val_knds = elements.iter().map(|k| k.to_value_kind(kinds)).collect::<MResult<Vec<ValueKind>>>()?;
97 Ok(ValueKind::Tuple(val_knds))
98 }
99 }
100 }
101}