Skip to main content

mech_core/
kind.rs

1use crate::*;
2
3// Kind -----------------------------------------------------------------------
4
5#[derive(Clone, Debug, PartialEq, Eq, Hash)]
6pub enum Kind {
7  Any,
8  None,
9  Atom(u64, String),
10  Empty,
11  Enum(u64, String),
12  //Fsm(Vec<Kind>,Vec<Kind>),
13  //Function(Vec<Kind>,Vec<Kind>),
14  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}