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 { Lambda {
params: Vec<FormalParam>, params: Vec<FormalParam>,
type_anno: Option<TypeIdentifier>,
body: Block, body: Block,
}, },
ListLiteral(Vec<Expression>), ListLiteral(Vec<Expression>),

View File

@ -188,7 +188,7 @@ typed_identifier := IDENTIFIER type_anno
func_declaration := func_signature func_body func_declaration := func_signature func_body
func_body := ε | nonempty_func_body func_body := ε | nonempty_func_body
nonempty_func_body := '{' (statement delimiter)* '}' 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 func_name := IDENTIFIER | operator
formal_param_list := '(' (formal_param ',')* ')' formal_param_list := '(' (formal_param ',')* ')'
formal_param := IDENTIFIER type_anno+ formal_param := IDENTIFIER type_anno+
@ -227,7 +227,7 @@ primary := literal | paren_expr | if_expr | for_expr | while_expr | identifier_e
/* Primary Expressions */ /* Primary Expressions */
list_expr := '[' (expression, ',')* ']' 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_expr := LParen paren_inner RParen
paren_inner := (expression ',')* paren_inner := (expression ',')*
identifier_expr := named_struct | IDENTIFIER identifier_expr := named_struct | IDENTIFIER
@ -639,22 +639,12 @@ impl Parser {
fn lambda_expr(&mut self) -> ParseResult<Expression> { fn lambda_expr(&mut self) -> ParseResult<Expression> {
expect!(self, Backslash); expect!(self, Backslash);
let params = self.formal_param_list()?; //TODO make this allow some more concise syntaxes 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 body = self.nonempty_func_body()?;
/* Ok(Expression(ExpressionType::Lambda { params, type_anno, body }, None)) //TODO need to handle types somehow
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
} }
#[recursive_descent_method] #[recursive_descent_method]
@ -1483,20 +1473,36 @@ fn a(x) {
#[test] #[test]
fn parsing_lambdas() { fn parsing_lambdas() {
parse_test! { r#"\(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)], type_anno: None, body: vec![exst!("+", val!("x"), NatLiteral(1))] }
) } ) }
parse_test!(r#"\ (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)],
type_anno: 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!(r#"\(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)],
type_anno: None,
body: vec![exprstatement!(val!("y"))] }
)),
arguments: vec![ex!(NatLiteral(1))] })])); 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] #[test]