Function calls work

This commit is contained in:
greg 2018-02-26 19:55:27 -08:00
parent c285ee182e
commit 2574a1b9c0
1 changed files with 20 additions and 4 deletions

View File

@ -8,11 +8,13 @@ pub struct State<'a> {
values: HashMap<Rc<String>, ValueEntry>, values: HashMap<Rc<String>, ValueEntry>,
} }
#[derive(Debug)]
enum ValueEntry { enum ValueEntry {
Binding { Binding {
val: FullyEvaluatedExpr, val: FullyEvaluatedExpr,
}, },
Function { Function {
param_names: Vec<Rc<String>>,
body: Vec<Statement>, body: Vec<Statement>,
} }
} }
@ -92,7 +94,8 @@ impl<'a> State<'a> {
match decl { match decl {
FuncDecl(signature, statements) => { FuncDecl(signature, statements) => {
let name = signature.name; let name = signature.name;
self.values.insert(name, ValueEntry::Function { body: statements.clone() }); let param_names: Vec<Rc<String>> = signature.params.iter().map(|fp| fp.0.clone()).collect();
self.values.insert(name, ValueEntry::Function { body: statements.clone(), param_names });
}, },
TypeDecl(_name, body) => { TypeDecl(_name, body) => {
for variant in body.0.iter() { for variant in body.0.iter() {
@ -136,20 +139,33 @@ impl<'a> State<'a> {
} }
Ok(Tuple(evals)) Ok(Tuple(evals))
} }
Call { f, arguments } => self.eval_application(*f, arguments), Call { f, arguments } => {
let mut evaled_arguments = Vec::new();
for arg in arguments.into_iter() {
evaled_arguments.push(self.eval_expr(arg)?);
}
self.eval_application(*f, evaled_arguments)
},
x => Err(format!("Unimplemented thing {:?}", x)), x => Err(format!("Unimplemented thing {:?}", x)),
} }
} }
fn eval_application(&mut self, f: Expression, _arguments: Vec<Expression>) -> EvalResult<FullyEvaluatedExpr> { fn eval_application(&mut self, f: Expression, arguments: Vec<FullyEvaluatedExpr>) -> EvalResult<FullyEvaluatedExpr> {
use self::ExpressionType::*; use self::ExpressionType::*;
match f { match f {
Expression(Value(identifier), _) => { Expression(Value(identifier), _) => {
match self.values.get(&identifier) { match self.values.get(&identifier) {
Some(&ValueEntry::Function { ref body }) => { Some(&ValueEntry::Function { ref body, ref param_names }) => {
let mut new_state = State::new_with_parent(self); let mut new_state = State::new_with_parent(self);
let sub_ast = body.clone(); let sub_ast = body.clone();
if arguments.len() != param_names.len() {
return Err(format!("Wrong number of arguments for the function"));
}
for (param, val) in param_names.iter().zip(arguments.into_iter()) {
new_state.values.insert(param.clone(), ValueEntry::Binding { val });
}
let mut ret: Option<FullyEvaluatedExpr> = None; let mut ret: Option<FullyEvaluatedExpr> = None;
for statement in sub_ast.into_iter() { for statement in sub_ast.into_iter() {
ret = new_state.eval_statement(statement)?; ret = new_state.eval_statement(statement)?;