Core: Fix mixing named and positional in compound expressions

This commit is contained in:
Krzosa Karol
2023-04-21 09:26:55 +02:00
parent 1e12f51451
commit 8c80f609af
2 changed files with 24 additions and 33 deletions

View File

@@ -58,20 +58,6 @@ Add(&guys, {100, 100})
// //
// Failed to cast from [[256]int] to [*int] // Failed to cast from [[256]int] to [*int]
// @reproduction
// map_data: [16*16]int
// map: Map = {data = &map_data[0], 16, 16}
//
// Map map = (Map ){.data = (&(map_data[0])), .data = 0x10, .x = 16};
// @reproduction Couldn't figure out type of compound expression when variable got declared and separetly
// got assigned a value
//
// Error! Couldn't infer type of compound expression
// if Mode == 0 && colliding && IsMouseButtonPressed(MOUSE_BUTTON_RIGHT) ;; GuyP = {x,y}
// Error! Couldn't infer type of compound expression
// if Mode == 1 && colliding && IsMouseButtonPressed(MOUSE_BUTTON_LEFT) ;; MAP.CurrentMAP.actors.data[0].p = {x,y}
#import "raylib.core" #import "raylib.core"
#load "array.core" #load "array.core"
@@ -104,7 +90,6 @@ MouseSelectionPivot: Vector2
MouseSelectionBox: Rectangle MouseSelectionBox: Rectangle
MouseSelectedActors: Array(*MAP.Actor) // @todo: ids MouseSelectedActors: Array(*MAP.Actor) // @todo: ids
main :: (): int main :: (): int
MAP.Init() MAP.Init()

View File

@@ -1064,50 +1064,56 @@ resolve_compound_struct(Ast_Call *node, Ast_Type *type) {
if (node->exprs.len != 1 && is_union(type)) if (node->exprs.len != 1 && is_union(type))
compiler_error(node->pos, "Too many union initializers. Only 1 named initializer required."); compiler_error(node->pos, "Too many union initializers. Only 1 named initializer required.");
int counter = 0;
bool named_field_appeared = false;
For(node->exprs) {
if (is_union(type) && !is_flag_set(it->call_flags, CALL_NAME)) compiler_error(it->pos, "Unions can only be initialized using named fields");
if (is_flag_set(it->call_flags, CALL_INDEX)) compiler_error(it->pos, "Index specifier in a struct compound expression is not legal");
if (is_flag_set(it->call_flags, CALL_NAME)) named_field_appeared = true;
if (!is_flag_set(it->call_flags, CALL_NAME) && named_field_appeared) compiler_error(it->pos, "Mixing positional and named fields in compound expressions is illegal");
if (counter >= type->agg.members.len) compiler_error(it->pos, "Too many struct initializers");
counter += 1;
}
S64 default_counter = 0; S64 default_counter = 0;
For(node->exprs) { For(node->exprs) {
if (is_flag_set(it->call_flags, CALL_INDEX))
compiler_error(it->pos, "Index specifier in a struct compound expression is not legal");
Ast_Type *item_type = 0; Ast_Type *item_type = 0;
if (is_flag_set(it->call_flags, CALL_NAME)) { if (is_flag_set(it->call_flags, CALL_NAME)) {
For2(type->agg.members, m) { For2(type->agg.members, m) {
if (it->name->intern_val == m.name) { if (it->name->intern_val == m.name) {
it->resolved_name = m.name; it->resolved_name = m.name;
it->resolved_index = (S32)type->agg.members.get_index(m); it->resolved_index = (S32)type->agg.members.get_index(m);
// @copy_paste
if (m.type == pctx->type_type) if (m.type == pctx->type_type) {
item_type = m.type_val; item_type = m.type_val;
else item_type = m.type; }
else {
item_type = m.type;
}
if (m.visited) { if (m.visited) {
compiler_error(it->pos, "Field already initialized"); compiler_error(it->pos, "Field already initialized");
} }
else m.visited = true; else {
m.visited = true;
}
break; break;
} }
} }
if (!item_type) if (!item_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)
compiler_error(it->pos, "Cant mix named fields and normal fields");
if (default_counter >= type->agg.members.len)
compiler_error(it->pos, "Too many struct initializers");
Ast_Resolved_Member *m = &type->agg.members[default_counter]; Ast_Resolved_Member *m = &type->agg.members[default_counter];
it->resolved_name = m->name; it->resolved_name = m->name;
it->resolved_index = (S32)default_counter; it->resolved_index = (S32)default_counter;
m->visited = true; m->visited = true;
// @copy_paste
if (m->type == pctx->type_type && m->type_val) { if (m->type == pctx->type_type && m->type_val) {
item_type = m->type_val; item_type = m->type_val;
} }
else item_type = m->type; else {
item_type = m->type;
}
default_counter += 1; default_counter += 1;
} }