From 8c80f609af406f225b56d50400e4b5568da4598c Mon Sep 17 00:00:00 2001 From: Krzosa Karol Date: Fri, 21 Apr 2023 09:26:55 +0200 Subject: [PATCH] Core: Fix mixing named and positional in compound expressions --- build/rtsgame/main.core | 15 --------------- core_typechecking.cpp | 42 +++++++++++++++++++++++------------------ 2 files changed, 24 insertions(+), 33 deletions(-) diff --git a/build/rtsgame/main.core b/build/rtsgame/main.core index 511940a..61c689a 100644 --- a/build/rtsgame/main.core +++ b/build/rtsgame/main.core @@ -58,20 +58,6 @@ Add(&guys, {100, 100}) // // 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" #load "array.core" @@ -104,7 +90,6 @@ MouseSelectionPivot: Vector2 MouseSelectionBox: Rectangle MouseSelectedActors: Array(*MAP.Actor) // @todo: ids - main :: (): int MAP.Init() diff --git a/core_typechecking.cpp b/core_typechecking.cpp index 2c28527..8843846 100644 --- a/core_typechecking.cpp +++ b/core_typechecking.cpp @@ -1064,50 +1064,56 @@ 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."); + 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; 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; if (is_flag_set(it->call_flags, CALL_NAME)) { For2(type->agg.members, m) { if (it->name->intern_val == m.name) { it->resolved_name = m.name; 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; - else item_type = m.type; + } + else { + item_type = m.type; + } if (m.visited) { compiler_error(it->pos, "Field already initialized"); } - else m.visited = true; + else { + m.visited = true; + } break; } } - if (!item_type) - compiler_error(it->pos, "No member with that name"); + if (!item_type) compiler_error(it->pos, "No member with that name"); } 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]; it->resolved_name = m->name; it->resolved_index = (S32)default_counter; m->visited = true; - // @copy_paste if (m->type == pctx->type_type && m->type_val) { item_type = m->type_val; } - else item_type = m->type; + else { + item_type = m->type; + } default_counter += 1; }