diff --git a/schala-lang/language/src/parsing.rs b/schala-lang/language/src/parsing.rs index 27b787b..24f2146 100644 --- a/schala-lang/language/src/parsing.rs +++ b/schala-lang/language/src/parsing.rs @@ -227,7 +227,8 @@ primary := literal | paren_expr | if_expr | for_expr | while_expr | identifier_e /* Primary Expressions */ list_expr := '[' (expression, ',')* ']' -lambda_expr := '\' formal_param_list type_anno+ nonempty_func_body +lambda_expr := '\' lambda_param_list type_anno+ nonempty_func_body +lambda_param_list := formal_param_list | formal_param paren_expr := LParen paren_inner RParen paren_inner := (expression ',')* identifier_expr := named_struct | IDENTIFIER @@ -638,7 +639,7 @@ impl Parser { #[recursive_descent_method] fn lambda_expr(&mut self) -> ParseResult { expect!(self, Backslash); - let params = self.formal_param_list()?; //TODO make this allow some more concise syntaxes + let params = self.lambda_param_list()?; let type_anno = match self.peek() { Colon => Some(self.type_anno()?), _ => None, @@ -647,6 +648,16 @@ impl Parser { Ok(Expression(ExpressionType::Lambda { params, type_anno, body }, None)) //TODO need to handle types somehow } + #[recursive_descent_method] + fn lambda_param_list(&mut self) -> ParseResult> { + if let LParen = self.peek() { + self.formal_param_list() + } else { + let single_param = self.formal_param()?; + Ok(vec![single_param]) + } + } + #[recursive_descent_method] fn paren_expr(&mut self) -> ParseResult { use self::ExpressionType::*; @@ -1511,6 +1522,27 @@ fn a(x) { } } + #[test] + fn single_param_lambda() { + parse_test_wrap_ast! { + r"\x { x + 10 }", + exst!(Lambda { + params: vec![(rc!(x), None)], + type_anno: None, + body: vec![exst!(s r"x + 10")] + }) + } + + parse_test_wrap_ast! { + r"\x: Nat { x + 10 }", + exst!(Lambda { + params: vec![(rc!(x), Some(ty!("Nat")))], + type_anno: None, + body: vec![exst!(s r"x + 10")] + }) + } + } + #[test] fn more_advanced_lambdas() { parse_test! {