1use std::collections::{HashMap, HashSet};
2use std::{u16, u32};
3
4use byteorder::{ByteOrder, LE};
5use gc::Trace;
6use oftlisp::{CompilerContext, Symbol, Value};
7use oftlisp::ast::Args;
8use oftlisp::modules::ExportedModule;
9use smallvec::SmallVec;
10
11use errors::CompileError;
12use types::{Context, Expr, Prim};
13
14const ANFIR_VERSION: u32 = 0x001_00_000;
15
16impl CompilerContext for Context {
17 type CompileError = CompileError;
18
19 fn compile(main_module: Symbol, mut exported_modules: HashMap<Symbol, ExportedModule<Self>>) -> Result<Vec<u8>, Self::CompileError> {
20 let mut modules = vec![];
23 let mut moved = HashSet::new();
24 move_modules(main_module, &mut exported_modules, &mut modules, &mut moved)?;
25
26 for (name, _) in exported_modules {
28 warn!("Unused module: {}", name);
29 }
30
31 if modules.len() > u32::MAX as usize {
33 return Err(CompileError::TooManyModules);
34 }
35 let num_modules = modules.len() as u32;
36
37 let mut buf = vec![0; 8];
39 LE::write_u32(&mut buf[0..4], ANFIR_VERSION);
40 LE::write_u32(&mut buf[4..8], num_modules);
41 for (name, m) in modules {
42 serialize_module(name, &m, &mut buf)?;
43 }
44 Ok(buf)
45 }
46}
47
48fn move_modules(name: Symbol, exported: &mut HashMap<Symbol, ExportedModule<Context>>, modules: &mut Vec<(Symbol, ExportedModule<Context>)>, moved: &mut HashSet<Symbol>) -> Result<(), CompileError> {
49 if moved.contains(&name) {
50 return Ok(());
51 }
52
53 if let Some(m) = exported.remove(&name) {
54 let imports = m.imports.iter()
55 .map(|(&n, _)| n)
56 .collect::<SmallVec<[Symbol; 64]>>();
57 modules.push((name, m));
58 moved.insert(name);
59 for name in imports {
60 move_modules(name, exported, modules, moved)?;
61 }
62 Ok(())
63 } else {
64 Err(CompileError::MissingModule(name))
65 }
66}
67
68fn serialize_module(name: Symbol, m: &ExportedModule<Context>, buf: &mut Vec<u8>) -> Result<(), CompileError> {
69 let mut out = vec![];
70 name.serialize(&mut out)?;
71
72 if m.exports.len() > u32::MAX as usize {
73 return Err(CompileError::TooManyExports(name));
74 } else {
75 let mut len = [0, 0, 0, 0];
76 LE::write_u32(&mut len, m.exports.len() as u32);
77 out.extend(&len);
78 }
79 for &ex in &m.exports {
80 ex.serialize(&mut out)?;
81 }
82
83 if m.imports.len() > u32::MAX as usize {
84 return Err(CompileError::TooManyImports(name));
85 } else {
86 let mut len = [0, 0, 0, 0];
87 LE::write_u32(&mut len, m.imports.len() as u32);
88 out.extend(&len);
89 }
90 for (&im, syms) in &m.imports {
91 im.serialize(&mut out)?;
92
93 if syms.len() > u32::MAX as usize {
94 return Err(CompileError::TooManyImportedSymbols(name, im));
95 } else {
96 let mut len = [0, 0, 0, 0];
97 LE::write_u32(&mut len, syms.len() as u32);
98 out.extend(&len);
99 }
100 for &sym in syms {
101 sym.serialize(&mut out)?;
102 }
103 }
104
105 if m.body.len() > u32::MAX as usize {
106 return Err(CompileError::TooManyDecls(name));
107 } else {
108 let mut len = [0, 0, 0, 0];
109 LE::write_u32(&mut len, m.body.len() as u32);
110 out.extend(&len);
111 }
112 for &(name, ref expr) in &m.body {
113 name.serialize(&mut out)?;
114 expr.serialize(&mut out)?;
115 }
116
117 buf.extend(out);
118 Ok(())
119}
120
121trait Serializable: Trace {
122 fn serialize(&self, buf: &mut Vec<u8>) -> Result<(), CompileError>;
123}
124
125impl Serializable for Symbol {
126 fn serialize(&self, buf: &mut Vec<u8>) -> Result<(), CompileError> {
127 if self.len() > u16::MAX as usize {
128 Err(CompileError::SymbolTooLong(*self))
129 } else {
130 let s = self.as_str();
131 let mut len = [0, 0];
132 LE::write_u16(&mut len, s.len() as u16);
133 buf.extend(&len);
134 buf.extend(s.bytes());
135 Ok(())
136 }
137 }
138}
139
140impl Serializable for Option<Symbol> {
141 fn serialize(&self, buf: &mut Vec<u8>) -> Result<(), CompileError> {
142 match *self {
143 Some(sym) => sym.serialize(buf),
144 None => {
145 buf.push(0);
146 buf.push(0);
147 Ok(())
148 },
149 }
150 }
151}
152
153impl Serializable for Args<Context> {
154 fn serialize(&self, buf: &mut Vec<u8>) -> Result<(), CompileError> {
155 if self.required.len() > u16::MAX as usize {
156 return Err(CompileError::TooManyArgsInDefn);
157 } else {
158 let mut len = [0, 0];
159 LE::write_u16(&mut len, self.required.len() as u16);
160 buf.extend(&len);
161 for sym in &self.required {
162 sym.serialize(buf)?;
163 }
164 }
165
166 if self.optional.len() > u16::MAX as usize {
167 return Err(CompileError::TooManyArgsInDefn);
168 } else {
169 let mut len = [0, 0];
170 LE::write_u16(&mut len, self.optional.len() as u16);
171 buf.extend(&len);
172 for &(sym, ref val) in &self.optional {
173 sym.serialize(buf)?;
174 val.serialize(buf)?;
175 }
176 }
177
178 self.rest.serialize(buf)
179 }
180}
181
182impl Serializable for Expr {
183 fn serialize(&self, buf: &mut Vec<u8>) -> Result<(), CompileError> {
184 match *self {
185 Expr::Call(ref f, ref a) => {
186 buf.push(0x80);
187 f.serialize(buf)?;
188 if a.len() > u16::MAX as usize {
189 Err(CompileError::TooManyArgsInCall)
190 } else {
191 let mut len = [0, 0];
192 LE::write_u16(&mut len, a.len() as u16);
193 buf.extend(&len);
194 for a in a {
195 a.serialize(buf)?;
196 }
197 Ok(())
198 }
199 },
200 Expr::If(ref c, ref t, ref e) => {
201 buf.push(0xc0);
202 c.serialize(buf)?;
203 t.serialize(buf)?;
204 e.serialize(buf)
205 },
206 Expr::Let(n, ref x, ref y) => {
207 buf.push(0xf0);
208 n.serialize(buf)?;
209 x.serialize(buf)?;
210 y.serialize(buf)
211 },
212 Expr::Prim(ref prim) => prim.serialize(buf),
213 }
214 }
215}
216
217impl Serializable for Prim {
218 fn serialize(&self, buf: &mut Vec<u8>) -> Result<(), CompileError> {
219 match *self {
220 Prim::Fn(ref n, ref a, ref b) => {
221 buf.push(0x10);
222 n.serialize(buf)?;
223 a.serialize(buf)?;
224 b.serialize(buf)
225 },
226 Prim::Lit(ref v) => v.serialize(buf),
227 Prim::Var(ref n) => {
228 buf.push(0x20);
229 n.serialize(buf)
230 },
231 Prim::Vec(ref ps) => {
232 buf.push(0x30);
233 if ps.len() > u16::MAX as usize {
234 Err(CompileError::TooManyArgsInCall)
235 } else {
236 let mut len = [0, 0];
237 LE::write_u16(&mut len, ps.len() as u16);
238 buf.extend(&len);
239 for p in ps {
240 p.serialize(buf)?;
241 }
242 Ok(())
243 }
244 },
245 }
246 }
247}
248
249impl Serializable for Value<Context> {
250 fn serialize(&self, buf: &mut Vec<u8>) -> Result<(), CompileError> {
251 match *self {
252 Value::AtomicWord(..) => Err(CompileError::CannotSerialize(self.clone())),
253 Value::BuiltinFunction(..) => Err(CompileError::CannotSerialize(self.clone())),
254 Value::Byte(n, _) => {
255 buf.push(0x01);
256 buf.push(n);
257 Ok(())
258 },
259 Value::Bytes(ref bs, _) => {
260 buf.push(0x02);
261 if bs.len() > u32::MAX as usize {
262 Err(CompileError::BytesTooLong(bs.clone()))
263 } else {
264 let mut len = [0, 0, 0, 0];
265 LE::write_u32(&mut len, bs.len() as u32);
266 buf.extend(&len);
267 buf.extend(bs.as_ref() as &[u8]);
268 Ok(())
269 }
270 },
271 Value::Cons(ref h, ref t, _) => {
272 buf.push(0x03);
273 h.serialize(buf)?;
274 t.serialize(buf)
275 },
276 Value::Fixnum(n, _) => {
277 buf.push(0x04);
278 let mut n_buf = [0, 0, 0, 0, 0, 0, 0, 0];
279 LE::write_i64(&mut n_buf, n as i64);
280 buf.extend(&n_buf);
281 Ok(())
282 },
283 Value::Func(..) => Err(CompileError::CannotSerialize(self.clone())),
284 Value::Object(..) => Err(CompileError::CannotSerialize(self.clone())),
285 Value::Nil(_) => {
286 buf.push(0x00);
287 Ok(())
288 },
289 Value::String(ref s, _) => {
290 buf.push(0x05);
291 if s.len() > u32::MAX as usize {
292 Err(CompileError::StringTooLong(s.clone()))
293 } else {
294 let mut len = [0, 0, 0, 0];
295 LE::write_u32(&mut len, s.len() as u32);
296 buf.extend(&len);
297 buf.extend(s.bytes());
298 Ok(())
299 }
300 },
301 Value::Symbol(s, _) => {
302 buf.push(0x06);
303 s.serialize(buf)
304 },
305 Value::Vector(ref vs, _) => {
306 buf.push(0x07);
307 if vs.len() > u32::MAX as usize {
308 Err(CompileError::VectorTooLong(vs.clone()))
309 } else {
310 let mut len = [0, 0, 0, 0];
311 LE::write_u32(&mut len, vs.len() as u32);
312 buf.extend(&len);
313 for v in vs {
314 v.serialize(buf)?;
315 }
316 Ok(())
317 }
318 },
319 }
320 }
321}