type annotations on lambdas

This commit is contained in:
greg 2018-11-05 19:10:34 -08:00
parent a74e09c761
commit 5953d9d815
2 changed files with 26 additions and 19 deletions

View File

@ -111,6 +111,7 @@ pub enum ExpressionType {
},
Lambda {
params: Vec<FormalParam>,
type_anno: Option<TypeIdentifier>,
body: Block,
},
ListLiteral(Vec<Expression>),

View File

@ -188,7 +188,7 @@ typed_identifier := IDENTIFIER type_anno
func_declaration := func_signature func_body
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 type_anno+
func_name := IDENTIFIER | operator
formal_param_list := '(' (formal_param ',')* ')'
formal_param := IDENTIFIER type_anno+
@ -227,7 +227,7 @@ primary := literal | paren_expr | if_expr | for_expr | while_expr | identifier_e
/* Primary Expressions */
list_expr := '[' (expression, ',')* ']'
lambda_expr := '\' formal_param_list nonempty_func_body
lambda_expr := '\' formal_param_list type_anno+ nonempty_func_body
paren_expr := LParen paren_inner RParen
paren_inner := (expression ',')*
identifier_expr := named_struct | IDENTIFIER
@ -639,22 +639,12 @@ impl Parser {
fn lambda_expr(&mut self) -> ParseResult<Expression> {
expect!(self, Backslash);
let params = self.formal_param_list()?; //TODO make this allow some more concise syntaxes
let type_anno = match self.peek() {
Colon => Some(self.type_anno()?),
_ => None,
};
let body = self.nonempty_func_body()?;
/*
let mut body = Vec::new();
loop {
match self.peek() {
EOF | RCurlyBrace => break,
Newline | Semicolon => {
self.next();
continue;
},
_ => body.push(self.statement()?),
}
}
expect!(self, RCurlyBrace);
*/
Ok(Expression(ExpressionType::Lambda { params, body }, None)) //TODO need to handle types somehow
Ok(Expression(ExpressionType::Lambda { params, type_anno, body }, None)) //TODO need to handle types somehow
}
#[recursive_descent_method]
@ -1483,20 +1473,36 @@ fn a(x) {
#[test]
fn parsing_lambdas() {
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)], type_anno: None, body: vec![exst!("+", val!("x"), NatLiteral(1))] }
) }
parse_test!(r#"\ (x: Int, y) { a;b;c;}"#, AST(vec![
exprstatement!(Lambda {
params: vec![(rc!(x), Some(ty!("Int"))), (rc!(y), None)],
type_anno: None,
body: vec![exst!(val!("a")), exst!(val!("b")), exst!(val!("c"))]
})
]));
parse_test!(r#"\(x){y}(1)"#, AST(vec![
exprstatement!(Call { f: bx!(ex!(
Lambda { params: vec![(rc!(x), None)], body: vec![exprstatement!(val!("y"))] })),
Lambda {
params: vec![(rc!(x), None)],
type_anno: None,
body: vec![exprstatement!(val!("y"))] }
)),
arguments: vec![ex!(NatLiteral(1))] })]));
parse_test! {
r#"\(x: Int): String { "q" }"#,
AST(vec![
exprstatement!(Lambda {
params: vec![(rc!(x), Some(ty!("Int")))],
type_anno: Some(ty!("String")),
body: vec![exprstatement!(StringLiteral(rc!(q)))]
})
])
}
}
#[test]