From f8a521fc9bbf19fd45505072035ae289906060a4 Mon Sep 17 00:00:00 2001 From: greg Date: Sun, 24 Jan 2016 01:03:57 -0800 Subject: [PATCH] Start making function calls work This commit isn't fully done yet --- src/eval.rs | 27 ++++++++++++++++++++++----- src/parser.rs | 6 +++--- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/eval.rs b/src/eval.rs index 8284258..0e31a68 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -21,6 +21,10 @@ impl Funcmap { let map = HashMap::new(); Funcmap { map: map } } + + fn lookup_function(&self, name: String) -> Option { + self.map.get(&name).map(|x| x.clone()) + } } pub struct Evaluator { @@ -66,9 +70,6 @@ impl Evaluator { self.funcmap.map.insert(name, function); } - fn lookup_function(&mut self, name: String) -> Option<&Function> { - self.funcmap.map.get(&name) - } } trait Evaluable { @@ -208,11 +209,27 @@ impl Evaluator { fn reduce_call(&mut self, name: String, arguments: Vec) -> Expression { use parser::Expression::*; - let function = match self.lookup_function(name) { - Some(ref func) => func.clone(), + let x = self.funcmap.lookup_function(name); + let function = match x { + Some(func) => func, None => return Null }; + if function.prototype.parameters.len() != arguments.len() { + return Null + } + + let mut frame: Varmap = Varmap::new(); + for (binding, expr) in function.prototype.parameters.iter().zip(arguments.iter()) { + frame.map.insert(binding.clone(), expr.clone()); + } + + self.frames.push(frame); + for expr in function.body.iter() { + self.reduce_expr(expr.clone()); + } + + self.frames.pop(); Null } } diff --git a/src/parser.rs b/src/parser.rs index e9b8cbe..3fcec92 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -33,7 +33,7 @@ pub struct Function { #[derive(Debug, Clone, PartialEq)] pub struct Prototype { pub name: String, - pub args: Vec + pub parameters: Vec } #[derive(Debug, Clone)] @@ -194,9 +194,9 @@ impl Parser { use tokenizer::Token::*; let name: String = expect_identifier!(self); expect!(self, LParen); - let args: Vec = try!(self.identlist()); + let parameters: Vec = try!(self.identlist()); expect!(self, RParen); - Ok(Prototype {name: name, args: args}) + Ok(Prototype {name: name, parameters: parameters}) } fn identlist(&mut self) -> ParseResult> {