Immediate lambda call

This commit is contained in:
greg 2017-02-17 01:54:47 -08:00
parent e4a42e7691
commit f3c3d4595e

View File

@ -1,4 +1,3 @@
use schala_lang::tokenizer::{Token, Kw, OpTok}; use schala_lang::tokenizer::{Token, Kw, OpTok};
use schala_lang::tokenizer::Token::*; use schala_lang::tokenizer::Token::*;
@ -16,18 +15,18 @@ use std::convert::From;
// identlist := Ident (Comma Ident)* | e // identlist := Ident (Comma Ident)* | e
// exprlist := Expression (Comma Expression)* | e // exprlist := Expression (Comma Expression)* | e
// //
// expression := primary_expression (op primary_expression)* // expression := postop_expression (op postop_expression)*
// primary_expression := number_expr | String | identifier_expr | paren_expr | conditional_expr | // postop_expression := primary_expression postop
// while_expr | lambda_expr // primary_expression := number_expr | String | identifier_expr | paren_expr | conditional_expr | while_expr | lambda_expr
// number_expr := (PLUS | MINUS ) number_expr | Number // number_expr := (PLUS | MINUS ) number_expr | Number
// identifier_expr := call_expression | Variable // identifier_expr := call_expression | Variable
// call_expr := Identifier LParen exprlist RParen // call_expression := Identifier LParen exprlist RParen
// while_expr := WHILE primary_expression LCurlyBrace (expression delimiter)* RCurlyBrace // while_expr := WHILE primary_expression LCurlyBrace (expression delimiter)* RCurlyBrace
// paren_expr := LParen expression RParen // paren_expr := LParen expression RParen
// conditional_expr := IF expression LCurlyBrace (expression delimiter)* RCurlyBrace (LCurlyBrace (expresion delimiter)* RCurlyBrace)? // conditional_expr := IF expression LCurlyBrace (expression delimiter)* RCurlyBrace (LCurlyBrace (expresion delimiter)* RCurlyBrace)?
// lambda_expr := FN LParen identlist RParen LCurlyBrace (expression delimiter)* RCurlyBrace // lambda_expr := FN LParen identlist RParen LCurlyBrace (expression delimiter)* RCurlyBrace
// lambda_call // lambda_call := | LParen exprlist RParen
// lambda_call := ε | LParen exprlist RParen // postop := ε | LParen exprlist RParen | LBracket expression RBracket
// op := '+', '-', etc. // op := '+', '-', etc.
// //
@ -358,7 +357,7 @@ impl Parser {
} }
fn expression(&mut self) -> ParseResult<Expression> { fn expression(&mut self) -> ParseResult<Expression> {
let lhs: Expression = try!(self.primary_expression()); let lhs: Expression = try!(self.postop_expression());
self.precedence_expr(lhs, 0) self.precedence_expr(lhs, 0)
} }
@ -372,7 +371,7 @@ impl Parser {
break; break;
} }
self.next(); self.next();
let mut rhs = try!(self.primary_expression()); let mut rhs = try!(self.postop_expression());
while let Some(Operator(ref op)) = self.peek() { while let Some(Operator(ref op)) = self.peek() {
if self.get_precedence(op) > precedence { if self.get_precedence(op) > precedence {
let new_prec = self.get_precedence(op); let new_prec = self.get_precedence(op);
@ -388,6 +387,30 @@ impl Parser {
Ok(lhs) Ok(lhs)
} }
fn postop_expression(&mut self) -> ParseResult<Expression> {
use self::Expression::*;
let expr = try!(self.primary_expression());
let ret = match self.peek() {
Some(LParen) => {
let args = try!(self.call_expression());
match expr {
Lambda(f) => Call(Callable::Lambda(f), args),
e => {
let err = format!("Expected lambda expression before a call, got {:?}", e);
return ParseError::result_from_str(&err);
},
}
},
Some(LSquareBracket) => {
unimplemented!()
},
_ => {
expr
}
};
Ok(ret)
}
fn primary_expression(&mut self) -> ParseResult<Expression> { fn primary_expression(&mut self) -> ParseResult<Expression> {
Ok(match self.peek() { Ok(match self.peek() {
Some(Keyword(Kw::Null)) => { Some(Keyword(Kw::Null)) => {
@ -463,13 +486,7 @@ impl Parser {
body: body, body: body,
}; };
match self.peek() { Ok(Lambda(function))
Some(LParen) => {
let args = try!(self.call_expr());
Ok(Call(Callable::Lambda(function), args))
},
_ => Ok(Lambda(function))
}
} }
fn while_expr(&mut self) -> ParseResult<Expression> { fn while_expr(&mut self) -> ParseResult<Expression> {
@ -523,7 +540,7 @@ impl Parser {
let name = expect_identifier!(self); let name = expect_identifier!(self);
let expr = match self.peek() { let expr = match self.peek() {
Some(LParen) => { Some(LParen) => {
let args = try!(self.call_expr()); let args = try!(self.call_expression());
Expression::Call(Callable::NamedFunction(name), args) Expression::Call(Callable::NamedFunction(name), args)
} }
__ => Expression::Variable(name), __ => Expression::Variable(name),
@ -531,7 +548,7 @@ impl Parser {
Ok(expr) Ok(expr)
} }
fn call_expr(&mut self) -> ParseResult<Vec<Expression>> { fn call_expression(&mut self) -> ParseResult<Vec<Expression>> {
expect!(self, LParen); expect!(self, LParen);
let args: Vec<Expression> = try!(self.exprlist()); let args: Vec<Expression> = try!(self.exprlist());
expect!(self, RParen); expect!(self, RParen);
@ -622,6 +639,12 @@ mod tests {
let t2 = "fn(x) { x + 2 }"; let t2 = "fn(x) { x + 2 }";
let tokens2 = tokenizer::tokenize(t2).unwrap(); let tokens2 = tokenizer::tokenize(t2).unwrap();
assert!(parse(&tokens2, &[]).is_err()); assert!(parse(&tokens2, &[]).is_err());
let t3 = "(fn(x) { x + 10 })(20)";
let tokens3 = tokenizer::tokenize(t3).unwrap();
match parse(&tokens3, &[]).unwrap() {
_ => (),
};
} }
#[test] #[test]