default struct fields
This commit is contained in:
@@ -2532,6 +2532,7 @@ parse_record_body :: proc(
|
||||
allow_anonymous_struct_payload := false,
|
||||
allow_keyword_names := false,
|
||||
tuple_result: ^bool = nil,
|
||||
defaults: ^[dynamic]ast.Expr_Id = nil,
|
||||
) -> bool {
|
||||
if _, ok := allow(parser, .Left_Brace); !ok {
|
||||
source.add(parser.diagnostics, current(parser).span, expected_open)
|
||||
@@ -2557,6 +2558,9 @@ parse_record_body :: proc(
|
||||
mode = 2
|
||||
field_type := parse_type(parser)
|
||||
append(fields, types.Field{name=0, type=field_type})
|
||||
if defaults != nil {
|
||||
append(defaults, ast.INVALID_EXPR)
|
||||
}
|
||||
} else {
|
||||
if mode == 2 {
|
||||
source.add(parser.diagnostics, current(parser).span, "struct fields cannot mix named and unnamed forms")
|
||||
@@ -2575,6 +2579,14 @@ parse_record_body :: proc(
|
||||
}
|
||||
field_type := parse_record_field_type(parser, allow_anonymous_struct_payload)
|
||||
append(fields, types.Field{name=u32(field_name.symbol), type=field_type})
|
||||
if defaults != nil {
|
||||
value := ast.INVALID_EXPR
|
||||
if _, ok := allow(parser, .Equal); ok {
|
||||
skip_newlines(parser)
|
||||
value = parse_expression(parser)
|
||||
}
|
||||
append(defaults, value)
|
||||
}
|
||||
}
|
||||
if _, ok := allow(parser, .Comma); ok {
|
||||
skip_newlines(parser)
|
||||
@@ -2678,6 +2690,9 @@ parse_struct :: proc(parser: ^Parser, name: token.Token, c_layout, file_hidden:
|
||||
fields: [dynamic]types.Field
|
||||
fields.allocator = parser.module.allocator
|
||||
defer delete(fields)
|
||||
defaults: [dynamic]ast.Expr_Id
|
||||
defaults.allocator = parser.module.allocator
|
||||
defer delete(defaults)
|
||||
allow_anonymous_struct_payload := is_union && (inferred_tag || types.is_valid(declared_tag))
|
||||
tuple := false
|
||||
_ = parse_record_body(
|
||||
@@ -2687,7 +2702,13 @@ parse_struct :: proc(parser: ^Parser, name: token.Token, c_layout, file_hidden:
|
||||
allow_anonymous_struct_payload,
|
||||
allow_anonymous_struct_payload,
|
||||
&tuple,
|
||||
&defaults,
|
||||
)
|
||||
for value in defaults {
|
||||
if value != ast.INVALID_EXPR && (c_layout || is_union || tuple) {
|
||||
source.add(parser.diagnostics, parser.module.exprs[value].span, "field defaults are only supported by named native structs")
|
||||
}
|
||||
}
|
||||
if tuple && (c_layout || is_union) {
|
||||
source.add(parser.diagnostics, start.span, "unnamed fields are only supported by native structs")
|
||||
tuple = false
|
||||
@@ -2697,6 +2718,19 @@ parse_struct :: proc(parser: ^Parser, name: token.Token, c_layout, file_hidden:
|
||||
}
|
||||
if !types.define_record(&parser.module.type_store, id, fields[:], c_layout, false, is_union, tag=tag, declared_tag=declared_tag, tuple=tuple) {
|
||||
source.addf(parser.diagnostics, name.span, "duplicate type declaration '%s'", token_text(parser, name))
|
||||
} else if !c_layout && !is_union && !tuple {
|
||||
for value, index in defaults {
|
||||
if value == ast.INVALID_EXPR {
|
||||
continue
|
||||
}
|
||||
append(&parser.module.struct_field_defaults, ast.Struct_Field_Default{
|
||||
record=id,
|
||||
field=symbol.Id(fields[index].name),
|
||||
expr=value,
|
||||
pkg=parser.pkg,
|
||||
file=parser.file,
|
||||
})
|
||||
}
|
||||
}
|
||||
_ = finish_statement(parser)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user