summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuhaitz <zuhaitz.zechhub@gmail.com>2026-01-25 10:37:37 +0000
committerGitHub <noreply@github.com>2026-01-25 10:37:37 +0000
commit2852e409a1acd55104aa8ed7679c566192c88607 (patch)
treecbbc7006ccd93082cc6b1da1c4a0c4a0f93f51ac
parent17cc0542def402f5b0788ff9e8fe0538f81d5ddf (diff)
parent026e3322b0cd6b1c813b05c1b65bea192a0be041 (diff)
Merge pull request #122 from Burnett01/fix/lambda-block-syntax-fn
fix(parser_expr): lambda block syntax "fn"
-rw-r--r--src/parser/parser_expr.c23
-rw-r--r--tests/functions/test_lambdas.zc31
2 files changed, 51 insertions, 3 deletions
diff --git a/src/parser/parser_expr.c b/src/parser/parser_expr.c
index 3d563e0..fc3abb7 100644
--- a/src/parser/parser_expr.c
+++ b/src/parser/parser_expr.c
@@ -789,6 +789,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;
@@ -820,9 +822,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);
@@ -830,7 +834,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;
@@ -851,9 +864,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!";