function literals (non-capturing)

This commit is contained in:
2026-07-07 17:04:38 +02:00
parent 95c61311ca
commit f171a6579d
5 changed files with 186 additions and 20 deletions
+52
View File
@@ -736,6 +736,8 @@ parse_primary :: proc(parser: ^Parser, nesting: int) -> ast.Expr_Id {
right=ast.INVALID_EXPR,
diagnostic=source.INVALID_DIAGNOSTIC,
})
case .Keyword_Func:
return parse_function_literal(parser)
case .Left_Bracket:
return parse_array_literal(parser, nesting)
case .Dot:
@@ -2111,6 +2113,56 @@ parse_function :: proc(parser: ^Parser, name: token.Token, c_abi: bool) {
})
}
parse_function_literal :: proc(parser: ^Parser) -> ast.Expr_Id {
start := advance(parser)
if _, ok := allow(parser, .Left_Paren); !ok {
source.add(parser.diagnostics, current(parser).span, "expected '(' after 'func'")
}
params, variadic := parse_params(parser)
if _, ok := allow(parser, .Right_Paren); !ok {
source.add(parser.diagnostics, current(parser).span, "expected ')' after parameters")
}
skip_newlines(parser)
result := parse_type(parser)
error_type := types.INVALID
if _, ok := allow(parser, .Bang); ok {
error_type = parse_error_type(parser)
}
if current(parser).kind == .Newline {
skip_newlines(parser)
}
if current(parser).kind != .Left_Brace {
delete(params, parser.module.allocator)
return invalid_expr(parser, start.span, "expected function literal body")
}
body := parse_block(parser)
end := previous(parser)
function_id := ast.function_id(len(parser.module.functions))
append(&parser.module.functions, ast.Function{
span=span_from(start.span, end.span),
name=symbol.INVALID,
pkg=parser.pkg,
file=parser.file,
c_abi=false,
generated=true,
has_body=true,
variadic=variadic,
params=params,
result=result,
error=error_type,
body=body,
diagnostic=source.INVALID_DIAGNOSTIC,
})
return add_expr(parser, ast.Expr{
kind=.Function_Literal,
span=span_from(start.span, end.span),
integer=u64(function_id),
left=ast.INVALID_EXPR,
right=ast.INVALID_EXPR,
diagnostic=source.INVALID_DIAGNOSTIC,
})
}
parse_record_field_type :: proc(parser: ^Parser, allow_anonymous_struct_payload: bool) -> types.Type {
if allow_anonymous_struct_payload && current(parser).kind == .Keyword_Struct {
return parse_inline_struct_payload_type(parser)