oftlisp_anf/
compile.rs

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        // First, convert the modules to serialize into a Vec. We can also
21        // detect some issues in the dependency graph here.
22        let mut modules = vec![];
23        let mut moved = HashSet::new();
24        move_modules(main_module, &mut exported_modules, &mut modules, &mut moved)?;
25
26        // Warn about any unused modules.
27        for (name, _) in exported_modules {
28            warn!("Unused module: {}", name);
29        }
30
31        // Convert `modules.len()` to a u32.
32        if modules.len() > u32::MAX as usize {
33            return Err(CompileError::TooManyModules);
34        }
35        let num_modules = modules.len() as u32;
36
37        // Serialize the modules.
38        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}