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::Kind(kind) => {
23      let kind_id = ts.get_or_intern(kind);
24      b.write_u32::<LittleEndian>(kind_id).unwrap();
25      TypeTag::Kind
26    },
27    ValueKind::U8 => TypeTag::U8, ValueKind::U16 => TypeTag::U16, ValueKind::U32 => TypeTag::U32,
28    ValueKind::U64 => TypeTag::U64, ValueKind::U128 => TypeTag::U128,
29    ValueKind::I8 => TypeTag::I8, ValueKind::I16 => TypeTag::I16, ValueKind::I32 => TypeTag::I32,
30    ValueKind::I64 => TypeTag::I64, ValueKind::I128 => TypeTag::I128,
31    ValueKind::F32 => TypeTag::F32, ValueKind::F64 => TypeTag::F64,
32    ValueKind::C64 => TypeTag::C64,
33    ValueKind::R64 => TypeTag::R64,
34    ValueKind::String => TypeTag::String,
35    ValueKind::Bool => TypeTag::Bool,
36    ValueKind::Id => TypeTag::Id,
37    ValueKind::Index => TypeTag::Index,
38    ValueKind::Empty => TypeTag::Empty,
39    ValueKind::Any => TypeTag::Any,
40    ValueKind::None => TypeTag::None,
41
42    ValueKind::Matrix(elem, dims) => {
43      let elem_id = ts.get_or_intern(elem);
44      b.write_u32::<LittleEndian>(elem_id).unwrap();
45      b.write_u32::<LittleEndian>(dims.len() as u32).unwrap();
46      for &d in dims { b.write_u32::<LittleEndian>(d as u32).unwrap(); }
47      match &**elem {
48        ValueKind::U8 => TypeTag::MatrixU8,
49        ValueKind::U16 => TypeTag::MatrixU16,
50        ValueKind::U32 => TypeTag::MatrixU32,
51        ValueKind::U64 => TypeTag::MatrixU64,
52        ValueKind::U128 => TypeTag::MatrixU128,
53        ValueKind::I8 => TypeTag::MatrixI8,
54        ValueKind::I16 => TypeTag::MatrixI16,
55        ValueKind::I32 => TypeTag::MatrixI32,
56        ValueKind::I64 => TypeTag::MatrixI64,
57        ValueKind::I128 => TypeTag::MatrixI128,
58        ValueKind::F32 => TypeTag::MatrixF32,
59        ValueKind::F64 => TypeTag::MatrixF64,
60        ValueKind::C64 => TypeTag::MatrixC64,
61        ValueKind::R64 => TypeTag::MatrixR64,
62        ValueKind::String => TypeTag::MatrixString,
63        ValueKind::Bool => TypeTag::MatrixBool,
64        ValueKind::Index => TypeTag::MatrixIndex,
65        _ => panic!("Unsupported matrix element type {:?}", elem),
66      }
67    }
68
69    ValueKind::Enum(id, name) => {
70      b.write_u64::<LittleEndian>(*id).unwrap();
71      let name_bytes = name.as_bytes();
72      b.write_u32::<LittleEndian>(name_bytes.len() as u32).unwrap();
73      b.extend_from_slice(name_bytes);
74      TypeTag::EnumTag
75    }
76
77    ValueKind::Record(fields) => {
78      b.write_u32::<LittleEndian>(fields.len() as u32).unwrap();
79      for (name, ty) in fields {
80        let name_bytes = name.as_bytes();
81        b.write_u32::<LittleEndian>(name_bytes.len() as u32).unwrap();
82        b.extend_from_slice(name_bytes);
83        let tid = ts.get_or_intern(ty);
84        b.write_u32::<LittleEndian>(tid).unwrap();
85      }
86      TypeTag::Record
87    }
88
89    ValueKind::Map(k,v) => {
90      let kid = ts.get_or_intern(k);
91      let vid = ts.get_or_intern(v);
92      b.write_u32::<LittleEndian>(kid).unwrap();
93      b.write_u32::<LittleEndian>(vid).unwrap();
94      TypeTag::Map
95    }
96
97    ValueKind::Atom(id, name) => {
98      b.write_u64::<LittleEndian>(*id).unwrap();
99      let name_bytes = name.as_bytes();
100      b.write_u32::<LittleEndian>(name_bytes.len() as u32).unwrap();
101      b.extend_from_slice(name_bytes);
102      TypeTag::Atom
103    }
104
105    ValueKind::Table(cols, pk_col) => {
106      b.write_u32::<LittleEndian>(cols.len() as u32).unwrap();
107      for (name, ty) in cols {
108        let name_b = name.as_bytes();
109        b.write_u32::<LittleEndian>(name_b.len() as u32).unwrap();
110        b.extend_from_slice(name_b);
111        let tid = ts.get_or_intern(ty);
112        b.write_u32::<LittleEndian>(tid).unwrap();
113      }
114      b.write_u32::<LittleEndian>(*pk_col as u32).unwrap();
115      TypeTag::Table
116    }
117
118    ValueKind::Tuple(elems) => {
119      b.write_u32::<LittleEndian>(elems.len() as u32).unwrap();
120      for t in elems {
121        let tid = ts.get_or_intern(t);
122        b.write_u32::<LittleEndian>(tid).unwrap();
123      }
124      TypeTag::Tuple
125    }
126
127    ValueKind::Reference(inner) => {
128      let id = ts.get_or_intern(inner);
129      b.write_u32::<LittleEndian>(id).unwrap();
130      TypeTag::Reference
131    }
132
133    ValueKind::Set(elem, max) => {
134      let id = ts.get_or_intern(elem);
135      b.write_u32::<LittleEndian>(id).unwrap();
136      match max {
137        Some(m) => { b.push(1); use byteorder::WriteBytesExt; b.write_u32::<LittleEndian>(*m as u32).unwrap(); }
138        None => { b.push(0); }
139      }
140      TypeTag::Set
141    }
142
143    ValueKind::Option(inner) => {
144      let id = ts.get_or_intern(inner);
145      b.write_u32::<LittleEndian>(id).unwrap();
146      TypeTag::OptionT
147    }
148  };
149  (tag, b)
150}