mech_core/program/compiler/
mod.rs

1use crate::*;
2use byteorder::{LittleEndian, WriteBytesExt, ReadBytesExt};
3use std::io::Cursor;
4#[cfg(not(feature = "no_std"))]
5use std::collections::HashSet;
6#[cfg(feature = "no_std")]
7use hashbrown::HashSet;
8
9pub mod sections;
10pub mod constants;
11pub mod context;
12
13pub use self::sections::*;
14pub use self::constants::*;
15pub use self::context::*;
16
17pub type Register = u32;
18
19pub fn encode_value_kind(ts: &mut TypeSection, vk: &ValueKind) -> (TypeTag, Vec<u8>) {
20  let mut b = Vec::new();
21  let tag = match vk {
22    ValueKind::U8 => TypeTag::U8, ValueKind::U16 => TypeTag::U16, ValueKind::U32 => TypeTag::U32,
23    ValueKind::U64 => TypeTag::U64, ValueKind::U128 => TypeTag::U128,
24    ValueKind::I8 => TypeTag::I8, ValueKind::I16 => TypeTag::I16, ValueKind::I32 => TypeTag::I32,
25    ValueKind::I64 => TypeTag::I64, ValueKind::I128 => TypeTag::I128,
26    ValueKind::F32 => TypeTag::F32, ValueKind::F64 => TypeTag::F64,
27    ValueKind::ComplexNumber => TypeTag::ComplexNumber,
28    ValueKind::RationalNumber => TypeTag::RationalNumber,
29    ValueKind::String => TypeTag::String,
30    ValueKind::Bool => TypeTag::Bool,
31    ValueKind::Id => TypeTag::Id,
32    ValueKind::Index => TypeTag::Index,
33    ValueKind::Empty => TypeTag::Empty,
34    ValueKind::Any => TypeTag::Any,
35
36    ValueKind::Matrix(elem, dims) => {
37      let elem_id = ts.get_or_intern(elem);
38      b.write_u32::<LittleEndian>(elem_id).unwrap();
39      b.write_u32::<LittleEndian>(dims.len() as u32).unwrap();
40      for &d in dims { b.write_u32::<LittleEndian>(d as u32).unwrap(); }
41      TypeTag::Matrix
42    }
43
44    ValueKind::Enum(space) => {
45      b.write_u64::<LittleEndian>(*space).unwrap();
46      TypeTag::EnumTag
47    }
48
49    ValueKind::Record(fields) => {
50      b.write_u32::<LittleEndian>(fields.len() as u32).unwrap();
51      for (name, ty) in fields {
52        let name_bytes = name.as_bytes();
53        b.write_u32::<LittleEndian>(name_bytes.len() as u32).unwrap();
54        b.extend_from_slice(name_bytes);
55        let tid = ts.get_or_intern(ty);
56        b.write_u32::<LittleEndian>(tid).unwrap();
57      }
58      TypeTag::Record
59    }
60
61    ValueKind::Map(k,v) => {
62      let kid = ts.get_or_intern(k);
63      let vid = ts.get_or_intern(v);
64      b.write_u32::<LittleEndian>(kid).unwrap();
65      b.write_u32::<LittleEndian>(vid).unwrap();
66      TypeTag::Map
67    }
68
69    ValueKind::Atom(id) => {
70      b.write_u64::<LittleEndian>(*id).unwrap();
71      TypeTag::Atom
72    }
73
74    ValueKind::Table(cols, pk_col) => {
75      b.write_u32::<LittleEndian>(cols.len() as u32).unwrap();
76      for (name, ty) in cols {
77        let name_b = name.as_bytes();
78        b.write_u32::<LittleEndian>(name_b.len() as u32).unwrap();
79        b.extend_from_slice(name_b);
80        let tid = ts.get_or_intern(ty);
81        b.write_u32::<LittleEndian>(tid).unwrap();
82      }
83      b.write_u32::<LittleEndian>(*pk_col as u32).unwrap();
84      TypeTag::Table
85    }
86
87    ValueKind::Tuple(elems) => {
88      b.write_u32::<LittleEndian>(elems.len() as u32).unwrap();
89      for t in elems {
90        let tid = ts.get_or_intern(t);
91        b.write_u32::<LittleEndian>(tid).unwrap();
92      }
93      TypeTag::Tuple
94    }
95
96    ValueKind::Reference(inner) => {
97      let id = ts.get_or_intern(inner);
98      b.write_u32::<LittleEndian>(id).unwrap();
99      TypeTag::Reference
100    }
101
102    ValueKind::Set(elem, max) => {
103      let id = ts.get_or_intern(elem);
104      b.write_u32::<LittleEndian>(id).unwrap();
105      match max {
106        Some(m) => { b.push(1); use byteorder::WriteBytesExt; b.write_u32::<LittleEndian>(*m as u32).unwrap(); }
107        None => { b.push(0); }
108      }
109      TypeTag::Set
110    }
111
112    ValueKind::Option(inner) => {
113      let id = ts.get_or_intern(inner);
114      b.write_u32::<LittleEndian>(id).unwrap();
115      TypeTag::OptionT
116    }
117  };
118  (tag, b)
119}