diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-05-17 21:23:52 +0100 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-05-17 21:23:52 +0100 |
| commit | 41aa4e606b41655b27eb8518ca9a6035c52df273 (patch) | |
| tree | 24f1a78549a99c43c24ef4bebf849a43b6355cb5 /src | |
| parent | e025a828ca6f8014e11837d6281a14313ec13714 (diff) | |
Optional main for DLL; access struct elements by "index"
Diffstat (limited to 'src')
| -rw-r--r-- | src/check_expr.c | 15 | ||||
| -rw-r--r-- | src/checker.c | 151 | ||||
| -rw-r--r-- | src/ir.c | 17 | ||||
| -rw-r--r-- | src/ir_print.c | 12 | ||||
| -rw-r--r-- | src/parser.c | 273 | ||||
| -rw-r--r-- | src/types.c | 2 |
6 files changed, 434 insertions, 36 deletions
diff --git a/src/check_expr.c b/src/check_expr.c index a7e85f819..db31c25ec 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -3054,8 +3054,8 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node, Type *type_h return NULL; } - // if (selector->kind != AstNode_Ident && selector->kind != AstNode_BasicLit) { - if (selector->kind != AstNode_Ident) { + if (selector->kind != AstNode_Ident && selector->kind != AstNode_BasicLit) { + // if (selector->kind != AstNode_Ident) { error_node(selector, "Illegal selector kind: `%.*s`", LIT(ast_node_strings[selector->kind])); operand->mode = Addressing_Invalid; operand->expr = node; @@ -5406,6 +5406,15 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t check_assignment(c, o, field->type, str_lit("structure literal")); } } else { + bool all_fields_are_blank = true; + for (isize i = 0; i < t->Record.field_count; i++) { + Entity *field = t->Record.fields_in_src_order[i]; + if (str_ne(field->token.string, str_lit("_"))) { + all_fields_are_blank = false; + break; + } + } + for_array(index, cl->elems) { AstNode *elem = cl->elems.e[index]; if (elem->kind == AstNode_FieldValue) { @@ -5414,7 +5423,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t } Entity *field = t->Record.fields_in_src_order[index]; - if (str_eq(field->token.string, str_lit("_"))) { + if (!all_fields_are_blank && str_eq(field->token.string, str_lit("_"))) { // NOTE(bill): Ignore blank identifiers continue; } diff --git a/src/checker.c b/src/checker.c index 989fd1256..72ebaf096 100644 --- a/src/checker.c +++ b/src/checker.c @@ -291,6 +291,13 @@ typedef struct DelayedDecl { AstNode *decl; } DelayedDecl; +typedef struct CheckerFileNode { + i32 id; + Array_i32 wheres; + Array_i32 whats; + i32 score; // Higher the score, the better +} CheckerFileNode; + typedef struct CheckerContext { Scope * file_scope; Scope * scope; @@ -326,6 +333,7 @@ typedef struct Checker { Array(ProcedureInfo) procs; // NOTE(bill): Procedures to check Array(DelayedDecl) delayed_imports; Array(DelayedDecl) delayed_foreign_libraries; + Array(CheckerFileNode) file_nodes; gbArena arena; gbArena tmp_arena; @@ -735,6 +743,16 @@ void init_checker(Checker *c, Parser *parser, BuildContext *bc) { array_init(&c->procs, a); array_init(&c->delayed_imports, a); array_init(&c->delayed_foreign_libraries, a); + array_init(&c->file_nodes, a); + + for_array(i, parser->files) { + AstFile *file = &parser->files.e[i]; + CheckerFileNode node = {0}; + node.id = file->id; + array_init(&node.whats, a); + array_init(&node.wheres, a); + array_add(&c->file_nodes, node); + } // NOTE(bill): Is this big enough or too small? isize item_size = gb_max3(gb_size_of(Entity), gb_size_of(Type), gb_size_of(Scope)); @@ -762,6 +780,7 @@ void destroy_checker(Checker *c) { array_free(&c->procs); array_free(&c->delayed_imports); array_free(&c->delayed_foreign_libraries); + array_free(&c->file_nodes); gb_arena_free(&c->arena); } @@ -1746,6 +1765,106 @@ String path_to_entity_name(String name, String fullpath) { } void check_import_entities(Checker *c, MapScope *file_scopes) { +#if 0 + // TODO(bill): Dependency ordering for imports + { + Array_i32 shared_global_file_ids = {0}; + array_init_reserve(&shared_global_file_ids, heap_allocator(), c->file_nodes.count); + for_array(i, c->file_nodes) { + CheckerFileNode *node = &c->file_nodes.e[i]; + AstFile *f = &c->parser->files.e[node->id]; + GB_ASSERT(f->id == node->id); + if (f->scope->is_global) { + array_add(&shared_global_file_ids, f->id); + } + } + + for_array(i, c->file_nodes) { + CheckerFileNode *node = &c->file_nodes.e[i]; + AstFile *f = &c->parser->files.e[node->id]; + if (!f->scope->is_global) { + for_array(j, shared_global_file_ids) { + array_add(&node->whats, shared_global_file_ids.e[j]); + } + } + } + + array_free(&shared_global_file_ids); + } + + for_array(i, c->delayed_imports) { + Scope *parent_scope = c->delayed_imports.e[i].parent; + AstNode *decl = c->delayed_imports.e[i].decl; + ast_node(id, ImportDecl, decl); + Token token = id->relpath; + + GB_ASSERT(parent_scope->is_file); + + if (!parent_scope->has_been_imported) { + continue; + } + + HashKey key = hash_string(id->fullpath); + Scope **found = map_scope_get(file_scopes, key); + if (found == NULL) { + for_array(scope_index, file_scopes->entries) { + Scope *scope = file_scopes->entries.e[scope_index].value; + gb_printf_err("%.*s\n", LIT(scope->file->tokenizer.fullpath)); + } + gb_printf_err("%.*s(%td:%td)\n", LIT(token.pos.file), token.pos.line, token.pos.column); + GB_PANIC("Unable to find scope for file: %.*s", LIT(id->fullpath)); + } + Scope *scope = *found; + + if (scope->is_global) { + continue; + } + + i32 parent_id = parent_scope->file->id; + i32 child_id = scope->file->id; + + // TODO(bill): Very slow + CheckerFileNode *parent_node = &c->file_nodes.e[parent_id]; + bool add_child = true; + for_array(j, parent_node->whats) { + if (parent_node->whats.e[j] == child_id) { + add_child = false; + break; + } + } + if (add_child) { + array_add(&parent_node->whats, child_id); + } + + CheckerFileNode *child_node = &c->file_nodes.e[child_id]; + bool add_parent = true; + for_array(j, parent_node->wheres) { + if (parent_node->wheres.e[j] == parent_id) { + add_parent = false; + break; + } + } + if (add_parent) { + array_add(&child_node->wheres, parent_id); + } + } + + for_array(i, c->file_nodes) { + CheckerFileNode *node = &c->file_nodes.e[i]; + AstFile *f = &c->parser->files.e[node->id]; + gb_printf_err("File %d %.*s", node->id, LIT(f->tokenizer.fullpath)); + gb_printf_err("\n wheres:"); + for_array(j, node->wheres) { + gb_printf_err(" %d", node->wheres.e[j]); + } + gb_printf_err("\n whats:"); + for_array(j, node->whats) { + gb_printf_err(" %d", node->whats.e[j]); + } + gb_printf_err("\n"); + } +#endif + for_array(i, c->delayed_imports) { Scope *parent_scope = c->delayed_imports.e[i].parent; AstNode *decl = c->delayed_imports.e[i].decl; @@ -2017,24 +2136,26 @@ void check_parsed_files(Checker *c) { // gb_printf_err("Count: %td\n", c->info.type_info_count++); - for_array(i, file_scopes.entries) { - Scope *s = file_scopes.entries.e[i].value; - if (s->is_init) { - Entity *e = current_scope_lookup_entity(s, str_lit("main")); - if (e == NULL) { - Token token = {0}; - if (s->file->tokens.count > 0) { - token = s->file->tokens.e[0]; - } else { - token.pos.file = s->file->tokenizer.fullpath; - token.pos.line = 1; - token.pos.column = 1; + if (!build_context.is_dll) { + for_array(i, file_scopes.entries) { + Scope *s = file_scopes.entries.e[i].value; + if (s->is_init) { + Entity *e = current_scope_lookup_entity(s, str_lit("main")); + if (e == NULL) { + Token token = {0}; + if (s->file->tokens.count > 0) { + token = s->file->tokens.e[0]; + } else { + token.pos.file = s->file->tokenizer.fullpath; + token.pos.line = 1; + token.pos.column = 1; + } + + error(token, "Undefined entry point procedure `main`"); } - error(token, "Undefined entry point procedure `main`"); + break; } - - break; } } @@ -4830,8 +4830,9 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { a = ir_emit_deep_field_gep(proc, a, sel); return ir_addr(a); } else { - Type *type = base_type(type_of_expr(proc->module->info, se->expr)); - GB_ASSERT(is_type_integer(type)); + Type *type = type_deref(type_of_expr(proc->module->info, se->expr)); + Type *selector_type = base_type(type_of_expr(proc->module->info, se->selector)); + GB_ASSERT_MSG(is_type_integer(selector_type), "%s", type_to_string(selector_type)); ExactValue val = type_and_value_of_expression(proc->module->info, sel)->value; i64 index = val.value_integer; @@ -7283,7 +7284,17 @@ void ir_gen_tree(irGen *s) { irBlock *done = ir_new_block(proc, NULL, "if.done"); // NOTE(bill): Append later ir_emit_if(proc, cond, then, done); ir_start_block(proc, then); - ir_emit_global_call(proc, "main", NULL, 0); + + { + String main_name = str_lit("main"); + irValue **found = map_ir_value_get(&m->members, hash_string(main_name)); + if (found != NULL) { + ir_emit_call(proc, *found, NULL, 0); + } else { + ir_emit(proc, ir_alloc_instr(proc, irInstr_StartupRuntime)); + } + } + ir_emit_jump(proc, done); ir_start_block(proc, done); diff --git a/src/ir_print.c b/src/ir_print.c index e6b77aec3..237d50773 100644 --- a/src/ir_print.c +++ b/src/ir_print.c @@ -573,14 +573,12 @@ void ir_print_exact_value(irFileBuffer *f, irModule *m, ExactValue value, Type * } else { for (isize i = 0; i < value_count; i++) { Entity *f = type->Record.fields_in_src_order[i]; - - if (str_eq(f->token.string, str_lit("_"))) { - values[f->Variable.field_index] = (ExactValue){0}; - } else { - TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems.e[i]); - GB_ASSERT(tav != NULL); - values[f->Variable.field_index] = tav->value; + TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems.e[i]); + ExactValue val = {0}; + if (tav != NULL) { + val = tav->value; } + values[f->Variable.field_index] = val; } } diff --git a/src/parser.c b/src/parser.c index 403fcdda2..74800dd44 100644 --- a/src/parser.c +++ b/src/parser.c @@ -17,8 +17,6 @@ typedef enum ParseFileError { typedef Array(AstNode *) AstNodeArray; -gb_global i32 global_file_id = 0; - typedef struct AstFile { i32 id; gbArena arena; @@ -504,8 +502,9 @@ Token ast_node_token(AstNode *node) { case AstNode_ReturnStmt: return node->ReturnStmt.token; case AstNode_ForStmt: return node->ForStmt.token; case AstNode_RangeStmt: return node->RangeStmt.token; - case AstNode_MatchStmt: return node->MatchStmt.token; case AstNode_CaseClause: return node->CaseClause.token; + case AstNode_MatchStmt: return node->MatchStmt.token; + case AstNode_TypeMatchStmt: return node->TypeMatchStmt.token; case AstNode_DeferStmt: return node->DeferStmt.token; case AstNode_BranchStmt: return node->BranchStmt.token; case AstNode_UsingStmt: return node->UsingStmt.token; @@ -547,6 +546,267 @@ Token ast_node_token(AstNode *node) { return empty_token; } +AstNode *clone_ast_node(gbAllocator a, AstNode *node); +AstNodeArray clone_ast_node_array(gbAllocator a, AstNodeArray array) { + AstNodeArray result = {0}; + if (array.count > 0) { + array_init_count(&result, a, array.count); + for_array(i, array) { + result.e[i] = clone_ast_node(a, array.e[i]); + } + } + return result; +} + +AstNode *clone_ast_node(gbAllocator a, AstNode *node) { + if (node == NULL) { + return NULL; + } + AstNode *n = gb_alloc_item(a, AstNode); + gb_memmove(n, node, gb_size_of(AstNode)); + + switch (n->kind) { + case AstNode_Ident: break; + case AstNode_Implicit: break; + case AstNode_BasicLit: break; + case AstNode_BasicDirective: break; + case AstNode_Ellipsis: + n->Ellipsis.expr = clone_ast_node(a, n->Ellipsis.expr); + break; + case AstNode_ProcLit: + n->ProcLit.type = clone_ast_node(a, n->ProcLit.type); + n->ProcLit.body = clone_ast_node(a, n->ProcLit.body); + n->ProcLit.foreign_library = clone_ast_node(a, n->ProcLit.foreign_library); + break; + case AstNode_CompoundLit: + n->CompoundLit.type = clone_ast_node(a, n->CompoundLit.type); + n->CompoundLit.elems = clone_ast_node_array(a, n->CompoundLit.elems); + break; + case AstNode_Alias: + n->Alias.expr = clone_ast_node(a, n->Alias.expr); + break; + + case AstNode_BadExpr: break; + case AstNode_TagExpr: + n->TagExpr.expr = clone_ast_node(a, n->TagExpr.expr); + break; + case AstNode_RunExpr: + n->RunExpr.expr = clone_ast_node(a, n->RunExpr.expr); + break; + case AstNode_UnaryExpr: + n->RunExpr.expr = clone_ast_node(a, n->RunExpr.expr); + break; + case AstNode_BinaryExpr: + n->BinaryExpr.left = clone_ast_node(a, n->BinaryExpr.left); + n->BinaryExpr.right = clone_ast_node(a, n->BinaryExpr.right); + break; + case AstNode_ParenExpr: + n->ParenExpr.expr = clone_ast_node(a, n->ParenExpr.expr); + break; + case AstNode_SelectorExpr: + n->SelectorExpr.expr = clone_ast_node(a, n->SelectorExpr.expr); + n->SelectorExpr.selector = clone_ast_node(a, n->SelectorExpr.selector); + break; + case AstNode_IndexExpr: + n->IndexExpr.expr = clone_ast_node(a, n->IndexExpr.expr); + n->IndexExpr.index = clone_ast_node(a, n->IndexExpr.index); + break; + case AstNode_DerefExpr: + n->DerefExpr.expr = clone_ast_node(a, n->DerefExpr.expr); + break; + case AstNode_SliceExpr: + n->SliceExpr.expr = clone_ast_node(a, n->SliceExpr.expr); + n->SliceExpr.low = clone_ast_node(a, n->SliceExpr.low); + n->SliceExpr.high = clone_ast_node(a, n->SliceExpr.high); + n->SliceExpr.max = clone_ast_node(a, n->SliceExpr.max); + break; + case AstNode_CallExpr: + n->CallExpr.proc = clone_ast_node(a, n->CallExpr.proc); + n->CallExpr.args = clone_ast_node_array(a, n->CallExpr.args); + break; + case AstNode_MacroCallExpr: + n->MacroCallExpr.macro = clone_ast_node(a, n->MacroCallExpr.macro); + n->MacroCallExpr.args = clone_ast_node_array(a, n->MacroCallExpr.args); + break; + + case AstNode_FieldValue: + n->FieldValue.field = clone_ast_node(a, n->FieldValue.field); + n->FieldValue.value = clone_ast_node(a, n->FieldValue.value); + break; + + case AstNode_TernaryExpr: + n->TernaryExpr.cond = clone_ast_node(a, n->TernaryExpr.cond); + n->TernaryExpr.x = clone_ast_node(a, n->TernaryExpr.x); + n->TernaryExpr.y = clone_ast_node(a, n->TernaryExpr.cond); + break; + case AstNode_TypeAssertion: + n->TypeAssertion.expr = clone_ast_node(a, n->TypeAssertion.expr); + n->TypeAssertion.type = clone_ast_node(a, n->TypeAssertion.type); + break; + + case AstNode_BadStmt: break; + case AstNode_EmptyStmt: break; + case AstNode_ExprStmt: + n->ExprStmt.expr = clone_ast_node(a, n->ExprStmt.expr); + break; + case AstNode_TagStmt: + n->TagStmt.stmt = clone_ast_node(a, n->TagStmt.stmt); + break; + case AstNode_AssignStmt: + n->AssignStmt.lhs = clone_ast_node_array(a, n->AssignStmt.lhs); + n->AssignStmt.rhs = clone_ast_node_array(a, n->AssignStmt.rhs); + break; + case AstNode_IncDecStmt: + n->IncDecStmt.expr = clone_ast_node(a, n->IncDecStmt.expr); + break; + case AstNode_BlockStmt: + n->BlockStmt.stmts = clone_ast_node_array(a, n->BlockStmt.stmts); + break; + case AstNode_IfStmt: + n->IfStmt.init = clone_ast_node(a, n->IfStmt.init); + n->IfStmt.cond = clone_ast_node(a, n->IfStmt.cond); + n->IfStmt.body = clone_ast_node(a, n->IfStmt.body); + n->IfStmt.else_stmt = clone_ast_node(a, n->IfStmt.else_stmt); + break; + case AstNode_WhenStmt: + n->WhenStmt.cond = clone_ast_node(a, n->WhenStmt.cond); + n->WhenStmt.body = clone_ast_node(a, n->WhenStmt.body); + n->WhenStmt.else_stmt = clone_ast_node(a, n->WhenStmt.else_stmt); + break; + case AstNode_ReturnStmt: + n->ReturnStmt.results = clone_ast_node_array(a, n->ReturnStmt.results); + break; + case AstNode_ForStmt: + n->ForStmt.label = clone_ast_node(a, n->ForStmt.label); + n->ForStmt.init = clone_ast_node(a, n->ForStmt.init); + n->ForStmt.cond = clone_ast_node(a, n->ForStmt.cond); + n->ForStmt.post = clone_ast_node(a, n->ForStmt.post); + n->ForStmt.body = clone_ast_node(a, n->ForStmt.body); + break; + case AstNode_RangeStmt: + n->RangeStmt.label = clone_ast_node(a, n->RangeStmt.label); + n->RangeStmt.value = clone_ast_node(a, n->RangeStmt.value); + n->RangeStmt.index = clone_ast_node(a, n->RangeStmt.index); + n->RangeStmt.expr = clone_ast_node(a, n->RangeStmt.expr); + n->RangeStmt.body = clone_ast_node(a, n->RangeStmt.body); + break; + case AstNode_CaseClause: + n->CaseClause.list = clone_ast_node_array(a, n->CaseClause.list); + n->CaseClause.stmts = clone_ast_node_array(a, n->CaseClause.stmts); + break; + case AstNode_MatchStmt: + n->MatchStmt.label = clone_ast_node(a, n->MatchStmt.label); + n->MatchStmt.init = clone_ast_node(a, n->MatchStmt.init); + n->MatchStmt.tag = clone_ast_node(a, n->MatchStmt.tag); + n->MatchStmt.body = clone_ast_node(a, n->MatchStmt.body); + break; + case AstNode_TypeMatchStmt: + n->TypeMatchStmt.label = clone_ast_node(a, n->TypeMatchStmt.label); + n->TypeMatchStmt.tag = clone_ast_node(a, n->TypeMatchStmt.tag); + n->TypeMatchStmt.body = clone_ast_node(a, n->TypeMatchStmt.body); + break; + case AstNode_DeferStmt: + n->DeferStmt.stmt = clone_ast_node(a, n->DeferStmt.stmt); + break; + case AstNode_BranchStmt: + n->BranchStmt.label = clone_ast_node(a, n->BranchStmt.label); + break; + case AstNode_UsingStmt: + n->UsingStmt.list = clone_ast_node_array(a, n->UsingStmt.list); + break; + case AstNode_AsmOperand: + n->AsmOperand.operand = clone_ast_node(a, n->AsmOperand.operand); + break; + case AstNode_AsmStmt: + n->AsmStmt.output_list = clone_ast_node(a, n->AsmStmt.output_list); + n->AsmStmt.input_list = clone_ast_node(a, n->AsmStmt.input_list); + n->AsmStmt.clobber_list = clone_ast_node(a, n->AsmStmt.clobber_list); + break; + case AstNode_PushAllocator: + n->PushAllocator.expr = clone_ast_node(a, n->PushAllocator.expr); + n->PushAllocator.body = clone_ast_node(a, n->PushAllocator.body); + break; + case AstNode_PushContext: + n->PushContext.expr = clone_ast_node(a, n->PushContext.expr); + n->PushContext.body = clone_ast_node(a, n->PushContext.body); + break; + + case AstNode_BadDecl: break; + case AstNode_ValueDecl: + n->ValueDecl.names = clone_ast_node_array(a, n->ValueDecl.names); + n->ValueDecl.type = clone_ast_node(a, n->ValueDecl.type); + n->ValueDecl.values = clone_ast_node_array(a, n->ValueDecl.values); + break; + case AstNode_ImportDecl: + n->ImportDecl.cond = clone_ast_node(a, n->ImportDecl.cond); + n->ImportDecl.note = clone_ast_node(a, n->ImportDecl.note); + break; + case AstNode_ForeignLibrary: + n->ForeignLibrary.cond = clone_ast_node(a, n->ForeignLibrary.cond); + break; + case AstNode_Label: + n->Label.name = clone_ast_node(a, n->Label.name); + break; + + + case AstNode_Field: + n->Field.names = clone_ast_node_array(a, n->Field.names); + n->Field.type = clone_ast_node(a, n->Field.type); + break; + case AstNode_FieldList: + n->FieldList.list = clone_ast_node_array(a, n->FieldList.list); + break; + case AstNode_UnionField: + n->UnionField.name = clone_ast_node(a, n->UnionField.name); + n->UnionField.list = clone_ast_node(a, n->UnionField.list); + break; + + case AstNode_HelperType: + n->HelperType.type = clone_ast_node(a, n->HelperType.type); + break; + case AstNode_ProcType: + break; + case AstNode_PointerType: + n->PointerType.type = clone_ast_node(a, n->PointerType.type); + break; + case AstNode_AtomicType: + n->AtomicType.type = clone_ast_node(a, n->AtomicType.type); + break; + case AstNode_ArrayType: + n->ArrayType.count = clone_ast_node(a, n->ArrayType.count); + n->ArrayType.elem = clone_ast_node(a, n->ArrayType.elem); + break; + case AstNode_DynamicArrayType: + n->DynamicArrayType.elem = clone_ast_node(a, n->DynamicArrayType.elem); + break; + case AstNode_VectorType: + n->VectorType.count = clone_ast_node(a, n->VectorType.count); + n->VectorType.elem = clone_ast_node(a, n->VectorType.elem); + break; + case AstNode_StructType: + n->StructType.fields = clone_ast_node_array(a, n->StructType.fields); + break; + case AstNode_UnionType: + n->UnionType.fields = clone_ast_node_array(a, n->UnionType.fields); + n->UnionType.variants = clone_ast_node_array(a, n->UnionType.variants); + break; + case AstNode_RawUnionType: + n->RawUnionType.fields = clone_ast_node_array(a, n->RawUnionType.fields); + break; + case AstNode_EnumType: + n->EnumType.base_type = clone_ast_node(a, n->EnumType.base_type); + n->EnumType.fields = clone_ast_node_array(a, n->EnumType.fields); + break; + case AstNode_MapType: + n->MapType.count = clone_ast_node(a, n->MapType.count); + n->MapType.key = clone_ast_node(a, n->MapType.key); + n->MapType.value = clone_ast_node(a, n->MapType.value); + break; + } + + return n; +} + void error_node(AstNode *node, char *fmt, ...) { va_list va; @@ -1971,9 +2231,9 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) { case Token_Ident: operand = ast_selector_expr(f, token, operand, parse_ident(f)); break; - // case Token_Integer: - // operand = ast_selector_expr(f, token, operand, parse_expr(f, lhs)); - // break; + case Token_Integer: + operand = ast_selector_expr(f, token, operand, parse_expr(f, lhs)); + break; case Token_OpenParen: { Token open = expect_token(f, Token_OpenParen); AstNode *type = parse_type(f); @@ -3653,7 +3913,6 @@ ParseFileError init_ast_file(AstFile *f, String fullpath) { gb_arena_init_from_allocator(&f->arena, heap_allocator(), arena_size); f->curr_proc = NULL; - f->id = ++global_file_id; return ParseFile_None; } diff --git a/src/types.c b/src/types.c index b4a2248cf..c5a5e6d1d 100644 --- a/src/types.c +++ b/src/types.c @@ -1226,7 +1226,7 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, bool is_ty } Selection lookup_field_from_index(gbAllocator a, Type *type, i64 index) { - GB_ASSERT(is_type_struct(type) || is_type_tuple(type)); + GB_ASSERT(is_type_struct(type) || is_type_union(type) || is_type_tuple(type)); type = base_type(type); i64 max_count = 0; |