From 84fbe73cf676618d2f3f2169fe5e208ec0e90110 Mon Sep 17 00:00:00 2001 From: greg Date: Mon, 2 Jan 2017 18:41:46 -0800 Subject: [PATCH] Add Lambda type And change name FuncNode -> FuncDefNode Now function definition nodes reduce to a Lambda, which is not reducible. --- src/compilation.rs | 2 +- src/eval.rs | 11 +++++++---- src/parser.rs | 23 ++++++++++++++++------- 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/src/compilation.rs b/src/compilation.rs index 7f71889..063eae8 100644 --- a/src/compilation.rs +++ b/src/compilation.rs @@ -100,7 +100,7 @@ impl CodeGen for ASTNode { use self::ASTNode::*; match self { &ExprNode(ref expr) => expr.codegen(data), - &FuncNode(ref func) => func.codegen(data), + &FuncDefNode(ref func) => func.codegen(data), } } } diff --git a/src/eval.rs b/src/eval.rs index e3c2d82..638f298 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -86,7 +86,7 @@ impl Evaluable for ASTNode { use parser::ASTNode::*; match self { &ExprNode(ref expr) => expr.is_reducible(), - &FuncNode(_) => true, + &FuncDefNode(_) => true, } } } @@ -97,6 +97,7 @@ impl Evaluable for Expression { match *self { Null => false, StringLiteral(_) => false, + Lambda(_) => false, Number(_) => false, _ => true, } @@ -156,10 +157,11 @@ impl Evaluator { (ExprNode(expr), None) } } - FuncNode(func) => { + FuncDefNode(func) => { let fn_name = func.prototype.name.clone(); - self.add_function(fn_name, func); - (ExprNode(Expression::Null), None) + //TODO get rid of this clone + self.add_function(fn_name, func.clone()); + (ExprNode(Expression::Lambda(func)), None) } } } @@ -170,6 +172,7 @@ impl Evaluator { Null => (Null, None), e @ StringLiteral(_) => (e, None), e @ Number(_) => (e, None), + e @ Lambda(_) => (e, None), Variable(var) => { match self.lookup_binding(var) { None => (Null, None), diff --git a/src/parser.rs b/src/parser.rs index aee670f..b7a6cc9 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -23,7 +23,7 @@ use std::collections::VecDeque; #[derive(Debug, Clone)] pub enum ASTNode { ExprNode(Expression), - FuncNode(Function), + FuncDefNode(Function), } #[derive(Debug, Clone)] @@ -47,15 +47,16 @@ pub enum Expression { BinExp(String, Box, Box), Call(String, Vec), Conditional(Box, Box, Option>), + Lambda(Function), Block(VecDeque), } impl fmt::Display for ASTNode { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use self::ASTNode::*; - match self { - &ExprNode(ref expr) => write!(f, "{}", expr), - &FuncNode(_) => write!(f, "UNIMPLEMENTED"), + match *self { + ExprNode(ref expr) => write!(f, "{}", expr), + FuncDefNode(_) => write!(f, "UNIMPLEMENTED"), } } } @@ -67,6 +68,14 @@ impl fmt::Display for Expression { &Null => write!(f, "null"), &StringLiteral(ref s) => write!(f, "\"{}\"", s), &Number(n) => write!(f, "{}", n), + &Lambda(Function { + prototype: Prototype { + ref name, + ref parameters, + .. + }, + .. + }) => write!(f, "«function: {}, {} arg(s)»", name, parameters.len()), _ => write!(f, "UNIMPLEMENTED"), } } @@ -203,7 +212,7 @@ impl Parser { let prototype = try!(self.prototype()); let body: Vec = try!(self.body()); expect!(self, Keyword(Kw::End)); - Ok(ASTNode::FuncNode(Function { + Ok(ASTNode::FuncDefNode(Function { prototype: prototype, body: body, })) @@ -444,14 +453,14 @@ mod tests { parsetest!( "fn a() 1 + 2 end", - &[FuncNode(Function {prototype: Prototype { ref name, ref parameters }, ref body})], + &[FuncDefNode(Function {prototype: Prototype { ref name, ref parameters }, ref body})], match &body[..] { &[BinExp(_, box Number(1.0), box Number(2.0))] => true, _ => false } && name == "a" && match ¶meters[..] { &[] => true, _ => false } ); parsetest!( "fn a(x,y) 1 + 2 end", - &[FuncNode(Function {prototype: Prototype { ref name, ref parameters }, ref body})], + &[FuncDefNode(Function {prototype: Prototype { ref name, ref parameters }, ref body})], match &body[..] { &[BinExp(_, box Number(1.0), box Number(2.0))] => true, _ => false } && name == "a" && *parameters == ["x","y"] );