diff --git a/src/compile/attrs.rs b/src/compile/attrs.rs new file mode 100644 index 0000000..59156ca --- /dev/null +++ b/src/compile/attrs.rs @@ -0,0 +1,34 @@ +use crate::{ + compile::ctx::Ctx, + obj::prelude::*, +}; + +pub struct AttrsBuilder<'c> { + ctx: &'c mut Ctx, + attrs: Ss, +} + +impl<'c> AttrsBuilder<'c> { + pub fn new(ctx: &'c mut Ctx) -> Self { + Self::with_base(ctx, Default::default()) + } + + pub fn with_base(ctx: &'c mut Ctx, attrs: Ss) -> Self { + AttrsBuilder { ctx, attrs, } + } + + pub fn attr(self, symbol_name: &str, value: DynRef) -> Self { + let sym = self.ctx.syms_mut().add(symbol_name.to_string()); + self.attr_sym(sym, value) + } + + pub fn attr_sym(mut self, sym: Sym, value: DynRef) -> Self { + self.attrs.insert(sym, value); + self + } + + pub fn finish(self, gc: &mut G) -> ObjRef { + let Self { attrs, .. } = self; + Attrs::new(gc, attrs) + } +} diff --git a/src/compile/block.rs b/src/compile/block.rs index dcac935..f63807a 100644 --- a/src/compile/block.rs +++ b/src/compile/block.rs @@ -6,8 +6,13 @@ use crate::{ // basic block pub enum Block { Body(ir::Body), + Blocks(Vec), } +//////////////////////////////////////////////////////////////////////////////// +// TranslateAst +//////////////////////////////////////////////////////////////////////////////// + pub struct TranslateAst<'c, 't> { ctx: &'c mut Ctx, text: &'t str, @@ -18,7 +23,7 @@ impl<'c, 't> TranslateAst<'c, 't> { TranslateAst { ctx, text } } - pub fn translate(&mut self, _ast: &Vec) -> Result { + pub fn translate(&mut self, _ast: &Vec) -> Result { todo!() } @@ -34,7 +39,7 @@ impl<'c, 't> TranslateAst<'c, 't> { todo!() //Ok(ir::Lhs::Name( } - _ => todo!(), + _ => Err(Error::InvalidLhs { span: expr.span() }), } } } @@ -50,15 +55,97 @@ impl Visit for TranslateAst<'_, '_> { impl Visit for TranslateAst<'_, '_> { type Out = Result; - fn visit(&mut self, _stmt: &AssignStmt) -> Self::Out { - todo!() + fn visit(&mut self, stmt: &AssignStmt) -> Self::Out { + let lhs = self.visit_lhs_expr(&stmt.lhs)?; + let rhs = self.visit(&stmt.rhs)?; + Ok(ir::Stmt::Assign(lhs, rhs)) } } -impl Visit for TranslateAst<'_, '_> { +default_visitor!(Expr for TranslateAst<'_, '_> where Out = Result); + +impl Visit for TranslateAst<'_, '_> { type Out = Result; - fn visit(&mut self, _expr: &Expr) -> Self::Out { + fn visit(&mut self, _expr: &BinExpr) -> Self::Out { todo!() } } + +impl Visit for TranslateAst<'_, '_> { + type Out = Result; + + fn visit(&mut self, _expr: &UnExpr) -> Self::Out { + todo!() + } +} + +impl Visit for TranslateAst<'_, '_> { + type Out = Result; + + fn visit(&mut self, _expr: &FunCallExpr) -> Self::Out { + todo!() + } +} + +impl Visit for TranslateAst<'_, '_> { + type Out = Result; + + fn visit(&mut self, _expr: &IndexExpr) -> Self::Out { + todo!() + } +} + +impl Visit for TranslateAst<'_, '_> { + type Out = Result; + + fn visit(&mut self, _expr: &FunExpr) -> Self::Out { + todo!() + } +} + +impl Visit for TranslateAst<'_, '_> { + type Out = Result; + + fn visit(&mut self, expr: &BaseExpr) -> Self::Out { + let base = match &expr.kind { + BaseExprKind::Ident => { + let _name = self + .ctx + .name_stack() + .get_scoped(expr.text_at(self.text)) + .unwrap(); + todo!() + } + BaseExprKind::Num => { + let num_text = expr.text_at(self.text); + let _num = if num_text.starts_with("0x") || num_text.starts_with("0X") { + i64::from_str_radix(&num_text[2..], 16).unwrap() + } else { + num_text.parse().unwrap() + }; + todo!() + } + BaseExprKind::Str => todo!(), + BaseExprKind::Sym => { + let _sym = self + .ctx + .syms() + .get(&expr.text_at(self.text)[1..]) + .unwrap(); + todo!() + } + BaseExprKind::List(_) => todo!(), + BaseExprKind::Object(_) => todo!(), + BaseExprKind::Tuple(_) => todo!(), + BaseExprKind::Block(block) => ir::Expr::Block( + block + .iter() + .map(|stmt| self.visit(stmt)) + .collect::>>()?, + ), + }; + + Ok(base) + } +} diff --git a/src/compile/ctx.rs b/src/compile/ctx.rs index bb2bfc6..5df72bc 100644 --- a/src/compile/ctx.rs +++ b/src/compile/ctx.rs @@ -1,9 +1,8 @@ -use crate::{compile::name::NameStack, obj::Sym}; -use std::collections::HashMap; +use crate::compile::{name::NameStack, sym::SymMap}; pub struct Ctx { name_stack: NameStack, - syms: HashMap, + syms: SymMap, } impl Ctx { @@ -22,16 +21,11 @@ impl Ctx { &mut self.name_stack } - pub fn syms(&self) -> &HashMap { + pub fn syms(&self) -> &SymMap { &self.syms } - pub fn syms_mut(&mut self) -> &mut HashMap { + pub fn syms_mut(&mut self) -> &mut SymMap { &mut self.syms } - - pub fn add_sym(&mut self, name: String) -> Sym { - let next_sym = self.syms().len(); - *self.syms_mut().entry(name).or_insert(next_sym.into()) - } } diff --git a/src/compile/ir.rs b/src/compile/ir.rs index 2166878..a9948e0 100644 --- a/src/compile/ir.rs +++ b/src/compile/ir.rs @@ -1,4 +1,4 @@ -use crate::{obj::Sym, syn::span::*}; +use crate::obj::{NameId, Sym}; pub type Body = Vec; @@ -17,19 +17,9 @@ pub enum Lhs { #[derive(Debug, Clone)] pub enum Expr { Call(Box, Vec), - Base(BaseExpr), -} - -#[derive(Debug, Clone)] -pub enum BaseExprKind { + Block(Vec), Num(i64), Str(String), Sym(Sym), - Ident(Sym), -} - -#[derive(Debug, Clone)] -pub struct BaseExpr { - pub kind: BaseExprKind, - pub span: Span, + Ident(NameId), } diff --git a/src/compile/mod.rs b/src/compile/mod.rs index b3a325d..93c4c39 100644 --- a/src/compile/mod.rs +++ b/src/compile/mod.rs @@ -1,11 +1,9 @@ #[macro_use] pub mod visit; +pub mod attrs; pub mod block; pub mod ctx; pub mod error; pub mod ir; pub mod name; - -// * Desugar -// * Collect names as symbols -// * Create basic blocks +pub mod sym; diff --git a/src/compile/name.rs b/src/compile/name.rs index 215c6a8..db5b67d 100644 --- a/src/compile/name.rs +++ b/src/compile/name.rs @@ -236,7 +236,7 @@ impl Visit for CollectSyms<'_, '_> { fn visit(&mut self, expr: &FunExpr) -> Self::Out { expr.params.iter().for_each(|name| { - self.ctx.add_sym(name.clone()); + self.ctx.syms_mut().add(name.clone()); }); self.visit(&expr.expr); } @@ -249,11 +249,11 @@ impl Visit for CollectSyms<'_, '_> { match &expr.kind { BaseExprKind::Ident => { let name = expr.text_at(self.text).to_string(); - self.ctx.add_sym(name); + self.ctx.syms_mut().add(name); } BaseExprKind::Sym => { let name = expr.text_at(self.text).chars().skip(1).collect::(); - self.ctx.add_sym(name); + self.ctx.syms_mut().add(name); } BaseExprKind::List(l) | BaseExprKind::Tuple(l) => { l.iter().for_each(|expr| self.visit(expr)) diff --git a/src/compile/sym.rs b/src/compile/sym.rs new file mode 100644 index 0000000..5fc58fb --- /dev/null +++ b/src/compile/sym.rs @@ -0,0 +1,31 @@ +use crate::obj::Sym; +use std::collections::HashMap; + +#[derive(Default, Debug, Clone)] +pub struct SymMap { + map: HashMap, +} + +impl SymMap { + pub fn new() -> Self { + Default::default() + } + + pub fn add(&mut self, name: String) -> Sym { + let next_sym = self.map.len(); + *self.map.entry(name) + .or_insert(next_sym.into()) + } + + pub fn get(&self, name: &str) -> Option { + self.map.get(name).copied() + } + + pub fn len(&self) -> usize { + self.map.len() + } + + pub fn entry(&mut self, k: String) -> std::collections::hash_map::Entry { + self.map.entry(k) + } +} diff --git a/src/main.rs b/src/main.rs index 39b1847..64c5c3e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -37,7 +37,7 @@ fn main() -> Result<()> { //println!("{:#?}", ast); let mut ctx = compile::ctx::Ctx::new(); - compile::name::CollectSyms::new(&mut ctx, text.as_str()).collect(&ast); + { compile::name::CollectSyms::new(&mut ctx, text.as_str()).collect(&ast); } println!("{:#?}", ctx.syms()); ctx.name_stack_mut().push_default(); diff --git a/src/mem/basic.rs b/src/mem/basic.rs index 9ccef93..1a616de 100644 --- a/src/mem/basic.rs +++ b/src/mem/basic.rs @@ -47,26 +47,3 @@ impl Gc for BasicGc { // // This will probably require a custom `ObjClone` trait to achieve the desired behavior with a ctx // object - -/* -#[test] -fn test_gc_clone() { - use crate::{obj::{attrs::AttrsBuilder, ctx::DefaultGc, Attrs, ObjCtx}}; - - let mut ctx = ObjCtx::new(DefaultGc::default()); - - let empty_attrs = Attrs::new(&mut ctx, Default::default()); - - let empty_sym = ctx.gc_mut().add_sym("empty"); - let attrs_source = AttrsBuilder::new(&mut ctx) - .attr_sym(empty_sym, empty_attrs.as_dyn()) - .finish(); - - let attrs_clone = ctx.gc_mut().cloned(attrs_source.borrow()); - - - assert!(!std::ptr::eq(attrs_source.as_ptr(), attrs_clone.as_ptr())); - - let empty1 = attrs_source.borrow().get(empty_sym).unwrap(); -} -*/ diff --git a/src/mem/mod.rs b/src/mem/mod.rs index 2630792..430de81 100644 --- a/src/mem/mod.rs +++ b/src/mem/mod.rs @@ -5,6 +5,8 @@ pub mod ptr; pub use basic::BasicGc; +pub type DefaultGc = BasicGc; + pub mod prelude { pub use crate::mem::{ gc::Gc, diff --git a/src/obj/attrs.rs b/src/obj/attrs.rs index ddf17d6..68950b9 100644 --- a/src/obj/attrs.rs +++ b/src/obj/attrs.rs @@ -20,7 +20,6 @@ impl Attrs { pub fn new(gc: &mut G, attrs: Ss) -> ObjRef { let obj: Box> = unsafe { let mut obj: Box>> = Box::new_uninit(); - // maybe UB? taking away the uninit right before it's initialized may be bad let this = &*obj as *const _ as *const ObjCell; obj.as_mut_ptr().write(ObjCell::new(Attrs { @@ -86,36 +85,6 @@ impl Obj for Attrs { } } -pub struct AttrsBuilder<'i, I: Intern> { - intern: &'i mut I, - attrs: Ss, -} - -impl<'i, I: Intern> AttrsBuilder<'i, I> { - pub fn new(intern: &'i mut I) -> Self { - Self::with_base(intern, Default::default()) - } - - pub fn with_base(intern: &'i mut I, attrs: Ss) -> Self { - AttrsBuilder { attrs, intern } - } - - pub fn attr(self, symbol_name: &str, value: DynRef) -> Self { - let sym = self.intern.intern_sym(symbol_name); - self.attr_sym(sym, value) - } - - pub fn attr_sym(mut self, sym: Sym, value: DynRef) -> Self { - self.attrs.insert(sym, value); - self - } - - pub fn finish(self, gc: &mut G) -> ObjRef { - let Self { intern: _, attrs } = self; - Attrs::new(gc, attrs) - } -} - #[test] fn test_attrs_new() { use crate::mem::BasicGc; diff --git a/src/obj/ctx.rs b/src/obj/ctx.rs index 280ca46..fcd4ebb 100644 --- a/src/obj/ctx.rs +++ b/src/obj/ctx.rs @@ -1,10 +1,8 @@ use crate::{ - mem::{gc::Gc, BasicGc}, + mem::gc::Gc, obj::prelude::*, }; -pub type DefaultGc = BasicGc; - pub struct ObjCtx<'g, 'n, G> where G: Gc + 'g, diff --git a/src/obj/mod.rs b/src/obj/mod.rs index 16ec9af..65b5ca0 100644 --- a/src/obj/mod.rs +++ b/src/obj/mod.rs @@ -36,7 +36,7 @@ pub mod prelude { } pub use self::{ - attrs::{Attrs, AttrsBuilder, AttrsRef}, + attrs::{Attrs, AttrsRef}, ctx::ObjCtx, dict::{Dict, DictRef}, fun::{Fun, NativeFun}, diff --git a/src/vm/mod.rs b/src/vm/mod.rs index 0325ff1..ab59422 100644 --- a/src/vm/mod.rs +++ b/src/vm/mod.rs @@ -8,31 +8,15 @@ use crate::{ }; use std::rc::Rc; -/* -fn root_ns(intern: &mut I, gc: &mut G) -> Ns { - let mut ns: Ns = Default::default(); - ns.insert( - intern.intern_sym("Unit"), - Attrs::new(gc, Default::default()), - ); - ns -} -*/ - -pub struct State { - intern: I, +pub struct State { gc: G, - root_ns: Ns, frames: Vec, } -impl State { - pub fn new(intern: I, gc: G, root_ns: Ns) -> Self { - //let root_ns = root_ns(&mut intern, &mut gc); +impl State { + pub fn new(gc: G) -> Self { State { - intern, gc, - root_ns, frames: Default::default(), } }