Immediate lambda call
This commit is contained in:
parent
e4a42e7691
commit
f3c3d4595e
@ -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]
|
||||||
|
Loading…
Reference in New Issue
Block a user