aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-11-22 20:29:46 +0000
committerGinger Bill <bill@gingerbill.org>2016-11-22 20:29:46 +0000
commit3517f96668636f80cac0ee726bb52976027e47d9 (patch)
tree5965ae0a4acf31d3367f0b1ead84448cd02aab7d
parent36ad9dae43cd21d8532994cd0d0e92a89af0ed04 (diff)
Remove: string overloads; defer
-rw-r--r--build.bat4
-rw-r--r--misc/shell.bat4
-rw-r--r--src/checker/checker.cpp89
-rw-r--r--src/checker/decl.cpp37
-rw-r--r--src/checker/entity.cpp2
-rw-r--r--src/checker/expr.cpp375
-rw-r--r--src/checker/stmt.cpp103
-rw-r--r--src/checker/types.cpp56
-rw-r--r--src/common.cpp48
-rw-r--r--src/gb/gb.h2
-rw-r--r--src/main.cpp73
-rw-r--r--src/parser.cpp100
-rw-r--r--src/ssa.cpp148
-rw-r--r--src/ssa_opt.cpp6
-rw-r--r--src/ssa_print.cpp31
-rw-r--r--src/string.cpp44
-rw-r--r--src/tokenizer.cpp57
-rw-r--r--src/vm.cpp356
18 files changed, 611 insertions, 924 deletions
diff --git a/build.bat b/build.bat
index 065057a63..873ed2fa0 100644
--- a/build.bat
+++ b/build.bat
@@ -47,8 +47,8 @@ rem pushd %build_dir%
del *.ilk > NUL 2> NUL
cl %compiler_settings% "src\main.cpp" ^
- /link %linker_settings% -OUT:%exe_name% ^
- && odin run code/demo.odin
+ /link %linker_settings% -OUT:%exe_name%
+ rem && odin run code/demo.odin
rem odin run code/demo.odin
diff --git a/misc/shell.bat b/misc/shell.bat
index e3c7f3f40..5d9271622 100644
--- a/misc/shell.bat
+++ b/misc/shell.bat
@@ -1,7 +1,7 @@
@echo off
-call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x64 1> NUL
-rem call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64 1> NUL
+rem call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x64 1> NUL
+call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64 1> NUL
rem call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86 1> NUL
set _NO_DEBUG_HEAP=1
diff --git a/src/checker/checker.cpp b/src/checker/checker.cpp
index f8c35bcc3..9e6330325 100644
--- a/src/checker/checker.cpp
+++ b/src/checker/checker.cpp
@@ -508,10 +508,10 @@ void init_universal_scope(void) {
}
// Constants
- add_global_constant(a, make_string("true"), t_untyped_bool, make_exact_value_bool(true));
- add_global_constant(a, make_string("false"), t_untyped_bool, make_exact_value_bool(false));
+ add_global_constant(a, str_lit("true"), t_untyped_bool, make_exact_value_bool(true));
+ add_global_constant(a, str_lit("false"), t_untyped_bool, make_exact_value_bool(false));
- add_global_entity(make_entity_nil(a, make_string("nil"), t_untyped_nil));
+ add_global_entity(make_entity_nil(a, str_lit("nil"), t_untyped_nil));
// Builtin Procedures
for (isize i = 0; i < gb_count_of(builtin_procs); i++) {
@@ -671,7 +671,7 @@ void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity)
}
b32 add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) {
- if (entity->token.string != make_string("_")) {
+ if (str_ne(entity->token.string, str_lit("_"))) {
Entity *insert_entity = scope_insert_entity(scope, entity);
if (insert_entity) {
Entity *up = insert_entity->using_parent;
@@ -714,7 +714,7 @@ void add_entity_use(Checker *c, AstNode *identifier, Entity *entity) {
void add_entity_and_decl_info(Checker *c, AstNode *identifier, Entity *e, DeclInfo *d) {
- GB_ASSERT(identifier->Ident.string == e->token.string);
+ GB_ASSERT(str_eq(identifier->Ident.string, e->token.string));
add_entity(c, e->scope, identifier, e);
map_set(&c->info.entities, hash_pointer(e), d);
}
@@ -925,7 +925,7 @@ void init_preload_types(Checker *c) {
if (t_type_info == NULL) {
- Entity *e = current_scope_lookup_entity(c->global_scope, make_string("Type_Info"));
+ Entity *e = current_scope_lookup_entity(c->global_scope, str_lit("Type_Info"));
if (e == NULL) {
compiler_error("Could not find type declaration for `Type_Info`\n"
"Is `runtime.odin` missing from the `core` directory relative to odin.exe?");
@@ -961,7 +961,7 @@ void init_preload_types(Checker *c) {
}
if (t_allocator == NULL) {
- Entity *e = current_scope_lookup_entity(c->global_scope, make_string("Allocator"));
+ 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?");
@@ -971,7 +971,7 @@ void init_preload_types(Checker *c) {
}
if (t_context == NULL) {
- Entity *e = current_scope_lookup_entity(c->global_scope, make_string("Context"));
+ 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?");
@@ -992,14 +992,42 @@ void add_implicit_value(Checker *c, ImplicitValueId id, String name, String back
c->info.implicit_values[id] = value;
}
+
+void check_global_entity(Checker *c, EntityKind kind) {
+ PROF_SCOPED("check_global_entity");
+ for_array(i, c->info.entities.entries) {
+ auto *entry = &c->info.entities.entries[i];
+ Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
+ if (e->kind == kind) {
+ DeclInfo *d = entry->value;
+
+ add_curr_ast_file(c, d->scope->file);
+
+ if (d->scope == e->scope) {
+ if (kind != Entity_Procedure && str_eq(e->token.string, str_lit("main"))) {
+ if (e->scope->is_init) {
+ error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
+ continue;
+ }
+ } else if (e->scope->is_global && str_eq(e->token.string, str_lit("main"))) {
+ error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
+ continue;
+ }
+
+ Scope *prev_scope = c->context.scope;
+ c->context.scope = d->scope;
+ check_entity_decl(c, e, d, NULL);
+ }
+ }
+ }
+}
+
void check_parsed_files(Checker *c) {
Array<AstNode *> import_decls;
array_init(&import_decls, heap_allocator());
- defer (array_free(&import_decls));
Map<Scope *> file_scopes; // Key: String (fullpath)
map_init(&file_scopes, heap_allocator());
- defer (map_destroy(&file_scopes));
// Map full filepaths to Scopes
for_array(i, c->parser->files) {
@@ -1176,7 +1204,7 @@ void check_parsed_files(Checker *c) {
warning(id->token, "Multiple #import of the same file within this scope");
}
- if (id->import_name.string == ".") {
+ if (str_eq(id->import_name.string, str_lit("."))) {
// NOTE(bill): Add imported entities to this file's scope
for_array(elem_index, scope->elements.entries) {
Entity *e = scope->elements.entries[elem_index].value;
@@ -1241,39 +1269,10 @@ void check_parsed_files(Checker *c) {
}
}
- auto check_global_entity = [](Checker *c, EntityKind kind) {
- PROF_SCOPED("check_global_entity");
- for_array(i, c->info.entities.entries) {
- auto *entry = &c->info.entities.entries[i];
- Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
- if (e->kind == kind) {
- DeclInfo *d = entry->value;
-
- add_curr_ast_file(c, d->scope->file);
-
- if (d->scope == e->scope) {
- if (kind != Entity_Procedure && e->token.string == "main") {
- if (e->scope->is_init) {
- error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
- continue;
- }
- } else if (e->scope->is_global && e->token.string == "main") {
- error(e->token, "`main` is reserved as the entry point procedure in the initial scope");
- continue;
- }
-
- Scope *prev_scope = c->context.scope;
- c->context.scope = d->scope;
- check_entity_decl(c, e, d, NULL);
- }
- }
- }
- };
-
check_global_entity(c, Entity_TypeName);
init_preload_types(c);
- add_implicit_value(c, ImplicitValue_context, make_string("context"), make_string("__context"), t_context);
+ add_implicit_value(c, ImplicitValue_context, str_lit("context"), str_lit("__context"), t_context);
check_global_entity(c, Entity_Constant);
check_global_entity(c, Entity_Procedure);
@@ -1299,8 +1298,8 @@ void check_parsed_files(Checker *c) {
b32 bounds_check = (pi->tags & ProcTag_bounds_check) != 0;
b32 no_bounds_check = (pi->tags & ProcTag_no_bounds_check) != 0;
- auto prev_context = c->context;
- defer (c->context = prev_context);
+ CheckerContext prev_context = c->context;
+
if (bounds_check) {
c->context.stmt_state_flags |= StmtStateFlag_bounds_check;
c->context.stmt_state_flags &= ~StmtStateFlag_no_bounds_check;
@@ -1310,6 +1309,8 @@ void check_parsed_files(Checker *c) {
}
check_proc_body(c, pi->token, pi->decl, pi->type, pi->body);
+
+ c->context = prev_context;
}
// Add untyped expression values
@@ -1365,6 +1366,8 @@ void check_parsed_files(Checker *c) {
// gb_printf("%td - %s\n", e->value, type_to_string(prev_type));
// }
+ map_destroy(&file_scopes);
+ array_free(&import_decls);
}
diff --git a/src/checker/decl.cpp b/src/checker/decl.cpp
index 63cd6e3ce..37a832b9a 100644
--- a/src/checker/decl.cpp
+++ b/src/checker/decl.cpp
@@ -16,7 +16,6 @@ Type *check_init_variable(Checker *c, Entity *e, Operand *operand, String contex
if (operand->mode == Addressing_Builtin) {
gbString expr_str = expr_to_string(operand->expr);
- defer (gb_string_free(expr_str));
// TODO(bill): is this a good enough error message?
error(ast_node_token(operand->expr),
@@ -25,6 +24,8 @@ Type *check_init_variable(Checker *c, Entity *e, Operand *operand, String contex
LIT(context_name));
operand->mode = Addressing_Invalid;
+
+ gb_string_free(expr_str);
}
@@ -64,7 +65,6 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra
}
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
// NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
// an extra allocation
@@ -102,6 +102,8 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra
if (rhs_count > 0 && lhs_count != rhs_count) {
error(lhs[0]->token, "Assignment count mismatch `%td` := `%td`", lhs_count, rhs_count);
}
+
+ gb_temp_arena_memory_end(tmp);
}
@@ -129,10 +131,9 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type, Cyc
check_proc_decl(c, e, d);
return;
}
- auto prev = c->context;
+ CheckerContext prev = c->context;
c->context.scope = d->scope;
c->context.decl = d;
- defer (c->context = prev);
switch (e->kind) {
case Entity_Constant:
@@ -145,6 +146,8 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type, Cyc
check_type_decl(c, e, d->type_expr, named_type, cycle_checker);
break;
}
+
+ c->context = prev;
}
@@ -165,7 +168,7 @@ void check_var_decl_node(Checker *c, AstNode *node) {
String str = token.string;
Entity *found = NULL;
// NOTE(bill): Ignore assignments to `_`
- if (str != make_string("_")) {
+ if (str_ne(str, str_lit("_"))) {
found = current_scope_lookup_entity(c->context.scope, str);
}
if (found == NULL) {
@@ -208,7 +211,7 @@ void check_var_decl_node(Checker *c, AstNode *node) {
e->type = init_type;
}
- check_init_variables(c, entities, entity_count, vd->values, make_string("variable declaration"));
+ check_init_variables(c, entities, entity_count, vd->values, str_lit("variable declaration"));
for_array(i, vd->names) {
if (entities[i] != NULL) {
@@ -256,7 +259,7 @@ void check_init_constant(Checker *c, Entity *e, Operand *operand) {
e->type = operand->type;
}
- check_assignment(c, operand, e->type, make_string("constant declaration"));
+ check_assignment(c, operand, e->type, str_lit("constant declaration"));
if (operand->mode == Addressing_Invalid) {
return;
}
@@ -311,7 +314,6 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, Cycle
if (cycle_checker == NULL) {
cycle_checker = &local_cycle_checker;
}
- defer (cycle_checker_destroy(&local_cycle_checker));
Type *bt = check_type(c, type_expr, named, cycle_checker_add(cycle_checker, e));
named->Named.base = bt;
@@ -319,6 +321,8 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, Cycle
if (named->Named.base == t_invalid) {
gb_printf("check_type_decl: %s\n", type_to_string(named));
}
+
+ cycle_checker_destroy(&local_cycle_checker);
}
@@ -368,8 +372,8 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
Type *proc_type = make_type_proc(c->allocator, e->scope, NULL, 0, NULL, 0, false);
e->type = proc_type;
ast_node(pd, ProcDecl, d->proc_decl);
+
check_open_scope(c, pd->type);
- defer (check_close_scope(c));
check_procedure_type(c, proc_type, pd->type);
b32 is_foreign = (pd->tags & ProcTag_foreign) != 0;
@@ -378,16 +382,15 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
b32 is_no_inline = (pd->tags & ProcTag_no_inline) != 0;
if ((d->scope->is_file || d->scope->is_global) &&
- e->token.string == "main") {
+ str_eq(e->token.string, str_lit("main"))) {
if (proc_type != NULL) {
auto *pt = &proc_type->Proc;
if (pt->param_count != 0 ||
pt->result_count) {
gbString str = type_to_string(proc_type);
- defer (gb_string_free(str));
-
error(e->token,
"Procedure type of `main` was expected to be `proc()`, got %s", str);
+ gb_string_free(str);
}
}
}
@@ -455,6 +458,8 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
map_set(fp, key, e);
}
}
+
+ check_close_scope(c);
}
void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count, AstNode *type_expr, AstNode *init_expr) {
@@ -482,7 +487,7 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
GB_ASSERT(entities == NULL || entities[0] == e);
Operand operand = {};
check_expr(c, &operand, init_expr);
- check_init_variable(c, e, &operand, make_string("variable declaration"));
+ check_init_variable(c, e, &operand, str_lit("variable declaration"));
}
if (type_expr != NULL) {
@@ -493,7 +498,7 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count
AstNodeArray inits;
array_init(&inits, c->allocator, 1);
array_add(&inits, init_expr);
- check_init_variables(c, entities, entity_count, inits, make_string("variable declaration"));
+ check_init_variables(c, entities, entity_count, inits, str_lit("variable declaration"));
}
void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNode *body) {
@@ -502,8 +507,6 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
CheckerContext old_context = c->context;
c->context.scope = decl->scope;
c->context.decl = decl;
- defer (c->context = old_context);
-
GB_ASSERT(type->kind == Type_Proc);
if (type->Proc.param_count > 0) {
@@ -552,6 +555,8 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
check_scope_usage(c, c->context.scope);
+
+ c->context = old_context;
}
diff --git a/src/checker/entity.cpp b/src/checker/entity.cpp
index 44c32bece..4c0e86ab8 100644
--- a/src/checker/entity.cpp
+++ b/src/checker/entity.cpp
@@ -186,7 +186,7 @@ Entity *make_entity_implicit_value(gbAllocator a, String name, Type *type, Impli
Entity *make_entity_dummy_variable(gbAllocator a, Scope *file_scope, Token token) {
- token.string = make_string("_");
+ token.string = str_lit("_");
return make_entity_variable(a, file_scope, token, NULL);
}
diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp
index 1b2353ac5..55011467b 100644
--- a/src/checker/expr.cpp
+++ b/src/checker/expr.cpp
@@ -181,12 +181,9 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
if (type != NULL) {
if (!check_is_assignable_to(c, operand, type, is_argument)) {
- gbString type_string = type_to_string(type);
- gbString op_type_string = type_to_string(operand->type);
- gbString expr_str = expr_to_string(operand->expr);
- defer (gb_string_free(type_string));
- defer (gb_string_free(op_type_string));
- defer (gb_string_free(expr_str));
+ gbString type_str = type_to_string(type);
+ gbString op_type_str = type_to_string(operand->type);
+ gbString expr_str = expr_to_string(operand->expr);
if (operand->mode == Addressing_Builtin) {
// TODO(bill): is this a good enough error message?
@@ -199,11 +196,15 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
error(ast_node_token(operand->expr),
"Cannot assign value `%s` of type `%s` to `%s` in %.*s",
expr_str,
- op_type_string,
- type_string,
+ op_type_str,
+ type_str,
LIT(context_name));
}
operand->mode = Addressing_Invalid;
+
+ gb_string_free(expr_str);
+ gb_string_free(op_type_str);
+ gb_string_free(type_str);
return;
}
}
@@ -215,7 +216,6 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, Map<Entity *>
t = base_type(type_deref(t));
gbString str = expr_to_string(node);
- defer (gb_string_free(str));
if (t->kind == Type_Record) {
for (isize i = 0; i < t->Record.field_count; i++) {
@@ -238,6 +238,7 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, Map<Entity *>
}
}
+ gb_string_free(str);
}
void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init_expr);
@@ -249,11 +250,9 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
PROF_PROC();
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
Map<Entity *> entity_map = {};
map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(field_count+other_field_count));
- // defer (map_destroy(&entity_map));
isize other_field_index = 0;
Entity *using_index_expr = NULL;
@@ -303,7 +302,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
AstNode *name = cd->names[i];
Entity *e = entities[i];
Token name_token = name->Ident;
- if (name_token.string == "_") {
+ if (str_eq(name_token.string, str_lit("_"))) {
other_fields[other_field_index++] = e;
} else {
HashKey key = hash_string(name_token.string);
@@ -325,7 +324,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
Delay delay = {e, td->type};
array_add(&delayed_type, delay);
- if (name_token.string == "_") {
+ if (str_eq(name_token.string, str_lit("_"))) {
other_fields[other_field_index++] = e;
} else {
HashKey key = hash_string(name_token.string);
@@ -370,7 +369,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
type->Named.type_name = e;
add_entity(c, c->context.scope, name, e);
- if (name_token.string == "_") {
+ if (str_eq(name_token.string, str_lit("_"))) {
error(name_token, "`_` cannot be used a union subtype");
continue;
}
@@ -410,7 +409,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
Entity *e = make_entity_field(c->allocator, c->context.scope, name_token, type, vd->is_using, cast(i32)field_index);
e->identifier = name;
- if (name_token.string == "_") {
+ if (str_eq(name_token.string, str_lit("_"))) {
fields[field_index++] = e;
} else {
HashKey key = hash_string(name_token.string);
@@ -461,6 +460,8 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
}
}
}
+
+ gb_temp_arena_memory_end(tmp);
}
@@ -523,7 +524,7 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, CycleChecke
Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count);
Entity **other_fields = gb_alloc_array(c->allocator, Entity *, other_field_count);
- check_fields(c, node, st->decls, fields, field_count, other_fields, other_field_count, cycle_checker, make_string("struct"));
+ check_fields(c, node, st->decls, fields, field_count, other_fields, other_field_count, cycle_checker, str_lit("struct"));
struct_type->Record.struct_is_packed = st->is_packed;
@@ -589,7 +590,7 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node, CycleChecker
Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count);
Entity **other_fields = gb_alloc_array(c->allocator, Entity *, other_field_count);
- check_fields(c, node, ut->decls, fields, field_count, other_fields, other_field_count, cycle_checker, make_string("union"));
+ check_fields(c, node, ut->decls, fields, field_count, other_fields, other_field_count, cycle_checker, str_lit("union"));
union_type->Record.fields = fields;
union_type->Record.field_count = field_count;
@@ -626,7 +627,7 @@ void check_raw_union_type(Checker *c, Type *union_type, AstNode *node, CycleChec
Entity **fields = gb_alloc_array(c->allocator, Entity *, field_count);
Entity **other_fields = gb_alloc_array(c->allocator, Entity *, other_field_count);
- check_fields(c, node, ut->decls, fields, field_count, other_fields, other_field_count, cycle_checker, make_string("raw union"));
+ check_fields(c, node, ut->decls, fields, field_count, other_fields, other_field_count, cycle_checker, str_lit("raw union"));
union_type->Record.fields = fields;
union_type->Record.field_count = field_count;
@@ -663,12 +664,6 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
ast_node(et, EnumType, node);
- gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
-
- Map<Entity *> entity_map = {};
- map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(et->fields.count));
- // defer (map_destroy(&entity_map));
Type *base_type = t_int;
if (et->base_type != NULL) {
@@ -694,6 +689,13 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
if (named_type != NULL) {
constant_type = named_type;
}
+
+
+ gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
+
+ Map<Entity *> entity_map = {};
+ map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(et->fields.count));
+
Entity *blank_entity = make_entity_constant(c->allocator, c->context.scope, blank_token, constant_type, make_exact_value_integer(0));;
for_array(i, et->fields) {
@@ -702,15 +704,15 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
ast_node(f, FieldValue, field);
Token name_token = f->field->Ident;
- if (name_token.string == "count") {
+ if (str_eq(name_token.string, str_lit("count"))) {
error(name_token, "`count` is a reserved identifier for enumerations");
fields[field_index++] = blank_entity;
continue;
- } else if (name_token.string == "min_value") {
+ } else if (str_eq(name_token.string, str_lit("min_value"))) {
error(name_token, "`min_value` is a reserved identifier for enumerations");
fields[field_index++] = blank_entity;
continue;
- } else if (name_token.string == "max_value") {
+ } else if (str_eq(name_token.string, str_lit("max_value"))) {
error(name_token, "`max_value` is a reserved identifier for enumerations");
fields[field_index++] = blank_entity;
continue;
@@ -724,7 +726,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
o.mode = Addressing_Invalid;
}
if (o.mode != Addressing_Invalid) {
- check_assignment(c, &o, constant_type, make_string("enumeration"));
+ check_assignment(c, &o, constant_type, str_lit("enumeration"));
}
if (o.mode != Addressing_Invalid) {
iota = o.value;
@@ -766,11 +768,13 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
enum_type->Record.other_field_count = field_index;
enum_type->Record.enum_count = make_entity_constant(c->allocator, NULL,
- make_token_ident(make_string("count")), t_int, make_exact_value_integer(enum_type->Record.other_field_count));
+ make_token_ident(str_lit("count")), t_int, make_exact_value_integer(enum_type->Record.other_field_count));
enum_type->Record.min_value = make_entity_constant(c->allocator, NULL,
- make_token_ident(make_string("min_value")), constant_type, make_exact_value_integer(min_value));
+ make_token_ident(str_lit("min_value")), constant_type, make_exact_value_integer(min_value));
enum_type->Record.max_value = make_entity_constant(c->allocator, NULL,
- make_token_ident(make_string("max_value")), constant_type, make_exact_value_integer(max_value));
+ make_token_ident(str_lit("max_value")), constant_type, make_exact_value_integer(max_value));
+
+ gb_temp_arena_memory_end(tmp);
}
Type *check_get_params(Checker *c, Scope *scope, AstNodeArray params, b32 *is_variadic_) {
@@ -852,7 +856,7 @@ Type *check_get_results(Checker *c, Scope *scope, AstNodeArray results) {
AstNode *item = results[i];
Type *type = check_type(c, item);
Token token = ast_node_token(item);
- token.string = make_string(""); // NOTE(bill): results are not named
+ token.string = str_lit(""); // NOTE(bill): results are not named
// TODO(bill): Should I have named results?
Entity *param = make_entity_param(c->allocator, scope, token, type, false);
// NOTE(bill): No need to record
@@ -898,7 +902,7 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl
o->expr = n;
Entity *e = scope_lookup_entity(c->context.scope, n->Ident.string);
if (e == NULL) {
- if (n->Ident.string == "_") {
+ if (str_eq(n->Ident.string, str_lit("_"))) {
error(n->Ident, "`_` cannot be used as a value type");
} else {
error(n->Ident, "Undeclared name: %.*s", LIT(n->Ident.string));
@@ -1041,7 +1045,6 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c
ExactValue null_value = {ExactValue_Invalid};
Type *type = NULL;
gbString err_str = NULL;
- defer (gb_string_free(err_str));
switch (e->kind) {
case_ast_node(i, Ident, e);
@@ -1202,6 +1205,8 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_c
type = t_invalid;
end:
+ gb_string_free(err_str);
+
if (type == NULL) {
type = t_invalid;
}
@@ -1210,6 +1215,8 @@ end:
GB_ASSERT(is_type_typed(type));
add_type_and_value(&c->info, e, Addressing_Type, type, null_value);
+
+
return type;
}
@@ -1218,13 +1225,13 @@ b32 check_unary_op(Checker *c, Operand *o, Token op) {
// TODO(bill): Handle errors correctly
Type *type = base_type(base_vector_type(o->type));
gbString str = NULL;
- defer (gb_string_free(str));
switch (op.kind) {
case Token_Add:
case Token_Sub:
if (!is_type_numeric(type)) {
str = expr_to_string(o->expr);
error(op, "Operator `%.*s` is not allowed with `%s`", LIT(op.string), str);
+ gb_string_free(str);
}
break;
@@ -1238,6 +1245,7 @@ b32 check_unary_op(Checker *c, Operand *o, Token op) {
if (!is_type_boolean(type)) {
str = expr_to_string(o->expr);
error(op, "Operator `%.*s` is only allowed on boolean expression", LIT(op.string));
+ gb_string_free(str);
}
break;
@@ -1264,8 +1272,8 @@ b32 check_binary_op(Checker *c, Operand *o, Token op) {
}
if (base_type(type) == t_rawptr) {
gbString str = type_to_string(type);
- defer (gb_string_free(str));
error(ast_node_token(o->expr), "Invalid pointer type for pointer arithmetic: `%s`", str);
+ gb_string_free(str);
return false;
}
break;
@@ -1415,8 +1423,6 @@ void check_is_expressible(Checker *c, Operand *o, Type *type) {
if (!check_value_is_expressible(c, o->value, type, &o->value)) {
gbString a = expr_to_string(o->expr);
gbString b = type_to_string(type);
- defer (gb_string_free(a));
- defer (gb_string_free(b));
if (is_type_numeric(o->type) && is_type_numeric(type)) {
if (!is_type_integer(o->type) && is_type_integer(type)) {
error(ast_node_token(o->expr), "`%s` truncated to `%s`", a, b);
@@ -1427,6 +1433,8 @@ void check_is_expressible(Checker *c, Operand *o, Type *type) {
error(ast_node_token(o->expr), "Cannot convert `%s` to `%s`", a, b);
}
+ gb_string_free(b);
+ gb_string_free(a);
o->mode = Addressing_Invalid;
}
}
@@ -1467,8 +1475,8 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
check_is_vector_elem(c, o->expr)) {
ast_node(ue, UnaryExpr, node);
gbString str = expr_to_string(ue->expr);
- defer (gb_string_free(str));
error(op, "Cannot take the pointer address of `%s`", str);
+ gb_string_free(str);
o->mode = Addressing_Invalid;
return;
}
@@ -1487,8 +1495,8 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
if (!is_value || is_type_untyped(t)) {
ast_node(ue, UnaryExpr, node);
gbString str = expr_to_string(ue->expr);
- defer (gb_string_free(str));
error(op, "Cannot convert `%s` to a maybe", str);
+ gb_string_free(str);
o->mode = Addressing_Invalid;
return;
}
@@ -1508,9 +1516,9 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
if (type->kind != Type_Basic) {
gbString xt = type_to_string(o->type);
gbString err_str = expr_to_string(node);
- defer (gb_string_free(xt));
- defer (gb_string_free(err_str));
error(op, "Invalid type, `%s`, for constant unary expression `%s`", xt, err_str);
+ gb_string_free(err_str);
+ gb_string_free(xt);
o->mode = Addressing_Invalid;
return;
}
@@ -1538,12 +1546,8 @@ void check_comparison(Checker *c, Operand *x, Operand *y, Token op) {
PROF_PROC();
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
gbString err_str = NULL;
- defer (if (err_str != NULL) {
- gb_string_free(err_str);
- });
if (check_is_assignable_to(c, x, y->type) ||
check_is_assignable_to(c, y, x->type)) {
@@ -1573,40 +1577,45 @@ void check_comparison(Checker *c, Operand *x, Operand *y, Token op) {
if (!defined) {
gbString type_string = type_to_string(err_type);
- defer (gb_string_free(type_string));
err_str = gb_string_make(c->tmp_allocator,
gb_bprintf("operator `%.*s` not defined for type `%s`", LIT(op.string), type_string));
+ gb_string_free(type_string);
}
} else {
gbString xt = type_to_string(x->type);
gbString yt = type_to_string(y->type);
- defer(gb_string_free(xt));
- defer(gb_string_free(yt));
err_str = gb_string_make(c->tmp_allocator,
gb_bprintf("mismatched types `%s` and `%s`", xt, yt));
+ gb_string_free(yt);
+ gb_string_free(xt);
}
if (err_str != NULL) {
error(ast_node_token(x->expr), "Cannot compare expression, %s", err_str);
x->type = t_untyped_bool;
- return;
- }
-
- if (x->mode == Addressing_Constant &&
- y->mode == Addressing_Constant) {
- x->value = make_exact_value_bool(compare_exact_values(op, x->value, y->value));
} else {
- x->mode = Addressing_Value;
+ if (x->mode == Addressing_Constant &&
+ y->mode == Addressing_Constant) {
+ x->value = make_exact_value_bool(compare_exact_values(op, x->value, y->value));
+ } else {
+ x->mode = Addressing_Value;
- update_expr_type(c, x->expr, default_type(x->type), true);
- update_expr_type(c, y->expr, default_type(y->type), true);
- }
+ update_expr_type(c, x->expr, default_type(x->type), true);
+ update_expr_type(c, y->expr, default_type(y->type), true);
+ }
- if (is_type_vector(base_type(y->type))) {
- x->type = make_type_vector(c->allocator, t_bool, base_type(y->type)->Vector.count);
- } else {
- x->type = t_untyped_bool;
+ if (is_type_vector(base_type(y->type))) {
+ x->type = make_type_vector(c->allocator, t_bool, base_type(y->type)->Vector.count);
+ } else {
+ x->type = t_untyped_bool;
+ }
}
+
+ if (err_str != NULL) {
+ gb_string_free(err_str);
+ };
+
+ gb_temp_arena_memory_end(tmp);
}
void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
@@ -1623,9 +1632,9 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
b32 x_is_untyped = is_type_untyped(x->type);
if (!(is_type_integer(x->type) || (x_is_untyped && x_val.kind == ExactValue_Integer))) {
gbString err_str = expr_to_string(x->expr);
- defer (gb_string_free(err_str));
error(ast_node_token(node),
"Shifted operand `%s` must be an integer", err_str);
+ gb_string_free(err_str);
x->mode = Addressing_Invalid;
return;
}
@@ -1640,9 +1649,9 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
}
} else {
gbString err_str = expr_to_string(y->expr);
- defer (gb_string_free(err_str));
error(ast_node_token(node),
"Shift amount `%s` must be an unsigned integer", err_str);
+ gb_string_free(err_str);
x->mode = Addressing_Invalid;
return;
}
@@ -1653,9 +1662,9 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
ExactValue y_val = exact_value_to_integer(y->value);
if (y_val.kind != ExactValue_Integer) {
gbString err_str = expr_to_string(y->expr);
- defer (gb_string_free(err_str));
error(ast_node_token(node),
"Shift amount `%s` must be an unsigned integer", err_str);
+ gb_string_free(err_str);
x->mode = Addressing_Invalid;
return;
}
@@ -1663,9 +1672,9 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
u64 amount = cast(u64)y_val.value_integer;
if (amount > 1074) {
gbString err_str = expr_to_string(y->expr);
- defer (gb_string_free(err_str));
error(ast_node_token(node),
"Shift amount too large: `%s`", err_str);
+ gb_string_free(err_str);
x->mode = Addressing_Invalid;
return;
}
@@ -1696,9 +1705,9 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
if (y->mode == Addressing_Constant && y->value.value_integer < 0) {
gbString err_str = expr_to_string(y->expr);
- defer (gb_string_free(err_str));
error(ast_node_token(node),
"Shift amount cannot be negative: `%s`", err_str);
+ gb_string_free(err_str);
}
x->mode = Addressing_Value;
@@ -1814,8 +1823,8 @@ Operand check_ptr_addition(Checker *c, TokenKind op, Operand *ptr, Operand *offs
if (base_type(ptr->type) == t_rawptr) {
gbString str = type_to_string(ptr->type);
- defer (gb_string_free(str));
error(ast_node_token(node), "Invalid pointer type for pointer arithmetic: `%s`", str);
+ gb_string_free(str);
operand.mode = Addressing_Invalid;
return operand;
}
@@ -1843,9 +1852,6 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
GB_ASSERT(node->kind == AstNode_BinaryExpr);
Operand y_ = {}, *y = &y_;
- gbString err_str = NULL;
- defer (gb_string_free(err_str));
-
ast_node(be, BinaryExpr, node);
@@ -1877,10 +1883,10 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
gbString expr_str = expr_to_string(x->expr);
gbString to_type = type_to_string(type);
gbString from_type = type_to_string(x->type);
- defer (gb_string_free(expr_str));
- defer (gb_string_free(to_type));
- defer (gb_string_free(from_type));
error(ast_node_token(x->expr), "Cannot cast `%s` as `%s` from `%s`", expr_str, to_type, from_type);
+ gb_string_free(from_type);
+ gb_string_free(to_type);
+ gb_string_free(expr_str);
x->mode = Addressing_Invalid;
return;
@@ -1905,16 +1911,16 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
if (x->mode == Addressing_Constant) {
gbString expr_str = expr_to_string(x->expr);
- defer (gb_string_free(expr_str));
error(ast_node_token(x->expr), "Cannot transmute constant expression: `%s`", expr_str);
+ gb_string_free(expr_str);
x->mode = Addressing_Invalid;
return;
}
if (is_type_untyped(x->type)) {
gbString expr_str = expr_to_string(x->expr);
- defer (gb_string_free(expr_str));
error(ast_node_token(x->expr), "Cannot transmute untyped expression: `%s`", expr_str);
+ gb_string_free(expr_str);
x->mode = Addressing_Invalid;
return;
}
@@ -1924,9 +1930,9 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
if (srcz != dstz) {
gbString expr_str = expr_to_string(x->expr);
gbString type_str = type_to_string(type);
- defer (gb_string_free(expr_str));
- defer (gb_string_free(type_str));
error(ast_node_token(x->expr), "Cannot transmute `%s` to `%s`, %lld vs %lld bytes", expr_str, type_str, srcz, dstz);
+ gb_string_free(type_str);
+ gb_string_free(expr_str);
x->mode = Addressing_Invalid;
return;
}
@@ -1943,24 +1949,24 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
if (x->mode == Addressing_Constant) {
gbString expr_str = expr_to_string(node);
- defer (gb_string_free(expr_str));
error(ast_node_token(node), "Cannot `down_cast` a constant expression: `%s`", expr_str);
+ gb_string_free(expr_str);
x->mode = Addressing_Invalid;
return;
}
if (is_type_untyped(x->type)) {
gbString expr_str = expr_to_string(node);
- defer (gb_string_free(expr_str));
error(ast_node_token(node), "Cannot `down_cast` an untyped expression: `%s`", expr_str);
+ gb_string_free(expr_str);
x->mode = Addressing_Invalid;
return;
}
if (!(is_type_pointer(x->type) && is_type_pointer(type))) {
gbString expr_str = expr_to_string(node);
- defer (gb_string_free(expr_str));
error(ast_node_token(node), "Can only `down_cast` pointers: `%s`", expr_str);
+ gb_string_free(expr_str);
x->mode = Addressing_Invalid;
return;
}
@@ -1972,16 +1978,16 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
if (!(is_type_struct(bsrc) || is_type_raw_union(bsrc))) {
gbString expr_str = expr_to_string(node);
- defer (gb_string_free(expr_str));
error(ast_node_token(node), "Can only `down_cast` pointer from structs or unions: `%s`", expr_str);
+ gb_string_free(expr_str);
x->mode = Addressing_Invalid;
return;
}
if (!(is_type_struct(bdst) || is_type_raw_union(bdst))) {
gbString expr_str = expr_to_string(node);
- defer (gb_string_free(expr_str));
error(ast_node_token(node), "Can only `down_cast` pointer to structs or unions: `%s`", expr_str);
+ gb_string_free(expr_str);
x->mode = Addressing_Invalid;
return;
}
@@ -1989,8 +1995,8 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
String param_name = check_down_cast_name(dst, src);
if (param_name.len == 0) {
gbString expr_str = expr_to_string(node);
- defer (gb_string_free(expr_str));
error(ast_node_token(node), "Illegal `down_cast`: `%s`", expr_str);
+ gb_string_free(expr_str);
x->mode = Addressing_Invalid;
return;
}
@@ -2007,16 +2013,16 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
if (x->mode == Addressing_Constant) {
gbString expr_str = expr_to_string(node);
- defer (gb_string_free(expr_str));
error(ast_node_token(node), "Cannot `union_cast` a constant expression: `%s`", expr_str);
+ gb_string_free(expr_str);
x->mode = Addressing_Invalid;
return;
}
if (is_type_untyped(x->type)) {
gbString expr_str = expr_to_string(node);
- defer (gb_string_free(expr_str));
error(ast_node_token(node), "Cannot `union_cast` an untyped expression: `%s`", expr_str);
+ gb_string_free(expr_str);
x->mode = Addressing_Invalid;
return;
}
@@ -2031,9 +2037,9 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
if (src_is_ptr != dst_is_ptr) {
gbString src_type_str = type_to_string(x->type);
gbString dst_type_str = type_to_string(type);
- defer (gb_string_free(src_type_str));
- defer (gb_string_free(dst_type_str));
error(ast_node_token(node), "Invalid `union_cast` types: `%s` and `%s`", src_type_str, dst_type_str);
+ gb_string_free(dst_type_str);
+ gb_string_free(src_type_str);
x->mode = Addressing_Invalid;
return;
}
@@ -2056,15 +2062,15 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
if (!ok) {
gbString expr_str = expr_to_string(node);
gbString dst_type_str = type_to_string(type);
- defer (gb_string_free(expr_str));
- defer (gb_string_free(dst_type_str));
error(ast_node_token(node), "Cannot `union_cast` `%s` to `%s`", expr_str, dst_type_str);
+ gb_string_free(dst_type_str);
+ gb_string_free(expr_str);
x->mode = Addressing_Invalid;
return;
}
Entity **variables = gb_alloc_array(c->allocator, Entity *, 2);
- Token tok = make_token_ident(make_string(""));
+ Token tok = make_token_ident(str_lit(""));
variables[0] = make_entity_param(c->allocator, NULL, tok, type, false);
variables[1] = make_entity_param(c->allocator, NULL, tok, t_bool, false);
@@ -2103,9 +2109,9 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
if (op.kind == Token_Sub) {
gbString lhs = expr_to_string(x->expr);
gbString rhs = expr_to_string(y->expr);
- defer (gb_string_free(lhs));
- defer (gb_string_free(rhs));
error(ast_node_token(node), "Invalid pointer arithmetic, did you mean `%s %.*s %s`?", rhs, LIT(op.string), lhs);
+ gb_string_free(rhs);
+ gb_string_free(lhs);
x->mode = Addressing_Invalid;
return;
}
@@ -2135,10 +2141,11 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
y->type != t_invalid) {
gbString xt = type_to_string(x->type);
gbString yt = type_to_string(y->type);
- defer (gb_string_free(xt));
- defer (gb_string_free(yt));
- err_str = expr_to_string(x->expr);
- error(op, "Mismatched types in binary expression `%s` : `%s` vs `%s`", err_str, xt, yt);
+ gbString expr_str = expr_to_string(x->expr);
+ error(op, "Mismatched types in binary expression `%s` : `%s` vs `%s`", expr_str, xt, yt);
+ gb_string_free(expr_str);
+ gb_string_free(yt);
+ gb_string_free(xt);
}
x->mode = Addressing_Invalid;
return;
@@ -2194,9 +2201,10 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
if (type->kind != Type_Basic) {
gbString xt = type_to_string(x->type);
- defer (gb_string_free(xt));
- err_str = expr_to_string(node);
+ gbString err_str = expr_to_string(node);
error(op, "Invalid type, `%s`, for constant binary expression `%s`", xt, err_str);
+ gb_string_free(err_str);
+ gb_string_free(xt);
x->mode = Addressing_Invalid;
return;
}
@@ -2260,9 +2268,9 @@ void update_expr_type(Checker *c, AstNode *e, Type *type, b32 final) {
if (old.is_lhs && !is_type_integer(type)) {
gbString expr_str = expr_to_string(e);
gbString type_str = type_to_string(type);
- defer (gb_string_free(expr_str));
- defer (gb_string_free(type_str));
error(ast_node_token(e), "Shifted operand %s must be an integer, got %s", expr_str, type_str);
+ gb_string_free(type_str);
+ gb_string_free(expr_str);
return;
}
@@ -2281,12 +2289,10 @@ void convert_untyped_error(Checker *c, Operand *operand, Type *target_type) {
gbString expr_str = expr_to_string(operand->expr);
gbString type_str = type_to_string(target_type);
char *extra_text = "";
- defer (gb_string_free(expr_str));
- defer (gb_string_free(type_str));
if (operand->mode == Addressing_Constant) {
if (operand->value.value_integer == 0) {
- if (make_string(expr_str) != "nil") { // HACK NOTE(bill): Just in case
+ if (str_ne(make_string_c(expr_str), str_lit("nil"))) { // HACK NOTE(bill): Just in case
// NOTE(bill): Doesn't matter what the type is as it's still zero in the union
extra_text = " - Did you want `nil`?";
}
@@ -2294,6 +2300,8 @@ void convert_untyped_error(Checker *c, Operand *operand, Type *target_type) {
}
error(ast_node_token(operand->expr), "Cannot convert `%s` to `%s`%s", expr_str, type_str, extra_text);
+ gb_string_free(type_str);
+ gb_string_free(expr_str);
operand->mode = Addressing_Invalid;
}
@@ -2482,8 +2490,8 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
if (is_not_exported) {
gbString sel_str = expr_to_string(selector);
- defer (gb_string_free(sel_str));
error(ast_node_token(op_expr), "`%s` is not exported by `%.*s`", sel_str, LIT(name));
+ gb_string_free(sel_str);
// NOTE(bill): Not really an error so don't goto error
}
@@ -2506,10 +2514,10 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
gbString op_str = expr_to_string(op_expr);
gbString type_str = type_to_string(operand->type);
gbString sel_str = expr_to_string(selector);
- defer (gb_string_free(op_str));
- defer (gb_string_free(type_str));
- defer (gb_string_free(sel_str));
error(ast_node_token(op_expr), "`%s` (`%s`) has no field `%s`", op_str, type_str, sel_str);
+ gb_string_free(sel_str);
+ gb_string_free(type_str);
+ gb_string_free(op_str);
goto error;
}
@@ -2517,10 +2525,10 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
gbString op_str = expr_to_string(op_expr);
gbString type_str = type_to_string(operand->type);
gbString sel_str = expr_to_string(selector);
- defer (gb_string_free(op_str));
- defer (gb_string_free(type_str));
- defer (gb_string_free(sel_str));
error(ast_node_token(op_expr), "Cannot access non-constant field `%s` from `%s`", sel_str, op_str);
+ gb_string_free(sel_str);
+ gb_string_free(type_str);
+ gb_string_free(op_str);
goto error;
}
@@ -2640,10 +2648,10 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
}
if (!is_type_integer(op.type)) {
gbString type_str = type_to_string(operand->type);
- defer (gb_string_free(type_str));
error(ast_node_token(call),
"Length for `new_slice` must be an integer, got `%s`",
type_str);
+ gb_string_free(type_str);
return false;
}
@@ -2654,10 +2662,10 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
}
if (!is_type_integer(op.type)) {
gbString type_str = type_to_string(operand->type);
- defer (gb_string_free(type_str));
error(ast_node_token(call),
"Capacity for `new_slice` must be an integer, got `%s`",
type_str);
+ gb_string_free(type_str);
return false;
}
if (ce->args.count > 3) {
@@ -2687,7 +2695,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
case BuiltinProc_size_of_val:
// size_of_val :: proc(val: Type) -> untyped int
- check_assignment(c, operand, NULL, make_string("argument of `size_of_val`"));
+ check_assignment(c, operand, NULL, str_lit("argument of `size_of_val`"));
if (operand->mode == Addressing_Invalid) {
return false;
}
@@ -2711,7 +2719,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
case BuiltinProc_align_of_val:
// align_of_val :: proc(val: Type) -> untyped int
- check_assignment(c, operand, NULL, make_string("argument of `align_of_val`"));
+ check_assignment(c, operand, NULL, str_lit("argument of `align_of_val`"));
if (operand->mode == Addressing_Invalid) {
return false;
}
@@ -2747,16 +2755,16 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
Selection sel = lookup_field(c->allocator, type, arg->string, operand->mode == Addressing_Type);
if (sel.entity == NULL) {
gbString type_str = type_to_string(bt);
- defer (gb_string_free(type_str));
error(ast_node_token(ce->args[0]),
"`%s` has no field named `%.*s`", type_str, LIT(arg->string));
+ gb_string_free(type_str);
return false;
}
if (sel.indirect) {
gbString type_str = type_to_string(bt);
- defer (gb_string_free(type_str));
error(ast_node_token(ce->args[0]),
"Field `%.*s` is embedded via a pointer in `%s`", LIT(arg->string), type_str);
+ gb_string_free(type_str);
return false;
}
@@ -2802,9 +2810,9 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
}
if (sel.indirect) {
gbString type_str = type_to_string(type);
- defer (gb_string_free(type_str));
error(ast_node_token(ce->args[0]),
"Field `%.*s` is embedded via a pointer in `%s`", LIT(i->string), type_str);
+ gb_string_free(type_str);
return false;
}
@@ -2817,7 +2825,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
case BuiltinProc_type_of_val:
// type_of_val :: proc(val: Type) -> type(Type)
- check_assignment(c, operand, NULL, make_string("argument of `type_of_val`"));
+ check_assignment(c, operand, NULL, str_lit("argument of `type_of_val`"));
if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin) {
return false;
}
@@ -2844,7 +2852,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
// type_info_of_val :: proc(val: Type) -> ^Type_Info
AstNode *expr = ce->args[0];
- check_assignment(c, operand, NULL, make_string("argument of `type_info_of_val`"));
+ check_assignment(c, operand, NULL, str_lit("argument of `type_info_of_val`"));
if (operand->mode == Addressing_Invalid || operand->mode == Addressing_Builtin)
return false;
add_type_info_type(c, operand->type);
@@ -2860,16 +2868,14 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
if (!is_type_boolean(operand->type) && operand->mode != Addressing_Constant) {
gbString str = expr_to_string(ce->args[0]);
- defer (gb_string_free(str));
- error(ast_node_token(call),
- "`%s` is not a constant boolean", str);
+ error(ast_node_token(call), "`%s` is not a constant boolean", str);
+ gb_string_free(str);
return false;
}
if (!operand->value.value_bool) {
gbString str = expr_to_string(ce->args[0]);
- defer (gb_string_free(str));
- error(ast_node_token(call),
- "Compile time assertion: `%s`", str);
+ error(ast_node_token(call), "Compile time assertion: `%s`", str);
+ gb_string_free(str);
}
break;
@@ -2878,9 +2884,8 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
if (!is_type_boolean(operand->type)) {
gbString str = expr_to_string(ce->args[0]);
- defer (gb_string_free(str));
- error(ast_node_token(call),
- "`%s` is not a boolean", str);
+ error(ast_node_token(call), "`%s` is not a boolean", str);
+ gb_string_free(str);
return false;
}
@@ -2892,9 +2897,8 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
if (!is_type_string(operand->type)) {
gbString str = expr_to_string(ce->args[0]);
- defer (gb_string_free(str));
- error(ast_node_token(call),
- "`%s` is not a string", str);
+ error(ast_node_token(call), "`%s` is not a string", str);
+ gb_string_free(str);
return false;
}
@@ -2906,16 +2910,18 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
Type *dest_type = NULL, *src_type = NULL;
Type *d = base_type(operand->type);
- if (d->kind == Type_Slice)
+ if (d->kind == Type_Slice) {
dest_type = d->Slice.elem;
-
+ }
Operand op = {};
check_expr(c, &op, ce->args[1]);
- if (op.mode == Addressing_Invalid)
+ if (op.mode == Addressing_Invalid) {
return false;
+ }
Type *s = base_type(op.type);
- if (s->kind == Type_Slice)
+ if (s->kind == Type_Slice) {
src_type = s->Slice.elem;
+ }
if (dest_type == NULL || src_type == NULL) {
error(ast_node_token(call), "`copy` only expects slices as arguments");
@@ -2927,13 +2933,13 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
gbString s_arg = expr_to_string(ce->args[1]);
gbString d_str = type_to_string(dest_type);
gbString s_str = type_to_string(src_type);
- defer (gb_string_free(d_arg));
- defer (gb_string_free(s_arg));
- defer (gb_string_free(d_str));
- defer (gb_string_free(s_str));
error(ast_node_token(call),
"Arguments to `copy`, %s, %s, have different elem types: %s vs %s",
d_arg, s_arg, d_str, s_str);
+ gb_string_free(s_str);
+ gb_string_free(d_str);
+ gb_string_free(s_arg);
+ gb_string_free(d_arg);
return false;
}
@@ -2948,8 +2954,9 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
Operand op = {};
check_expr(c, &op, ce->args[1]);
- if (op.mode == Addressing_Invalid)
+ if (op.mode == Addressing_Invalid) {
return false;
+ }
y_type = base_type(op.type);
if (!(is_type_pointer(x_type) && is_type_slice(x_type->Pointer.elem))) {
@@ -2963,13 +2970,13 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
gbString s_arg = expr_to_string(ce->args[1]);
gbString d_str = type_to_string(elem_type);
gbString s_str = type_to_string(y_type);
- defer (gb_string_free(d_arg));
- defer (gb_string_free(s_arg));
- defer (gb_string_free(d_str));
- defer (gb_string_free(s_str));
error(ast_node_token(call),
"Arguments to `append`, %s, %s, have different element types: %s vs %s",
d_arg, s_arg, d_str, s_str);
+ gb_string_free(s_str);
+ gb_string_free(d_str);
+ gb_string_free(s_arg);
+ gb_string_free(d_arg);
return false;
}
@@ -2982,22 +2989,25 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
Type *vector_type = base_type(operand->type);
if (!is_type_vector(vector_type)) {
gbString type_str = type_to_string(operand->type);
- defer (gb_string_free(type_str));
error(ast_node_token(call),
"You can only `swizzle` a vector, got `%s`",
type_str);
+ gb_string_free(type_str);
return false;
}
isize max_count = vector_type->Vector.count;
isize arg_count = 0;
for_array(i, ce->args) {
- if (i == 0) continue;
+ if (i == 0) {
+ continue;
+ }
AstNode *arg = ce->args[i];
Operand op = {};
check_expr(c, &op, arg);
- if (op.mode == Addressing_Invalid)
+ if (op.mode == Addressing_Invalid) {
return false;
+ }
Type *arg_type = base_type(op.type);
if (!is_type_integer(arg_type) || op.mode != Addressing_Constant) {
error(ast_node_token(op.expr), "Indices to `swizzle` must be constant integers");
@@ -3138,10 +3148,10 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
Type *ptr_type = base_type(operand->type);
if (!is_type_pointer(ptr_type)) {
gbString type_str = type_to_string(operand->type);
- defer (gb_string_free(type_str));
error(ast_node_token(call),
"Expected a pointer to `slice_ptr`, got `%s`",
type_str);
+ gb_string_free(type_str);
return false;
}
@@ -3163,10 +3173,10 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
return false;
if (!is_type_integer(op.type)) {
gbString type_str = type_to_string(operand->type);
- defer (gb_string_free(type_str));
error(ast_node_token(call),
"Length for `slice_ptr` must be an integer, got `%s`",
type_str);
+ gb_string_free(type_str);
return false;
}
@@ -3176,10 +3186,10 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
return false;
if (!is_type_integer(op.type)) {
gbString type_str = type_to_string(operand->type);
- defer (gb_string_free(type_str));
error(ast_node_token(call),
"Capacity for `slice_ptr` must be an integer, got `%s`",
type_str);
+ gb_string_free(type_str);
return false;
}
if (ce->args.count > 3) {
@@ -3198,10 +3208,10 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
Type *type = base_type(operand->type);
if (!is_type_comparable(type) || !is_type_numeric(type)) {
gbString type_str = type_to_string(operand->type);
- defer (gb_string_free(type_str));
error(ast_node_token(call),
"Expected a comparable numeric type to `min`, got `%s`",
type_str);
+ gb_string_free(type_str);
return false;
}
@@ -3214,10 +3224,10 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
}
if (!is_type_comparable(b.type) || !is_type_numeric(type)) {
gbString type_str = type_to_string(b.type);
- defer (gb_string_free(type_str));
error(ast_node_token(call),
"Expected a comparable numeric type to `min`, got `%s`",
type_str);
+ gb_string_free(type_str);
return false;
}
@@ -3251,11 +3261,11 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
if (!are_types_identical(operand->type, b.type)) {
gbString type_a = type_to_string(a.type);
gbString type_b = type_to_string(b.type);
- defer (gb_string_free(type_a));
- defer (gb_string_free(type_b));
error(ast_node_token(call),
"Mismatched types to `min`, `%s` vs `%s`",
type_a, type_b);
+ gb_string_free(type_b);
+ gb_string_free(type_a);
return false;
}
}
@@ -3267,10 +3277,10 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
Type *type = base_type(operand->type);
if (!is_type_comparable(type) || !is_type_numeric(type)) {
gbString type_str = type_to_string(operand->type);
- defer (gb_string_free(type_str));
error(ast_node_token(call),
"Expected a comparable numeric type to `max`, got `%s`",
type_str);
+ gb_string_free(type_str);
return false;
}
@@ -3283,10 +3293,10 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
}
if (!is_type_comparable(b.type) || !is_type_numeric(type)) {
gbString type_str = type_to_string(b.type);
- defer (gb_string_free(type_str));
error(ast_node_token(call),
"Expected a comparable numeric type to `max`, got `%s`",
type_str);
+ gb_string_free(type_str);
return false;
}
@@ -3320,11 +3330,11 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
if (!are_types_identical(operand->type, b.type)) {
gbString type_a = type_to_string(a.type);
gbString type_b = type_to_string(b.type);
- defer (gb_string_free(type_a));
- defer (gb_string_free(type_b));
error(ast_node_token(call),
"Mismatched types to `max`, `%s` vs `%s`",
type_a, type_b);
+ gb_string_free(type_b);
+ gb_string_free(type_a);
return false;
}
}
@@ -3336,10 +3346,10 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
Type *type = base_type(operand->type);
if (!is_type_numeric(type)) {
gbString type_str = type_to_string(operand->type);
- defer (gb_string_free(type_str));
error(ast_node_token(call),
"Expected a numeric type to `abs`, got `%s`",
type_str);
+ gb_string_free(type_str);
return false;
}
@@ -3366,7 +3376,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
Type *type = base_type(operand->type);
if (!is_type_enum(type)) {
gbString type_str = type_to_string(operand->type);
- defer (gb_string_free(type_str));
+ gb_string_free(type_str);
error(ast_node_token(call),
"Expected an enum to `enum_to_string`, got `%s`",
type_str);
@@ -3374,7 +3384,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
}
if (operand->mode == Addressing_Constant) {
- ExactValue value = make_exact_value_string(make_string(""));
+ ExactValue value = make_exact_value_string(str_lit(""));
if (operand->value.kind == ExactValue_Integer) {
i64 index = operand->value.value_integer;
for (isize i = 0; i < type->Record.other_field_count; i++) {
@@ -3435,7 +3445,6 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
}
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
Array<Operand> operands;
array_init(&operands, c->tmp_allocator, 2*param_count);
@@ -3451,7 +3460,7 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
error(ast_node_token(ce->args[i]),
"`..` in a variadic procedure cannot be applied to a %td-valued expression", tuple->variable_count);
operand->mode = Addressing_Invalid;
- return;
+ goto end;
}
for (isize j = 0; j < tuple->variable_count; j++) {
o.type = tuple->variables[j]->type;
@@ -3473,10 +3482,10 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
}
gbString proc_str = expr_to_string(ce->proc);
- defer (gb_string_free(proc_str));
error(ast_node_token(call), err_fmt, proc_str, param_count);
+ gb_string_free(proc_str);
operand->mode = Addressing_Invalid;
- return;
+ goto end;
}
GB_ASSERT(proc_type->Proc.params != NULL);
@@ -3488,7 +3497,7 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
if (variadic) {
o = operands[operand_index];
}
- check_assignment(c, &o, arg_type, make_string("argument"), true);
+ check_assignment(c, &o, arg_type, str_lit("argument"), true);
}
if (variadic) {
@@ -3508,9 +3517,11 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
break;
}
}
- check_assignment(c, &o, t, make_string("argument"), true);
+ check_assignment(c, &o, t, str_lit("argument"), true);
}
}
+end:
+ gb_temp_arena_memory_end(tmp);
}
@@ -3566,8 +3577,8 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
if (proc_type == NULL || proc_type->kind != Type_Proc) {
AstNode *e = operand->expr;
gbString str = expr_to_string(e);
- defer (gb_string_free(str));
error(ast_node_token(e), "Cannot call a non-procedure: `%s`", str);
+ gb_string_free(str);
operand->mode = Addressing_Invalid;
operand->expr = call;
@@ -3612,8 +3623,8 @@ void check_expr_with_type_hint(Checker *c, Operand *o, AstNode *e, Type *t) {
}
if (err_str != NULL) {
gbString str = expr_to_string(e);
- defer (gb_string_free(str));
error(ast_node_token(e), "`%s` %s", str, err_str);
+ gb_string_free(str);
o->mode = Addressing_Invalid;
}
}
@@ -3653,17 +3664,18 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
case_ast_node(pl, ProcLit, node);
check_open_scope(c, pl->type);
- defer (check_close_scope(c));
c->context.decl = make_declaration_info(c->allocator, c->context.scope);
Type *proc_type = check_type(c, pl->type);
if (proc_type != NULL) {
check_proc_body(c, empty_token, c->context.decl, proc_type, pl->body);
o->mode = Addressing_Value;
o->type = proc_type;
+ check_close_scope(c);
} else {
gbString str = expr_to_string(node);
error(ast_node_token(node), "Invalid procedure literal `%s`", str);
gb_string_free(str);
+ check_close_scope(c);
goto error;
}
case_end;
@@ -3722,9 +3734,9 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
ast_node(fv, FieldValue, elem);
if (fv->field->kind != AstNode_Ident) {
gbString expr_str = expr_to_string(fv->field);
- defer (gb_string_free(expr_str));
error(ast_node_token(elem),
"Invalid field name `%s` in structure literal", expr_str);
+ gb_string_free(expr_str);
continue;
}
String name = fv->field->Ident.string;
@@ -3762,7 +3774,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
}
- check_assignment(c, o, field->type, make_string("structure literal"));
+ check_assignment(c, o, field->type, str_lit("structure literal"));
}
} else {
for_array(index, cl->elems) {
@@ -3787,7 +3799,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
is_constant = o->mode == Addressing_Constant;
}
- check_assignment(c, o, field->type, make_string("structure literal"));
+ check_assignment(c, o, field->type, str_lit("structure literal"));
}
if (cl->elems.count < field_count) {
error(cl->close, "Too few values in structure literal, expected %td, got %td", field_count, cl->elems.count);
@@ -3805,13 +3817,13 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
String context_name = {};
if (t->kind == Type_Slice) {
elem_type = t->Slice.elem;
- context_name = make_string("slice literal");
+ context_name = str_lit("slice literal");
} else if (t->kind == Type_Vector) {
elem_type = t->Vector.elem;
- context_name = make_string("vector literal");
+ context_name = str_lit("vector literal");
} else {
elem_type = t->Array.elem;
- context_name = make_string("array literal");
+ context_name = str_lit("array literal");
}
@@ -4136,7 +4148,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
if (t->kind == Type_Maybe) {
Entity **variables = gb_alloc_array(c->allocator, Entity *, 2);
Type *elem = t->Maybe.elem;
- Token tok = make_token_ident(make_string(""));
+ Token tok = make_token_ident(str_lit(""));
variables[0] = make_entity_param(c->allocator, NULL, tok, elem, false);
variables[1] = make_entity_param(c->allocator, NULL, tok, t_bool, false);
@@ -4208,8 +4220,6 @@ ExprKind check_expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint)
void check_multi_expr(Checker *c, Operand *o, AstNode *e) {
gbString err_str = NULL;
- defer (gb_string_free(err_str));
-
check_expr_base(c, o, e);
switch (o->mode) {
default:
@@ -4224,6 +4234,7 @@ void check_multi_expr(Checker *c, Operand *o, AstNode *e) {
error(ast_node_token(e), "`%s` is not an expression", err_str);
break;
}
+ gb_string_free(err_str);
o->mode = Addressing_Invalid;
}
@@ -4251,10 +4262,10 @@ void check_expr_or_type(Checker *c, Operand *o, AstNode *e) {
check_not_tuple(c, o);
if (o->mode == Addressing_NoValue) {
gbString str = expr_to_string(o->expr);
- defer (gb_string_free(str));
error(ast_node_token(o->expr),
"`%s` used as value or type", str);
o->mode = Addressing_Invalid;
+ gb_string_free(str);
}
}
diff --git a/src/checker/stmt.cpp b/src/checker/stmt.cpp
index ecfc48cdd..b5db09efc 100644
--- a/src/checker/stmt.cpp
+++ b/src/checker/stmt.cpp
@@ -18,12 +18,11 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
}
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
- struct Delay {
+ typedef struct {
Entity *e;
DeclInfo *d;
- };
+ } Delay;
Array<Delay> delayed_const; array_init(&delayed_const, c->tmp_allocator, stmts.count);
Array<Delay> delayed_type; array_init(&delayed_type, c->tmp_allocator, stmts.count);
@@ -95,6 +94,8 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
}
check_stmt(c, n, new_flags);
}
+
+ gb_temp_arena_memory_end(tmp);
}
b32 check_is_terminating_list(AstNodeArray stmts) {
@@ -238,9 +239,9 @@ Type *check_assignment_variable(Checker *c, Operand *op_a, AstNode *lhs) {
// NOTE(bill): Ignore assignments to `_`
if (node->kind == AstNode_Ident &&
- node->Ident.string == "_") {
+ str_eq(node->Ident.string, str_lit("_"))) {
add_entity_definition(&c->info, node, NULL);
- check_assignment(c, op_a, NULL, make_string("assignment to `_` identifier"));
+ check_assignment(c, op_a, NULL, str_lit("assignment to `_` identifier"));
if (op_a->mode == Addressing_Invalid)
return NULL;
return op_a->type;
@@ -282,7 +283,6 @@ Type *check_assignment_variable(Checker *c, Operand *op_a, AstNode *lhs) {
}
gbString str = expr_to_string(op_b.expr);
- defer (gb_string_free(str));
switch (op_b.mode) {
case Addressing_Value:
error(ast_node_token(op_b.expr), "Cannot assign to `%s`", str);
@@ -291,13 +291,14 @@ Type *check_assignment_variable(Checker *c, Operand *op_a, AstNode *lhs) {
error(ast_node_token(op_b.expr), "Cannot assign to `%s`", str);
break;
}
-
+ gb_string_free(str);
} break;
}
- check_assignment(c, op_a, op_b.type, make_string("assignment"));
- if (op_a->mode == Addressing_Invalid)
+ check_assignment(c, op_a, op_b.type, str_lit("assignment"));
+ if (op_a->mode == Addressing_Invalid) {
return NULL;
+ }
return op_a->type;
}
@@ -314,15 +315,13 @@ b32 check_valid_type_match_type(Type *type, b32 *is_union_ptr, b32 *is_any) {
return false;
}
-
+void check_stmt_internal(Checker *c, AstNode *node, u32 flags);
void check_stmt(Checker *c, AstNode *node, u32 flags) {
u32 prev_stmt_state_flags = c->context.stmt_state_flags;
- defer (c->context.stmt_state_flags = prev_stmt_state_flags);
if (node->stmt_state_flags != 0) {
u32 in = node->stmt_state_flags;
u32 out = c->context.stmt_state_flags;
- defer (c->context.stmt_state_flags = out);
if (in & StmtStateFlag_bounds_check) {
out |= StmtStateFlag_bounds_check;
@@ -331,9 +330,16 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
out |= StmtStateFlag_no_bounds_check;
out &= ~StmtStateFlag_bounds_check;
}
+
+ c->context.stmt_state_flags = out;
}
+ check_stmt_internal(c, node, flags);
+
+ c->context.stmt_state_flags = prev_stmt_state_flags;
+}
+void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
u32 mod_flags = flags & (~Stmt_FallthroughAllowed);
switch (node->kind) {
case_ast_node(_, EmptyStmt, node); case_end;
@@ -352,16 +358,15 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
case Addressing_NoValue:
return;
default: {
- gbString expr_str = expr_to_string(operand.expr);
- defer (gb_string_free(expr_str));
if (kind == Expr_Stmt) {
return;
}
if (operand.expr->kind == AstNode_CallExpr) {
return;
}
-
+ gbString expr_str = expr_to_string(operand.expr);
error(ast_node_token(node), "Expression is not used: `%s`", expr_str);
+ gb_string_free(expr_str);
} break;
}
case_end;
@@ -403,7 +408,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
ast_node(bl, BasicLit, &basic_lit);
*bl = ids->op;
bl->kind = Token_Integer;
- bl->string = make_string("1");
+ bl->string = str_lit("1");
AstNode binary_expr = {AstNode_BinaryExpr};
ast_node(be, BinaryExpr, &binary_expr);
@@ -425,7 +430,6 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
}
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
// NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
// an extra allocation
@@ -458,6 +462,8 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
if (lhs_count != rhs_count) {
error(ast_node_token(as->lhs[0]), "Assignment count mismatch `%td` = `%td`", lhs_count, rhs_count);
}
+
+ gb_temp_arena_memory_end(tmp);
} break;
default: {
@@ -501,10 +507,10 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
PROF_SCOPED("check_stmt - IfStmt");
check_open_scope(c, node);
- defer (check_close_scope(c));
- if (is->init != NULL)
+ if (is->init != NULL) {
check_stmt(c, is->init, 0);
+ }
Operand operand = {Addressing_Invalid};
check_expr(c, &operand, is->cond);
@@ -528,6 +534,8 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
break;
}
}
+
+ check_close_scope(c);
case_end;
case_ast_node(rs, ReturnStmt, node);
@@ -558,7 +566,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
error(ast_node_token(node), "Expected %td return values, got 0", result_count);
} else {
check_init_variables(c, variables, result_count,
- rs->results, make_string("return statement"));
+ rs->results, str_lit("return statement"));
}
} else if (rs->results.count > 0) {
error(ast_node_token(rs->results[0]), "No return values expected");
@@ -570,10 +578,10 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
u32 new_flags = mod_flags | Stmt_BreakAllowed | Stmt_ContinueAllowed;
check_open_scope(c, node);
- defer (check_close_scope(c));
- if (fs->init != NULL)
+ if (fs->init != NULL) {
check_stmt(c, fs->init, 0);
+ }
if (fs->cond) {
Operand operand = {Addressing_Invalid};
check_expr(c, &operand, fs->cond);
@@ -583,9 +591,12 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
"Non-boolean condition in `for` statement");
}
}
- if (fs->post != NULL)
+ if (fs->post != NULL) {
check_stmt(c, fs->post, 0);
+ }
check_stmt(c, fs->body, new_flags);
+
+ check_close_scope(c);
case_end;
case_ast_node(ms, MatchStmt, node);
@@ -595,14 +606,13 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
mod_flags |= Stmt_BreakAllowed;
check_open_scope(c, node);
- defer (check_close_scope(c));
if (ms->init != NULL) {
check_stmt(c, ms->init, 0);
}
if (ms->tag != NULL) {
check_expr(c, &x, ms->tag);
- check_assignment(c, &x, NULL, make_string("match expression"));
+ check_assignment(c, &x, NULL, str_lit("match expression"));
} else {
x.mode = Addressing_Constant;
x.type = t_bool;
@@ -610,7 +620,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
Token token = {};
token.pos = ast_node_token(ms->body).pos;
- token.string = make_string("true");
+ token.string = str_lit("true");
x.expr = make_ident(c->curr_ast_file, token);
}
@@ -649,7 +659,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
Map<TypeAndToken> seen = {}; // NOTE(bill): Multimap
map_init(&seen, heap_allocator());
- defer (map_destroy(&seen));
+
for_array(i, bs->stmts) {
AstNode *stmt = bs->stmts[i];
if (stmt->kind != AstNode_CaseClause) {
@@ -689,8 +699,6 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
auto *found = map_get(&seen, key);
if (found != NULL) {
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
-
isize count = multi_map_count(&seen, key);
TypeAndToken *taps = gb_alloc_array(c->tmp_allocator, TypeAndToken, count);
@@ -713,6 +721,8 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
}
}
+ gb_temp_arena_memory_end(tmp);
+
if (continue_outer) {
continue;
}
@@ -730,6 +740,10 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
check_stmt_list(c, cc->stmts, ft_flags);
check_close_scope(c);
}
+
+ map_destroy(&seen);
+
+ check_close_scope(c);
case_end;
case_ast_node(ms, TypeMatchStmt, node);
@@ -739,18 +753,17 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
mod_flags |= Stmt_BreakAllowed;
check_open_scope(c, node);
- defer (check_close_scope(c));
b32 is_union_ptr = false;
b32 is_any = false;
check_expr(c, &x, ms->tag);
- check_assignment(c, &x, NULL, make_string("type match expression"));
+ check_assignment(c, &x, NULL, str_lit("type match expression"));
if (!check_valid_type_match_type(x.type, &is_union_ptr, &is_any)) {
gbString str = type_to_string(x.type);
- defer (gb_string_free(str));
error(ast_node_token(x.expr),
"Invalid type for this type match expression, got `%s`", str);
+ gb_string_free(str);
break;
}
@@ -789,8 +802,6 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
Map<b32> seen = {};
map_init(&seen, heap_allocator());
- defer (map_destroy(&seen));
-
for_array(i, bs->stmts) {
AstNode *stmt = bs->stmts[i];
@@ -822,9 +833,9 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
}
if (!tag_type_found) {
gbString type_str = type_to_string(y.type);
- defer (gb_string_free(type_str));
error(ast_node_token(y.expr),
"Unknown tag type, got `%s`", type_str);
+ gb_string_free(type_str);
continue;
}
case_type = y.type;
@@ -868,6 +879,9 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
check_stmt_list(c, cc->stmts, mod_flags);
check_close_scope(c);
}
+ map_destroy(&seen);
+
+ check_close_scope(c);
case_end;
@@ -930,9 +944,6 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
return;
}
- gbString expr_str = expr_to_string(expr);
- defer (gb_string_free(expr_str));
-
switch (e->kind) {
case Entity_TypeName: {
Type *t = base_type(e->type);
@@ -941,7 +952,9 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
Entity *f = t->Record.other_fields[i];
Entity *found = scope_insert_entity(c->context.scope, f);
if (found != NULL) {
+ gbString expr_str = expr_to_string(expr);
error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
+ gb_string_free(expr_str);
return;
}
f->using_parent = e;
@@ -951,7 +964,9 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
Entity *f = t->Record.fields[i];
Entity *found = scope_insert_entity(c->context.scope, f);
if (found != NULL) {
+ gbString expr_str = expr_to_string(expr);
error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
+ gb_string_free(expr_str);
return;
}
f->using_parent = e;
@@ -960,7 +975,9 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
Entity *f = t->Record.other_fields[i];
Entity *found = scope_insert_entity(c->context.scope, f);
if (found != NULL) {
+ gbString expr_str = expr_to_string(expr);
error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string));
+ gb_string_free(expr_str);
return;
}
f->using_parent = e;
@@ -974,6 +991,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
Entity *decl = scope->elements.entries[i].value;
Entity *found = scope_insert_entity(c->context.scope, decl);
if (found != NULL) {
+ gbString expr_str = expr_to_string(expr);
error(us->token,
"Namespace collision while `using` `%s` of: %.*s\n"
"\tat %.*s(%td:%td)\n"
@@ -982,6 +1000,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
LIT(found->token.pos.file), found->token.pos.line, found->token.pos.column,
LIT(decl->token.pos.file), decl->token.pos.line, decl->token.pos.column
);
+ gb_string_free(expr_str);
return;
}
}
@@ -1001,7 +1020,9 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
}
Entity *prev = scope_insert_entity(c->context.scope, uvar);
if (prev != NULL) {
+ gbString expr_str = expr_to_string(expr);
error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(prev->token.string));
+ gb_string_free(expr_str);
return;
}
}
@@ -1085,7 +1106,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
case_ast_node(pa, PushAllocator, node);
Operand op = {};
check_expr(c, &op, pa->expr);
- check_assignment(c, &op, t_allocator, make_string("argument to push_allocator"));
+ check_assignment(c, &op, t_allocator, str_lit("argument to push_allocator"));
check_stmt(c, pa->body, mod_flags);
case_end;
@@ -1093,7 +1114,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
case_ast_node(pa, PushContext, node);
Operand op = {};
check_expr(c, &op, pa->expr);
- check_assignment(c, &op, t_context, make_string("argument to push_context"));
+ check_assignment(c, &op, t_context, str_lit("argument to push_context"));
check_stmt(c, pa->body, mod_flags);
case_end;
@@ -1128,7 +1149,5 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
add_entity_and_decl_info(c, pd->name, e, d);
check_entity_decl(c, e, d, NULL);
case_end;
-
-
}
}
diff --git a/src/checker/types.cpp b/src/checker/types.cpp
index 965798be9..c10b8e6f1 100644
--- a/src/checker/types.cpp
+++ b/src/checker/types.cpp
@@ -719,7 +719,7 @@ b32 are_types_identical(Type *x, Type *y) {
if (!are_types_identical(x->Record.fields[i]->type, y->Record.fields[i]->type)) {
return false;
}
- if (x->Record.fields[i]->token.string != y->Record.fields[i]->token.string) {
+ if (str_ne(x->Record.fields[i]->token.string, y->Record.fields[i]->token.string)) {
return false;
}
}
@@ -836,7 +836,7 @@ gb_global Entity *entity__slice_capacity = NULL;
Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_type, Selection sel = empty_selection) {
GB_ASSERT(type_ != NULL);
- if (field_name == "_") {
+ if (str_eq(field_name, str_lit("_"))) {
return empty_selection;
}
@@ -849,8 +849,8 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
if (type->kind == Type_Basic) {
switch (type->Basic.kind) {
case Basic_any: {
- String type_info_str = make_string("type_info");
- String data_str = make_string("data");
+ String type_info_str = str_lit("type_info");
+ String data_str = str_lit("data");
if (entity__any_type_info == NULL) {
entity__any_type_info = make_entity_field(a, NULL, make_token_ident(type_info_str), t_type_info_ptr, false, 0);
}
@@ -858,19 +858,19 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
entity__any_data = make_entity_field(a, NULL, make_token_ident(data_str), t_rawptr, false, 1);
}
- if (field_name == type_info_str) {
+ if (str_eq(field_name, type_info_str)) {
selection_add_index(&sel, 0);
sel.entity = entity__any_type_info;
return sel;
- } else if (field_name == data_str) {
+ } else if (str_eq(field_name, data_str)) {
selection_add_index(&sel, 1);
sel.entity = entity__any_data;
return sel;
}
} break;
case Basic_string: {
- String data_str = make_string("data");
- String count_str = make_string("count");
+ String data_str = str_lit("data");
+ String count_str = str_lit("count");
if (entity__string_data == NULL) {
entity__string_data = make_entity_field(a, NULL, make_token_ident(data_str), make_type_pointer(a, t_u8), false, 0);
}
@@ -879,11 +879,11 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
entity__string_count = make_entity_field(a, NULL, make_token_ident(count_str), t_int, false, 1);
}
- if (field_name == data_str) {
+ if (str_eq(field_name, data_str)) {
selection_add_index(&sel, 0);
sel.entity = entity__string_data;
return sel;
- } else if (field_name == count_str) {
+ } else if (str_eq(field_name, count_str)) {
selection_add_index(&sel, 1);
sel.entity = entity__string_count;
return sel;
@@ -893,17 +893,17 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
return sel;
} else if (type->kind == Type_Array) {
- String count_str = make_string("count");
+ String count_str = str_lit("count");
// NOTE(bill): Underlying memory address cannot be changed
- if (field_name == count_str) {
+ if (str_eq(field_name, count_str)) {
// HACK(bill): Memory leak
sel.entity = make_entity_constant(a, NULL, make_token_ident(count_str), t_int, make_exact_value_integer(type->Array.count));
return sel;
}
} else if (type->kind == Type_Vector) {
- String count_str = make_string("count");
+ String count_str = str_lit("count");
// NOTE(bill): Vectors are not addressable
- if (field_name == count_str) {
+ if (str_eq(field_name, count_str)) {
// HACK(bill): Memory leak
sel.entity = make_entity_constant(a, NULL, make_token_ident(count_str), t_int, make_exact_value_integer(type->Vector.count));
return sel;
@@ -914,9 +914,9 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
switch (type->Vector.count) {
#define _VECTOR_FIELD_CASE(_length, _name) \
case (_length): \
- if (field_name == _name) { \
+ if (str_eq(field_name, str_lit(_name))) { \
selection_add_index(&sel, (_length)-1); \
- sel.entity = make_entity_vector_elem(a, NULL, make_token_ident(make_string(_name)), type->Vector.elem, (_length)-1); \
+ sel.entity = make_entity_vector_elem(a, NULL, make_token_ident(str_lit(_name)), type->Vector.elem, (_length)-1); \
return sel; \
} \
/*fallthrough*/
@@ -932,16 +932,16 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
}
} else if (type->kind == Type_Slice) {
- String data_str = make_string("data");
- String count_str = make_string("count");
- String capacity_str = make_string("capacity");
+ String data_str = str_lit("data");
+ String count_str = str_lit("count");
+ String capacity_str = str_lit("capacity");
- if (field_name == data_str) {
+ if (str_eq(field_name, data_str)) {
selection_add_index(&sel, 0);
// HACK(bill): Memory leak
sel.entity = make_entity_field(a, NULL, make_token_ident(data_str), make_type_pointer(a, type->Slice.elem), false, 0);
return sel;
- } else if (field_name == count_str) {
+ } else if (str_eq(field_name, count_str)) {
selection_add_index(&sel, 1);
if (entity__slice_count == NULL) {
entity__slice_count = make_entity_field(a, NULL, make_token_ident(count_str), t_int, false, 1);
@@ -949,7 +949,7 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
sel.entity = entity__slice_count;
return sel;
- } else if (field_name == capacity_str) {
+ } else if (str_eq(field_name, capacity_str)) {
selection_add_index(&sel, 2);
if (entity__slice_capacity == NULL) {
entity__slice_capacity = make_entity_field(a, NULL, make_token_ident(capacity_str), t_int, false, 2);
@@ -972,7 +972,7 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
GB_ASSERT(f->kind == Entity_TypeName);
String str = f->token.string;
- if (field_name == str) {
+ if (str_eq(field_name, str)) {
sel.entity = f;
selection_add_index(&sel, i);
return sel;
@@ -985,7 +985,7 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
GB_ASSERT(f->kind != Entity_Variable);
String str = f->token.string;
- if (field_name == str) {
+ if (str_eq(field_name, str)) {
sel.entity = f;
selection_add_index(&sel, i);
return sel;
@@ -993,13 +993,13 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
}
if (is_type_enum(type)) {
- if (field_name == "count") {
+ if (str_eq(field_name, str_lit("count"))) {
sel.entity = type->Record.enum_count;
return sel;
- } else if (field_name == "min_value") {
+ } else if (str_eq(field_name, str_lit("min_value"))) {
sel.entity = type->Record.min_value;
return sel;
- } else if (field_name == "max_value") {
+ } else if (str_eq(field_name, str_lit("max_value"))) {
sel.entity = type->Record.max_value;
return sel;
}
@@ -1010,7 +1010,7 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
Entity *f = type->Record.fields[i];
GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field);
String str = f->token.string;
- if (field_name == str) {
+ if (str_eq(field_name, str)) {
selection_add_index(&sel, i); // HACK(bill): Leaky memory
sel.entity = f;
return sel;
diff --git a/src/common.cpp b/src/common.cpp
index e07ea362a..ee4ca9817 100644
--- a/src/common.cpp
+++ b/src/common.cpp
@@ -1,3 +1,4 @@
+#define GB_NO_DEFER
#define GB_IMPLEMENTATION
#include "gb/gb.h"
@@ -8,7 +9,7 @@ gbAllocator heap_allocator(void) {
#include "string.cpp"
#include "array.cpp"
-gb_global String global_module_path = {};
+gb_global String global_module_path = {0};
gb_global b32 global_module_path_set = false;
@@ -19,7 +20,6 @@ String get_module_dir() {
Array<wchar_t> path_buf;
array_init(&path_buf, heap_allocator(), 300);
- defer (array_free(&path_buf));
array_resize(&path_buf, 300);
isize len = 0;
@@ -35,7 +35,6 @@ String get_module_dir() {
}
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&string_buffer_arena);
- defer (gb_temp_arena_memory_end(tmp));
wchar_t *text = gb_alloc_array(string_buffer_allocator, wchar_t, len+1);
@@ -52,40 +51,29 @@ String get_module_dir() {
global_module_path = path;
global_module_path_set = true;
+ gb_temp_arena_memory_end(tmp);
+
+ array_free(&path_buf);
+
return path;
}
String path_to_fullpath(gbAllocator a, String s) {
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&string_buffer_arena);
- defer (gb_temp_arena_memory_end(tmp));
-
String16 string16 = string_to_string16(string_buffer_allocator, s);
+ String result = {0};
DWORD len = GetFullPathNameW(string16.text, 0, NULL, NULL);
- if (len == 0) {
- return make_string(NULL, 0);
+ if (len != 0) {
+ wchar_t *text = gb_alloc_array(string_buffer_allocator, wchar_t, len+1);
+ GetFullPathNameW(string16.text, len, text, NULL);
+ text[len] = 0;
+ result = string16_to_string(a, make_string16(text, len));
}
- wchar_t *text = gb_alloc_array(string_buffer_allocator, wchar_t, len+1);
- GetFullPathNameW(string16.text, len, text, NULL);
- text[len] = 0;
-
- return string16_to_string(a, make_string16(text, len));
+ gb_temp_arena_memory_end(tmp);
+ return result;
}
-struct BlockTimer {
- u64 start;
- u64 finish;
- char *msg;
- BlockTimer(char *msg) : msg(msg) {
- start = gb_utc_time_now();
- }
- ~BlockTimer() {
- finish = gb_utc_time_now();
- gb_printf_err("%llu us\n", finish-start);
- }
-};
-
-
// Hasing
enum HashKeyKind {
HashKey_Default,
@@ -103,7 +91,7 @@ struct HashKey {
};
gb_inline HashKey hashing_proc(void const *data, isize len) {
- HashKey h = {};
+ HashKey h = {HashKey_Default};
h.kind = HashKey_Default;
// h.key = gb_murmur64(data, len);
h.key = gb_fnv64a(data, len);
@@ -118,7 +106,7 @@ gb_inline HashKey hash_string(String s) {
}
gb_inline HashKey hash_pointer(void *ptr) {
- HashKey h = {};
+ HashKey h = {HashKey_Default};
h.key = cast(u64)cast(uintptr)ptr;
h.ptr = ptr;
h.kind = HashKey_Default;
@@ -130,7 +118,7 @@ b32 hash_key_equal(HashKey a, HashKey b) {
// NOTE(bill): If two string's hashes collide, compare the strings themselves
if (a.kind == HashKey_String) {
if (b.kind == HashKey_String) {
- return a.string == b.string;
+ return str_eq(a.string, b.string);
}
return false;
}
@@ -364,7 +352,7 @@ gb_inline void map_grow(Map<T> *h) {
template <typename T>
void map_rehash(Map<T> *h, isize new_count) {
isize i, j;
- Map<T> nh = {};
+ Map<T> nh = {0};
map_init(&nh, h->hashes.allocator);
array_resize(&nh.hashes, new_count);
array_reserve(&nh.entries, h->entries.count);
diff --git a/src/gb/gb.h b/src/gb/gb.h
index 6c6cc4037..1094c11b4 100644
--- a/src/gb/gb.h
+++ b/src/gb/gb.h
@@ -615,7 +615,7 @@ extern "C++" {
//
// NOTE: C++11 (and above) only!
//
-#if defined(__cplusplus) && ((defined(_MSC_VER) && _MSC_VER >= 1400) || (__cplusplus >= 201103L))
+#if !defined(GB_NO_DEFER) && defined(__cplusplus) && ((defined(_MSC_VER) && _MSC_VER >= 1400) || (__cplusplus >= 201103L))
extern "C++" {
// NOTE(bill): Stupid fucking templates
template <typename T> struct gbRemoveReference { typedef T Type; };
diff --git a/src/main.cpp b/src/main.cpp
index 6fea6d583..a7a95a555 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -16,12 +16,13 @@
// NOTE(bill): `name` is used in debugging and profiling modes
i32 win32_exec_command_line_app(char *name, char *fmt, ...) {
STARTUPINFOW start_info = {gb_size_of(STARTUPINFOW)};
- PROCESS_INFORMATION pi = {};
- char cmd_line[4096] = {};
+ PROCESS_INFORMATION pi = {0};
+ char cmd_line[4096] = {0};
isize cmd_len;
va_list va;
gbTempArenaMemory tmp;
String16 cmd;
+ i32 exit_code = 0;
start_info.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
start_info.wShowWindow = SW_SHOW;
@@ -35,57 +36,55 @@ i32 win32_exec_command_line_app(char *name, char *fmt, ...) {
// gb_printf("%.*s\n", cast(int)cmd_len, cmd_line);
tmp = gb_temp_arena_memory_begin(&string_buffer_arena);
- defer (gb_temp_arena_memory_end(tmp));
cmd = string_to_string16(string_buffer_allocator, make_string(cast(u8 *)cmd_line, cmd_len-1));
if (CreateProcessW(NULL, cmd.text,
NULL, NULL, true, 0, NULL, NULL,
&start_info, &pi)) {
- DWORD exit_code = 0;
-
WaitForSingleObject(pi.hProcess, INFINITE);
- GetExitCodeProcess(pi.hProcess, &exit_code);
+ GetExitCodeProcess(pi.hProcess, cast(DWORD *)&exit_code);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
-
- return cast(i32)exit_code;
} else {
// NOTE(bill): failed to create process
gb_printf_err("Failed to execute command:\n\t%s\n", cmd_line);
- return -1;
+ exit_code = -1;
}
+
+ gb_temp_arena_memory_end(tmp);
+ return exit_code;
}
-enum ArchKind {
+typedef enum {
ArchKind_x64,
ArchKind_x86,
-};
+} ArchKind;
-struct ArchData {
+typedef struct {
BaseTypeSizes sizes;
String llc_flags;
String link_flags;
-};
+} ArchData;
ArchData make_arch_data(ArchKind kind) {
- ArchData data = {};
+ ArchData data = {0};
switch (kind) {
case ArchKind_x64:
default:
data.sizes.word_size = 8;
data.sizes.max_align = 16;
- data.llc_flags = make_string("-march=x86-64 ");
- data.link_flags = make_string("/machine:x64 ");
+ data.llc_flags = str_lit("-march=x86-64 ");
+ data.link_flags = str_lit("/machine:x64 ");
break;
case ArchKind_x86:
data.sizes.word_size = 4;
data.sizes.max_align = 8;
- data.llc_flags = make_string("-march=x86 ");
- data.link_flags = make_string("/machine:x86 ");
+ data.llc_flags = str_lit("-march=x86 ");
+ data.link_flags = str_lit("/machine:x86 ");
break;
}
@@ -110,9 +109,9 @@ int main(int argc, char **argv) {
}
prof_init();
- Timings timings = {};
- timings_init(&timings, make_string("Total Time"), 128);
- defer (timings_destroy(&timings));
+ Timings timings = {0};
+ timings_init(&timings, str_lit("Total Time"), 128);
+ // defer (timings_destroy(&timings));
#if 1
init_string_buffer_memory();
@@ -124,13 +123,13 @@ int main(int argc, char **argv) {
char *init_filename = NULL;
b32 run_output = false;
- String arg1 = make_string(argv[1]);
- if (arg1 == "run") {
+ String arg1 = make_string_c(argv[1]);
+ if (str_eq(arg1, str_lit("run"))) {
run_output = true;
init_filename = argv[2];
- } else if (arg1 == "build") {
+ } else if (str_eq(arg1, str_lit("build"))) {
init_filename = argv[2];
- } else if (arg1 == "version") {
+ } else if (str_eq(arg1, str_lit("version"))) {
gb_printf("%s version %s", argv[0], VERSION_STRING);
return 0;
} else {
@@ -140,7 +139,7 @@ int main(int argc, char **argv) {
// TODO(bill): prevent compiling without a linker
- timings_start_section(&timings, make_string("parse files"));
+ timings_start_section(&timings, str_lit("parse files"));
Parser parser = {0};
if (!init_parser(&parser)) {
@@ -154,9 +153,9 @@ int main(int argc, char **argv) {
#if 1
- timings_start_section(&timings, make_string("type check"));
+ timings_start_section(&timings, str_lit("type check"));
- Checker checker = {};
+ Checker checker = {0};
ArchData arch_data = make_arch_data(ArchKind_x64);
init_checker(&checker, &parser, arch_data.sizes);
@@ -168,25 +167,25 @@ int main(int argc, char **argv) {
#endif
#if 1
- ssaGen ssa = {};
+ ssaGen ssa = {0};
if (!ssa_gen_init(&ssa, &checker)) {
return 1;
}
// defer (ssa_gen_destroy(&ssa));
- timings_start_section(&timings, make_string("ssa gen"));
+ timings_start_section(&timings, str_lit("ssa gen"));
ssa_gen_tree(&ssa);
- timings_start_section(&timings, make_string("ssa opt"));
+ timings_start_section(&timings, str_lit("ssa opt"));
ssa_opt_tree(&ssa);
- timings_start_section(&timings, make_string("ssa print"));
+ timings_start_section(&timings, str_lit("ssa print"));
ssa_print_llvm_ir(&ssa);
// prof_print_all();
#if 1
- timings_start_section(&timings, make_string("llvm-opt"));
+ timings_start_section(&timings, str_lit("llvm-opt"));
char const *output_name = ssa.output_file.filename;
isize base_name_len = gb_path_extension(output_name)-1 - output_name;
@@ -213,7 +212,7 @@ int main(int argc, char **argv) {
}
#if 1
- timings_start_section(&timings, make_string("llvm-llc"));
+ timings_start_section(&timings, str_lit("llvm-llc"));
// For more arguments: http://llvm.org/docs/CommandGuide/llc.html
exit_code = win32_exec_command_line_app("llvm-llc",
"%.*sbin/llc %.*s.bc -filetype=obj -O%d "
@@ -228,11 +227,11 @@ int main(int argc, char **argv) {
return exit_code;
}
- timings_start_section(&timings, make_string("msvc-link"));
+ timings_start_section(&timings, str_lit("msvc-link"));
gbString lib_str = gb_string_make(heap_allocator(), "Kernel32.lib");
// defer (gb_string_free(lib_str));
- char lib_str_buf[1024] = {};
+ char lib_str_buf[1024] = {0};
for_array(i, parser.foreign_libraries) {
String lib = parser.foreign_libraries[i];
isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
@@ -243,7 +242,7 @@ int main(int argc, char **argv) {
exit_code = win32_exec_command_line_app("msvc-link",
"link %.*s.obj -OUT:%.*s.exe %s "
"/defaultlib:libcmt "
- "/nologo /incremental:no /opt:ref /subsystem:console /debug "
+ "/nologo /incremental:no /opt:ref /subsystem:console "
" %.*s "
"",
LIT(output), LIT(output),
diff --git a/src/parser.cpp b/src/parser.cpp
index d263fa1dd..ae6043204 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -1133,7 +1133,7 @@ AstNode *parse_identifier(AstFile *f) {
if (token.kind == Token_Identifier) {
next_token(f);
} else {
- token.string = make_string("_");
+ token.string = str_lit("_");
expect_token(f, Token_Identifier);
}
return make_ident(f, token);
@@ -1274,11 +1274,11 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n
String tag_name = te->name.string;
#define ELSE_IF_ADD_TAG(name) \
- else if (tag_name == #name) { \
+ else if (str_eq(tag_name, str_lit(#name))) { \
check_proc_add_tag(f, tag_expr, tags, ProcTag_##name, tag_name); \
}
- if (tag_name == "foreign") {
+ if (str_eq(tag_name, str_lit("foreign"))) {
check_proc_add_tag(f, tag_expr, tags, ProcTag_foreign, tag_name);
if (f->curr_token.kind == Token_String) {
*foreign_name = f->curr_token.string;
@@ -1289,7 +1289,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n
next_token(f);
}
- } else if (tag_name == "link_name") {
+ } else if (str_eq(tag_name, str_lit("link_name"))) {
check_proc_add_tag(f, tag_expr, tags, ProcTag_link_name, tag_name);
if (f->curr_token.kind == Token_String) {
*link_name = f->curr_token.string;
@@ -1372,7 +1372,7 @@ AstNode *parse_operand(AstFile *f, b32 lhs) {
case Token_Hash: {
Token token = expect_token(f, Token_Hash);
Token name = expect_token(f, Token_Identifier);
- if (name.string == "rune") {
+ if (str_eq(name.string, str_lit("rune"))) {
if (f->curr_token.kind == Token_String) {
Token *s = &f->curr_token;
@@ -1384,19 +1384,19 @@ AstNode *parse_operand(AstFile *f, b32 lhs) {
expect_token(f, Token_String);
}
operand = parse_operand(f, lhs);
- } else if (name.string == "file") {
+ } else if (str_eq(name.string, str_lit("file"))) {
Token token = name;
token.kind = Token_String;
token.string = token.pos.file;
return make_basic_lit(f, token);
- } else if (name.string == "line") {
+ } else if (str_eq(name.string, str_lit("line"))) {
Token token = name;
token.kind = Token_Integer;
char *str = gb_alloc_array(gb_arena_allocator(&f->arena), char, 20);
gb_i64_to_str(token.pos.line, str, 10);
- token.string = make_string(str);
+ token.string = make_string_c(str);
return make_basic_lit(f, token);
- } else if (name.string == "run") {
+ } else if (str_eq(name.string, str_lit("run"))) {
AstNode *expr = parse_expr(f, false);
operand = make_run_expr(f, token, name, expr);
if (unparen_expr(expr)->kind != AstNode_CallExpr) {
@@ -1415,7 +1415,6 @@ AstNode *parse_operand(AstFile *f, b32 lhs) {
AstNode *curr_proc = f->curr_proc;
AstNode *type = parse_proc_type(f);
f->curr_proc = type;
- defer (f->curr_proc = curr_proc);
u64 tags = 0;
String foreign_name = {};
@@ -1428,17 +1427,17 @@ AstNode *parse_operand(AstFile *f, b32 lhs) {
syntax_error(f->curr_token, "#link_name cannot be applied to procedure literals");
}
- if (f->curr_token.kind != Token_OpenBrace) {
- return type;
- } else {
+ if (f->curr_token.kind == Token_OpenBrace) {
AstNode *body;
f->expr_level++;
body = parse_body(f);
f->expr_level--;
- return make_proc_lit(f, type, body, tags);
+ type = make_proc_lit(f, type, body, tags);
}
+ f->curr_proc = curr_proc;
+ return type;
}
default: {
@@ -2087,12 +2086,12 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
b32 is_ordered = false;
while (allow_token(f, Token_Hash)) {
Token tag = expect_token_after(f, Token_Identifier, "`#`");
- if (tag.string == "packed") {
+ if (str_eq(tag.string, str_lit("packed"))) {
if (is_packed) {
syntax_error(tag, "Duplicate struct tag `#%.*s`", LIT(tag.string));
}
is_packed = true;
- } else if (tag.string == "ordered") {
+ } else if (str_eq(tag.string, str_lit("ordered"))) {
if (is_ordered) {
syntax_error(tag, "Duplicate struct tag `#%.*s`", LIT(tag.string));
}
@@ -2264,7 +2263,6 @@ AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) {
AstNode *curr_proc = f->curr_proc;
f->curr_proc = proc_type;
- defer (f->curr_proc = curr_proc);
if (f->curr_token.kind == Token_OpenBrace) {
if ((tags & ProcTag_foreign) != 0) {
@@ -2273,6 +2271,7 @@ AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) {
body = parse_body(f);
}
+ f->curr_proc = curr_proc;
return make_proc_decl(f, name, proc_type, body, tags, foreign_name, link_name);
}
@@ -2285,7 +2284,7 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) {
if (name->kind == AstNode_Ident) {
String n = name->Ident.string;
// NOTE(bill): Check for reserved identifiers
- if (n == "context") {
+ if (str_eq(n, str_lit("context"))) {
syntax_error(ast_node_token(name), "`context` is a reserved identifier");
break;
}
@@ -2399,7 +2398,7 @@ AstNode *parse_if_stmt(AstFile *f) {
if (allow_token(f, Token_Semicolon)) {
cond = parse_expr(f, false);
} else {
- cond = convert_stmt_to_expr(f, init, make_string("boolean expression"));
+ cond = convert_stmt_to_expr(f, init, str_lit("boolean expression"));
init = NULL;
}
}
@@ -2489,7 +2488,7 @@ AstNode *parse_for_stmt(AstFile *f) {
}
body = parse_block_stmt(f);
- cond = convert_stmt_to_expr(f, cond, make_string("boolean expression"));
+ cond = convert_stmt_to_expr(f, cond, str_lit("boolean expression"));
return make_for_stmt(f, token, init, cond, end, body);
}
@@ -2559,7 +2558,7 @@ AstNode *parse_match_stmt(AstFile *f) {
close = expect_token(f, Token_CloseBrace);
body = make_block_stmt(f, list, open, close);
- tag = convert_stmt_to_expr(f, tag, make_string("type match expression"));
+ tag = convert_stmt_to_expr(f, tag, str_lit("type match expression"));
return make_type_match_stmt(f, token, tag, var, body);
} else {
if (f->curr_token.kind != Token_OpenBrace) {
@@ -2591,7 +2590,7 @@ AstNode *parse_match_stmt(AstFile *f) {
body = make_block_stmt(f, list, open, close);
- tag = convert_stmt_to_expr(f, tag, make_string("match expression"));
+ tag = convert_stmt_to_expr(f, tag, str_lit("match expression"));
return make_match_stmt(f, token, init, tag, body);
}
}
@@ -2747,14 +2746,14 @@ AstNode *parse_stmt(AstFile *f) {
case Token_Hash: {
s = parse_tag_stmt(f, NULL);
String tag = s->TagStmt.name.string;
- if (tag == "shared_global_scope") {
+ if (str_eq(tag, str_lit("shared_global_scope"))) {
if (f->curr_proc == NULL) {
f->is_global_scope = true;
return make_empty_stmt(f, f->curr_token);
}
syntax_error(token, "You cannot use #shared_global_scope within a procedure. This must be done at the file scope");
return make_bad_decl(f, token, f->curr_token);
- } else if (tag == "import") {
+ } else if (str_eq(tag, str_lit("import"))) {
// TODO(bill): better error messages
Token import_name = {};
Token file_path = expect_token_after(f, Token_String, "#import");
@@ -2768,7 +2767,7 @@ AstNode *parse_stmt(AstFile *f) {
import_name = expect_token_after(f, Token_Identifier, "`as` for import declaration");
}
- if (import_name.string == "_") {
+ if (str_eq(import_name.string, str_lit("_"))) {
syntax_error(token, "Illegal import name: `_`");
return make_bad_decl(f, token, f->curr_token);
}
@@ -2779,32 +2778,32 @@ AstNode *parse_stmt(AstFile *f) {
}
syntax_error(token, "You cannot use #import within a procedure. This must be done at the file scope");
return make_bad_decl(f, token, file_path);
- } else if (tag == "load") {
+ } else if (str_eq(tag, str_lit("load"))) {
// TODO(bill): better error messages
Token file_path = expect_token(f, Token_String);
Token import_name = file_path;
- import_name.string = make_string(".");
+ import_name.string = str_lit(".");
if (f->curr_proc == NULL) {
return make_import_decl(f, s->TagStmt.token, file_path, import_name, true);
}
syntax_error(token, "You cannot use #load within a procedure. This must be done at the file scope");
return make_bad_decl(f, token, file_path);
- } else if (tag == "foreign_system_library") {
+ } else if (str_eq(tag, str_lit("foreign_system_library"))) {
Token file_path = expect_token(f, Token_String);
if (f->curr_proc == NULL) {
return make_foreign_library(f, s->TagStmt.token, file_path, true);
}
syntax_error(token, "You cannot use #foreign_system_library within a procedure. This must be done at the file scope");
return make_bad_decl(f, token, file_path);
- } else if (tag == "foreign_library") {
+ } else if (str_eq(tag, str_lit("foreign_library"))) {
Token file_path = expect_token(f, Token_String);
if (f->curr_proc == NULL) {
return make_foreign_library(f, s->TagStmt.token, file_path, false);
}
syntax_error(token, "You cannot use #foreign_library within a procedure. This must be done at the file scope");
return make_bad_decl(f, token, file_path);
- } else if (tag == "thread_local") {
+ } else if (str_eq(tag, str_lit("thread_local"))) {
AstNode *var_decl = parse_simple_stmt(f);
if (var_decl->kind != AstNode_VarDecl) {
syntax_error(token, "#thread_local may only be applied to variable declarations");
@@ -2816,14 +2815,14 @@ AstNode *parse_stmt(AstFile *f) {
}
var_decl->VarDecl.tags |= VarDeclTag_thread_local;
return var_decl;
- } else if (tag == "bounds_check") {
+ } else if (str_eq(tag, str_lit("bounds_check"))) {
s = parse_stmt(f);
s->stmt_state_flags |= StmtStateFlag_bounds_check;
if ((s->stmt_state_flags & StmtStateFlag_no_bounds_check) != 0) {
syntax_error(token, "#bounds_check and #no_bounds_check cannot be applied together");
}
return s;
- } else if (tag == "no_bounds_check") {
+ } else if (str_eq(tag, str_lit("no_bounds_check"))) {
s = parse_stmt(f);
s->stmt_state_flags |= StmtStateFlag_no_bounds_check;
if ((s->stmt_state_flags & StmtStateFlag_bounds_check) != 0) {
@@ -2870,7 +2869,7 @@ AstNodeArray parse_stmt_list(AstFile *f) {
ParseFileError init_ast_file(AstFile *f, String fullpath) {
- if (!string_has_extension(fullpath, make_string("odin"))) {
+ if (!string_has_extension(fullpath, str_lit("odin"))) {
return ParseFile_WrongExtension;
}
TokenizerInitError err = init_tokenizer(&f->tokenizer, fullpath);
@@ -2951,11 +2950,10 @@ void destroy_parser(Parser *p) {
// NOTE(bill): Returns true if it's added
b32 try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) {
gb_mutex_lock(&p->mutex);
- defer (gb_mutex_unlock(&p->mutex));
for_array(i, p->imports) {
String import = p->imports[i].path;
- if (import == path) {
+ if (str_eq(import, path)) {
return false;
}
}
@@ -2965,52 +2963,59 @@ b32 try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) {
item.rel_path = rel_path;
item.pos = pos;
array_add(&p->imports, item);
+
+ gb_mutex_unlock(&p->mutex);
+
return true;
}
String get_fullpath_relative(gbAllocator a, String base_dir, String path) {
+ String res = {};
isize str_len = base_dir.len+path.len;
u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1);
- defer (gb_free(heap_allocator(), str));
isize i = 0;
gb_memmove(str+i, base_dir.text, base_dir.len); i += base_dir.len;
gb_memmove(str+i, path.text, path.len);
str[str_len] = '\0';
- return path_to_fullpath(a, make_string(str, str_len));
+ res = path_to_fullpath(a, make_string(str, str_len));
+ gb_free(heap_allocator(), str);
+ return res;
}
String get_fullpath_core(gbAllocator a, String path) {
String module_dir = get_module_dir();
+ String res = {};
char core[] = "core/";
isize core_len = gb_size_of(core)-1;
isize str_len = module_dir.len + core_len + path.len;
u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1);
- defer (gb_free(heap_allocator(), str));
gb_memmove(str, module_dir.text, module_dir.len);
gb_memmove(str+module_dir.len, core, core_len);
gb_memmove(str+module_dir.len+core_len, path.text, path.len);
str[str_len] = '\0';
- return path_to_fullpath(a, make_string(str, str_len));
+ res = path_to_fullpath(a, make_string(str, str_len));
+ gb_free(heap_allocator(), str);
+ return res;
}
// NOTE(bill): Returns true if it's added
b32 try_add_foreign_library_path(Parser *p, String import_file) {
gb_mutex_lock(&p->mutex);
- defer (gb_mutex_unlock(&p->mutex));
for_array(i, p->foreign_libraries) {
String import = p->foreign_libraries[i];
- if (import == import_file) {
+ if (str_eq(import, import_file)) {
return false;
}
}
array_add(&p->foreign_libraries, import_file);
+ gb_mutex_unlock(&p->mutex);
return true;
}
@@ -3064,7 +3069,7 @@ String get_filepath_extension(String path) {
if (c == '.') {
if (seen_slash) {
- return make_string("");
+ return str_lit("");
}
dot = i;
@@ -3166,19 +3171,19 @@ void parse_file(Parser *p, AstFile *f) {
ParseFileError parse_files(Parser *p, char *init_filename) {
char *fullpath_str = gb_path_get_full_name(heap_allocator(), init_filename);
- String init_fullpath = make_string(fullpath_str);
+ String init_fullpath = make_string_c(fullpath_str);
TokenPos init_pos = {};
ImportedFile init_imported_file = {init_fullpath, init_fullpath, init_pos};
array_add(&p->imports, init_imported_file);
p->init_fullpath = init_fullpath;
{
- String s = get_fullpath_core(heap_allocator(), make_string("_preload.odin"));
+ String s = get_fullpath_core(heap_allocator(), str_lit("_preload.odin"));
ImportedFile runtime_file = {s, s, init_pos};
array_add(&p->imports, runtime_file);
}
{
- String s = get_fullpath_core(heap_allocator(), make_string("_soft_numbers.odin"));
+ String s = get_fullpath_core(heap_allocator(), str_lit("_soft_numbers.odin"));
ImportedFile runtime_file = {s, s, init_pos};
array_add(&p->imports, runtime_file);
}
@@ -3196,7 +3201,6 @@ ParseFileError parse_files(Parser *p, char *init_filename) {
gb_printf_err("%.*s(%td:%td) ", LIT(pos.file), pos.line, pos.column);
}
gb_printf_err("Failed to parse file: %.*s\n\t", LIT(import_rel_path));
- defer (gb_printf_err("\n"));
switch (err) {
case ParseFile_WrongExtension:
gb_printf_err("Invalid file extension: File must have the extension `.odin`");
@@ -3217,16 +3221,16 @@ ParseFileError parse_files(Parser *p, char *init_filename) {
gb_printf_err("Invalid token found in file");
break;
}
+ gb_printf_err("\n");
return err;
}
parse_file(p, &file);
{
gb_mutex_lock(&p->mutex);
- defer (gb_mutex_unlock(&p->mutex));
-
file.id = p->files.count;
array_add(&p->files, file);
+ gb_mutex_unlock(&p->mutex);
}
}
diff --git a/src/ssa.cpp b/src/ssa.cpp
index 0563f0022..76ec843a8 100644
--- a/src/ssa.cpp
+++ b/src/ssa.cpp
@@ -1085,7 +1085,7 @@ ssaBlock *ssa_add_block(ssaProcedure *proc, AstNode *node, char *label) {
}
ssaValue *v = ssa_alloc_value(proc->module->allocator, ssaValue_Block);
- v->Block.label = make_string(label);
+ v->Block.label = make_string_c(label);
v->Block.node = node;
v->Block.scope = scope;
v->Block.parent = proc;
@@ -1346,7 +1346,7 @@ ssaValue *ssa_emit_call(ssaProcedure *p, ssaValue *value, ssaValue **args, isize
}
ssaValue *ssa_emit_global_call(ssaProcedure *proc, char *name_, ssaValue **args, isize arg_count) {
- String name = make_string(name_);
+ String name = make_string_c(name_);
ssaValue **found = map_get(&proc->module->members, hash_string(name));
GB_ASSERT_MSG(found != NULL, "%.*s", LIT(name));
ssaValue *gp = *found;
@@ -1425,7 +1425,7 @@ void ssa_emit_if(ssaProcedure *proc, ssaValue *cond, ssaBlock *true_block, ssaBl
}
void ssa_emit_startup_runtime(ssaProcedure *proc) {
- GB_ASSERT(proc->parent == NULL && proc->name == "main");
+ GB_ASSERT(proc->parent == NULL && str_eq(proc->name, str_lit("main")));
ssa_emit(proc, ssa_alloc_instr(proc, ssaInstr_StartupRuntime));
}
@@ -1896,7 +1896,7 @@ String lookup_polymorphic_field(CheckerInfo *info, Type *dst, Type *src) {
}
}
}
- return make_string("");
+ return str_lit("");
}
ssaValue *ssa_emit_bitcast(ssaProcedure *proc, ssaValue *data, Type *type) {
@@ -2017,7 +2017,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) {
for (isize i = 0; i < dst->Record.field_count; i++) {
Entity *f = dst->Record.fields[i];
if (are_types_identical(f->type, src_type)) {
- ssa_emit_comment(proc, make_string("union - child to parent"));
+ ssa_emit_comment(proc, str_lit("union - child to parent"));
gbAllocator allocator = proc->module->allocator;
ssaValue *parent = ssa_add_local_generated(proc, t);
ssaValue *tag = ssa_make_const_int(allocator, i);
@@ -2047,7 +2047,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) {
// NOTE(bill): It can be casted
Selection sel = lookup_field(proc->module->allocator, sb, field_name, false);
if (sel.entity != NULL) {
- ssa_emit_comment(proc, make_string("cast - polymorphism"));
+ ssa_emit_comment(proc, str_lit("cast - polymorphism"));
if (src_is_ptr) {
value = ssa_emit_load(proc, value);
}
@@ -2230,7 +2230,6 @@ ssaValue *ssa_emit_down_cast(ssaProcedure *proc, ssaValue *value, Type *t) {
String field_name = check_down_cast_name(t, type_deref(ssa_type(value)));
GB_ASSERT(field_name.len > 0);
Selection sel = lookup_field(proc->module->allocator, t, field_name, false);
- Type *t_u8_ptr = make_type_pointer(allocator, t_u8);
ssaValue *bytes = ssa_emit_conv(proc, value, t_u8_ptr);
i64 offset_ = type_offset_of_from_selection(proc->module->sizes, allocator, type_deref(t), sel);
@@ -2355,7 +2354,7 @@ isize ssa_type_info_index(CheckerInfo *info, Type *type) {
}
ssaValue *ssa_type_info(ssaProcedure *proc, Type *type) {
- ssaValue **found = map_get(&proc->module->members, hash_string(make_string(SSA_TYPE_INFO_DATA_NAME)));
+ ssaValue **found = map_get(&proc->module->members, hash_string(str_lit(SSA_TYPE_INFO_DATA_NAME)));
GB_ASSERT(found != NULL);
ssaValue *type_info_data = *found;
CheckerInfo *info = proc->module->info;
@@ -2558,7 +2557,7 @@ void ssa_build_defer_stmt(ssaProcedure *proc, ssaDefer d) {
ssa_emit_jump(proc, b);
}
proc->curr_block = b;
- ssa_emit_comment(proc, make_string("defer"));
+ ssa_emit_comment(proc, str_lit("defer"));
if (d.kind == ssaDefer_Node) {
ssa_build_stmt(proc, d.stmt);
} else if (d.kind == ssaDefer_Instr) {
@@ -2700,19 +2699,19 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
return ssa_emit_logical_binary_expr(proc, expr);
case Token_as:
- ssa_emit_comment(proc, make_string("cast - as"));
+ ssa_emit_comment(proc, str_lit("cast - as"));
return ssa_emit_conv(proc, left, type);
case Token_transmute:
- ssa_emit_comment(proc, make_string("cast - transmute"));
+ ssa_emit_comment(proc, str_lit("cast - transmute"));
return ssa_emit_transmute(proc, left, type);
case Token_down_cast:
- ssa_emit_comment(proc, make_string("cast - down_cast"));
+ ssa_emit_comment(proc, str_lit("cast - down_cast"));
return ssa_emit_down_cast(proc, left, type);
case Token_union_cast:
- ssa_emit_comment(proc, make_string("cast - union_cast"));
+ ssa_emit_comment(proc, str_lit("cast - union_cast"));
return ssa_emit_union_cast(proc, left, type);
default:
@@ -2764,7 +2763,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
} break;
case BuiltinProc_new: {
- ssa_emit_comment(proc, make_string("new"));
+ ssa_emit_comment(proc, str_lit("new"));
// new :: proc(Type) -> ^Type
gbAllocator allocator = proc->module->allocator;
@@ -2783,7 +2782,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
} break;
case BuiltinProc_new_slice: {
- ssa_emit_comment(proc, make_string("new_slice"));
+ ssa_emit_comment(proc, str_lit("new_slice"));
// new_slice :: proc(Type, len: int[, cap: int]) -> ^Type
gbAllocator allocator = proc->module->allocator;
@@ -2825,7 +2824,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
} break;
case BuiltinProc_assert: {
- ssa_emit_comment(proc, make_string("assert"));
+ ssa_emit_comment(proc, str_lit("assert"));
ssaValue *cond = ssa_build_expr(proc, ce->args[0]);
GB_ASSERT(is_type_boolean(ssa_type(cond)));
@@ -2840,11 +2839,12 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
Token token = ast_node_token(ce->args[0]);
TokenPos pos = token.pos;
gbString expr = expr_to_string(ce->args[0]);
- defer (gb_string_free(expr));
isize expr_len = gb_string_length(expr);
String expr_str = {};
expr_str.text = cast(u8 *)gb_alloc_copy_align(proc->module->allocator, expr, expr_len, 1);
expr_str.len = expr_len;
+ gb_string_free(expr);
+
ssaValue **args = gb_alloc_array(proc->module->allocator, ssaValue *, 4);
args[0] = ssa_make_const_string(proc->module->allocator, pos.file);
@@ -2860,7 +2860,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
} break;
case BuiltinProc_panic: {
- ssa_emit_comment(proc, make_string("panic"));
+ ssa_emit_comment(proc, str_lit("panic"));
ssaValue *msg = ssa_build_expr(proc, ce->args[0]);
GB_ASSERT(is_type_string(ssa_type(msg)));
@@ -2879,7 +2879,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
case BuiltinProc_copy: {
- ssa_emit_comment(proc, make_string("copy"));
+ ssa_emit_comment(proc, str_lit("copy"));
// copy :: proc(dst, src: []Type) -> int
AstNode *dst_node = ce->args[0];
AstNode *src_node = ce->args[1];
@@ -2913,7 +2913,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
return len;
} break;
case BuiltinProc_append: {
- ssa_emit_comment(proc, make_string("append"));
+ ssa_emit_comment(proc, str_lit("append"));
// append :: proc(s: ^[]Type, item: Type) -> bool
AstNode *sptr_node = ce->args[0];
AstNode *item_node = ce->args[1];
@@ -2970,7 +2970,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
} break;
case BuiltinProc_swizzle: {
- ssa_emit_comment(proc, make_string("swizzle"));
+ ssa_emit_comment(proc, str_lit("swizzle"));
ssaValue *vector = ssa_build_expr(proc, ce->args[0]);
isize index_count = ce->args.count-1;
if (index_count == 0) {
@@ -2993,14 +2993,14 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
#if 0
case BuiltinProc_ptr_offset: {
- ssa_emit_comment(proc, make_string("ptr_offset"));
+ ssa_emit_comment(proc, str_lit("ptr_offset"));
ssaValue *ptr = ssa_build_expr(proc, ce->args[0]);
ssaValue *offset = ssa_build_expr(proc, ce->args[1]);
return ssa_emit_ptr_offset(proc, ptr, offset);
} break;
case BuiltinProc_ptr_sub: {
- ssa_emit_comment(proc, make_string("ptr_sub"));
+ ssa_emit_comment(proc, str_lit("ptr_sub"));
ssaValue *ptr_a = ssa_build_expr(proc, ce->args[0]);
ssaValue *ptr_b = ssa_build_expr(proc, ce->args[1]);
Type *ptr_type = base_type(ssa_type(ptr_a));
@@ -3018,7 +3018,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
#endif
case BuiltinProc_slice_ptr: {
- ssa_emit_comment(proc, make_string("slice_ptr"));
+ ssa_emit_comment(proc, str_lit("slice_ptr"));
ssaValue *ptr = ssa_build_expr(proc, ce->args[0]);
ssaValue *len = ssa_build_expr(proc, ce->args[1]);
ssaValue *cap = len;
@@ -3040,7 +3040,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
} break;
case BuiltinProc_min: {
- ssa_emit_comment(proc, make_string("min"));
+ ssa_emit_comment(proc, str_lit("min"));
ssaValue *x = ssa_build_expr(proc, ce->args[0]);
ssaValue *y = ssa_build_expr(proc, ce->args[1]);
Type *t = base_type(ssa_type(x));
@@ -3049,7 +3049,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
} break;
case BuiltinProc_max: {
- ssa_emit_comment(proc, make_string("max"));
+ ssa_emit_comment(proc, str_lit("max"));
ssaValue *x = ssa_build_expr(proc, ce->args[0]);
ssaValue *y = ssa_build_expr(proc, ce->args[1]);
Type *t = base_type(ssa_type(x));
@@ -3058,7 +3058,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
} break;
case BuiltinProc_abs: {
- ssa_emit_comment(proc, make_string("abs"));
+ ssa_emit_comment(proc, str_lit("abs"));
gbAllocator a = proc->module->allocator;
ssaValue *x = ssa_build_expr(proc, ce->args[0]);
@@ -3099,7 +3099,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
} break;
case BuiltinProc_enum_to_string: {
- ssa_emit_comment(proc, make_string("enum_to_string"));
+ ssa_emit_comment(proc, str_lit("enum_to_string"));
ssaValue *x = ssa_build_expr(proc, ce->args[0]);
Type *t = ssa_type(x);
ssaValue *ti = ssa_type_info(proc, t);
@@ -3173,7 +3173,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
}
if (variadic && !vari_expand) {
- ssa_emit_comment(proc, make_string("variadic call argument generation"));
+ ssa_emit_comment(proc, str_lit("variadic call argument generation"));
gbAllocator allocator = proc->module->allocator;
Type *slice_type = pt->variables[type->param_count-1]->type;
Type *elem_type = base_type(slice_type)->Slice.elem;
@@ -3301,7 +3301,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
case_end;
case_ast_node(se, SelectorExpr, expr);
- ssa_emit_comment(proc, make_string("SelectorExpr"));
+ ssa_emit_comment(proc, str_lit("SelectorExpr"));
String selector = unparen_expr(se->selector)->Ident.string;
Type *type = base_type(type_of_expr(proc->module->info, se->expr));
@@ -3335,7 +3335,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
case_ast_node(be, BinaryExpr, expr);
switch (be->op.kind) {
case Token_as: {
- ssa_emit_comment(proc, make_string("Cast - as"));
+ ssa_emit_comment(proc, str_lit("Cast - as"));
// NOTE(bill): Needed for dereference of pointer conversion
Type *type = type_of_expr(proc->module->info, expr);
ssaValue *v = ssa_add_local_generated(proc, type);
@@ -3343,7 +3343,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
return ssa_make_addr(v, expr);
}
case Token_transmute: {
- ssa_emit_comment(proc, make_string("Cast - transmute"));
+ ssa_emit_comment(proc, str_lit("Cast - transmute"));
// NOTE(bill): Needed for dereference of pointer conversion
Type *type = type_of_expr(proc->module->info, expr);
ssaValue *v = ssa_add_local_generated(proc, type);
@@ -3357,7 +3357,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
case_end;
case_ast_node(ie, IndexExpr, expr);
- ssa_emit_comment(proc, make_string("IndexExpr"));
+ ssa_emit_comment(proc, str_lit("IndexExpr"));
Type *t = base_type(type_of_expr(proc->module->info, ie->expr));
gbAllocator a = proc->module->allocator;
@@ -3459,7 +3459,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
case_end;
case_ast_node(se, SliceExpr, expr);
- ssa_emit_comment(proc, make_string("SliceExpr"));
+ ssa_emit_comment(proc, str_lit("SliceExpr"));
gbAllocator a = proc->module->allocator;
ssaValue *low = v_zero;
ssaValue *high = NULL;
@@ -3564,7 +3564,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
case_end;
case_ast_node(de, DemaybeExpr, expr);
- ssa_emit_comment(proc, make_string("DemaybeExpr"));
+ ssa_emit_comment(proc, str_lit("DemaybeExpr"));
ssaValue *maybe = ssa_build_expr(proc, de->expr);
Type *t = default_type(type_of_expr(proc->module->info, expr));
GB_ASSERT(is_type_tuple(t));
@@ -3584,7 +3584,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
case_ast_node(cl, CompoundLit, expr);
- ssa_emit_comment(proc, make_string("CompoundLit"));
+ ssa_emit_comment(proc, str_lit("CompoundLit"));
Type *type = type_of_expr(proc->module->info, expr);
Type *bt = base_type(type);
ssaValue *v = ssa_add_local_generated(proc, type);
@@ -3700,7 +3700,6 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
Type *elem_type = bt->Slice.elem;
Type *elem_ptr_type = make_type_pointer(proc->module->allocator, elem_type);
Type *elem_ptr_ptr_type = make_type_pointer(proc->module->allocator, elem_ptr_type);
- Type *t_int_ptr = make_type_pointer(proc->module->allocator, t_int);
ssaValue *slice = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr));
GB_ASSERT(slice->kind == ssaValue_ConstantSlice);
@@ -3807,14 +3806,13 @@ void ssa_build_stmt_list(ssaProcedure *proc, AstNodeArray stmts) {
}
}
+void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node);
void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
u32 prev_stmt_state_flags = proc->module->stmt_state_flags;
- defer (proc->module->stmt_state_flags = prev_stmt_state_flags);
if (node->stmt_state_flags != 0) {
u32 in = node->stmt_state_flags;
u32 out = proc->module->stmt_state_flags;
- defer (proc->module->stmt_state_flags = out);
if (in & StmtStateFlag_bounds_check) {
out |= StmtStateFlag_bounds_check;
@@ -3823,9 +3821,16 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
out |= StmtStateFlag_no_bounds_check;
out &= ~StmtStateFlag_bounds_check;
}
+
+ proc->module->stmt_state_flags = out;
}
+ ssa_build_stmt_internal(proc, node);
+
+ proc->module->stmt_state_flags = prev_stmt_state_flags;
+}
+void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
switch (node->kind) {
case_ast_node(bs, EmptyStmt, node);
case_end;
@@ -3840,7 +3845,6 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
case_ast_node(vd, VarDecl, node);
ssaModule *m = proc->module;
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
if (vd->values.count == 0) { // declared and zero-initialized
for_array(i, vd->names) {
@@ -3889,6 +3893,8 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
ssa_addr_store(proc, lvals[i], v);
}
}
+
+ gb_temp_arena_memory_end(tmp);
case_end;
case_ast_node(pd, ProcDecl, node);
@@ -3985,7 +3991,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
case_end;
case_ast_node(ids, IncDecStmt, node);
- ssa_emit_comment(proc, make_string("IncDecStmt"));
+ ssa_emit_comment(proc, str_lit("IncDecStmt"));
TokenKind op = ids->op.kind;
if (op == Token_Increment) {
op = Token_Add;
@@ -3999,11 +4005,10 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
case_end;
case_ast_node(as, AssignStmt, node);
- ssa_emit_comment(proc, make_string("AssignStmt"));
+ ssa_emit_comment(proc, str_lit("AssignStmt"));
ssaModule *m = proc->module;
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
switch (as->op.kind) {
case Token_Eq: {
@@ -4073,6 +4078,8 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
ssa_build_assign_op(proc, lhs, value, cast(TokenKind)op);
} break;
}
+
+ gb_temp_arena_memory_end(tmp);
case_end;
case_ast_node(es, ExprStmt, node);
@@ -4087,7 +4094,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
case_end;
case_ast_node(ds, DeferStmt, node);
- ssa_emit_comment(proc, make_string("DeferStmt"));
+ ssa_emit_comment(proc, str_lit("DeferStmt"));
isize scope_index = proc->scope_index;
if (ds->stmt->kind == AstNode_BlockStmt) {
scope_index--;
@@ -4096,7 +4103,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
case_end;
case_ast_node(rs, ReturnStmt, node);
- ssa_emit_comment(proc, make_string("ReturnStmt"));
+ ssa_emit_comment(proc, str_lit("ReturnStmt"));
ssaValue *v = NULL;
auto *return_type_tuple = &proc->type->Proc.results->Tuple;
isize return_count = proc->type->Proc.result_count;
@@ -4107,7 +4114,6 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
v = ssa_emit_conv(proc, ssa_build_expr(proc, rs->results[0]), e->type);
} else {
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
Array<ssaValue *> results;
array_init(&results, proc->module->tmp_allocator, return_count);
@@ -4137,13 +4143,14 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
v = ssa_emit_load(proc, v);
+ gb_temp_arena_memory_end(tmp);
}
ssa_emit_return(proc, v);
case_end;
case_ast_node(is, IfStmt, node);
- ssa_emit_comment(proc, make_string("IfStmt"));
+ ssa_emit_comment(proc, str_lit("IfStmt"));
if (is->init != NULL) {
ssaBlock *init = ssa_add_block(proc, node, "if.init");
ssa_emit_jump(proc, init);
@@ -4179,7 +4186,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
case_end;
case_ast_node(fs, ForStmt, node);
- ssa_emit_comment(proc, make_string("ForStmt"));
+ ssa_emit_comment(proc, str_lit("ForStmt"));
if (fs->init != NULL) {
ssaBlock *init = ssa_add_block(proc, node, "for.init");
ssa_emit_jump(proc, init);
@@ -4227,7 +4234,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
case_end;
case_ast_node(ms, MatchStmt, node);
- ssa_emit_comment(proc, make_string("MatchStmt"));
+ ssa_emit_comment(proc, str_lit("MatchStmt"));
if (ms->init != NULL) {
ssa_build_stmt(proc, ms->init);
}
@@ -4316,7 +4323,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
case_ast_node(ms, TypeMatchStmt, node);
- ssa_emit_comment(proc, make_string("TypeMatchStmt"));
+ ssa_emit_comment(proc, str_lit("TypeMatchStmt"));
gbAllocator allocator = proc->module->allocator;
ssaValue *parent = ssa_build_expr(proc, ms->tag);
@@ -4327,7 +4334,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
ssaValue *tag_index = NULL;
ssaValue *union_data = NULL;
if (is_union_ptr) {
- ssa_emit_comment(proc, make_string("get union's tag"));
+ ssa_emit_comment(proc, str_lit("get union's tag"));
tag_index = ssa_emit_load(proc, ssa_emit_union_tag_ptr(proc, parent));
union_data = ssa_emit_conv(proc, parent, t_rawptr);
}
@@ -4454,9 +4461,9 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
ssa_emit_defer_stmts(proc, ssaDeferExit_Branch, block);
}
switch (bs->token.kind) {
- case Token_break: ssa_emit_comment(proc, make_string("break")); break;
- case Token_continue: ssa_emit_comment(proc, make_string("continue")); break;
- case Token_fallthrough: ssa_emit_comment(proc, make_string("fallthrough")); break;
+ case Token_break: ssa_emit_comment(proc, str_lit("break")); break;
+ case Token_continue: ssa_emit_comment(proc, str_lit("continue")); break;
+ case Token_fallthrough: ssa_emit_comment(proc, str_lit("fallthrough")); break;
}
ssa_emit_jump(proc, block);
ssa_emit_unreachable(proc);
@@ -4465,9 +4472,8 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
case_ast_node(pa, PushAllocator, node);
- ssa_emit_comment(proc, make_string("PushAllocator"));
+ ssa_emit_comment(proc, str_lit("PushAllocator"));
ssa_open_scope(proc);
- defer (ssa_close_scope(proc, ssaDeferExit_Default, NULL));
ssaValue *context_ptr = ssa_find_implicit_value_backing(proc, ImplicitValue_context);
ssaValue *prev_context = ssa_add_local_generated(proc, t_context);
@@ -4480,13 +4486,13 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
ssa_build_stmt(proc, pa->body);
+ ssa_close_scope(proc, ssaDeferExit_Default, NULL);
case_end;
case_ast_node(pa, PushContext, node);
- ssa_emit_comment(proc, make_string("PushContext"));
+ ssa_emit_comment(proc, str_lit("PushContext"));
ssa_open_scope(proc);
- defer (ssa_close_scope(proc, ssaDeferExit_Default, NULL));
ssaValue *context_ptr = ssa_find_implicit_value_backing(proc, ImplicitValue_context);
ssaValue *prev_context = ssa_add_local_generated(proc, t_context);
@@ -4497,6 +4503,8 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
ssa_emit_store(proc, context_ptr, ssa_build_expr(proc, pa->expr));
ssa_build_stmt(proc, pa->body);
+
+ ssa_close_scope(proc, ssaDeferExit_Default, NULL);
case_end;
@@ -4573,7 +4581,7 @@ void ssa_end_procedure_body(ssaProcedure *proc) {
void ssa_insert_code_before_proc(ssaProcedure* proc, ssaProcedure *parent) {
if (parent == NULL) {
- if (proc->name == "main") {
+ if (str_eq(proc->name, str_lit("main"))) {
ssa_emit_startup_runtime(proc);
}
}
@@ -4607,13 +4615,10 @@ void ssa_build_proc(ssaValue *value, ssaProcedure *parent) {
if (proc->body != NULL) {
u32 prev_stmt_state_flags = proc->module->stmt_state_flags;
- defer (proc->module->stmt_state_flags = prev_stmt_state_flags);
if (proc->tags != 0) {
u32 in = proc->tags;
u32 out = proc->module->stmt_state_flags;
- defer (proc->module->stmt_state_flags = out);
-
if (in & ProcTag_bounds_check) {
out |= StmtStateFlag_bounds_check;
out &= ~StmtStateFlag_no_bounds_check;
@@ -4621,6 +4626,7 @@ void ssa_build_proc(ssaValue *value, ssaProcedure *parent) {
out |= StmtStateFlag_no_bounds_check;
out &= ~StmtStateFlag_bounds_check;
}
+ proc->module->stmt_state_flags = out;
}
@@ -4628,6 +4634,8 @@ void ssa_build_proc(ssaValue *value, ssaProcedure *parent) {
ssa_insert_code_before_proc(proc, parent);
ssa_build_stmt(proc, proc->body);
ssa_end_procedure_body(proc);
+
+ proc->module->stmt_state_flags = prev_stmt_state_flags;
}
}
@@ -4674,7 +4682,7 @@ void ssa_init_module(ssaModule *m, Checker *c) {
{
// Add type info data
{
- String name = make_string(SSA_TYPE_INFO_DATA_NAME);
+ String name = str_lit(SSA_TYPE_INFO_DATA_NAME);
isize count = c->info.type_info_map.entries.count;
Entity *e = make_entity_variable(m->allocator, NULL, make_token_ident(name), make_type_array(m->allocator, t_type_info, count));
ssaValue *g = ssa_make_value_global(m->allocator, e, NULL);
@@ -4706,7 +4714,7 @@ void ssa_init_module(ssaModule *m, Checker *c) {
}
}
- String name = make_string(SSA_TYPE_INFO_DATA_MEMBER_NAME);
+ String name = str_lit(SSA_TYPE_INFO_DATA_MEMBER_NAME);
Entity *e = make_entity_variable(m->allocator, NULL, make_token_ident(name),
make_type_array(m->allocator, t_type_info_member, count));
ssaValue *g = ssa_make_value_global(m->allocator, e, NULL);
@@ -4718,7 +4726,7 @@ void ssa_init_module(ssaModule *m, Checker *c) {
{
ssaDebugInfo *di = ssa_alloc_debug_info(m->allocator, ssaDebugInfo_CompileUnit);
di->CompileUnit.file = m->info->files.entries[0].value; // Zeroth is the init file
- di->CompileUnit.producer = make_string("odin");
+ di->CompileUnit.producer = str_lit("odin");
map_set(&m->debug_info, hash_pointer(m), di);
}
@@ -4830,7 +4838,7 @@ void ssa_gen_tree(ssaGen *s) {
if (e->kind == Entity_Variable) {
global_variable_max_count++;
} else if (e->kind == Entity_Procedure) {
- if (e->scope->is_init && name == "main") {
+ if (e->scope->is_init && str_eq(name, str_lit("main"))) {
entry_point = e;
}
}
@@ -4965,7 +4973,7 @@ void ssa_gen_tree(ssaGen *s) {
{ // Startup Runtime
// Cleanup(bill): probably better way of doing code insertion
- String name = make_string(SSA_STARTUP_RUNTIME_PROC_NAME);
+ String name = str_lit(SSA_STARTUP_RUNTIME_PROC_NAME);
Type *proc_type = make_type_proc(a, gb_alloc_item(a, Scope),
NULL, 0,
NULL, 0, false);
@@ -5016,11 +5024,11 @@ void ssa_gen_tree(ssaGen *s) {
ssaValue *type_info_member_data = NULL;
ssaValue **found = NULL;
- found = map_get(&proc->module->members, hash_string(make_string(SSA_TYPE_INFO_DATA_NAME)));
+ found = map_get(&proc->module->members, hash_string(str_lit(SSA_TYPE_INFO_DATA_NAME)));
GB_ASSERT(found != NULL);
type_info_data = *found;
- found = map_get(&proc->module->members, hash_string(make_string(SSA_TYPE_INFO_DATA_MEMBER_NAME)));
+ found = map_get(&proc->module->members, hash_string(str_lit(SSA_TYPE_INFO_DATA_MEMBER_NAME)));
GB_ASSERT(found != NULL);
type_info_member_data = *found;
@@ -5421,6 +5429,6 @@ void ssa_gen_tree(ssaGen *s) {
- // m->layout = make_string("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64");
+ // m->layout = str_lit("e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64");
}
diff --git a/src/ssa_opt.cpp b/src/ssa_opt.cpp
index 0fb4bd873..2b572be84 100644
--- a/src/ssa_opt.cpp
+++ b/src/ssa_opt.cpp
@@ -274,7 +274,6 @@ void ssa_opt_blocks(ssaProcedure *proc) {
}
void ssa_opt_build_referrers(ssaProcedure *proc) {
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
Array<ssaValue *> ops = {}; // NOTE(bill): Act as a buffer
array_init(&ops, proc->module->tmp_allocator, 64); // HACK(bill): This _could_ overflow the temp arena
@@ -296,6 +295,8 @@ void ssa_opt_build_referrers(ssaProcedure *proc) {
}
}
}
+
+ gb_temp_arena_memory_end(tmp);
}
@@ -370,7 +371,6 @@ void ssa_opt_build_dom_tree(ssaProcedure *proc) {
// Based on this paper: http://jgaa.info/accepted/2006/GeorgiadisTarjanWerneck2006.10.1.pdf
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
isize n = proc->blocks.count;
ssaBlock **buf = gb_alloc_array(proc->module->tmp_allocator, ssaBlock *, 5*n);
@@ -450,6 +450,8 @@ void ssa_opt_build_dom_tree(ssaProcedure *proc) {
}
ssa_opt_number_dom_tree(root, 0, 0);
+
+ gb_temp_arena_memory_end(tmp);
}
void ssa_opt_mem2reg(ssaProcedure *proc) {
diff --git a/src/ssa_print.cpp b/src/ssa_print.cpp
index 2f074008d..28df7e42c 100644
--- a/src/ssa_print.cpp
+++ b/src/ssa_print.cpp
@@ -90,7 +90,6 @@ void ssa_print_escape_string(ssaFileBuffer *f, String name, b32 print_quotes) {
isize buf_len = name.len + extra + 2;
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&string_buffer_arena);
- defer (gb_temp_arena_memory_end(tmp));
u8 *buf = gb_alloc_array(string_buffer_allocator, u8, buf_len);
@@ -117,6 +116,8 @@ void ssa_print_escape_string(ssaFileBuffer *f, String name, b32 print_quotes) {
}
ssa_file_write(f, buf, j);
+
+ gb_temp_arena_memory_end(tmp);
}
@@ -128,7 +129,7 @@ void ssa_print_encoded_local(ssaFileBuffer *f, String name) {
void ssa_print_encoded_global(ssaFileBuffer *f, String name, b32 global_scope) {
ssa_fprintf(f, "@");
- if (!global_scope && name != make_string("main")) {
+ if (!global_scope && str_ne(name, str_lit("main"))) {
ssa_fprintf(f, ".");
}
ssa_print_escape_string(f, name, true);
@@ -482,7 +483,6 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ
ssa_fprintf(f, ">");
} else if (is_type_struct(type)) {
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);
- defer (gb_temp_arena_memory_end(tmp));
ast_node(cl, CompoundLit, value.value_compound);
@@ -543,6 +543,8 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ
if (type->Record.struct_is_packed) {
ssa_fprintf(f, ">");
}
+
+ gb_temp_arena_memory_end(tmp);
} else {
ssa_fprintf(f, "zeroinitializer");
}
@@ -638,7 +640,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
switch (instr->kind) {
case ssaInstr_StartupRuntime: {
ssa_fprintf(f, "call void ");
- ssa_print_encoded_global(f, make_string(SSA_STARTUP_RUNTIME_PROC_NAME), false);
+ ssa_print_encoded_global(f, str_lit(SSA_STARTUP_RUNTIME_PROC_NAME), false);
ssa_fprintf(f, "()\n");
} break;
@@ -889,7 +891,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
}
ssa_fprintf(f, " ");
- ssa_print_encoded_global(f, make_string(runtime_proc), false);
+ ssa_print_encoded_global(f, make_string_c(runtime_proc), false);
ssa_fprintf(f, "(");
ssa_print_type(f, m, type);
ssa_fprintf(f, " ");
@@ -1090,7 +1092,7 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
case ssaInstr_BoundsCheck: {
auto *bc = &instr->BoundsCheck;
ssa_fprintf(f, "call void ");
- ssa_print_encoded_global(f, make_string("__bounds_check_error"), false);
+ ssa_print_encoded_global(f, str_lit("__bounds_check_error"), false);
ssa_fprintf(f, "(");
ssa_print_compound_element(f, m, make_exact_value_string(bc->pos.file), t_string);
ssa_fprintf(f, ", ");
@@ -1121,9 +1123,9 @@ void ssa_print_instr(ssaFileBuffer *f, ssaModule *m, ssaValue *value) {
auto *bc = &instr->SliceBoundsCheck;
ssa_fprintf(f, "call void ");
if (bc->is_substring) {
- ssa_print_encoded_global(f, make_string("__substring_expr_error"), false);
+ ssa_print_encoded_global(f, str_lit("__substring_expr_error"), false);
} else {
- ssa_print_encoded_global(f, make_string("__slice_expr_error"), false);
+ ssa_print_encoded_global(f, str_lit("__slice_expr_error"), false);
}
ssa_fprintf(f, "(");
@@ -1273,21 +1275,19 @@ void ssa_print_llvm_ir(ssaGen *ssa) {
ssaModule *m = &ssa->module;
ssaFileBuffer buf = {}, *f = &buf;
ssa_file_buffer_init(f, &ssa->output_file);
- defer (ssa_file_buffer_destroy(f));
-
if (m->layout.len > 0) {
ssa_fprintf(f, "target datalayout = \"%.*s\"\n", LIT(m->layout));
}
- ssa_print_encoded_local(f, make_string("..string"));
+ ssa_print_encoded_local(f, str_lit("..string"));
ssa_fprintf(f, " = type {i8*, ");
ssa_print_type(f, m, t_int);
ssa_fprintf(f, "} ; Basic_string\n");
- ssa_print_encoded_local(f, make_string("..rawptr"));
+ ssa_print_encoded_local(f, str_lit("..rawptr"));
ssa_fprintf(f, " = type i8* ; Basic_rawptr\n");
- ssa_print_encoded_local(f, make_string("..any"));
+ ssa_print_encoded_local(f, str_lit("..any"));
ssa_fprintf(f, " = type {");
ssa_print_type(f, m, t_type_info_ptr);
ssa_fprintf(f, ", ");
@@ -1379,7 +1379,6 @@ void ssa_print_llvm_ir(ssaGen *ssa) {
auto *entry = &m->debug_info.entries[di_index];
ssaDebugInfo *di = entry->value;
ssa_fprintf(f, "!%d = ", di->id);
- defer (ssa_fprintf(f, "\n"));
switch (di->kind) {
case ssaDebugInfo_CompileUnit: {
@@ -1430,6 +1429,10 @@ void ssa_print_llvm_ir(ssaGen *ssa) {
ssa_fprintf(f, "}");
break;
}
+
+ ssa_fprintf(f, "\n");
}
}
+
+ ssa_file_buffer_destroy(f);
}
diff --git a/src/string.cpp b/src/string.cpp
index d62a0e900..552ba2a4b 100644
--- a/src/string.cpp
+++ b/src/string.cpp
@@ -1,5 +1,5 @@
-gb_global gbArena string_buffer_arena = {};
-gb_global gbAllocator string_buffer_allocator = {};
+gb_global gbArena string_buffer_arena = {0};
+gb_global gbAllocator string_buffer_allocator = {0};
void init_string_buffer_memory(void) {
// NOTE(bill): This should be enough memory for file systems
@@ -42,14 +42,12 @@ gb_inline String16 make_string16(wchar_t *text, isize len) {
}
-gb_inline String make_string(char *text) {
+gb_inline String make_string_c(char *text) {
return make_string(cast(u8 *)cast(void *)text, gb_strlen(text));
}
-template <size_t N>
-gb_inline String make_string(char const (&text)[N]) {
- return make_string(cast(u8 *)cast(void *)text, N-1);
-}
+#define str_lit(c_str) make_string(cast(u8 *)c_str, gb_size_of(c_str)-1)
+
gb_inline b32 are_strings_equal(String a, String b) {
if (a.len == b.len) {
@@ -58,7 +56,7 @@ gb_inline b32 are_strings_equal(String a, String b) {
return false;
}
-gb_inline b32 are_strings_equal_ignore_case(String a, String b) {
+gb_inline b32 str_eq_ignore_case(String a, String b) {
if (a.len == b.len) {
for (isize i = 0; i < a.len; i++) {
char x = cast(char)a.text[i];
@@ -115,18 +113,24 @@ GB_COMPARE_PROC(string_cmp_proc) {
}
-gb_inline bool operator ==(String a, String b) { return are_strings_equal(a, b) != 0; }
-gb_inline bool operator !=(String a, String b) { return !operator==(a, b); }
-gb_inline bool operator < (String a, String b) { return string_compare(a, b) < 0; }
-gb_inline bool operator > (String a, String b) { return string_compare(a, b) > 0; }
-gb_inline bool operator <=(String a, String b) { return string_compare(a, b) <= 0; }
-gb_inline bool operator >=(String a, String b) { return string_compare(a, b) >= 0; }
+// gb_inline bool operator ==(String a, String b) { return are_strings_equal(a, b) != 0; }
+// gb_inline bool operator !=(String a, String b) { return !operator==(a, b); }
+// gb_inline bool operator < (String a, String b) { return string_compare(a, b) < 0; }
+// gb_inline bool operator > (String a, String b) { return string_compare(a, b) > 0; }
+// gb_inline bool operator <=(String a, String b) { return string_compare(a, b) <= 0; }
+// gb_inline bool operator >=(String a, String b) { return string_compare(a, b) >= 0; }
-template <size_t N> gb_inline bool operator ==(String a, char const (&b)[N]) { return a == make_string(cast(u8 *)b, N-1); }
-template <size_t N> gb_inline bool operator !=(String a, char const (&b)[N]) { return a != make_string(cast(u8 *)b, N-1); }
-template <size_t N> gb_inline bool operator ==(char const (&a)[N], String b) { return make_string(cast(u8 *)a, N-1) == b; }
-template <size_t N> gb_inline bool operator !=(char const (&a)[N], String b) { return make_string(cast(u8 *)a, N-1) != b; }
+// template <size_t N> gb_inline bool operator ==(String a, char const (&b)[N]) { return a == make_string(cast(u8 *)b, N-1); }
+// template <size_t N> gb_inline bool operator !=(String a, char const (&b)[N]) { return a != make_string(cast(u8 *)b, N-1); }
+// template <size_t N> gb_inline bool operator ==(char const (&a)[N], String b) { return make_string(cast(u8 *)a, N-1) == b; }
+// template <size_t N> gb_inline bool operator !=(char const (&a)[N], String b) { return make_string(cast(u8 *)a, N-1) != b; }
+gb_inline bool str_eq(String a, String b) { return are_strings_equal(a, b) != 0; }
+gb_inline bool str_ne(String a, String b) { return !str_eq(a, b); }
+gb_inline bool str_lt(String a, String b) { return string_compare(a, b) < 0; }
+gb_inline bool str_gt(String a, String b) { return string_compare(a, b) > 0; }
+gb_inline bool str_le(String a, String b) { return string_compare(a, b) <= 0; }
+gb_inline bool str_ge(String a, String b) { return string_compare(a, b) >= 0; }
@@ -385,12 +389,12 @@ i32 unquote_string(gbAllocator a, String *s_) {
}
- u8 rune_temp[4] = {};
+ u8 rune_temp[4] = {0};
isize buf_len = 3*s.len / 2;
u8 *buf = gb_alloc_array(a, u8, buf_len);
isize offset = 0;
while (s.len > 0) {
- String tail_string = {};
+ String tail_string = {0};
Rune r = 0;
b32 multiple_bytes = false;
b32 success = unquote_char(s, quote, &r, &multiple_bytes, &tail_string);
diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp
index d0f14990a..42c2b7b69 100644
--- a/src/tokenizer.cpp
+++ b/src/tokenizer.cpp
@@ -180,7 +180,6 @@ void init_global_error_collector(void) {
void warning(Token token, char *fmt, ...) {
gb_mutex_lock(&global_error_collector.mutex);
- defer (gb_mutex_unlock(&global_error_collector.mutex));
global_error_collector.warning_count++;
// NOTE(bill): Duplicate error, skip it
@@ -195,11 +194,12 @@ void warning(Token token, char *fmt, ...) {
gb_bprintf_va(fmt, va));
va_end(va);
}
+
+ gb_mutex_unlock(&global_error_collector.mutex);
}
void error(Token token, char *fmt, ...) {
gb_mutex_lock(&global_error_collector.mutex);
- defer (gb_mutex_unlock(&global_error_collector.mutex));
global_error_collector.count++;
// NOTE(bill): Duplicate error, skip it
@@ -214,11 +214,12 @@ void error(Token token, char *fmt, ...) {
gb_bprintf_va(fmt, va));
va_end(va);
}
+
+ gb_mutex_unlock(&global_error_collector.mutex);
}
void syntax_error(Token token, char *fmt, ...) {
gb_mutex_lock(&global_error_collector.mutex);
- defer (gb_mutex_unlock(&global_error_collector.mutex));
global_error_collector.count++;
// NOTE(bill): Duplicate error, skip it
@@ -233,6 +234,8 @@ void syntax_error(Token token, char *fmt, ...) {
gb_bprintf_va(fmt, va));
va_end(va);
}
+
+ gb_mutex_unlock(&global_error_collector.mutex);
}
@@ -349,13 +352,12 @@ void advance_to_next_rune(Tokenizer *t) {
TokenizerInitError init_tokenizer(Tokenizer *t, String fullpath) {
PROF_PROC();
+ TokenizerInitError err = TokenizerInit_None;
+
char *c_str = gb_alloc_array(heap_allocator(), char, fullpath.len+1);
memcpy(c_str, fullpath.text, fullpath.len);
c_str[fullpath.len] = '\0';
- defer (gb_free(heap_allocator(), c_str));
-
-
// TODO(bill): Memory map rather than copy contents
gbFileContents fc = gb_file_read_contents(heap_allocator(), true, c_str);
gb_zero_item(t);
@@ -363,9 +365,7 @@ TokenizerInitError init_tokenizer(Tokenizer *t, String fullpath) {
t->start = cast(u8 *)fc.data;
t->line = t->read_curr = t->curr = t->start;
t->end = t->start + fc.size;
-
t->fullpath = fullpath;
-
t->line_count = 1;
advance_to_next_rune(t);
@@ -374,28 +374,25 @@ TokenizerInitError init_tokenizer(Tokenizer *t, String fullpath) {
}
array_init(&t->allocated_strings, heap_allocator());
+ } else {
+ gbFile f = {};
+ gbFileError file_err = gb_file_open(&f, c_str);
- return TokenizerInit_None;
- }
+ switch (file_err) {
+ case gbFileError_Invalid: err = TokenizerInit_Invalid; break;
+ case gbFileError_NotExists: err = TokenizerInit_NotExists; break;
+ case gbFileError_Permission: err = TokenizerInit_Permission; break;
+ }
- gbFile f = {};
- gbFileError err = gb_file_open(&f, c_str);
- defer (gb_file_close(&f));
-
- switch (err) {
- case gbFileError_Invalid:
- return TokenizerInit_Invalid;
- case gbFileError_NotExists:
- return TokenizerInit_NotExists;
- case gbFileError_Permission:
- return TokenizerInit_Permission;
- }
+ if (err == TokenizerInit_None && gb_file_size(&f) == 0) {
+ err = TokenizerInit_Empty;
+ }
- if (gb_file_size(&f) == 0) {
- return TokenizerInit_Empty;
+ gb_file_close(&f);
}
- return TokenizerInit_None;
+ gb_free(heap_allocator(), c_str);
+ return err;
}
gb_inline void destroy_tokenizer(Tokenizer *t) {
@@ -634,17 +631,17 @@ Token tokenizer_get_token(Tokenizer *t) {
// NOTE(bill): All keywords are > 1
if (token.string.len > 1) {
- if (token.string == token_strings[Token_as]) {
+ if (str_eq(token.string, token_strings[Token_as])) {
token.kind = Token_as;
- } else if (token.string == token_strings[Token_transmute]) {
+ } else if (str_eq(token.string, token_strings[Token_transmute])) {
token.kind = Token_transmute;
- } else if (token.string == token_strings[Token_down_cast]) {
+ } else if (str_eq(token.string, token_strings[Token_down_cast])) {
token.kind = Token_down_cast;
- } else if (token.string == token_strings[Token_union_cast]) {
+ } else if (str_eq(token.string, token_strings[Token_union_cast])) {
token.kind = Token_union_cast;
} else {
for (i32 k = Token__KeywordBegin+1; k < Token__KeywordEnd; k++) {
- if (token.string == token_strings[k]) {
+ if (str_eq(token.string, token_strings[k])) {
token.kind = cast(TokenKind)k;
break;
}
diff --git a/src/vm.cpp b/src/vm.cpp
deleted file mode 100644
index db9941553..000000000
--- a/src/vm.cpp
+++ /dev/null
@@ -1,356 +0,0 @@
-#if 0
-// TODO(bill): COMPLETELY REWORK THIS ENTIRE INTERPRETER
-#include "dyncall/include/dyncall.h"
-
-struct vmInterpreter;
-
-/*
-Types:
-boolean
-integer
-float
-pointer
-string
-any
-array
-vector
-slice
-maybe
-struct
-union
-raw_union
-enum
-tuple
-proc
-*/
-
-struct vmProcedure {
- Type * type;
- String name;
- b32 is_external;
-};
-
-struct vmValue {
- void *data;
- i32 id;
- Type *type;
- union {
- i64 v_int;
- f32 v_f32;
- f64 v_f64;
- vmProcedure * v_proc;
- };
-};
-
-Array<vmValue> vm_empty_args = {};
-
-struct vmFrame {
- vmInterpreter *i;
- vmFrame * caller;
- ssaProcedure * proc;
- ssaBlock * block;
- ssaBlock * prev_block;
- isize instr_index; // For the current block
-
- Array<void *> env; // Index == instr id
- vmValue result;
-};
-
-struct vmInterpreter {
- ssaModule * module;
- BaseTypeSizes sizes;
- gbArena stack_arena;
- gbAllocator stack_allocator;
- gbAllocator heap_allocator;
-
- Array<vmFrame> frame_stack;
- Map<vmValue> globals;
-};
-
-enum vmContinuation {
- vmContinuation_Next,
- vmContinuation_Return,
- vmContinuation_Branch,
-};
-
-
-
-
-i64 vm_size_of(vmInterpreter *i, Type *type) {
- return type_size_of(i->sizes, i->heap_allocator, type);
-}
-i64 vm_align_of(vmInterpreter *i, Type *type) {
- return type_align_of(i->sizes, i->heap_allocator, type);
-}
-i64 vm_offset_of(vmInterpreter *i, Type *type, i64 index) {
- return type_offset_of(i->sizes, i->heap_allocator, type, index);
-}
-
-
-
-
-
-
-Array<vmValue> vm_prepare_call(vmFrame *f, ssaInstr *instr, vmValue *proc) {
- GB_ASSERT(instr->kind == ssaInstr_Call);
-
- *proc = vm_get_value(f, instr->Call.value);
-
- Array<vmValue> args = {};
- array_init_count(&args, f->i->stack_allocator, instr->Call.arg_count);
-
- for (isize i = 0; i < instr->Call.arg_count; i++) {
- args[i] = vm_get_value(f, instr->Call.args[i]);
- }
-
- return args;
-}
-
-
-vmContinuation vm_visit_instr(vmFrame *f, ssaValue *value) {
- ssaInstr *instr = &value->Instr;
-#if 1
- if (instr->kind != ssaInstr_Comment) {
- gb_printf("instr: %.*s\n", LIT(ssa_instr_strings[instr->kind]));
- }
-#endif
- switch (instr->kind) {
- case ssaInstr_StartupRuntime: {
-
- } break;
-
- case ssaInstr_Comment: break;
-
- case ssaInstr_Local: {
- Type *type = ssa_type(value);
- GB_ASSERT(is_type_pointer(type));
- i64 size = gb_max(1, vm_size_of(f->i, type));
- i64 align = gb_max(1, vm_align_of(f->i, type));
- void *mem = gb_alloc_align(f->i->stack_allocator, size, align);
-
- array_add(&f->locals, mem);
- } break;
-
- case ssaInstr_ZeroInit: {
- Type *pt = ssa_type(instr->ZeroInit.address);
- GB_ASSERT(is_type_pointer(pt));
- vmValue addr = vm_get_value(f, instr->ZeroInit.address);
- GB_ASSERT(are_types_identical(addr.type, ptr));
- i64 size = vm_size_of(vm, type_deref(pt));
- gb_zero(addr.v_ptr, size);
- } break;
-
- case ssaInstr_Store: {
- ssaValue *addr = instr->Store.Address;
- ssaValue *value = instr->Store.Value;
- } break;
-
- case ssaInstr_Load: {
- ssaValue *addr = instr->Load.Address;
- } break;
-
- case ssaInstr_ArrayElementPtr: {
-
- } break;
-
- case ssaInstr_StructElementPtr: {
-
- } break;
-
- case ssaInstr_PtrOffset: {
-
- } break;
-
- case ssaInstr_Phi:
- for_array(i, f->block->preds) {
- ssaBlock *pred = f->block->preds[i];
- if (f->prev_block == pred) {
- vmValue edge = vm_get_value(f, instr->Phi.edges[i]);
- // vm_set_value(f, value, edge);
- break;
- }
- }
- break;
-
- case ssaInstr_ArrayExtractValue: {
-
- } break;
-
- case ssaInstr_StructExtractValue: {
-
- } break;
-
- case ssaInstr_Jump:
- f->prev_block = f->block;
- f->block = instr->Jump.block;
- return vmContinuation_Branch;
-
- case ssaInstr_If:
- f->prev_block = f->block;
- if (vm_get_value(f, instr->If.cond).v_int != 0) {
- f->block = instr->If.true_block;
- } else {
- f->block = instr->If.false_block;
- }
- return vmContinuation_Branch;
-
- case ssaInstr_Return:
- if (instr->Return.value != NULL) {
- Type *type = base_type(ssa_type(instr->Return.value));
- GB_ASSERT(is_type_tuple(type));
- f->result = vm_get_value(f, instr->Return.value);
- if (type->Tuple.variable_count == 1) {
- f->result.type = type->Tuple.variables[0]->type;
- }
- }
- f->block = NULL;
- return vmContinuation_Return;
-
- case ssaInstr_Conv: {
-
- } break;
-
- case ssaInstr_Unreachable: {
- GB_PANIC("Unreachable");
- } break;
-
- case ssaInstr_BinaryOp: {
-
- } break;
-
- case ssaInstr_Call: {
-
- } break;
-
- case ssaInstr_Select: {
-
- } break;
-
- case ssaInstr_VectorExtractElement: {
-
- } break;
-
- case ssaInstr_VectorInsertElement: {
-
- } break;
-
- case ssaInstr_VectorShuffle: {
-
- } break;
-
- case ssaInstr_BoundsCheck: {
-
- } break;
-
- case ssaInstr_SliceBoundsCheck: {
-
- } break;
-
- default: {
- GB_PANIC("<unknown instr> %d\n", instr->kind);
- } break;
- }
-
- return vmContinuation_Next;
-}
-
-
-void vm_run_frame(vmFrame *f) {
- for (;;) {
- for_array(i, f->block->instrs) {
- ssaValue *v = f->block->instrs[i];
- GB_ASSERT(v->kind == ssaValue_Instr);
- switch (vm_visit_instr(f, v)) {
- case vmContinuation_Return:
- return;
- case vmContinuation_Next:
- // Do nothing
- break;
- case vmContinuation_Branch:
- goto end;
- }
- }
- end:
- ;
- }
-}
-
-ssaProcedure *vm_lookup_proc(vmInterpreter *i, String name) {
- ssaValue **found = map_get(&i->module->members, hash_string(name));
- if (found == NULL) {
- return NULL;
- }
- ssaValue *v = *found;
- if (v->kind != ssaValue_Proc) {
- return NULL;
- }
-
- return &v->Proc;
-}
-
-vmValue vm_ext(vmFrame *caller, Array<vmValue> args) {
- GB_PANIC("TODO(bill): vm_ext");
- vmValue v = {};
- return v;
-}
-
-vmValue vm_call(vmInterpreter *i, vmFrame *caller, ssaProcedure *proc, Array<vmValue> args) {
- if (proc == NULL) {
- GB_PANIC("Call to NULL procedure");
- }
-
- gb_printf("Call: %.*s", LIT(proc->name));
-
- vmFrame f = {};
- f.i = i;
- f.caller = caller;
- f.proc = proc;
- if (proc->body == NULL) {
- return vm_ext(&f, args);
- }
- f.block = proc->blocks[0];
-
- map_init_with_reserve(&f.env, i->heap_allocator, 1.5*proc->instr_count);
- defer (map_destroy(&f.env));
-
- array_init_count(&f.locals, i->heap_allocator, proc->local_count);
- defer (array_free(&f.locals));
-
- for_array(i, proc->params) {
- map_set(&f.env, hash_pointer(proc->params[i]), args[i]);
- }
-
- while (f.block != NULL) {
- vm_run_frame(&f);
- }
-
- return f.result;
-}
-
-i32 vm_interpret(ssaModule *m) {
- i32 exit_code = 2;
-
- vmInterpreter i = {};
-
- i.module = m;
- i.sizes = m->sizes;
-
- gb_arena_init_from_allocator(&i.stack_arena, heap_allocator(), gb_megabytes(64));
- defer (gb_arena_free(&i.stack_arena));
-
- i.stack_allocator = gb_arena_allocator(&i.stack_arena);
- i.heap_allocator = heap_allocator();
-
- ssaProcedure *main_proc = vm_lookup_proc(&i, make_string("main"));
- if (main_proc != NULL) {
- vm_call(&i, NULL, main_proc, vm_empty_args);
- exit_code = 0;
- } else {
- gb_printf_err("No main procedure.");
- exit_code = 1;
- }
-
- return exit_code;
-}
-
-#endif