Compound expression for union

This commit is contained in:
Krzosa Karol
2023-03-29 10:06:55 +02:00
parent c9072711b5
commit cb630951fd
5 changed files with 40 additions and 9 deletions

View File

@@ -517,7 +517,7 @@ gen_expr(Ast_Expr *ast) {
} }
For(node->exprs) { For(node->exprs) {
if (is_struct(node->resolved_type)) if (is_struct(node->resolved_type) || is_union(node->resolved_type))
gen(".%Q = ", it->resolved_name); gen(".%Q = ", it->resolved_name);
else if (is_array(node->resolved_type)) else if (is_array(node->resolved_type))
gen("[%d] = ", (int)it->resolved_index); gen("[%d] = ", (int)it->resolved_index);

View File

@@ -192,7 +192,7 @@ int main(int argument_count, char **arguments) {
else { else {
String program_name = string_from_cstring(arguments[1]); String program_name = string_from_cstring(arguments[1]);
compile_file(&arena, program_name, COMPILE_PRINT_STATS); compile_file(&arena, program_name, COMPILE_PRINT_STATS | COMPILE_AND_RUN);
} }
} }
printf("End of program\n"); printf("End of program\n");

View File

@@ -1047,6 +1047,9 @@ resolve_compound_array(Ast_Call *node, Ast_Type *type) {
CORE_Static void CORE_Static void
resolve_compound_struct(Ast_Call *node, Ast_Type *type) { resolve_compound_struct(Ast_Call *node, Ast_Type *type) {
if (node->exprs.len != 1 && is_union(type))
compiler_error(node->pos, "Too many union initializers. Only 1 named initializer required.");
S64 default_counter = 0; S64 default_counter = 0;
For(node->exprs) { For(node->exprs) {
if (is_flag_set(it->call_flags, CALL_INDEX)) if (is_flag_set(it->call_flags, CALL_INDEX))
@@ -1074,6 +1077,8 @@ resolve_compound_struct(Ast_Call *node, Ast_Type *type) {
compiler_error(it->pos, "No member with that name"); compiler_error(it->pos, "No member with that name");
} }
else { else {
if (is_union(type))
compiler_error(it->pos, "Unions can only be initialized using named fields");
if (default_counter == -1) if (default_counter == -1)
compiler_error(it->pos, "Cant mix named fields and normal fields"); compiler_error(it->pos, "Cant mix named fields and normal fields");
if (default_counter >= type->agg.members.len) if (default_counter >= type->agg.members.len)
@@ -1463,7 +1468,7 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_and_const_str
if (is_array(type) || is_slice(type)) { if (is_array(type) || is_slice(type)) {
resolve_compound_array(node, type); resolve_compound_array(node, type);
} }
else if (is_struct(type)) { else if (is_struct(type) || is_union(type)) {
resolve_compound_struct(node, type); resolve_compound_struct(node, type);
} }
else { else {

View File

@@ -12,15 +12,9 @@ PushStruct :: (a: *MA.Arena, type: Type): *void
result := MA.PushSize(a, ti.size->U64) result := MA.PushSize(a, ti.size->U64)
return result return result
U :: union
a: F64
b: F32
main :: (argc: int, argv: **char): int main :: (argc: int, argv: **char): int
arena: MA.Arena arena: MA.Arena
a: *int = PushStruct(&arena, int) a: *int = PushStruct(&arena, int)
Assert(arena.len == SizeOf(int)) Assert(arena.len == SizeOf(int))
memes: U
return 0 return 0

32
examples/unions.core Normal file
View File

@@ -0,0 +1,32 @@
U :: union
a: F64
b: F32
C :: struct
a: int
b: int
Test :: struct
a: int
main :: (argc: int, argv: **char): int
memes: U
memes.b = 10
Assert(memes.b == 10)
Assert(memes.a != 0)
compound: U = {b = 10.0}
c2: C = {b = 10}
/* @reproduction @todo
```
examples/unions.core - Error! Couldn't infer type of compound expression
c = {10}
```
c: C
c = {10}
*/
return 0