Change lambda syntax
This commit is contained in:
parent
ad53d4394b
commit
a74e09c761
@ -186,7 +186,8 @@ typed_identifier := IDENTIFIER type_anno
|
||||
/* Declaration - Functions */
|
||||
|
||||
func_declaration := func_signature func_body
|
||||
func_body := ε | '{' (statement delimiter)* '}'
|
||||
func_body := ε | nonempty_func_body
|
||||
nonempty_func_body := '{' (statement delimiter)* '}'
|
||||
func_signature := 'fn' func_name formal_param_list func_body
|
||||
func_name := IDENTIFIER | operator
|
||||
formal_param_list := '(' (formal_param ',')* ')'
|
||||
@ -221,13 +222,12 @@ prefix_op := '+' | '-' | '!' | '~'
|
||||
call_expr := index_expr ( '(' expr_list ')' )*
|
||||
expr_list := expression (',' expression)* | ε
|
||||
index_expr := primary ( '[' (expression (',' (expression)* | ε) ']' )*
|
||||
primary := literal | paren_expr | if_expr | for_expr | while_expr | identifier_expr | curly_brace_expr | list_expr
|
||||
primary := literal | paren_expr | if_expr | for_expr | while_expr | identifier_expr | lambda_expr | anonymous_struct | list_expr
|
||||
|
||||
/* Primary Expressions */
|
||||
|
||||
curly_brace_expr := lambda_expr | anonymous_struct //TODO
|
||||
list_expr := '[' (expression, ',')* ']'
|
||||
lambda_expr := '{' '|' (formal_param ',')* '|' (type_anno)* (statement delimiter)* '}'
|
||||
lambda_expr := '\' formal_param_list nonempty_func_body
|
||||
paren_expr := LParen paren_inner RParen
|
||||
paren_inner := (expression ',')*
|
||||
identifier_expr := named_struct | IDENTIFIER
|
||||
@ -389,7 +389,7 @@ impl Parser {
|
||||
fn func_declaration(&mut self) -> ParseResult<Declaration> {
|
||||
let signature = self.func_signature()?;
|
||||
if let LCurlyBrace = self.peek() {
|
||||
let statements = delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict);
|
||||
let statements = self.nonempty_func_body()?;
|
||||
Ok(Declaration::FuncDecl(signature, statements))
|
||||
} else {
|
||||
Ok(Declaration::FuncSig(signature))
|
||||
@ -407,7 +407,7 @@ impl Parser {
|
||||
},
|
||||
_ => (self.identifier()?, false)
|
||||
};
|
||||
let params = delimited!(self, LParen, formal_param, Comma, RParen);
|
||||
let params = self.formal_param_list()?;
|
||||
let type_anno = match self.peek() {
|
||||
Colon => Some(self.type_anno()?),
|
||||
_ => None,
|
||||
@ -415,6 +415,16 @@ impl Parser {
|
||||
Ok(Signature { name, operator, params, type_anno })
|
||||
}
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn nonempty_func_body(&mut self) -> ParseResult<Vec<Statement>> {
|
||||
Ok(delimited!(self, LCurlyBrace, statement, Newline | Semicolon, RCurlyBrace, nonstrict))
|
||||
}
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn formal_param_list(&mut self) -> ParseResult<Vec<FormalParam>> {
|
||||
Ok(delimited!(self, LParen, formal_param, Comma, RParen))
|
||||
}
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn formal_param(&mut self) -> ParseResult<FormalParam> {
|
||||
let name = self.identifier()?;
|
||||
@ -603,6 +613,7 @@ impl Parser {
|
||||
fn primary(&mut self) -> ParseResult<Expression> {
|
||||
match self.peek() {
|
||||
LCurlyBrace => self.curly_brace_expr(),
|
||||
Backslash => self.lambda_expr(),
|
||||
LParen => self.paren_expr(),
|
||||
LSquareBracket => self.list_expr(),
|
||||
Keyword(Kw::If) => self.if_expr(),
|
||||
@ -621,13 +632,15 @@ impl Parser {
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn curly_brace_expr(&mut self) -> ParseResult<Expression> {
|
||||
self.lambda_expr()
|
||||
ParseError::new("Not implemented")
|
||||
}
|
||||
|
||||
#[recursive_descent_method]
|
||||
fn lambda_expr(&mut self) -> ParseResult<Expression> {
|
||||
expect!(self, LCurlyBrace);
|
||||
let params = delimited!(self, Pipe, formal_param, Comma, Pipe);
|
||||
expect!(self, Backslash);
|
||||
let params = self.formal_param_list()?; //TODO make this allow some more concise syntaxes
|
||||
let body = self.nonempty_func_body()?;
|
||||
/*
|
||||
let mut body = Vec::new();
|
||||
loop {
|
||||
match self.peek() {
|
||||
@ -640,6 +653,7 @@ impl Parser {
|
||||
}
|
||||
}
|
||||
expect!(self, RCurlyBrace);
|
||||
*/
|
||||
Ok(Expression(ExpressionType::Lambda { params, body }, None)) //TODO need to handle types somehow
|
||||
}
|
||||
|
||||
@ -1468,18 +1482,18 @@ fn a(x) {
|
||||
|
||||
#[test]
|
||||
fn parsing_lambdas() {
|
||||
parse_test! { "{|x| x + 1}", single_expr!(
|
||||
parse_test! { r#"\(x) { x + 1}"#, single_expr!(
|
||||
Lambda { params: vec![(rc!(x), None)], body: vec![exst!("+", val!("x"), NatLiteral(1))] }
|
||||
) }
|
||||
|
||||
parse_test!("{ |x: Int, y| a;b;c;}", AST(vec![
|
||||
parse_test!(r#"\ (x: Int, y) { a;b;c;}"#, AST(vec![
|
||||
exprstatement!(Lambda {
|
||||
params: vec![(rc!(x), Some(ty!("Int"))), (rc!(y), None)],
|
||||
body: vec![exst!(val!("a")), exst!(val!("b")), exst!(val!("c"))]
|
||||
})
|
||||
]));
|
||||
|
||||
parse_test!("{|x| y}(1)", AST(vec![
|
||||
parse_test!(r#"\(x){y}(1)"#, AST(vec![
|
||||
exprstatement!(Call { f: bx!(ex!(
|
||||
Lambda { params: vec![(rc!(x), None)], body: vec![exprstatement!(val!("y"))] })),
|
||||
arguments: vec![ex!(NatLiteral(1))] })]));
|
||||
|
@ -12,7 +12,7 @@ pub enum TokenType {
|
||||
LSquareBracket, RSquareBracket,
|
||||
LAngleBracket, RAngleBracket,
|
||||
LCurlyBrace, RCurlyBrace,
|
||||
Pipe,
|
||||
Pipe, Backslash,
|
||||
|
||||
Comma, Period, Colon, Underscore,
|
||||
Slash,
|
||||
@ -157,6 +157,7 @@ pub fn tokenize(input: &str) -> Vec<Token> {
|
||||
'{' => LCurlyBrace, '}' => RCurlyBrace,
|
||||
'[' => LSquareBracket, ']' => RSquareBracket,
|
||||
'"' => handle_quote(&mut input),
|
||||
'\\' => Backslash,
|
||||
c if c.is_digit(10) => handle_digit(c, &mut input),
|
||||
c if c.is_alphabetic() || c == '_' => handle_alphabetic(c, &mut input), //TODO I'll probably have to rewrite this if I care about types being uppercase, also type parameterization
|
||||
c if is_operator(&c) => handle_operator(c, &mut input),
|
||||
|
Loading…
Reference in New Issue
Block a user