Change lambda syntax

This commit is contained in:
greg 2018-11-05 18:50:45 -08:00
parent ad53d4394b
commit a74e09c761
2 changed files with 28 additions and 13 deletions

View File

@ -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))] })]));

View File

@ -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),