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::*;
|
use self::ASTNode::*;
|
||||||
match self {
|
match self {
|
||||||
&ExprNode(ref expr) => expr.codegen(data),
|
&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::*;
|
use parser::ASTNode::*;
|
||||||
match self {
|
match self {
|
||||||
&ExprNode(ref expr) => expr.is_reducible(),
|
&ExprNode(ref expr) => expr.is_reducible(),
|
||||||
&FuncNode(_) => true,
|
&FuncDefNode(_) => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,6 +97,7 @@ impl Evaluable for Expression {
|
|||||||
match *self {
|
match *self {
|
||||||
Null => false,
|
Null => false,
|
||||||
StringLiteral(_) => false,
|
StringLiteral(_) => false,
|
||||||
|
Lambda(_) => false,
|
||||||
Number(_) => false,
|
Number(_) => false,
|
||||||
_ => true,
|
_ => true,
|
||||||
}
|
}
|
||||||
@ -156,10 +157,11 @@ impl Evaluator {
|
|||||||
(ExprNode(expr), None)
|
(ExprNode(expr), None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FuncNode(func) => {
|
FuncDefNode(func) => {
|
||||||
let fn_name = func.prototype.name.clone();
|
let fn_name = func.prototype.name.clone();
|
||||||
self.add_function(fn_name, func);
|
//TODO get rid of this clone
|
||||||
(ExprNode(Expression::Null), None)
|
self.add_function(fn_name, func.clone());
|
||||||
|
(ExprNode(Expression::Lambda(func)), None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,6 +172,7 @@ impl Evaluator {
|
|||||||
Null => (Null, None),
|
Null => (Null, None),
|
||||||
e @ StringLiteral(_) => (e, None),
|
e @ StringLiteral(_) => (e, None),
|
||||||
e @ Number(_) => (e, None),
|
e @ Number(_) => (e, None),
|
||||||
|
e @ Lambda(_) => (e, None),
|
||||||
Variable(var) => {
|
Variable(var) => {
|
||||||
match self.lookup_binding(var) {
|
match self.lookup_binding(var) {
|
||||||
None => (Null, None),
|
None => (Null, None),
|
||||||
|
@ -23,7 +23,7 @@ use std::collections::VecDeque;
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ASTNode {
|
pub enum ASTNode {
|
||||||
ExprNode(Expression),
|
ExprNode(Expression),
|
||||||
FuncNode(Function),
|
FuncDefNode(Function),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -47,15 +47,16 @@ pub enum Expression {
|
|||||||
BinExp(String, Box<Expression>, Box<Expression>),
|
BinExp(String, Box<Expression>, Box<Expression>),
|
||||||
Call(String, Vec<Expression>),
|
Call(String, Vec<Expression>),
|
||||||
Conditional(Box<Expression>, Box<Expression>, Option<Box<Expression>>),
|
Conditional(Box<Expression>, Box<Expression>, Option<Box<Expression>>),
|
||||||
|
Lambda(Function),
|
||||||
Block(VecDeque<Expression>),
|
Block(VecDeque<Expression>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ASTNode {
|
impl fmt::Display for ASTNode {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
use self::ASTNode::*;
|
use self::ASTNode::*;
|
||||||
match self {
|
match *self {
|
||||||
&ExprNode(ref expr) => write!(f, "{}", expr),
|
ExprNode(ref expr) => write!(f, "{}", expr),
|
||||||
&FuncNode(_) => write!(f, "UNIMPLEMENTED"),
|
FuncDefNode(_) => write!(f, "UNIMPLEMENTED"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,6 +68,14 @@ impl fmt::Display for Expression {
|
|||||||
&Null => write!(f, "null"),
|
&Null => write!(f, "null"),
|
||||||
&StringLiteral(ref s) => write!(f, "\"{}\"", s),
|
&StringLiteral(ref s) => write!(f, "\"{}\"", s),
|
||||||
&Number(n) => write!(f, "{}", n),
|
&Number(n) => write!(f, "{}", n),
|
||||||
|
&Lambda(Function {
|
||||||
|
prototype: Prototype {
|
||||||
|
ref name,
|
||||||
|
ref parameters,
|
||||||
|
..
|
||||||
|
},
|
||||||
|
..
|
||||||
|
}) => write!(f, "«function: {}, {} arg(s)»", name, parameters.len()),
|
||||||
_ => write!(f, "UNIMPLEMENTED"),
|
_ => write!(f, "UNIMPLEMENTED"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,7 +212,7 @@ impl Parser {
|
|||||||
let prototype = try!(self.prototype());
|
let prototype = try!(self.prototype());
|
||||||
let body: Vec<Expression> = try!(self.body());
|
let body: Vec<Expression> = try!(self.body());
|
||||||
expect!(self, Keyword(Kw::End));
|
expect!(self, Keyword(Kw::End));
|
||||||
Ok(ASTNode::FuncNode(Function {
|
Ok(ASTNode::FuncDefNode(Function {
|
||||||
prototype: prototype,
|
prototype: prototype,
|
||||||
body: body,
|
body: body,
|
||||||
}))
|
}))
|
||||||
@ -444,14 +453,14 @@ mod tests {
|
|||||||
|
|
||||||
parsetest!(
|
parsetest!(
|
||||||
"fn a() 1 + 2 end",
|
"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 }
|
match &body[..] { &[BinExp(_, box Number(1.0), box Number(2.0))] => true, _ => false }
|
||||||
&& name == "a" && match ¶meters[..] { &[] => true, _ => false }
|
&& name == "a" && match ¶meters[..] { &[] => true, _ => false }
|
||||||
);
|
);
|
||||||
|
|
||||||
parsetest!(
|
parsetest!(
|
||||||
"fn a(x,y) 1 + 2 end",
|
"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 }
|
match &body[..] { &[BinExp(_, box Number(1.0), box Number(2.0))] => true, _ => false }
|
||||||
&& name == "a" && *parameters == ["x","y"]
|
&& name == "a" && *parameters == ["x","y"]
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user