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