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