use std::rc::Rc; use std::collections::BTreeMap; use std::fmt; use std::cell::RefCell; use anyhow::{anyhow,bail,Result}; // This first Simple Lisp really is // // No fexprs, no mutation, no continuations, no macros, no strings. // Int/Bool/Nil/Pair/Symbol/Closure/Prim. // // Figuring out GC between a JIT and Rust will be tricky. // Can start with a like tracing-JIT-into-bytecode // Replcing Env with pairs or somesuch would make JIT interop easier I think, because we wouldn't // have to deal with refcell, but then we would again for mutation. // Maybe doing all allocation on the Rust side with #[no_mangle] functions would make things easier // mmmm no let's make our own Box, Rc, maybe Arc, Vec too? // rustonomicon // What if we're cute and use the ID // like we will eventually use value tagging // like, use the same encoding // interned symbols and all #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Copy)] pub struct ID { id: i64 } impl fmt::Display for ID { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.id) } } #[derive(Debug)] pub enum Form { Nil, Int(i32), Bool(bool), Symbol(String), Pair(Rc