struct type construction

This commit is contained in:
2026-07-19 21:35:48 +02:00
parent 944648fce6
commit 59bbb197e0
15 changed files with 331415 additions and 253804 deletions
+37 -2
View File
@@ -434,6 +434,18 @@ parse_type_atom :: proc(parser: ^Parser) -> ast.Type_Syntax {
u32(parser.file),
!symbol.is_valid(qualifier) && file_hidden_name(parser, name.symbol),
)
if current(parser).kind == .Bang && peek(parser).kind == .Left_Paren {
advance(parser)
if symbol.is_valid(qualifier) {
source.add(parser.diagnostics, first.span, "intrinsic calls must be unqualified")
return types.INVALID
}
call := parse_call(parser, qualifier, first, name, 0, true)
return types.intern(&parser.module.type_store, types.Node{
kind=.Type_Call,
count_expr=u32(call),
})
}
if current(parser).kind == .Left_Paren {
call := parse_call(parser, qualifier, first, name, 0, false)
return types.intern(&parser.module.type_store, types.Node{
@@ -620,6 +632,7 @@ parse_keyed_initializers :: proc(
left_brace: token.Token,
nesting: int,
close_message: string,
require_values := false,
) -> ([]ast.Expr_Id, token.Token) {
parser.delimiter_depth += 1
defer parser.delimiter_depth -= 1
@@ -640,6 +653,8 @@ parse_keyed_initializers :: proc(
skip_newlines(parser)
value = parse_expression_bp(parser, 0, nesting+1)
key_end = parser.module.exprs[value].span
} else if require_values {
source.add(parser.diagnostics, field.span, "anonymous record fields require '= value'")
}
append(&args, add_expr(parser, ast.Expr{
kind=.Keyed,
@@ -696,6 +711,15 @@ brace_starts_tuple :: proc(parser: ^Parser) -> bool {
if current(parser).kind != .Left_Brace {
return false
}
first := parser.cursor+1
for first < len(parser.tokens.items) && parser.tokens.items[first].kind == .Newline {
first += 1
}
if first+1 < len(parser.tokens.items) &&
(parser.tokens.items[first].kind == .Identifier || token.is_keyword(parser.tokens.items[first].kind)) &&
parser.tokens.items[first+1].kind == .Equal {
return true
}
depth := 0
for cursor := parser.cursor; cursor < len(parser.tokens.items); cursor += 1 {
#partial switch parser.tokens.items[cursor].kind {
@@ -720,12 +744,23 @@ brace_starts_tuple :: proc(parser: ^Parser) -> bool {
parse_tuple_literal :: proc(parser: ^Parser, nesting: int) -> ast.Expr_Id {
left_brace := advance(parser)
args, right_brace := parse_positional_initializers(parser, left_brace, nesting, "expected '}' after tuple literal")
skip_newlines(parser)
keyed := (current(parser).kind == .Identifier || token.is_keyword(current(parser).kind)) &&
peek(parser).kind == .Equal
args: []ast.Expr_Id
right_brace: token.Token
if keyed {
args, right_brace = parse_keyed_initializers(
parser, left_brace, nesting, "expected '}' after anonymous record literal", true,
)
} else {
args, right_brace = parse_positional_initializers(parser, left_brace, nesting, "expected '}' after tuple literal")
}
return add_expr(parser, ast.Expr{
kind=.Struct_Literal,
span=span_from(left_brace.span, right_brace.span),
args=args,
tuple=true,
tuple=!keyed,
left=ast.INVALID_EXPR,
right=ast.INVALID_EXPR,
diagnostic=source.INVALID_DIAGNOSTIC,