From 88d2571401df0b2fcad305c8b38c345b0ba1735b Mon Sep 17 00:00:00 2001 From: Greg Shuflin Date: Fri, 19 Nov 2021 00:52:00 -0800 Subject: [PATCH] Lambdas --- schala-lang/src/parsing/combinator.rs | 11 ++++++++++- schala-lang/src/parsing/test.rs | 14 +++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/schala-lang/src/parsing/combinator.rs b/schala-lang/src/parsing/combinator.rs index 2b00366..c8deb5a 100644 --- a/schala-lang/src/parsing/combinator.rs +++ b/schala-lang/src/parsing/combinator.rs @@ -454,13 +454,13 @@ fn primary_expr(allow_struct: bool) -> impl FnMut(Span) -> ParseResult ParseResult { - println!("PRIM EXPR: {}", input.fragment()); context( "primary-expr-no-struct", alt(( while_expr, for_expr, if_expr, + lambda_expr, list_expr, paren_expr, string_literal, @@ -487,6 +487,15 @@ fn record_block(input: Span) -> ParseResult, Expression)>> { delimited(tok(char('{')), separated_list0(tok(char(',')), record_entry), tok(char('}')))(input) } +fn lambda_expr(input: Span) -> ParseResult { + alt(( + map(preceded(tok(char('\\')), tuple((formal_params, opt(type_anno), block))), + |(params, type_anno, body)| ExpressionKind::Lambda { params, type_anno, body }), + map(preceded(tok(char('\\')), tuple((formal_param, opt(type_anno), block))), + |(param, type_anno, body)| ExpressionKind::Lambda { params: vec![param], type_anno, body }), + ))(input) +} + fn while_expr(input: Span) -> ParseResult { let id = fresh_id(&input); map(preceded(kw("while"), pair(opt(expression_no_struct), block)), move |(condition, body)| { diff --git a/schala-lang/src/parsing/test.rs b/schala-lang/src/parsing/test.rs index 71739c1..76519ca 100644 --- a/schala-lang/src/parsing/test.rs +++ b/schala-lang/src/parsing/test.rs @@ -416,7 +416,7 @@ fn for_expression() { fn lambda_expressions() { use ExpressionKind::*; - assert_expr!( + assert_expr_comb!( r#"\(x) { x + 1}"#, expr(Lambda { params: vec![FormalParam { name: rc!(x), anno: None, default: None }], @@ -427,7 +427,7 @@ fn lambda_expressions() { }) ); - assert_expr!( + assert_expr_comb!( r#"\ (x: Int, y) { a;b;c;}"#, expr(Lambda { params: vec![ @@ -444,7 +444,7 @@ fn lambda_expressions() { }) ); - assert_expr!( + assert_expr_comb!( r#"\(x){y}(1)"#, expr(Call { f: bx(expr(Lambda { @@ -456,7 +456,7 @@ fn lambda_expressions() { }) ); - assert_expr!( + assert_expr_comb!( r#"\(x: Int): String { "q" }"#, expr(Lambda { params: vec![FormalParam { name: rc!(x), anno: Some(ty_simple("Int")), default: None },], @@ -473,7 +473,7 @@ fn lambda_expressions() { fn single_param_lambda() { use ExpressionKind::*; - assert_expr!( + assert_expr_comb!( r#"\x { x + 10 }"#, expr(Lambda { params: vec![FormalParam { name: rc!(x), anno: None, default: None },], @@ -487,7 +487,7 @@ fn single_param_lambda() { }) ); - assert_expr!( + assert_expr_comb!( r#"\x: Int { x + 10 }"#, expr(Lambda { params: vec![FormalParam { name: rc!(x), anno: Some(ty_simple("Int")), default: None },], @@ -507,7 +507,7 @@ fn complex_lambdas() { use ExpressionKind::*; //TODO support this without the semicolon after the lambda - assert_ast! { + assert_ast_comb! { r#"fn wahoo() { let a = 10; \(x) { x + a }; } wahoo()(3) "#, vec![