Simpler syntax for single param in lambdas

This kind of implies that I might want -> for function types after all,
instead of :
This commit is contained in:
greg 2018-11-06 02:58:57 -08:00
parent 837a55c718
commit cee5b085d5
1 changed files with 34 additions and 2 deletions

View File

@ -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<Expression> {
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<Vec<FormalParam>> {
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<Expression> {
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! {