Add Lambda type
And change name FuncNode -> FuncDefNode Now function definition nodes reduce to a Lambda, which is not reducible.
This commit is contained in:
parent
ad994c38ae
commit
84fbe73cf6
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
src/eval.rs
11
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),
|
||||
|
@ -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<Expression>, Box<Expression>),
|
||||
Call(String, Vec<Expression>),
|
||||
Conditional(Box<Expression>, Box<Expression>, Option<Box<Expression>>),
|
||||
Lambda(Function),
|
||||
Block(VecDeque<Expression>),
|
||||
}
|
||||
|
||||
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<Expression> = 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"]
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user