diff options
| -rw-r--r-- | src/parser/parser_expr.c | 23 | ||||
| -rw-r--r-- | tests/functions/test_lambdas.zc | 31 |
2 files changed, 51 insertions, 3 deletions
diff --git a/src/parser/parser_expr.c b/src/parser/parser_expr.c index 28c19ad..f84d52a 100644 --- a/src/parser/parser_expr.c +++ b/src/parser/parser_expr.c @@ -783,6 +783,8 @@ ASTNode *parse_lambda(ParserContext *ctx, Lexer *l) lexer_next(l); + Type *t = type_new(TYPE_FUNCTION); + t->args = xmalloc(sizeof(Type *) * 16); char **param_names = xmalloc(sizeof(char *) * 16); char **param_types = xmalloc(sizeof(char *) * 16); int num_params = 0; @@ -814,9 +816,11 @@ ASTNode *parse_lambda(ParserContext *ctx, Lexer *l) lexer_next(l); - char *param_type_str = parse_type(ctx, l); - param_types[num_params] = param_type_str; + Type *typef = parse_type_formal(ctx, l); + t->args[t->arg_count] = typef; + param_types[num_params] = type_to_string(typef); num_params++; + t->arg_count = num_params; } lexer_next(l); @@ -824,7 +828,16 @@ ASTNode *parse_lambda(ParserContext *ctx, Lexer *l) if (lexer_peek(l).type == TOK_ARROW) { lexer_next(l); - return_type = parse_type(ctx, l); + + t->inner = parse_type_formal(ctx, l); + return_type = type_to_string(t->inner); + } + + enter_scope(ctx); + + for (int i = 0; i < num_params; i++) + { + add_symbol(ctx, param_names[i], param_types[i], t->args[i]); } ASTNode *body = NULL; @@ -845,9 +858,13 @@ ASTNode *parse_lambda(ParserContext *ctx, Lexer *l) lambda->lambda.num_params = num_params; lambda->lambda.lambda_id = ctx->lambda_counter++; lambda->lambda.is_expression = 0; + lambda->type_info = t; + lambda->resolved_type = type_to_string(t); register_lambda(ctx, lambda); analyze_lambda_captures(ctx, lambda); + exit_scope(ctx); + return lambda; } diff --git a/tests/functions/test_lambdas.zc b/tests/functions/test_lambdas.zc index 5f2c086..a0daaf1 100644 --- a/tests/functions/test_lambdas.zc +++ b/tests/functions/test_lambdas.zc @@ -60,6 +60,37 @@ test "test_complex_lambdas" { println " -> Nested application: Failed"; exit(1); } + + // Lambda with "fn" syntax (eg. block lambda) + var factor = 2; + var full = fn(x: int) -> int { return x * factor }; + + if (full(3) == 6) { + println " -> Lambda fn syntax: Passed"; + } else { + println " -> Lambda fn syntax: Failed"; + exit(1); + } + + // Lambda with "fn" syntax (eg. block lambda) + multiple params + var addition = fn(sum1: int, sum2: int) -> int { return sum1 + sum2 }; + + if (addition(100, 505) == 605) { + println " -> Lambda fn syntax: Passed"; + } else { + println " -> Lambda fn syntax: Failed"; + exit(1); + } + + // Lambda with "fn" syntax (eg. block lambda) + named args + var substract = fn(arg1: int, arg2: int) -> int { return arg1 - arg2 }; + + if (substract(arg1: 500, arg2: 100) == 400) { + println " -> Lambda fn syntax: Passed"; + } else { + println " -> Lambda fn syntax: Failed"; + exit(1); + } println "All complex lambda tests passed!"; |
