From: Brendan Hansen Date: Mon, 30 Aug 2021 00:37:16 +0000 (-0500) Subject: bugfixes with aliasing to poly structs; added 'Map' and 'Set' aliases X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=cfcd65294adeb4ca3d7fb47fd6df57764fd24363;p=onyx.git bugfixes with aliasing to poly structs; added 'Map' and 'Set' aliases --- diff --git a/bin/onyx b/bin/onyx index 15df3245..a5bf1b64 100755 Binary files a/bin/onyx and b/bin/onyx differ diff --git a/core/builtin.onyx b/core/builtin.onyx index 3d7db024..62072103 100644 --- a/core/builtin.onyx +++ b/core/builtin.onyx @@ -182,7 +182,6 @@ CallSite :: struct { } - any :: struct { data: rawptr; type: type_expr; @@ -190,4 +189,20 @@ any :: struct { // Represents a code block. Not constructable outside of using a '#code' directive. -Code :: struct {_:i32;} \ No newline at end of file +Code :: struct {_:i32;} + + +// Define aliases for common datastructures in the core library, if the core library is available. +// I'm on the fence about keeping this, as the programmer may want to use these names for their own +// structures, but for the moment I don't see any harm. I'm also thinking about removing the '[..]' +// syntax for dynamic arrays and just make them like Map's and Set's, i.e. Array(T). This would +// remove some confusion around the 3 different array types as dynamic arrays would clearly just be +// normal structures. With the recent addition of macros and iterators, there really wouldn't be much +// difference anyway. +#if #defined((package core.map).Map) { + Map :: (package core.map).Map; +} + +#if #defined((package core.set).Set) { + Set :: (package core.set).Set; +} \ No newline at end of file diff --git a/core/wasi/env.onyx b/core/wasi/env.onyx index 568dea45..67fabd25 100644 --- a/core/wasi/env.onyx +++ b/core/wasi/env.onyx @@ -11,7 +11,7 @@ use package wasi { environ_get, environ_sizes_get, Size } #private string :: package core.string Environment :: struct { - vars : map.Map(str, str); + vars : Map(str, str); buffer : [] u8; buffer_allocator : Allocator; diff --git a/include/onyxastnodes.h b/include/onyxastnodes.h index aaf7be65..e2ee4d54 100644 --- a/include/onyxastnodes.h +++ b/include/onyxastnodes.h @@ -902,7 +902,7 @@ struct AstOverloadedFunction { AstTyped_base; bh_arr(OverloadOption) overloads; - + // CLEANUP: This is unused right now, but should be used to cache // the complete set of overloads that can be used by an overloaded // function. diff --git a/modules/bmfont/types.onyx b/modules/bmfont/types.onyx index fa97bc59..9dfe0f6e 100644 --- a/modules/bmfont/types.onyx +++ b/modules/bmfont/types.onyx @@ -7,8 +7,8 @@ BMFont :: struct { info : BMFont_Info; common : BMFont_Common; - pages : map.Map(i32, str); - glyphs : map.Map(i32, BMFont_Glyph); + pages : Map(i32, str); + glyphs : Map(i32, BMFont_Glyph); get_glyph :: (use bmfont: ^BMFont, char: u8) -> ^BMFont_Glyph { return map.get_ptr(^glyphs, ~~char); diff --git a/modules/json/encoder.onyx b/modules/json/encoder.onyx index 84dceba8..a3aeab46 100644 --- a/modules/json/encoder.onyx +++ b/modules/json/encoder.onyx @@ -80,7 +80,7 @@ encode :: #match { return .None; }, - (w: ^io.Writer, v: map.Map(str, $T)) -> Encoding_Error { + (w: ^io.Writer, v: Map(str, $T)) -> Encoding_Error { io.write_byte(w, #char "{"); for i: v.entries.count { diff --git a/modules/ttf/ttf.onyx b/modules/ttf/ttf.onyx index 819952e2..07a68b50 100644 --- a/modules/ttf/ttf.onyx +++ b/modules/ttf/ttf.onyx @@ -10,7 +10,7 @@ True_Type_Font :: struct { entry_selector : u16; range_shift : u16; - tables : map.Map(u32, TTF_Table_Info); + tables : Map(u32, TTF_Table_Info); char_maps : [..] TTF_Cmap; version : u32; @@ -99,7 +99,7 @@ TTF_Cmap4 :: struct { range_shift : u16; segments : [..] TTF_Segment; - cache : map.Map(i32, i32); + cache : Map(i32, i32); } TTF_Segment :: struct { diff --git a/modules/ui/components/scrollable_region.onyx b/modules/ui/components/scrollable_region.onyx index 5b9d188d..9511e4bd 100644 --- a/modules/ui/components/scrollable_region.onyx +++ b/modules/ui/components/scrollable_region.onyx @@ -10,7 +10,7 @@ Scrollable_Region_State :: struct { } #private -scrollable_region_states : map.Map(UI_Id, Scrollable_Region_State); +scrollable_region_states : Map(UI_Id, Scrollable_Region_State); Scrollable_Region_Controls :: struct { minimum_y := 0.0f; diff --git a/modules/ui/components/workspace.onyx b/modules/ui/components/workspace.onyx index 4977611f..d5f4f275 100644 --- a/modules/ui/components/workspace.onyx +++ b/modules/ui/components/workspace.onyx @@ -21,7 +21,7 @@ Workspace_State :: struct { } #private -workspace_states : map.Map(UI_Id, Workspace_State); +workspace_states : Map(UI_Id, Workspace_State); workspace_start :: (use r: Rectangle, site := #callsite, state: ^Workspace_State = null) { hash := get_site_hash(site, 0); diff --git a/modules/ui/font.onyx b/modules/ui/font.onyx index 874126e1..f2f809ff 100644 --- a/modules/ui/font.onyx +++ b/modules/ui/font.onyx @@ -71,7 +71,7 @@ create_font :: (bmfont_data: [] u8, font_texture_data: [] u8) -> Font { Font_Index :: i32; -#private font_registry : map.Map(Font_Index, Font); +#private font_registry : Map(Font_Index, Font); register_font :: (index: Font_Index, font: Font) { assert(!map.has(^font_registry, index), "Font with this index already exists."); map.put(^font_registry, index, font); diff --git a/modules/ui/ui.onyx b/modules/ui/ui.onyx index 9b41a7e1..4fb159f6 100644 --- a/modules/ui/ui.onyx +++ b/modules/ui/ui.onyx @@ -178,7 +178,7 @@ Animation_Theme :: struct { // Animation states are stored globally as there is not much to the state of a button. // Forcing the end user to store a structure for each button that is just the animation // state of the component feels very wrong. -#private animation_states : map.Map(UI_Id, Animation_State); +#private animation_states : Map(UI_Id, Animation_State); Animation_State :: struct { hover_time := 0.0f; diff --git a/modules/wasm_utils/types.onyx b/modules/wasm_utils/types.onyx index 4bc34076..446a6c32 100644 --- a/modules/wasm_utils/types.onyx +++ b/modules/wasm_utils/types.onyx @@ -16,7 +16,7 @@ WasmSection :: enum { DataCount :: 0x0c; } -#add_match hash.to_u32, (w: WasmSection) -> u32 { +#add_match hash.to_u32, macro (w: WasmSection) -> u32 { return hash.to_u32(cast(u32) w); } @@ -25,13 +25,13 @@ WasmBinary :: struct { // Section number -> Offset+size of data // This does not work for custom sections, as they all have the same section number - sections: map.Map(WasmSection, WasmSectionData); + sections: Map(WasmSection, WasmSectionData); // Custom section name -> Offset into data // So there is a custom section location that maps the name of the custom section // to the offset into the file. The backing-store for the keys is just the data // itself, as the names are in the data for the binary. - custom_section_locations : map.Map(str, i32); + custom_section_locations : Map(str, i32); } WasmSectionData :: struct { @@ -109,7 +109,7 @@ WasmElement :: struct { WasmData :: struct { memory_index : u32; offset : WasmInstruction; - + data : [] u8; } diff --git a/src/onyxchecker.c b/src/onyxchecker.c index 7f3c359d..dd8b2d4a 100644 --- a/src/onyxchecker.c +++ b/src/onyxchecker.c @@ -1619,8 +1619,11 @@ CheckStatus check_expression(AstTyped** pexpr) { CHECK(type, (AstType *) expr); } - if (type_build_from_ast(context.ast_alloc, (AstType*) expr) == NULL) { - YIELD(expr->token->pos, "Trying to construct type."); + // Don't try to construct a polystruct ahead of time because you can't. + if (expr->kind != Ast_Kind_Poly_Struct_Type) { + if (type_build_from_ast(context.ast_alloc, (AstType*) expr) == NULL) { + YIELD(expr->token->pos, "Trying to construct type."); + } } expr->type = &basic_types[Basic_Kind_Type_Index]; diff --git a/src/onyxentities.c b/src/onyxentities.c index 1f3b84f5..7a938621 100644 --- a/src/onyxentities.c +++ b/src/onyxentities.c @@ -24,7 +24,7 @@ static i32 entity_compare(Entity* e1, Entity* e2) { else if (e1->micro_attempts != e2->micro_attempts) return (i32) (e1->micro_attempts - e2->micro_attempts); else - return (i32) (e1->id - e2->id); + return (i32) (e1->id - e2->id); } #define eh_parent(index) (((index) - 1) / 2) @@ -32,37 +32,37 @@ static i32 entity_compare(Entity* e1, Entity* e2) { #define eh_rchild(index) (((index) * 2) + 2) static void eh_shift_up(EntityHeap* entities, i32 index) { - while (index > 0 && entity_compare(entities->entities[eh_parent(index)], entities->entities[index]) > 0) { - Entity* tmp = entities->entities[eh_parent(index)]; - entities->entities[eh_parent(index)] = entities->entities[index]; - entities->entities[index] = tmp; + while (index > 0 && entity_compare(entities->entities[eh_parent(index)], entities->entities[index]) > 0) { + Entity* tmp = entities->entities[eh_parent(index)]; + entities->entities[eh_parent(index)] = entities->entities[index]; + entities->entities[index] = tmp; - index = eh_parent(index); - } + index = eh_parent(index); + } } static void eh_shift_down(EntityHeap* entities, i32 index) { - i32 min_index = index; - - i32 l = eh_lchild(index); - if (l < bh_arr_length(entities->entities) - && entity_compare(entities->entities[l], entities->entities[min_index]) < 0) { - min_index = l; - } - - i32 r = eh_rchild(index); - if (r < bh_arr_length(entities->entities) - && entity_compare(entities->entities[r], entities->entities[min_index]) < 0) { - min_index = r; - } - - if (index != min_index) { - Entity* tmp = entities->entities[min_index]; - entities->entities[min_index] = entities->entities[index]; - entities->entities[index] = tmp; - - eh_shift_down(entities, min_index); - } + i32 min_index = index; + + i32 l = eh_lchild(index); + if (l < bh_arr_length(entities->entities) + && entity_compare(entities->entities[l], entities->entities[min_index]) < 0) { + min_index = l; + } + + i32 r = eh_rchild(index); + if (r < bh_arr_length(entities->entities) + && entity_compare(entities->entities[r], entities->entities[min_index]) < 0) { + min_index = r; + } + + if (index != min_index) { + Entity* tmp = entities->entities[min_index]; + entities->entities[min_index] = entities->entities[index]; + entities->entities[index] = tmp; + + eh_shift_down(entities, min_index); + } } void entity_heap_init(EntityHeap* entities) { @@ -84,12 +84,12 @@ Entity* entity_heap_register(EntityHeap* entities, Entity e) { void entity_heap_insert_existing(EntityHeap* entities, Entity* e) { if (e->entered_in_queue) return; - if (entities->entities == NULL) { - bh_arr_new(global_heap_allocator, entities->entities, 128); - } + if (entities->entities == NULL) { + bh_arr_new(global_heap_allocator, entities->entities, 128); + } - bh_arr_push(entities->entities, e); - eh_shift_up(entities, bh_arr_length(entities->entities) - 1); + bh_arr_push(entities->entities, e); + eh_shift_up(entities, bh_arr_length(entities->entities) - 1); e->entered_in_queue = 1; entities->state_count[e->state]++; @@ -104,7 +104,7 @@ Entity* entity_heap_insert(EntityHeap* entities, Entity e) { } Entity* entity_heap_top(EntityHeap* entities) { - return entities->entities[0]; + return entities->entities[0]; } void entity_heap_change_top(EntityHeap* entities, Entity* new_top) { @@ -116,9 +116,9 @@ void entity_heap_change_top(EntityHeap* entities, Entity* new_top) { entities->all_count[entities->entities[0]->state][entities->entities[0]->type]--; entities->all_count[new_top->state][new_top->type]++; - - entities->entities[0] = new_top; - eh_shift_down(entities, 0); + + entities->entities[0] = new_top; + eh_shift_down(entities, 0); } void entity_heap_remove_top(EntityHeap* entities) { @@ -127,9 +127,9 @@ void entity_heap_remove_top(EntityHeap* entities) { entities->all_count[entities->entities[0]->state][entities->entities[0]->type]--; entities->entities[0]->entered_in_queue = 0; - entities->entities[0] = entities->entities[bh_arr_length(entities->entities) - 1]; - bh_arr_pop(entities->entities); - eh_shift_down(entities, 0); + entities->entities[0] = entities->entities[bh_arr_length(entities->entities) - 1]; + bh_arr_pop(entities->entities); + eh_shift_down(entities, 0); } // NOTE(Brendan Hansen): Uses the entity heap in the context structure @@ -143,17 +143,17 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s } else { \ entity_heap_insert_existing(entities, entity); \ } \ - + EntityHeap* entities = &context.entities; Entity* entity; - + Entity ent; ent.id = entities->next_id++; ent.state = Entity_State_Resolve_Symbols; ent.package = package; ent.scope = scope; - + switch (node->kind) { case Ast_Kind_Load_File: { ent.state = Entity_State_Parse; @@ -162,7 +162,7 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s ENTITY_INSERT(ent); break; } - + case Ast_Kind_Load_Path: { ent.state = Entity_State_Parse; ent.type = Entity_Type_Load_Path; @@ -170,7 +170,7 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s ENTITY_INSERT(ent); break; } - + case Ast_Kind_Binding: { ent.state = Entity_State_Introduce_Symbols; ent.type = Entity_Type_Binding; @@ -178,19 +178,19 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s ENTITY_INSERT(ent); break; } - + case Ast_Kind_Function: { if ((node->flags & Ast_Flag_Foreign) != 0) { ent.type = Entity_Type_Foreign_Function_Header; ent.function = (AstFunction *) node; ENTITY_INSERT(ent); - + } else { ent.type = Entity_Type_Function_Header; ent.function = (AstFunction *) node; ENTITY_INSERT(ent); ((AstFunction *) node)->entity_header = entity; - + ent.id = entities->next_id++; ent.type = Entity_Type_Function; ent.function = (AstFunction *) node; @@ -199,25 +199,25 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s } break; } - + case Ast_Kind_Overloaded_Function: { ent.type = Entity_Type_Overloaded_Function; ent.overloaded_function = (AstOverloadedFunction *) node; ENTITY_INSERT(ent); break; } - + case Ast_Kind_Global: { if ((node->flags & Ast_Flag_Foreign) != 0) { ent.type = Entity_Type_Foreign_Global_Header; ent.global = (AstGlobal *) node; ENTITY_INSERT(ent); - + } else { ent.type = Entity_Type_Global_Header; ent.global = (AstGlobal *) node; ENTITY_INSERT(ent); - + ent.id = entities->next_id++; ent.type = Entity_Type_Global; ent.global = (AstGlobal *) node; @@ -225,21 +225,21 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s } break; } - + case Ast_Kind_StrLit: { ent.type = Entity_Type_String_Literal; ent.strlit = (AstStrLit *) node; ENTITY_INSERT(ent); break; } - + case Ast_Kind_File_Contents: { ent.type = Entity_Type_File_Contents; ent.file_contents = (AstFileContents *) node; ENTITY_INSERT(ent); break; } - + case Ast_Kind_Struct_Type: { ent.type = Entity_Type_Struct_Member_Default; ent.type_alias = (AstType *) node; @@ -249,7 +249,7 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s ent.id = entities->next_id++; // fallthrough } - + case Ast_Kind_Poly_Struct_Type: case Ast_Kind_Type_Alias: { ent.type = Entity_Type_Type_Alias; @@ -262,14 +262,14 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s break; } - + case Ast_Kind_Enum_Type: { ent.type = Entity_Type_Enum; ent.enum_type = (AstEnumType *) node; ENTITY_INSERT(ent); break; } - + case Ast_Kind_Use: { if (((AstUse *) node)->expr->kind == Ast_Kind_Package) { ent.state = Entity_State_Resolve_Symbols; @@ -282,12 +282,12 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s ENTITY_INSERT(ent); break; } - + case Ast_Kind_Memres: { ent.type = Entity_Type_Memory_Reservation_Type; ent.mem_res = (AstMemRes *) node; ENTITY_INSERT(ent); - + ent.id = entities->next_id++; ent.type = Entity_Type_Memory_Reservation; ent.mem_res = (AstMemRes *) node; @@ -301,7 +301,7 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s ENTITY_INSERT(ent); break; } - + case Ast_Kind_Polymorphic_Proc: { ent.type = Entity_Type_Polymorphic_Proc; ent.poly_proc = (AstPolyProc *) node; @@ -322,7 +322,7 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s ent.type = Entity_Type_Error; ent.error = (AstDirectiveError *) node; ENTITY_INSERT(ent); - break; + break; } case Ast_Kind_Directive_Export: @@ -341,7 +341,7 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s ENTITY_INSERT(ent); break; } - + default: { ent.type = Entity_Type_Expression; ent.expr = (AstTyped *) node; @@ -349,6 +349,6 @@ void add_entities_for_node(bh_arr(Entity *) *target_arr, AstNode* node, Scope* s break; } } - + node->entity = entity; } diff --git a/src/onyxparser.c b/src/onyxparser.c index 83e8173f..74126e77 100644 --- a/src/onyxparser.c +++ b/src/onyxparser.c @@ -2425,21 +2425,11 @@ static AstMacro* parse_macro(OnyxParser* parser) { } static AstTyped* parse_top_level_expression(OnyxParser* parser) { - #if 0 - if (parser->curr->type == Token_Type_Keyword_Proc) { - OnyxToken* proc_token = expect_token(parser, Token_Type_Keyword_Proc); - onyx_report_warning(proc_token->pos, "Warning: 'proc' is a deprecated keyword."); - AstFunction* func_node = parse_function_definition(parser, proc_token); - - return (AstTyped *) func_node; - } - #endif - if (parser->curr->type == Token_Type_Keyword_Global) return parse_global_declaration(parser); if (parser->curr->type == Token_Type_Keyword_Struct) return (AstTyped *) parse_struct(parser); if (parser->curr->type == Token_Type_Keyword_Enum) return (AstTyped *) parse_enum_declaration(parser); if (parser->curr->type == Token_Type_Keyword_Macro) return (AstTyped *) parse_macro(parser); - + if (parse_possible_directive(parser, "type")) { AstTypeAlias* alias = make_node(AstTypeAlias, Ast_Kind_Type_Alias); alias->to = parse_type(parser); @@ -2452,7 +2442,7 @@ static AstTyped* parse_top_level_expression(OnyxParser* parser) { AstOverloadedFunction* ofunc = parse_overloaded_function(parser, directive_token); return (AstTyped *) ofunc; } - + return parse_expression(parser, 1); } @@ -2462,7 +2452,7 @@ static AstBinding* parse_top_level_binding(OnyxParser* parser, OnyxToken* symbol AstTyped* node = parse_top_level_expression(parser); if (parser->hit_unexpected_token || node == NULL) return NULL; - + // CLEANUP if (node->kind == Ast_Kind_Function) { AstFunction* func = (AstFunction *) node; @@ -2504,11 +2494,8 @@ static AstBinding* parse_top_level_binding(OnyxParser* parser, OnyxToken* symbol "%b", symbol->text, symbol->length); } - if (node->kind == Ast_Kind_Type_Alias) { - node->token = symbol; - } - - if (node_is_type((AstNode *) node)); + if (node->kind == Ast_Kind_Type_Alias) node->token = symbol; + else if (node_is_type((AstNode *) node)); else if (node->kind == Ast_Kind_Package); else if (node->kind == Ast_Kind_NumLit); else { diff --git a/src/onyxsymres.c b/src/onyxsymres.c index 1ea73838..18f6ef5e 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -719,7 +719,7 @@ static SymresStatus symres_directive_solidify(AstDirectiveSolidify** psolid) { solid->poly_proc = potentially_resolved_proc; } - + if (!solid->poly_proc || solid->poly_proc->kind != Ast_Kind_Polymorphic_Proc) { onyx_report_error(solid->token->pos, "Expected polymorphic procedure in #solidify directive."); return Symres_Error; diff --git a/src/onyxtypes.c b/src/onyxtypes.c index ec20f8be..ed4f955e 100644 --- a/src/onyxtypes.c +++ b/src/onyxtypes.c @@ -496,19 +496,22 @@ Type* type_build_from_ast(bh_allocator alloc, AstType* type_node) { return ((AstTypeRawAlias *) type_node)->to; case Ast_Kind_Poly_Struct_Type: - onyx_report_error(type_node->token->pos, - "This structure is polymorphic, which means you need to provide arguments to it to make it a concrete structure. " - "This error message is probably in the wrong place, so look through your code for uses of this struct."); + //onyx_report_error(type_node->token->pos, + // "This structure is polymorphic, which means you need to provide arguments to it to make it a concrete structure. " + // "This error message is probably in the wrong place, so look through your code for uses of this struct."); + return NULL; break; case Ast_Kind_Poly_Call_Type: { AstPolyCallType* pc_type = (AstPolyCallType *) type_node; + pc_type->callee = (AstType *) strip_aliases((AstNode *) pc_type->callee); if (!(pc_type->callee && pc_type->callee->kind == Ast_Kind_Poly_Struct_Type)) { - // If it is an unresolved field access, just return because an error will be printed elsewhere. - if (pc_type->callee->kind == Ast_Kind_Field_Access) return NULL; + // If it is an unresolved field access or symbol, just return because an error will be printed elsewhere. + if (pc_type->callee->kind == Ast_Kind_Field_Access || pc_type->callee->kind == Ast_Kind_Symbol) return NULL; onyx_report_error(pc_type->token->pos, "Cannot instantiate a concrete type off of a non-polymorphic type."); + onyx_report_error(pc_type->callee->token->pos, "Here is the type trying to be instantiated. (%s)", onyx_ast_node_kind_string(pc_type->callee->kind)); return NULL; } diff --git a/tests/i32map.onyx b/tests/i32map.onyx index 05ab5d3a..a61bc63a 100644 --- a/tests/i32map.onyx +++ b/tests/i32map.onyx @@ -5,7 +5,7 @@ package main use package core main :: (args: [] cstr) { - imap : map.Map(i32, str); + imap : Map(i32, str); map.init(^imap, ""); defer { print("Freeing map\n");