Moved sym lookup logic from eval to ast reducer
This commit is contained in:
parent
2cd325ba12
commit
e4a1a23f4d
@ -208,7 +208,10 @@ impl<'a> State<'a> {
|
||||
Node::Expr(expr) => match expr {
|
||||
literal @ Lit(_) => Ok(Node::Expr(literal)),
|
||||
Call { box f, args } => self.call_expression(f, args),
|
||||
Sym(v) => self.handle_sym(v),
|
||||
Sym(name) => Ok(match self.values.lookup(&name) {
|
||||
Some(ValueEntry::Binding { val, .. }) => val.clone(),
|
||||
None => return Err(format!("Could not look up symbol {}", name))
|
||||
}),
|
||||
Constructor { arity, ref name, tag, .. } if arity == 0 => Ok(Node::PrimObject { name: name.clone(), tag, items: vec![] }),
|
||||
constructor @ Constructor { .. } => Ok(Node::Expr(constructor)),
|
||||
func @ Func(_) => Ok(Node::Expr(func)),
|
||||
@ -452,46 +455,4 @@ impl<'a> State<'a> {
|
||||
}
|
||||
Err(format!("{:?} failed pattern match", cond))
|
||||
}
|
||||
|
||||
//TODO if I don't need to lookup by name here...
|
||||
fn handle_sym(&mut self, name: Rc<String>) -> EvalResult<Node> {
|
||||
use self::ValueEntry::*;
|
||||
use self::Func::*;
|
||||
//TODO add a layer of indirection here to talk to the symbol table first, and only then look up
|
||||
//in the values table
|
||||
|
||||
let symbol_table = self.symbol_table_handle.borrow();
|
||||
let value = symbol_table.lookup_by_fqsn(&fqsn!(name ; tr));
|
||||
Ok(match value {
|
||||
Some(Symbol { local_name, spec, .. }) => match spec {
|
||||
//TODO I'll need this type_name later to do a table lookup
|
||||
SymbolSpec::DataConstructor { type_name: _type_name, type_args, .. } => {
|
||||
if type_args.len() == 0 {
|
||||
Node::PrimObject { name: local_name.clone(), tag: 0, items: vec![] }
|
||||
} else {
|
||||
return Err(format!("This data constructor thing not done"))
|
||||
}
|
||||
},
|
||||
SymbolSpec::Func(_) => match self.values.lookup(&name) {
|
||||
Some(Binding { val: Node::Expr(Expr::Func(UserDefined { name, params, body })), .. }) => {
|
||||
Node::Expr(Expr::Func(UserDefined { name: name.clone(), params: params.clone(), body: body.clone() }))
|
||||
},
|
||||
_ => unreachable!(),
|
||||
},
|
||||
SymbolSpec::RecordConstructor { .. } => return Err(format!("This shouldn't be a record!")),
|
||||
SymbolSpec::Binding => match self.values.lookup(&name) {
|
||||
Some(Binding { val, .. }) => val.clone(),
|
||||
None => return Err(format!("Symbol {} exists in symbol table but not in evaluator table", name))
|
||||
}
|
||||
SymbolSpec::Type { name } => return Err(format!("Symbol {} not in scope", name)),
|
||||
},
|
||||
//TODO ideally this should be returning a runtime error if this is ever None, but it's not
|
||||
//handling all bindings correctly yet
|
||||
//None => return Err(format!("Couldn't find value {}", name)),
|
||||
None => match self.values.lookup(&name) {
|
||||
Some(Binding { val, .. }) => val.clone(),
|
||||
None => return Err(format!("Couldn't find value {}", name)),
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -42,9 +42,9 @@ pub enum Stmt {
|
||||
pub enum Expr {
|
||||
Unit,
|
||||
Lit(Lit),
|
||||
Sym(Rc<String>), //a Sym is anything that can be looked up by name at runtime - i.e. a function or variable address
|
||||
Tuple(Vec<Expr>),
|
||||
Func(Func),
|
||||
Sym(Rc<String>),
|
||||
Constructor {
|
||||
type_name: Rc<String>,
|
||||
name: Rc<String>,
|
||||
@ -56,7 +56,7 @@ pub enum Expr {
|
||||
args: Vec<Expr>,
|
||||
},
|
||||
Assign {
|
||||
val: Box<Expr>,
|
||||
val: Box<Expr>, //TODO this probably can't be a val
|
||||
expr: Box<Expr>,
|
||||
},
|
||||
Conditional {
|
||||
@ -196,15 +196,16 @@ impl<'a> Reducer<'a> {
|
||||
};
|
||||
|
||||
match spec {
|
||||
SymbolSpec::DataConstructor { index, type_args, type_name} => {
|
||||
Expr::Constructor {
|
||||
SymbolSpec::RecordConstructor { .. } => Expr::ReductionError(format!("AST reducer doesn't expect a RecordConstructor here")),
|
||||
SymbolSpec::DataConstructor { index, type_args, type_name } => Expr::Constructor {
|
||||
type_name: type_name.clone(),
|
||||
name: name.clone(),
|
||||
tag: index.clone(),
|
||||
arity: type_args.len(),
|
||||
}
|
||||
},
|
||||
_ => Expr::Sym(name.clone()),
|
||||
SymbolSpec::Func(_) => Expr::Sym(local_name.clone()),
|
||||
SymbolSpec::Binding => Expr::Sym(local_name.clone()), //TODO not sure if this is right, probably needs to eventually be fqsn
|
||||
SymbolSpec::Type { .. } => Expr::ReductionError("AST reducer doesnt expect a type here".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user