diff options
| author | Ginger Bill <bill@gingerbill.org> | 2017-02-01 17:52:55 +0000 |
|---|---|---|
| committer | Ginger Bill <bill@gingerbill.org> | 2017-02-01 17:52:55 +0000 |
| commit | 4e7082a68dd5261c3c36eccf92a62a0ce84995a8 (patch) | |
| tree | 01b5d690870b28b43a5e5c0c434495e56059babc | |
| parent | 502e63b9c50e71735c7989e59155a490bca991d2 (diff) | |
Change internals of `context`; Disable `immutable`
| -rw-r--r-- | code/demo.odin | 10 | ||||
| -rw-r--r-- | core/_preload.odin | 20 | ||||
| -rw-r--r-- | core/utf8.odin | 4 | ||||
| -rw-r--r-- | src/build.c | 2 | ||||
| -rw-r--r-- | src/check_expr.c | 18 | ||||
| -rw-r--r-- | src/checker.c | 70 | ||||
| -rw-r--r-- | src/entity.c | 2 | ||||
| -rw-r--r-- | src/ir.c | 44 | ||||
| -rw-r--r-- | src/parser.c | 232 | ||||
| -rw-r--r-- | src/tokenizer.c | 8 | ||||
| -rw-r--r-- | src/types.c | 60 |
11 files changed, 239 insertions, 231 deletions
diff --git a/code/demo.odin b/code/demo.odin index 61516e5b7..805a9690b 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -1,6 +1,16 @@ #import "fmt.odin"; +#import "atomic.odin"; +#import "hash.odin"; +#import "math.odin"; +#import "mem.odin"; +#import "opengl.odin"; +#import "os.odin"; +#import "sync.odin"; +#import "utf8.odin"; main :: proc() { + i: int; + x: [dynamic]f64; defer free(x); append(^x, 2_000_000.500_000, 3, 5, 7); diff --git a/core/_preload.odin b/core/_preload.odin index 24c682c8d..107e61dd2 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -321,6 +321,21 @@ __string_decode_rune :: proc(s: string) -> (rune, int) #inline { } +Raw_Any :: struct #ordered { + type_info: ^Type_Info, + data: rawptr, +} + +Raw_String :: struct #ordered { + data: ^byte, + count: int, +}; + +Raw_Slice :: struct #ordered { + data: rawptr, + count: int, +}; + Raw_Dynamic_Array :: struct #ordered { data: rawptr, count: int, @@ -360,6 +375,11 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int, items: rawptr, item_count: int) -> int { array := cast(^Raw_Dynamic_Array)array_; + if item_count <= 0 || items == nil { + return array.count; + } + + ok := true; if array.capacity <= array.count+item_count { capacity := 2 * array.capacity + max(8, item_count); diff --git a/core/utf8.odin b/core/utf8.odin index 8720e1f20..d1798547d 100644 --- a/core/utf8.odin +++ b/core/utf8.odin @@ -30,7 +30,7 @@ HICB :: 0b1011_1111; Accept_Range :: struct { lo, hi: u8 } -immutable accept_ranges := [5]Accept_Range{ +accept_ranges := [5]Accept_Range{ {0x80, 0xbf}, {0xa0, 0xbf}, {0x80, 0x9f}, @@ -38,7 +38,7 @@ immutable accept_ranges := [5]Accept_Range{ {0x80, 0x8f}, }; -immutable accept_sizes := [256]byte{ +accept_sizes := [256]byte{ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x00-0x0f 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x10-0x1f 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, // 0x20-0x2f diff --git a/src/build.c b/src/build.c index b1dc08bc4..f929dcc6d 100644 --- a/src/build.c +++ b/src/build.c @@ -148,7 +148,7 @@ String get_filepath_extension(String path) { void init_build_context(BuildContext *bc) { bc->ODIN_VENDOR = str_lit("odin"); - bc->ODIN_VERSION = str_lit("0.0.6b"); + bc->ODIN_VERSION = str_lit("0.1.0"); bc->ODIN_ROOT = odin_root_dir(); #if defined(GB_SYSTEM_WINDOWS) diff --git a/src/check_expr.c b/src/check_expr.c index f8d966319..c8b1c3175 100644 --- a/src/check_expr.c +++ b/src/check_expr.c @@ -876,6 +876,7 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Type o->mode = Addressing_Invalid; o->expr = n; String name = n->Ident.string; + Entity *e = scope_lookup_entity(c->context.scope, name); if (e == NULL) { if (str_eq(name, str_lit("_"))) { @@ -3987,6 +3988,23 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint goto error; case_end; + case_ast_node(i, Implicit, node) + switch (i->kind) { + case Token_context: + if (c->context.proc_name.len == 0) { + error_node(node, "`context` is only allowed within procedures"); + goto error; + } + + o->mode = Addressing_Value; + o->type = t_context; + break; + default: + error_node(node, "Illegal implicit name `%.*s`", LIT(i->string)); + goto error; + } + case_end; + case_ast_node(i, Ident, node); check_identifier(c, o, node, NULL, type_hint); case_end; diff --git a/src/checker.c b/src/checker.c index 7108eb4b7..7d3ca0d82 100644 --- a/src/checker.c +++ b/src/checker.c @@ -275,7 +275,6 @@ typedef struct CheckerInfo { MapAstFile files; // Key: String (full path) MapIsize type_info_map; // Key: Type * isize type_info_count; - Entity * implicit_values[ImplicitValue_Count]; } CheckerInfo; typedef struct Checker { @@ -1067,37 +1066,26 @@ MapEntity generate_minimum_dependency_map(CheckerInfo *info, Entity *start) { } -void add_implicit_value(Checker *c, ImplicitValueId id, String name, String backing_name, Type *type) { - ImplicitValueInfo info = {name, backing_name, type}; - Entity *value = make_entity_implicit_value(c->allocator, info.name, info.type, id); - Entity *prev = scope_insert_entity(c->global_scope, value); - GB_ASSERT(prev == NULL); - implicit_value_infos[id] = info; - c->info.implicit_values[id] = value; +Entity *find_core_entity(Checker *c, String name) { + Entity *e = current_scope_lookup_entity(c->global_scope, name); + if (e == NULL) { + compiler_error("Could not find type declaration for `%.*s`\n" + "Is `_preload.odin` missing from the `core` directory relative to odin.exe?", LIT(name)); + // NOTE(bill): This will exit the program as it's cannot continue without it! + } + return e; } - void init_preload(Checker *c) { if (c->done_preload) { return; } if (t_type_info == NULL) { - Entity *type_info_entity = current_scope_lookup_entity(c->global_scope, str_lit("Type_Info")); - if (type_info_entity == NULL) { - compiler_error("Could not find type declaration for `Type_Info`\n" - "Is `runtime.odin` missing from the `core` directory relative to odin.exe?"); - } - Entity *type_info_member_entity = current_scope_lookup_entity(c->global_scope, str_lit("Type_Info_Member")); - if (type_info_entity == NULL) { - compiler_error("Could not find type declaration for `Type_Info_Member`\n" - "Is `runtime.odin` missing from the `core` directory relative to odin.exe?"); - } - Entity *type_info_enum_value_entity = current_scope_lookup_entity(c->global_scope, str_lit("Type_Info_Enum_Value")); - if (type_info_entity == NULL) { - compiler_error("Could not find type declaration for `Type_Info_Enum_Value`\n" - "Is `runtime.odin` missing from the `core` directory relative to odin.exe?"); - } + Entity *type_info_entity = find_core_entity(c, str_lit("Type_Info")); + Entity *type_info_member_entity = find_core_entity(c, str_lit("Type_Info_Member")); + Entity *type_info_enum_value_entity = find_core_entity(c, str_lit("Type_Info_Enum_Value")); + t_type_info = type_info_entity->type; t_type_info_ptr = make_type_pointer(c->allocator, t_type_info); GB_ASSERT(is_type_union(type_info_entity->type)); @@ -1110,6 +1098,7 @@ void init_preload(Checker *c) { t_type_info_enum_value_ptr = make_type_pointer(c->allocator, t_type_info_enum_value); + if (record->field_count != 19) { compiler_error("Invalid `Type_Info` layout"); } @@ -1153,21 +1142,14 @@ void init_preload(Checker *c) { } if (t_allocator == NULL) { - Entity *e = current_scope_lookup_entity(c->global_scope, str_lit("Allocator")); - if (e == NULL) { - compiler_error("Could not find type declaration for `Allocator`\n" - "Is `runtime.odin` missing from the `core` directory relative to odin.exe?"); - } + Entity *e = find_core_entity(c, str_lit("Allocator")); t_allocator = e->type; t_allocator_ptr = make_type_pointer(c->allocator, t_allocator); } if (t_context == NULL) { - Entity *e = current_scope_lookup_entity(c->global_scope, str_lit("Context")); - if (e == NULL) { - compiler_error("Could not find type declaration for `Context`\n" - "Is `runtime.odin` missing from the `core` directory relative to odin.exe?"); - } + Entity *e = find_core_entity(c, str_lit("Context")); + e_context = e; t_context = e->type; t_context_ptr = make_type_pointer(c->allocator, t_context); } @@ -1768,26 +1750,6 @@ void check_parsed_files(Checker *c) { check_all_global_entities(c); init_preload(c); // NOTE(bill): This could be setup previously through the use of `type_info(_of_val)` - // NOTE(bill): Nothing in the global scope _should_ depend on this implicit value as implicit - // values are only useful within procedures - add_implicit_value(c, ImplicitValue_context, str_lit("context"), str_lit("__context"), t_context); - - // Initialize implicit values with backing variables - // TODO(bill): Are implicit values "too implicit"? - for (isize i = 1; i < ImplicitValue_Count; i++) { - // NOTE(bill): 0th is invalid - Entity *e = c->info.implicit_values[i]; - GB_ASSERT(e->kind == Entity_ImplicitValue); - - ImplicitValueInfo *ivi = &implicit_value_infos[i]; - Entity *backing = scope_lookup_entity(e->scope, ivi->backing_name); - // GB_ASSERT(backing != NULL); - if (backing == NULL) { - gb_exit(1); - } - e->ImplicitValue.backing = backing; - } - // Check procedure bodies // NOTE(bill): Nested procedures bodies will be added to this "queue" diff --git a/src/entity.c b/src/entity.c index 3464ad82e..3ca709aa4 100644 --- a/src/entity.c +++ b/src/entity.c @@ -101,6 +101,8 @@ struct Entity { }; }; +gb_global Entity *e_context = NULL; + Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token, Type *type) { Entity *entity = gb_alloc_item(a, Entity); @@ -1425,6 +1425,7 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue * Type *t_right = ir_type(right); if (is_type_vector(t_left)) { + ir_emit_comment(proc, str_lit("vector.arith.begin")); // IMPORTANT TODO(bill): This is very wasteful with regards to stack memory Type *tl = base_type(t_left); irValue *lhs = ir_address_from_load_or_generate_local(proc, left); @@ -1439,7 +1440,7 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue * irValue *z = ir_emit_arith(proc, op, x, y, elem_type); ir_emit_store(proc, ir_emit_array_epi(proc, res, i), z); } - + ir_emit_comment(proc, str_lit("vector.arith.end")); return ir_emit_load(proc, res); } @@ -1533,7 +1534,7 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal } if (is_type_vector(a)) { - // IMPORTANT TODO(bill): This is very wasteful with regards to stack memory + ir_emit_comment(proc, str_lit("vector.comp.begin")); Type *tl = base_type(a); irValue *lhs = ir_address_from_load_or_generate_local(proc, left); irValue *rhs = ir_address_from_load_or_generate_local(proc, right); @@ -1549,6 +1550,7 @@ irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irVal ir_emit_store(proc, ir_emit_array_epi(proc, res, i), z); } + ir_emit_comment(proc, str_lit("vector.comp.end")); return ir_emit_load(proc, res); } @@ -2560,15 +2562,6 @@ irValue *ir_find_global_variable(irProcedure *proc, String name) { return *value; } -irValue *ir_find_implicit_value_backing(irProcedure *proc, ImplicitValueId id) { - Entity *e = proc->module->info->implicit_values[id]; - GB_ASSERT(e->kind == Entity_ImplicitValue); - Entity *backing = e->ImplicitValue.backing; - irValue **value = map_ir_value_get(&proc->module->values, hash_pointer(backing)); - GB_ASSERT_MSG(value != NULL, "Unable to find implicit value backing `%.*s`", LIT(backing->token.string)); - return *value; -} - void ir_build_stmt_list(irProcedure *proc, AstNodeArray stmts); irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv) { @@ -2584,6 +2577,10 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv GB_PANIC("Non-constant basic literal %.*s(%td:%td) - %.*s", LIT(pos.file), pos.line, pos.column, LIT(bd->name)); case_end; + case_ast_node(i, Implicit, expr); + return ir_addr_load(proc, ir_build_addr(proc, expr)); + case_end; + case_ast_node(i, Ident, expr); Entity *e = *map_entity_get(&proc->module->info->uses, hash_pointer(expr)); if (e->kind == Entity_Builtin) { @@ -2595,7 +2592,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv } else if (e->kind == Entity_Nil) { return ir_make_value_nil(proc->module->allocator, tv->type); } else if (e->kind == Entity_ImplicitValue) { - return ir_emit_load(proc, ir_find_implicit_value_backing(proc, e->ImplicitValue.id)); + GB_PANIC("Illegal use of implicit value"); } irValue **found = map_ir_value_get(&proc->module->values, hash_pointer(e)); @@ -3171,7 +3168,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv return len; } break; case BuiltinProc_swizzle: { - ir_emit_comment(proc, str_lit("swizzle")); + ir_emit_comment(proc, str_lit("swizzle.begin")); irAddr vector_addr = ir_build_addr(proc, ce->args.e[0]); isize index_count = ce->args.count-1; if (index_count == 0) { @@ -3193,7 +3190,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv ir_emit_store(proc, dst_elem, ir_emit_load(proc, src_elem)); } - + ir_emit_comment(proc, str_lit("swizzle.end")); return ir_emit_load(proc, dst); // return ir_emit(proc, ir_make_instr_vector_shuffle(proc, vector, indices, index_count)); } break; @@ -3423,9 +3420,6 @@ irAddr ir_build_addr_from_entity(irProcedure *proc, Entity *e, AstNode *expr) { v = *found; } else if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) { v = ir_add_using_variable(proc, e); - } else if (e->kind == Entity_ImplicitValue) { - // TODO(bill): Should a copy be made? - v = ir_find_implicit_value_backing(proc, e->ImplicitValue.id); } if (v == NULL) { @@ -3437,6 +3431,18 @@ irAddr ir_build_addr_from_entity(irProcedure *proc, Entity *e, AstNode *expr) { irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { switch (expr->kind) { + case_ast_node(i, Implicit, expr); + irValue *v = NULL; + switch (i->kind) { + case Token_context: + v = ir_find_global_variable(proc, str_lit("__context")); + break; + } + + GB_ASSERT(v != NULL); + return ir_make_addr(v, expr); + case_end; + case_ast_node(i, Ident, expr); if (ir_is_blank_ident(expr)) { irAddr val = {0}; @@ -5063,7 +5069,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { ir_emit_comment(proc, str_lit("PushAllocator")); ir_open_scope(proc); - irValue *context_ptr = ir_find_implicit_value_backing(proc, ImplicitValue_context); + irValue *context_ptr = ir_find_global_variable(proc, str_lit("__context")); irValue *prev_context = ir_add_local_generated(proc, t_context); ir_emit_store(proc, prev_context, ir_emit_load(proc, context_ptr)); @@ -5082,7 +5088,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { ir_emit_comment(proc, str_lit("PushContext")); ir_open_scope(proc); - irValue *context_ptr = ir_find_implicit_value_backing(proc, ImplicitValue_context); + irValue *context_ptr = ir_find_global_variable(proc, str_lit("__context")); irValue *prev_context = ir_add_local_generated(proc, t_context); ir_emit_store(proc, prev_context, ir_emit_load(proc, context_ptr)); diff --git a/src/parser.c b/src/parser.c index 733ba0d8d..4f058777e 100644 --- a/src/parser.c +++ b/src/parser.c @@ -114,6 +114,7 @@ AstNodeArray make_ast_node_array(AstFile *f) { #define AST_NODE_KINDS \ AST_NODE_KIND(Ident, "identifier", Token) \ + AST_NODE_KIND(Implicit, "implicit", Token) \ AST_NODE_KIND(BasicLit, "basic literal", Token) \ AST_NODE_KIND(BasicDirective, "basic directive", struct { \ Token token; \ @@ -432,110 +433,65 @@ gb_inline bool is_ast_node_when_stmt(AstNode *node) { Token ast_node_token(AstNode *node) { switch (node->kind) { - case AstNode_Ident: - return node->Ident; - case AstNode_BasicLit: - return node->BasicLit; - case AstNode_BasicDirective: - return node->BasicDirective.token; - case AstNode_ProcLit: - return ast_node_token(node->ProcLit.type); + case AstNode_Ident: return node->Ident; + case AstNode_Implicit: return node->Implicit; + case AstNode_BasicLit: return node->BasicLit; + case AstNode_BasicDirective: return node->BasicDirective.token; + case AstNode_ProcLit: return ast_node_token(node->ProcLit.type); case AstNode_CompoundLit: if (node->CompoundLit.type != NULL) { return ast_node_token(node->CompoundLit.type); } return node->CompoundLit.open; - case AstNode_TagExpr: - return node->TagExpr.token; - case AstNode_RunExpr: - return node->RunExpr.token; - case AstNode_BadExpr: - return node->BadExpr.begin; - case AstNode_UnaryExpr: - return node->UnaryExpr.op; - case AstNode_BinaryExpr: - return ast_node_token(node->BinaryExpr.left); - case AstNode_ParenExpr: - return node->ParenExpr.open; - case AstNode_CallExpr: - return ast_node_token(node->CallExpr.proc); - case AstNode_MacroCallExpr: - return ast_node_token(node->MacroCallExpr.macro); + case AstNode_TagExpr: return node->TagExpr.token; + case AstNode_RunExpr: return node->RunExpr.token; + case AstNode_BadExpr: return node->BadExpr.begin; + case AstNode_UnaryExpr: return node->UnaryExpr.op; + case AstNode_BinaryExpr: return ast_node_token(node->BinaryExpr.left); + case AstNode_ParenExpr: return node->ParenExpr.open; + case AstNode_CallExpr: return ast_node_token(node->CallExpr.proc); + case AstNode_MacroCallExpr: return ast_node_token(node->MacroCallExpr.macro); case AstNode_SelectorExpr: if (node->SelectorExpr.selector != NULL) { return ast_node_token(node->SelectorExpr.selector); } return node->SelectorExpr.token; - case AstNode_IndexExpr: - return node->IndexExpr.open; - case AstNode_SliceExpr: - return node->SliceExpr.open; - case AstNode_Ellipsis: - return node->Ellipsis.token; - case AstNode_CastExpr: - return node->CastExpr.token; - case AstNode_FieldValue: - return node->FieldValue.eq; - case AstNode_DerefExpr: - return node->DerefExpr.op; - case AstNode_DemaybeExpr: - return node->DemaybeExpr.op; - case AstNode_BlockExpr: - return node->BlockExpr.open; - case AstNode_GiveExpr: - return node->GiveExpr.token; - case AstNode_IfExpr: - return node->IfExpr.token; - case AstNode_IntervalExpr: - return ast_node_token(node->IntervalExpr.left); - - case AstNode_BadStmt: - return node->BadStmt.begin; - case AstNode_EmptyStmt: - return node->EmptyStmt.token; - case AstNode_ExprStmt: - return ast_node_token(node->ExprStmt.expr); - case AstNode_TagStmt: - return node->TagStmt.token; - case AstNode_AssignStmt: - return node->AssignStmt.op; - case AstNode_BlockStmt: - return node->BlockStmt.open; - case AstNode_IfStmt: - return node->IfStmt.token; - case AstNode_WhenStmt: - return node->WhenStmt.token; - 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_DeferStmt: - return node->DeferStmt.token; - case AstNode_BranchStmt: - return node->BranchStmt.token; - case AstNode_UsingStmt: - return node->UsingStmt.token; - case AstNode_AsmStmt: - return node->AsmStmt.token; - case AstNode_PushAllocator: - return node->PushAllocator.token; - case AstNode_PushContext: - return node->PushContext.token; - - case AstNode_BadDecl: - return node->BadDecl.begin; - case AstNode_ValueDecl: - return ast_node_token(node->ValueDecl.names.e[0]); - case AstNode_ImportDecl: - return node->ImportDecl.token; - case AstNode_ForeignLibrary: - return node->ForeignLibrary.token; + case AstNode_IndexExpr: return node->IndexExpr.open; + case AstNode_SliceExpr: return node->SliceExpr.open; + case AstNode_Ellipsis: return node->Ellipsis.token; + case AstNode_CastExpr: return node->CastExpr.token; + case AstNode_FieldValue: return node->FieldValue.eq; + case AstNode_DerefExpr: return node->DerefExpr.op; + case AstNode_DemaybeExpr: return node->DemaybeExpr.op; + case AstNode_BlockExpr: return node->BlockExpr.open; + case AstNode_GiveExpr: return node->GiveExpr.token; + case AstNode_IfExpr: return node->IfExpr.token; + case AstNode_IntervalExpr: return ast_node_token(node->IntervalExpr.left); + + case AstNode_BadStmt: return node->BadStmt.begin; + case AstNode_EmptyStmt: return node->EmptyStmt.token; + case AstNode_ExprStmt: return ast_node_token(node->ExprStmt.expr); + case AstNode_TagStmt: return node->TagStmt.token; + case AstNode_AssignStmt: return node->AssignStmt.op; + case AstNode_BlockStmt: return node->BlockStmt.open; + case AstNode_IfStmt: return node->IfStmt.token; + case AstNode_WhenStmt: return node->WhenStmt.token; + 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_DeferStmt: return node->DeferStmt.token; + case AstNode_BranchStmt: return node->BranchStmt.token; + case AstNode_UsingStmt: return node->UsingStmt.token; + case AstNode_AsmStmt: return node->AsmStmt.token; + case AstNode_PushAllocator: return node->PushAllocator.token; + case AstNode_PushContext: return node->PushContext.token; + + case AstNode_BadDecl: return node->BadDecl.begin; + case AstNode_ValueDecl: return ast_node_token(node->ValueDecl.names.e[0]); + case AstNode_ImportDecl: return node->ImportDecl.token; + case AstNode_ForeignLibrary: return node->ForeignLibrary.token; case AstNode_Field: { @@ -547,28 +503,17 @@ Token ast_node_token(AstNode *node) { } - case AstNode_HelperType: - return node->HelperType.token; - case AstNode_ProcType: - return node->ProcType.token; - case AstNode_PointerType: - return node->PointerType.token; - case AstNode_MaybeType: - return node->MaybeType.token; - case AstNode_ArrayType: - return node->ArrayType.token; - case AstNode_DynamicArrayType: - return node->DynamicArrayType.token; - case AstNode_VectorType: - return node->VectorType.token; - case AstNode_StructType: - return node->StructType.token; - case AstNode_UnionType: - return node->UnionType.token; - case AstNode_RawUnionType: - return node->RawUnionType.token; - case AstNode_EnumType: - return node->EnumType.token; + case AstNode_HelperType: return node->HelperType.token; + case AstNode_ProcType: return node->ProcType.token; + case AstNode_PointerType: return node->PointerType.token; + case AstNode_MaybeType: return node->MaybeType.token; + case AstNode_ArrayType: return node->ArrayType.token; + case AstNode_DynamicArrayType: return node->DynamicArrayType.token; + case AstNode_VectorType: return node->VectorType.token; + case AstNode_StructType: return node->StructType.token; + case AstNode_UnionType: return node->UnionType.token; + case AstNode_RawUnionType: return node->RawUnionType.token; + case AstNode_EnumType: return node->EnumType.token; } return empty_token; @@ -766,6 +711,13 @@ AstNode *make_ident(AstFile *f, Token token) { return result; } +AstNode *make_implicit(AstFile *f, Token token) { + AstNode *result = make_node(f, AstNode_Implicit); + result->Implicit = token; + return result; +} + + AstNode *make_basic_lit(AstFile *f, Token basic_lit) { AstNode *result = make_node(f, AstNode_BasicLit); result->BasicLit = basic_lit; @@ -1284,7 +1236,9 @@ void fix_advance_to_next_stmt(AstFile *f) { case Token_defer: case Token_asm: case Token_using: - case Token_immutable: + case Token_thread_local: + case Token_no_alias: + // case Token_immutable: case Token_break: case Token_continue: @@ -1400,7 +1354,7 @@ void parse_proc_signature(AstFile *f, AstNodeArray *params, AstNodeArray -AstNode *parse_identifier(AstFile *f) { +AstNode *parse_ident(AstFile *f) { Token token = f->curr_token; if (token.kind == Token_Ident) { next_token(f); @@ -1553,7 +1507,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, AstNode **foreign_library_token, Str if (str_eq(tag_name, str_lit("foreign"))) { check_proc_add_tag(f, tag_expr, tags, ProcTag_foreign, tag_name); - *foreign_library_token = parse_identifier(f); + *foreign_library_token = parse_ident(f); if (f->curr_token.kind == Token_String) { *foreign_name = f->curr_token.string; // TODO(bill): Check if valid string @@ -1735,12 +1689,15 @@ AstNode *parse_operand(AstFile *f, bool lhs) { AstNode *operand = NULL; // Operand switch (f->curr_token.kind) { case Token_Ident: - operand = parse_identifier(f); + operand = parse_ident(f); if (!lhs) { // TODO(bill): Handle? } return operand; + case Token_context: + return make_implicit(f, expect_token(f, Token_context)); + case Token_Integer: case Token_Float: case Token_Rune: @@ -1965,7 +1922,7 @@ AstNode *parse_atom_expr(AstFile *f, bool lhs) { next_token(f); switch (f->curr_token.kind) { case Token_Ident: - operand = make_selector_expr(f, token, operand, parse_identifier(f)); + operand = make_selector_expr(f, token, operand, parse_ident(f)); break; // case Token_Integer: // operand = make_selector_expr(f, token, operand, parse_expr(f, lhs)); @@ -2190,7 +2147,7 @@ AstNodeArray parse_ident_list(AstFile *f) { AstNodeArray list = make_ast_node_array(f); do { - array_add(&list, parse_identifier(f)); + array_add(&list, parse_ident(f)); if (f->curr_token.kind != Token_Comma || f->curr_token.kind == Token_EOF) { break; @@ -2201,19 +2158,6 @@ AstNodeArray parse_ident_list(AstFile *f) { return list; } -void parse_check_name_list_for_reserves(AstFile *f, AstNodeArray names) { - for_array(i, names) { - AstNode *name = names.e[i]; - if (name->kind == AstNode_Ident) { - String n = name->Ident.string; - // NOTE(bill): Check for reserved identifiers - if (str_eq(n, str_lit("context"))) { - syntax_error_node(name, "`context` is a reserved identifier"); - break; - } - } - } -} AstNode *parse_type_attempt(AstFile *f) { AstNode *type = parse_type_or_ident(f); @@ -2236,8 +2180,6 @@ AstNode *parse_type(AstFile *f) { AstNode *parse_value_decl(AstFile *f, AstNodeArray lhs) { - parse_check_name_list_for_reserves(f, lhs); - AstNode *type = NULL; AstNodeArray values = {0}; bool is_mutable = true; @@ -2455,7 +2397,7 @@ u32 parse_field_prefixes(AstFile *f) { default: loop = false; break; case Token_using: using_count += 1; next_token(f); break; case Token_no_alias: no_alias_count += 1; next_token(f); break; - case Token_immutable: immutable_count += 1; next_token(f); break; + // case Token_immutable: immutable_count += 1; next_token(f); break; } } if (using_count > 1) syntax_error(f->curr_token, "Multiple `using` in this field list"); @@ -2575,12 +2517,13 @@ AstNodeArray parse_record_fields(AstFile *f, isize *field_count_, u32 flags, Str AstNode *parse_type_or_ident(AstFile *f) { switch (f->curr_token.kind) { - case Token_Ident: { - AstNode *e = parse_identifier(f); + case Token_Ident: + { + AstNode *e = parse_ident(f); while (f->curr_token.kind == Token_Period) { Token token = f->curr_token; next_token(f); - AstNode *sel = parse_identifier(f); + AstNode *sel = parse_ident(f); e = make_selector_expr(f, token, e, sel); } if (f->curr_token.kind == Token_OpenParen) { @@ -2794,7 +2737,7 @@ AstNode *parse_proc_decl(AstFile *f) { AstNodeArray results = {0}; Token proc_token = expect_token(f, Token_proc); - AstNode *name = parse_identifier(f); + AstNode *name = parse_ident(f); parse_proc_signature(f, ¶ms, &results); u64 tags = 0; @@ -3118,7 +3061,7 @@ AstNode *parse_match_stmt(AstFile *f) { isize prev_level = f->expr_level; f->expr_level = -1; - AstNode *var = parse_identifier(f); + AstNode *var = parse_ident(f); expect_token_after(f, Token_in, "match type name"); tag = parse_simple_stmt(f, false); @@ -3230,6 +3173,7 @@ AstNode *parse_stmt(AstFile *f) { Token token = f->curr_token; switch (token.kind) { // Operands + case Token_context: case Token_Ident: case Token_Integer: case Token_Float: @@ -3294,6 +3238,7 @@ AstNode *parse_stmt(AstFile *f) { return make_bad_stmt(f, token, f->curr_token); } break; +#if 0 case Token_immutable: { Token token = expect_token(f, Token_immutable); AstNode *node = parse_stmt(f); @@ -3309,6 +3254,7 @@ AstNode *parse_stmt(AstFile *f) { syntax_error(token, "`immutable` may only be applied to a variable declaration"); return make_bad_stmt(f, token, f->curr_token); } break; +#endif case Token_thread_local: { Token token = expect_token(f, Token_thread_local); diff --git a/src/tokenizer.c b/src/tokenizer.c index 63d1192be..c7607a0fa 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -80,6 +80,7 @@ TOKEN_KIND(Token__ComparisonEnd, "_ComparisonEnd"), \ TOKEN_KIND(Token__OperatorEnd, "_OperatorEnd"), \ \ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ + /* TODO(bill): So of these keywords are not used but "reserved", why not remove them? */ \ TOKEN_KIND(Token_when, "when"), \ TOKEN_KIND(Token_if, "if"), \ TOKEN_KIND(Token_else, "else"), \ @@ -102,17 +103,20 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ TOKEN_KIND(Token_raw_union, "raw_union"), \ TOKEN_KIND(Token_enum, "enum"), \ TOKEN_KIND(Token_vector, "vector"), \ + TOKEN_KIND(Token_static, "static"), \ TOKEN_KIND(Token_dynamic, "dynamic"), \ TOKEN_KIND(Token_using, "using"), \ TOKEN_KIND(Token_no_alias, "no_alias"), \ - TOKEN_KIND(Token_immutable, "immutable"), \ + /* TOKEN_KIND(Token_mutable, "mutable"), */\ + /* TOKEN_KIND(Token_immutable, "immutable"), */\ TOKEN_KIND(Token_thread_local, "thread_local"), \ TOKEN_KIND(Token_cast, "cast"), \ TOKEN_KIND(Token_transmute, "transmute"), \ TOKEN_KIND(Token_down_cast, "down_cast"), \ TOKEN_KIND(Token_union_cast, "union_cast"), \ - TOKEN_KIND(Token_push_allocator, "push_allocator"), \ + TOKEN_KIND(Token_context, "context"), \ TOKEN_KIND(Token_push_context, "push_context"), \ + TOKEN_KIND(Token_push_allocator, "push_allocator"), \ TOKEN_KIND(Token_asm, "asm"), \ TOKEN_KIND(Token__KeywordEnd, "_KeywordEnd"), \ TOKEN_KIND(Token_Count, "") diff --git a/src/types.c b/src/types.c index 099f0e05e..185438c03 100644 --- a/src/types.c +++ b/src/types.c @@ -166,6 +166,7 @@ typedef struct BaseTypeSizes { i64 max_align; } BaseTypeSizes; + typedef Array(isize) Array_isize; typedef struct Selection { @@ -263,6 +264,7 @@ gb_global Type *t_int_ptr = NULL; gb_global Type *t_i64_ptr = NULL; gb_global Type *t_f64_ptr = NULL; + gb_global Type *t_type_info = NULL; gb_global Type *t_type_info_member = NULL; gb_global Type *t_type_info_enum_value = NULL; @@ -892,6 +894,9 @@ bool is_type_cte_safe(Type *type) { case Type_Array: return is_type_cte_safe(type->Array.elem); + case Type_DynamicArray: + return false; + case Type_Vector: // NOTE(bill): This should always to be true but this is for sanity reasons return is_type_cte_safe(type->Vector.elem); @@ -1745,20 +1750,26 @@ i64 type_offset_of(BaseTypeSizes s, gbAllocator allocator, Type *t, isize index) } else if (t->kind == Type_Basic) { if (t->Basic.kind == Basic_string) { switch (index) { - case 0: return 0; - case 1: return s.word_size; + case 0: return 0; // data + case 1: return s.word_size; // count } } else if (t->Basic.kind == Basic_any) { switch (index) { - case 0: return 0; - case 1: return s.word_size; + case 0: return 0; // type_info + case 1: return s.word_size; // data } } } else if (t->kind == Type_Slice) { switch (index) { - case 0: return 0; - case 1: return 1*s.word_size; - case 2: return 2*s.word_size; + case 0: return 0; // data + case 1: return 1*s.word_size; // count + } + } else if (t->kind == Type_DynamicArray) { + switch (index) { + case 0: return 0; // data + case 1: return 1*s.word_size; // count + case 2: return 2*s.word_size; // capacity + case 3: return 3*s.word_size; // allocator } } return 0; @@ -1777,7 +1788,36 @@ i64 type_offset_of_from_selection(BaseTypeSizes s, gbAllocator allocator, Type * if (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct) { t = t->Record.fields[index]->type; } else { - // NOTE(bill): string/any/slices don't have record fields so this case doesn't need to be handled + // NOTE(bill): No need to worry about custom types, just need the alignment + switch (t->kind) { + case Type_Basic: + if (t->Basic.kind == Basic_string) { + switch (index) { + case 0: t = t_rawptr; break; + case 1: t = t_int; break; + } + } else if (t->Basic.kind == Basic_any) { + switch (index) { + case 0: t = t_type_info_ptr; break; + case 1: t = t_rawptr; break; + } + } + break; + case Type_DynamicArray: + switch (index) { + case 0: t = t_rawptr; break; + case 1: t = t_int; break; + case 2: t = t_int; break; + case 3: t = t_allocator; break; + } + break; + case Type_Slice: + switch (index) { + case 0: t = t_rawptr; break; + case 1: t = t_int; break; + } + break; + } } } return offset; @@ -1806,12 +1846,12 @@ gbString write_type_to_string(gbString str, Type *type) { break; case Type_Array: - str = gb_string_appendc(str, gb_bprintf("[%td]", type->Array.count)); + str = gb_string_appendc(str, gb_bprintf("[%lld]", type->Array.count)); str = write_type_to_string(str, type->Array.elem); break; case Type_Vector: - str = gb_string_appendc(str, gb_bprintf("[vector %td]", type->Vector.count)); + str = gb_string_appendc(str, gb_bprintf("[vector %lld]", type->Vector.count)); str = write_type_to_string(str, type->Vector.elem); break; |