}
-
any :: struct {
data: rawptr;
type: type_expr;
// 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
#private string :: package core.string
Environment :: struct {
- vars : map.Map(str, str);
+ vars : Map(str, str);
buffer : [] u8;
buffer_allocator : Allocator;
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.
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);
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 {
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;
range_shift : u16;
segments : [..] TTF_Segment;
- cache : map.Map(i32, i32);
+ cache : Map(i32, i32);
}
TTF_Segment :: 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;
}
#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);
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);
// 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;
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);
}
// 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 {
WasmData :: struct {
memory_index : u32;
offset : WasmInstruction;
-
+
data : [] u8;
}
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];
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)
#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) {
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]++;
}
Entity* entity_heap_top(EntityHeap* entities) {
- return entities->entities[0];
+ return entities->entities[0];
}
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) {
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
} 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;
ENTITY_INSERT(ent);
break;
}
-
+
case Ast_Kind_Load_Path: {
ent.state = Entity_State_Parse;
ent.type = Entity_Type_Load_Path;
ENTITY_INSERT(ent);
break;
}
-
+
case Ast_Kind_Binding: {
ent.state = Entity_State_Introduce_Symbols;
ent.type = Entity_Type_Binding;
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;
}
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;
}
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;
ent.id = entities->next_id++;
// fallthrough
}
-
+
case Ast_Kind_Poly_Struct_Type:
case Ast_Kind_Type_Alias: {
ent.type = Entity_Type_Type_Alias;
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;
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;
ENTITY_INSERT(ent);
break;
}
-
+
case Ast_Kind_Polymorphic_Proc: {
ent.type = Entity_Type_Polymorphic_Proc;
ent.poly_proc = (AstPolyProc *) node;
ent.type = Entity_Type_Error;
ent.error = (AstDirectiveError *) node;
ENTITY_INSERT(ent);
- break;
+ break;
}
case Ast_Kind_Directive_Export:
ENTITY_INSERT(ent);
break;
}
-
+
default: {
ent.type = Entity_Type_Expression;
ent.expr = (AstTyped *) node;
break;
}
}
-
+
node->entity = entity;
}
}
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);
AstOverloadedFunction* ofunc = parse_overloaded_function(parser, directive_token);
return (AstTyped *) ofunc;
}
-
+
return parse_expression(parser, 1);
}
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;
"%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 {
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;
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;
}
use package core
main :: (args: [] cstr) {
- imap : map.Map(i32, str);
+ imap : Map(i32, str);
map.init(^imap, "");
defer {
print("Freeing map\n");