Fix looking up functions

This commit is contained in:
greg 2018-06-12 19:37:53 -07:00
parent 3b9084810e
commit ebcea685f3
2 changed files with 22 additions and 21 deletions

View File

@ -144,13 +144,10 @@ impl<'a> State<'a> {
match expr { match expr {
literal @ Lit(_) => Ok(literal), literal @ Lit(_) => Ok(literal),
Call { box f, args } => { Call { box f, args } => {
if let Val(name) = f { match self.expression(f)? {
self.apply_data_constructor(name, args) Constructor {name} => self.apply_data_constructor(name, args),
} else { Func(f) => self.apply_function(f, args),
match self.expression(f)? { other => return Err(format!("Tried to call {:?} which is not a function or data constructor", other)),
Func(f) => self.apply_function(f, args),
other => return Err(format!("Tried to call {:?} which is not a function or data constructor", other)),
}
} }
}, },
Val(v) => self.value(v), Val(v) => self.value(v),
@ -179,16 +176,21 @@ impl<'a> State<'a> {
} }
fn apply_data_constructor(&mut self, name: Rc<String>, args: Vec<Expr>) -> EvalResult<Expr> { fn apply_data_constructor(&mut self, name: Rc<String>, args: Vec<Expr>) -> EvalResult<Expr> {
let symbol_table = self.symbol_table_handle.borrow(); {
match symbol_table.values.get(&name) { let symbol_table = self.symbol_table_handle.borrow();
Some(Symbol { spec: SymbolSpec::DataConstructor { type_name, type_args }, name }) => { match symbol_table.values.get(&name) {
if args.len() != type_args.len() { Some(Symbol { spec: SymbolSpec::DataConstructor { type_name, type_args }, name }) => {
return Err(format!("Data constructor {} requires {} args", name, type_args.len())); if args.len() != type_args.len() {
} return Err(format!("Data constructor {} requires {} args", name, type_args.len()));
Ok(Expr::Lit(self::Lit::Custom(name.clone(), vec![]))) }
}, ()
_ => return Err(format!("Bad symbol {}", name)) },
_ => return Err(format!("Bad symbol {}", name))
}
} }
let evaled_args = args.into_iter().map(|expr| self.expression(expr)).collect::<Result<Vec<Expr>,_>>()?;
//let evaled_args = vec![];
Ok(Expr::Lit(self::Lit::Custom(name.clone(), evaled_args)))
} }
fn apply_function(&mut self, f: Func, args: Vec<Expr>) -> EvalResult<Expr> { fn apply_function(&mut self, f: Func, args: Vec<Expr>) -> EvalResult<Expr> {
@ -285,7 +287,8 @@ impl<'a> State<'a> {
//in the values table //in the values table
let symbol_table = self.symbol_table_handle.borrow(); let symbol_table = self.symbol_table_handle.borrow();
Ok(match symbol_table.values.get(&name) { let value = symbol_table.values.get(&name);
Ok(match value {
Some(Symbol { name, spec }) => match spec { Some(Symbol { name, spec }) => match spec {
SymbolSpec::DataConstructor { type_name, type_args } => { SymbolSpec::DataConstructor { type_name, type_args } => {
if type_args.len() == 0 { if type_args.len() == 0 {

View File

@ -31,7 +31,6 @@ pub enum Expr {
Val(Rc<String>), Val(Rc<String>),
Constructor { Constructor {
name: Rc<String>, name: Rc<String>,
args: Vec<Expr>,
}, },
Call { Call {
f: Box<Expr>, f: Box<Expr>,
@ -102,9 +101,8 @@ impl Expression {
PrefixExp(op, arg) => op.reduce(symbol_table, arg), PrefixExp(op, arg) => op.reduce(symbol_table, arg),
Value(name) => { Value(name) => {
match symbol_table.values.get(name) { match symbol_table.values.get(name) {
Some(Symbol { name, spec: SymbolSpec::DataConstructor { type_name, type_args } }) => { Some(Symbol { spec: SymbolSpec::DataConstructor { type_args, .. }, .. }) => {
//TODO finish Expr::Constructor { name: name.clone() }
Expr::Val(name.clone())
}, },
_ => Expr::Val(name.clone()), _ => Expr::Val(name.clone()),
} }