Spread out implementations of symbol and attrs-related things, add impl

blocks for TranslateAst

Signed-off-by: Alek Ratzloff <alekratz@gmail.com>
This commit is contained in:
2020-05-21 18:51:54 -04:00
parent 926447a62d
commit 7b470b1e76
14 changed files with 178 additions and 114 deletions

34
src/compile/attrs.rs Normal file
View File

@@ -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<G: Gc>(self, gc: &mut G) -> ObjRef<Attrs> {
let Self { attrs, .. } = self;
Attrs::new(gc, attrs)
}
}

View File

@@ -6,8 +6,13 @@ use crate::{
// basic block // basic block
pub enum Block { pub enum Block {
Body(ir::Body), Body(ir::Body),
Blocks(Vec<Block>),
} }
////////////////////////////////////////////////////////////////////////////////
// TranslateAst
////////////////////////////////////////////////////////////////////////////////
pub struct TranslateAst<'c, 't> { pub struct TranslateAst<'c, 't> {
ctx: &'c mut Ctx, ctx: &'c mut Ctx,
text: &'t str, text: &'t str,
@@ -18,7 +23,7 @@ impl<'c, 't> TranslateAst<'c, 't> {
TranslateAst { ctx, text } TranslateAst { ctx, text }
} }
pub fn translate(&mut self, _ast: &Vec<Stmt>) -> Result<ir::Body> { pub fn translate(&mut self, _ast: &Vec<Stmt>) -> Result<Block> {
todo!() todo!()
} }
@@ -34,7 +39,7 @@ impl<'c, 't> TranslateAst<'c, 't> {
todo!() todo!()
//Ok(ir::Lhs::Name( //Ok(ir::Lhs::Name(
} }
_ => todo!(), _ => Err(Error::InvalidLhs { span: expr.span() }),
} }
} }
} }
@@ -50,15 +55,97 @@ impl Visit<Stmt> for TranslateAst<'_, '_> {
impl Visit<AssignStmt> for TranslateAst<'_, '_> { impl Visit<AssignStmt> for TranslateAst<'_, '_> {
type Out = Result<ir::Stmt>; type Out = Result<ir::Stmt>;
fn visit(&mut self, _stmt: &AssignStmt) -> Self::Out { fn visit(&mut self, stmt: &AssignStmt) -> Self::Out {
todo!() let lhs = self.visit_lhs_expr(&stmt.lhs)?;
let rhs = self.visit(&stmt.rhs)?;
Ok(ir::Stmt::Assign(lhs, rhs))
} }
} }
impl Visit<Expr> for TranslateAst<'_, '_> { default_visitor!(Expr for TranslateAst<'_, '_> where Out = Result<ir::Expr>);
impl Visit<BinExpr> for TranslateAst<'_, '_> {
type Out = Result<ir::Expr>; type Out = Result<ir::Expr>;
fn visit(&mut self, _expr: &Expr) -> Self::Out { fn visit(&mut self, _expr: &BinExpr) -> Self::Out {
todo!() todo!()
} }
} }
impl Visit<UnExpr> for TranslateAst<'_, '_> {
type Out = Result<ir::Expr>;
fn visit(&mut self, _expr: &UnExpr) -> Self::Out {
todo!()
}
}
impl Visit<FunCallExpr> for TranslateAst<'_, '_> {
type Out = Result<ir::Expr>;
fn visit(&mut self, _expr: &FunCallExpr) -> Self::Out {
todo!()
}
}
impl Visit<IndexExpr> for TranslateAst<'_, '_> {
type Out = Result<ir::Expr>;
fn visit(&mut self, _expr: &IndexExpr) -> Self::Out {
todo!()
}
}
impl Visit<FunExpr> for TranslateAst<'_, '_> {
type Out = Result<ir::Expr>;
fn visit(&mut self, _expr: &FunExpr) -> Self::Out {
todo!()
}
}
impl Visit<BaseExpr> for TranslateAst<'_, '_> {
type Out = Result<ir::Expr>;
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::<Result<Vec<_>>>()?,
),
};
Ok(base)
}
}

View File

@@ -1,9 +1,8 @@
use crate::{compile::name::NameStack, obj::Sym}; use crate::compile::{name::NameStack, sym::SymMap};
use std::collections::HashMap;
pub struct Ctx { pub struct Ctx {
name_stack: NameStack, name_stack: NameStack,
syms: HashMap<String, Sym>, syms: SymMap,
} }
impl Ctx { impl Ctx {
@@ -22,16 +21,11 @@ impl Ctx {
&mut self.name_stack &mut self.name_stack
} }
pub fn syms(&self) -> &HashMap<String, Sym> { pub fn syms(&self) -> &SymMap {
&self.syms &self.syms
} }
pub fn syms_mut(&mut self) -> &mut HashMap<String, Sym> { pub fn syms_mut(&mut self) -> &mut SymMap {
&mut self.syms &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())
}
} }

View File

@@ -1,4 +1,4 @@
use crate::{obj::Sym, syn::span::*}; use crate::obj::{NameId, Sym};
pub type Body = Vec<Stmt>; pub type Body = Vec<Stmt>;
@@ -17,19 +17,9 @@ pub enum Lhs {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum Expr { pub enum Expr {
Call(Box<Expr>, Vec<Expr>), Call(Box<Expr>, Vec<Expr>),
Base(BaseExpr), Block(Vec<Stmt>),
}
#[derive(Debug, Clone)]
pub enum BaseExprKind {
Num(i64), Num(i64),
Str(String), Str(String),
Sym(Sym), Sym(Sym),
Ident(Sym), Ident(NameId),
}
#[derive(Debug, Clone)]
pub struct BaseExpr {
pub kind: BaseExprKind,
pub span: Span,
} }

View File

@@ -1,11 +1,9 @@
#[macro_use] #[macro_use]
pub mod visit; pub mod visit;
pub mod attrs;
pub mod block; pub mod block;
pub mod ctx; pub mod ctx;
pub mod error; pub mod error;
pub mod ir; pub mod ir;
pub mod name; pub mod name;
pub mod sym;
// * Desugar
// * Collect names as symbols
// * Create basic blocks

View File

@@ -236,7 +236,7 @@ impl Visit<FunExpr> for CollectSyms<'_, '_> {
fn visit(&mut self, expr: &FunExpr) -> Self::Out { fn visit(&mut self, expr: &FunExpr) -> Self::Out {
expr.params.iter().for_each(|name| { expr.params.iter().for_each(|name| {
self.ctx.add_sym(name.clone()); self.ctx.syms_mut().add(name.clone());
}); });
self.visit(&expr.expr); self.visit(&expr.expr);
} }
@@ -249,11 +249,11 @@ impl Visit<BaseExpr> for CollectSyms<'_, '_> {
match &expr.kind { match &expr.kind {
BaseExprKind::Ident => { BaseExprKind::Ident => {
let name = expr.text_at(self.text).to_string(); let name = expr.text_at(self.text).to_string();
self.ctx.add_sym(name); self.ctx.syms_mut().add(name);
} }
BaseExprKind::Sym => { BaseExprKind::Sym => {
let name = expr.text_at(self.text).chars().skip(1).collect::<String>(); let name = expr.text_at(self.text).chars().skip(1).collect::<String>();
self.ctx.add_sym(name); self.ctx.syms_mut().add(name);
} }
BaseExprKind::List(l) | BaseExprKind::Tuple(l) => { BaseExprKind::List(l) | BaseExprKind::Tuple(l) => {
l.iter().for_each(|expr| self.visit(expr)) l.iter().for_each(|expr| self.visit(expr))

31
src/compile/sym.rs Normal file
View File

@@ -0,0 +1,31 @@
use crate::obj::Sym;
use std::collections::HashMap;
#[derive(Default, Debug, Clone)]
pub struct SymMap {
map: HashMap<String, Sym>,
}
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<Sym> {
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<String, Sym> {
self.map.entry(k)
}
}

View File

@@ -37,7 +37,7 @@ fn main() -> Result<()> {
//println!("{:#?}", ast); //println!("{:#?}", ast);
let mut ctx = compile::ctx::Ctx::new(); 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()); println!("{:#?}", ctx.syms());
ctx.name_stack_mut().push_default(); ctx.name_stack_mut().push_default();

View File

@@ -47,26 +47,3 @@ impl Gc for BasicGc {
// //
// This will probably require a custom `ObjClone` trait to achieve the desired behavior with a ctx // This will probably require a custom `ObjClone` trait to achieve the desired behavior with a ctx
// object // 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();
}
*/

View File

@@ -5,6 +5,8 @@ pub mod ptr;
pub use basic::BasicGc; pub use basic::BasicGc;
pub type DefaultGc = BasicGc;
pub mod prelude { pub mod prelude {
pub use crate::mem::{ pub use crate::mem::{
gc::Gc, gc::Gc,

View File

@@ -20,7 +20,6 @@ impl Attrs {
pub fn new<G: Gc>(gc: &mut G, attrs: Ss) -> ObjRef<Self> { pub fn new<G: Gc>(gc: &mut G, attrs: Ss) -> ObjRef<Self> {
let obj: Box<ObjCell<Attrs>> = unsafe { let obj: Box<ObjCell<Attrs>> = unsafe {
let mut obj: Box<MaybeUninit<ObjCell<Attrs>>> = Box::new_uninit(); let mut obj: Box<MaybeUninit<ObjCell<Attrs>>> = 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<Attrs>; let this = &*obj as *const _ as *const ObjCell<Attrs>;
obj.as_mut_ptr().write(ObjCell::new(Attrs { 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<G: Gc>(self, gc: &mut G) -> ObjRef<Attrs> {
let Self { intern: _, attrs } = self;
Attrs::new(gc, attrs)
}
}
#[test] #[test]
fn test_attrs_new() { fn test_attrs_new() {
use crate::mem::BasicGc; use crate::mem::BasicGc;

View File

@@ -1,10 +1,8 @@
use crate::{ use crate::{
mem::{gc::Gc, BasicGc}, mem::gc::Gc,
obj::prelude::*, obj::prelude::*,
}; };
pub type DefaultGc = BasicGc;
pub struct ObjCtx<'g, 'n, G> pub struct ObjCtx<'g, 'n, G>
where where
G: Gc + 'g, G: Gc + 'g,

View File

@@ -36,7 +36,7 @@ pub mod prelude {
} }
pub use self::{ pub use self::{
attrs::{Attrs, AttrsBuilder, AttrsRef}, attrs::{Attrs, AttrsRef},
ctx::ObjCtx, ctx::ObjCtx,
dict::{Dict, DictRef}, dict::{Dict, DictRef},
fun::{Fun, NativeFun}, fun::{Fun, NativeFun},

View File

@@ -8,31 +8,15 @@ use crate::{
}; };
use std::rc::Rc; use std::rc::Rc;
/* pub struct State<G: Gc> {
fn root_ns<I: Intern, G: Gc>(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<I: Intern, G: Gc> {
intern: I,
gc: G, gc: G,
root_ns: Ns,
frames: Vec<Frame>, frames: Vec<Frame>,
} }
impl<I: Intern, G: Gc> State<I, G> { impl<G: Gc> State<G> {
pub fn new(intern: I, gc: G, root_ns: Ns) -> Self { pub fn new(gc: G) -> Self {
//let root_ns = root_ns(&mut intern, &mut gc);
State { State {
intern,
gc, gc,
root_ns,
frames: Default::default(), frames: Default::default(),
} }
} }