mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-15 07:43:13 +00:00
Remove templated Map; replace with #include macro "templates" trick
This commit is contained in:
@@ -2,6 +2,11 @@
|
||||
#include "entity.cpp"
|
||||
#include "types.cpp"
|
||||
|
||||
#define MAP_TYPE Entity *
|
||||
#define MAP_FUNC map_entity_
|
||||
#define MAP_NAME MapEntity
|
||||
#include "../map.c"
|
||||
|
||||
enum AddressingMode {
|
||||
Addressing_Invalid,
|
||||
Addressing_NoValue,
|
||||
@@ -27,6 +32,8 @@ struct TypeAndValue {
|
||||
ExactValue value;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct DeclInfo {
|
||||
Scope *scope;
|
||||
|
||||
@@ -38,18 +45,18 @@ struct DeclInfo {
|
||||
AstNode *proc_decl; // AstNode_ProcDecl
|
||||
u32 var_decl_tags;
|
||||
|
||||
Map<b32> deps; // Key: Entity *
|
||||
MapBool deps; // Key: Entity *
|
||||
};
|
||||
|
||||
struct ExpressionInfo {
|
||||
b32 is_lhs; // Debug info
|
||||
struct ExprInfo {
|
||||
bool is_lhs; // Debug info
|
||||
AddressingMode mode;
|
||||
Type * type; // Type_Basic
|
||||
ExactValue value;
|
||||
};
|
||||
|
||||
ExpressionInfo make_expression_info(b32 is_lhs, AddressingMode mode, Type *type, ExactValue value) {
|
||||
ExpressionInfo ei = {is_lhs, mode, type, value};
|
||||
ExprInfo make_expr_info(bool is_lhs, AddressingMode mode, Type *type, ExactValue value) {
|
||||
ExprInfo ei = {is_lhs, mode, type, value};
|
||||
return ei;
|
||||
}
|
||||
|
||||
@@ -67,15 +74,15 @@ struct Scope {
|
||||
Scope * prev, *next;
|
||||
Scope * first_child;
|
||||
Scope * last_child;
|
||||
Map<Entity *> elements; // Key: String
|
||||
Map<Entity *> implicit; // Key: String
|
||||
MapEntity elements; // Key: String
|
||||
MapEntity implicit; // Key: String
|
||||
|
||||
Array(Scope *) shared;
|
||||
Array(Scope *) imported;
|
||||
b32 is_proc;
|
||||
b32 is_global;
|
||||
b32 is_file;
|
||||
b32 is_init;
|
||||
bool is_proc;
|
||||
bool is_global;
|
||||
bool is_file;
|
||||
bool is_init;
|
||||
AstFile * file;
|
||||
};
|
||||
gb_global Scope *universal_scope = NULL;
|
||||
@@ -126,7 +133,7 @@ enum BuiltinProcId {
|
||||
struct BuiltinProc {
|
||||
String name;
|
||||
isize arg_count;
|
||||
b32 variadic;
|
||||
bool variadic;
|
||||
ExprKind kind;
|
||||
};
|
||||
gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
|
||||
@@ -189,19 +196,45 @@ struct CheckerContext {
|
||||
u32 stmt_state_flags;
|
||||
};
|
||||
|
||||
#define MAP_TYPE TypeAndValue
|
||||
#define MAP_FUNC map_tav_
|
||||
#define MAP_NAME MapTypeAndValue
|
||||
#include "../map.c"
|
||||
|
||||
#define MAP_TYPE Scope *
|
||||
#define MAP_FUNC map_scope_
|
||||
#define MAP_NAME MapScope
|
||||
#include "../map.c"
|
||||
|
||||
#define MAP_TYPE DeclInfo *
|
||||
#define MAP_FUNC map_decl_info_
|
||||
#define MAP_NAME MapDeclInfo
|
||||
#include "../map.c"
|
||||
|
||||
#define MAP_TYPE AstFile *
|
||||
#define MAP_FUNC map_ast_file_
|
||||
#define MAP_NAME MapAstFile
|
||||
#include "../map.c"
|
||||
|
||||
#define MAP_TYPE ExprInfo
|
||||
#define MAP_FUNC map_expr_info_
|
||||
#define MAP_NAME MapExprInfo
|
||||
#include "../map.c"
|
||||
|
||||
|
||||
// NOTE(bill): Symbol tables
|
||||
struct CheckerInfo {
|
||||
Map<TypeAndValue> types; // Key: AstNode * | Expression -> Type (and value)
|
||||
Map<Entity *> definitions; // Key: AstNode * | Identifier -> Entity
|
||||
Map<Entity *> uses; // Key: AstNode * | Identifier -> Entity
|
||||
Map<Scope *> scopes; // Key: AstNode * | Node -> Scope
|
||||
Map<ExpressionInfo> untyped; // Key: AstNode * | Expression -> ExpressionInfo
|
||||
Map<DeclInfo *> entities; // Key: Entity *
|
||||
Map<Entity *> foreign_procs; // Key: String
|
||||
Map<AstFile *> files; // Key: String (full path)
|
||||
Map<isize> type_info_map; // Key: Type *
|
||||
isize type_info_count;
|
||||
Entity * implicit_values[ImplicitValue_Count];
|
||||
MapTypeAndValue types; // Key: AstNode * | Expression -> Type (and value)
|
||||
MapEntity definitions; // Key: AstNode * | Identifier -> Entity
|
||||
MapEntity uses; // Key: AstNode * | Identifier -> Entity
|
||||
MapScope scopes; // Key: AstNode * | Node -> Scope
|
||||
MapExprInfo untyped; // Key: AstNode * | Expression -> ExprInfo
|
||||
MapDeclInfo entities; // Key: Entity *
|
||||
MapEntity foreign_procs; // Key: String
|
||||
MapAstFile files; // Key: String (full path)
|
||||
MapIsize type_info_map; // Key: Type *
|
||||
isize type_info_count;
|
||||
Entity * implicit_values[ImplicitValue_Count];
|
||||
};
|
||||
|
||||
struct Checker {
|
||||
@@ -221,7 +254,7 @@ struct Checker {
|
||||
CheckerContext context;
|
||||
|
||||
Array(Type *) proc_stack;
|
||||
b32 in_defer; // TODO(bill): Actually handle correctly
|
||||
bool in_defer; // TODO(bill): Actually handle correctly
|
||||
};
|
||||
|
||||
struct CycleChecker {
|
||||
@@ -252,7 +285,7 @@ void cycle_checker_destroy(CycleChecker *cc) {
|
||||
|
||||
void init_declaration_info(DeclInfo *d, Scope *scope) {
|
||||
d->scope = scope;
|
||||
map_init(&d->deps, heap_allocator());
|
||||
map_bool_init(&d->deps, heap_allocator());
|
||||
}
|
||||
|
||||
DeclInfo *make_declaration_info(gbAllocator a, Scope *scope) {
|
||||
@@ -262,10 +295,10 @@ DeclInfo *make_declaration_info(gbAllocator a, Scope *scope) {
|
||||
}
|
||||
|
||||
void destroy_declaration_info(DeclInfo *d) {
|
||||
map_destroy(&d->deps);
|
||||
map_bool_destroy(&d->deps);
|
||||
}
|
||||
|
||||
b32 decl_info_has_init(DeclInfo *d) {
|
||||
bool decl_info_has_init(DeclInfo *d) {
|
||||
if (d->init_expr != NULL) {
|
||||
return true;
|
||||
}
|
||||
@@ -286,8 +319,8 @@ b32 decl_info_has_init(DeclInfo *d) {
|
||||
Scope *make_scope(Scope *parent, gbAllocator allocator) {
|
||||
Scope *s = gb_alloc_item(allocator, Scope);
|
||||
s->parent = parent;
|
||||
map_init(&s->elements, heap_allocator());
|
||||
map_init(&s->implicit, heap_allocator());
|
||||
map_entity_init(&s->elements, heap_allocator());
|
||||
map_entity_init(&s->implicit, heap_allocator());
|
||||
array_init(&s->shared, heap_allocator());
|
||||
array_init(&s->imported, heap_allocator());
|
||||
|
||||
@@ -313,8 +346,8 @@ void destroy_scope(Scope *scope) {
|
||||
destroy_scope(child);
|
||||
}
|
||||
|
||||
map_destroy(&scope->elements);
|
||||
map_destroy(&scope->implicit);
|
||||
map_entity_destroy(&scope->elements);
|
||||
map_entity_destroy(&scope->implicit);
|
||||
array_free(&scope->shared);
|
||||
array_free(&scope->imported);
|
||||
|
||||
@@ -324,7 +357,7 @@ void destroy_scope(Scope *scope) {
|
||||
void add_scope(Checker *c, AstNode *node, Scope *scope) {
|
||||
GB_ASSERT(node != NULL);
|
||||
GB_ASSERT(scope != NULL);
|
||||
map_set(&c->info.scopes, hash_pointer(node), scope);
|
||||
map_scope_set(&c->info.scopes, hash_pointer(node), scope);
|
||||
}
|
||||
|
||||
|
||||
@@ -347,10 +380,10 @@ void check_close_scope(Checker *c) {
|
||||
}
|
||||
|
||||
void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entity **entity_) {
|
||||
b32 gone_thru_proc = false;
|
||||
bool gone_thru_proc = false;
|
||||
HashKey key = hash_string(name);
|
||||
for (Scope *s = scope; s != NULL; s = s->parent) {
|
||||
Entity **found = map_get(&s->elements, key);
|
||||
Entity **found = map_entity_get(&s->elements, key);
|
||||
if (found) {
|
||||
Entity *e = *found;
|
||||
if (gone_thru_proc) {
|
||||
@@ -372,7 +405,7 @@ void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entit
|
||||
// Check shared scopes - i.e. other files @ global scope
|
||||
for_array(i, s->shared) {
|
||||
Scope *shared = s->shared.e[i];
|
||||
Entity **found = map_get(&shared->elements, key);
|
||||
Entity **found = map_entity_get(&shared->elements, key);
|
||||
if (found) {
|
||||
Entity *e = *found;
|
||||
if (e->kind == Entity_Variable &&
|
||||
@@ -409,12 +442,12 @@ Entity *scope_lookup_entity(Scope *s, String name) {
|
||||
|
||||
Entity *current_scope_lookup_entity(Scope *s, String name) {
|
||||
HashKey key = hash_string(name);
|
||||
Entity **found = map_get(&s->elements, key);
|
||||
Entity **found = map_entity_get(&s->elements, key);
|
||||
if (found) {
|
||||
return *found;
|
||||
}
|
||||
for_array(i, s->shared) {
|
||||
Entity **found = map_get(&s->shared.e[i]->elements, key);
|
||||
Entity **found = map_entity_get(&s->shared.e[i]->elements, key);
|
||||
if (found) {
|
||||
return *found;
|
||||
}
|
||||
@@ -427,11 +460,11 @@ Entity *current_scope_lookup_entity(Scope *s, String name) {
|
||||
Entity *scope_insert_entity(Scope *s, Entity *entity) {
|
||||
String name = entity->token.string;
|
||||
HashKey key = hash_string(name);
|
||||
Entity **found = map_get(&s->elements, key);
|
||||
Entity **found = map_entity_get(&s->elements, key);
|
||||
if (found) {
|
||||
return *found;
|
||||
}
|
||||
map_set(&s->elements, key, entity);
|
||||
map_entity_set(&s->elements, key, entity);
|
||||
if (entity->scope == NULL) {
|
||||
entity->scope = s;
|
||||
}
|
||||
@@ -460,7 +493,7 @@ void check_scope_usage(Checker *c, Scope *scope) {
|
||||
|
||||
|
||||
void add_dependency(DeclInfo *d, Entity *e) {
|
||||
map_set(&d->deps, hash_pointer(e), cast(b32)true);
|
||||
map_bool_set(&d->deps, hash_pointer(e), cast(bool)true);
|
||||
}
|
||||
|
||||
void add_declaration_dependency(Checker *c, Entity *e) {
|
||||
@@ -468,7 +501,7 @@ void add_declaration_dependency(Checker *c, Entity *e) {
|
||||
return;
|
||||
}
|
||||
if (c->context.decl != NULL) {
|
||||
auto found = map_get(&c->info.entities, hash_pointer(e));
|
||||
DeclInfo **found = map_decl_info_get(&c->info.entities, hash_pointer(e));
|
||||
if (found) {
|
||||
add_dependency(c->context.decl, e);
|
||||
}
|
||||
@@ -530,35 +563,33 @@ void init_universal_scope(void) {
|
||||
|
||||
void init_checker_info(CheckerInfo *i) {
|
||||
gbAllocator a = heap_allocator();
|
||||
map_init(&i->types, a);
|
||||
map_init(&i->definitions, a);
|
||||
map_init(&i->uses, a);
|
||||
map_init(&i->scopes, a);
|
||||
map_init(&i->entities, a);
|
||||
map_init(&i->untyped, a);
|
||||
map_init(&i->foreign_procs, a);
|
||||
map_init(&i->type_info_map, a);
|
||||
map_init(&i->files, a);
|
||||
map_tav_init(&i->types, a);
|
||||
map_entity_init(&i->definitions, a);
|
||||
map_entity_init(&i->uses, a);
|
||||
map_scope_init(&i->scopes, a);
|
||||
map_decl_info_init(&i->entities, a);
|
||||
map_expr_info_init(&i->untyped, a);
|
||||
map_entity_init(&i->foreign_procs, a);
|
||||
map_isize_init(&i->type_info_map, a);
|
||||
map_ast_file_init(&i->files, a);
|
||||
i->type_info_count = 0;
|
||||
|
||||
}
|
||||
|
||||
void destroy_checker_info(CheckerInfo *i) {
|
||||
map_destroy(&i->types);
|
||||
map_destroy(&i->definitions);
|
||||
map_destroy(&i->uses);
|
||||
map_destroy(&i->scopes);
|
||||
map_destroy(&i->entities);
|
||||
map_destroy(&i->untyped);
|
||||
map_destroy(&i->foreign_procs);
|
||||
map_destroy(&i->type_info_map);
|
||||
map_destroy(&i->files);
|
||||
map_tav_destroy(&i->types);
|
||||
map_entity_destroy(&i->definitions);
|
||||
map_entity_destroy(&i->uses);
|
||||
map_scope_destroy(&i->scopes);
|
||||
map_decl_info_destroy(&i->entities);
|
||||
map_expr_info_destroy(&i->untyped);
|
||||
map_entity_destroy(&i->foreign_procs);
|
||||
map_isize_destroy(&i->type_info_map);
|
||||
map_ast_file_destroy(&i->files);
|
||||
}
|
||||
|
||||
|
||||
void init_checker(Checker *c, Parser *parser, BaseTypeSizes sizes) {
|
||||
PROF_PROC();
|
||||
|
||||
gbAllocator a = heap_allocator();
|
||||
|
||||
c->parser = parser;
|
||||
@@ -598,18 +629,18 @@ void destroy_checker(Checker *c) {
|
||||
|
||||
|
||||
TypeAndValue *type_and_value_of_expression(CheckerInfo *i, AstNode *expression) {
|
||||
TypeAndValue *found = map_get(&i->types, hash_pointer(expression));
|
||||
TypeAndValue *found = map_tav_get(&i->types, hash_pointer(expression));
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
Entity *entity_of_ident(CheckerInfo *i, AstNode *identifier) {
|
||||
if (identifier->kind == AstNode_Ident) {
|
||||
Entity **found = map_get(&i->definitions, hash_pointer(identifier));
|
||||
Entity **found = map_entity_get(&i->definitions, hash_pointer(identifier));
|
||||
if (found) {
|
||||
return *found;
|
||||
}
|
||||
found = map_get(&i->uses, hash_pointer(identifier));
|
||||
found = map_entity_get(&i->uses, hash_pointer(identifier));
|
||||
if (found) {
|
||||
return *found;
|
||||
}
|
||||
@@ -633,8 +664,8 @@ Type *type_of_expr(CheckerInfo *i, AstNode *expression) {
|
||||
}
|
||||
|
||||
|
||||
void add_untyped(CheckerInfo *i, AstNode *expression, b32 lhs, AddressingMode mode, Type *basic_type, ExactValue value) {
|
||||
map_set(&i->untyped, hash_pointer(expression), make_expression_info(lhs, mode, basic_type, value));
|
||||
void add_untyped(CheckerInfo *i, AstNode *expression, bool lhs, AddressingMode mode, Type *basic_type, ExactValue value) {
|
||||
map_expr_info_set(&i->untyped, hash_pointer(expression), make_expr_info(lhs, mode, basic_type, value));
|
||||
}
|
||||
|
||||
void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode, Type *type, ExactValue value) {
|
||||
@@ -656,7 +687,7 @@ void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode
|
||||
tv.type = type;
|
||||
tv.value = value;
|
||||
tv.mode = mode;
|
||||
map_set(&i->types, hash_pointer(expression), tv);
|
||||
map_tav_set(&i->types, hash_pointer(expression), tv);
|
||||
}
|
||||
|
||||
void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity) {
|
||||
@@ -664,13 +695,13 @@ void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity)
|
||||
if (identifier->kind == AstNode_Ident) {
|
||||
GB_ASSERT(identifier->kind == AstNode_Ident);
|
||||
HashKey key = hash_pointer(identifier);
|
||||
map_set(&i->definitions, key, entity);
|
||||
map_entity_set(&i->definitions, key, entity);
|
||||
} else {
|
||||
// NOTE(bill): Error should handled elsewhere
|
||||
}
|
||||
}
|
||||
|
||||
b32 add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) {
|
||||
bool add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) {
|
||||
if (str_ne(entity->token.string, str_lit("_"))) {
|
||||
Entity *insert_entity = scope_insert_entity(scope, entity);
|
||||
if (insert_entity) {
|
||||
@@ -708,7 +739,7 @@ void add_entity_use(Checker *c, AstNode *identifier, Entity *entity) {
|
||||
if (identifier->kind != AstNode_Ident) {
|
||||
return;
|
||||
}
|
||||
map_set(&c->info.uses, hash_pointer(identifier), entity);
|
||||
map_entity_set(&c->info.uses, hash_pointer(identifier), entity);
|
||||
add_declaration_dependency(c, entity); // TODO(bill): Should this be here?
|
||||
}
|
||||
|
||||
@@ -716,7 +747,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(str_eq(identifier->Ident.string, e->token.string));
|
||||
add_entity(c, e->scope, identifier, e);
|
||||
map_set(&c->info.entities, hash_pointer(e), d);
|
||||
map_decl_info_set(&c->info.entities, hash_pointer(e), d);
|
||||
}
|
||||
|
||||
void add_type_info_type(Checker *c, Type *t) {
|
||||
@@ -728,7 +759,7 @@ void add_type_info_type(Checker *c, Type *t) {
|
||||
return; // Could be nil
|
||||
}
|
||||
|
||||
if (map_get(&c->info.type_info_map, hash_pointer(t)) != NULL) {
|
||||
if (map_isize_get(&c->info.type_info_map, hash_pointer(t)) != NULL) {
|
||||
// Types have already been added
|
||||
return;
|
||||
}
|
||||
@@ -749,7 +780,7 @@ void add_type_info_type(Checker *c, Type *t) {
|
||||
ti_index = c->info.type_info_count;
|
||||
c->info.type_info_count++;
|
||||
}
|
||||
map_set(&c->info.type_info_map, hash_pointer(t), ti_index);
|
||||
map_isize_set(&c->info.type_info_map, hash_pointer(t), ti_index);
|
||||
|
||||
|
||||
|
||||
@@ -873,17 +904,17 @@ void add_curr_ast_file(Checker *c, AstFile *file) {
|
||||
|
||||
|
||||
|
||||
void add_dependency_to_map(Map<Entity *> *map, CheckerInfo *info, Entity *node) {
|
||||
void add_dependency_to_map(MapEntity *map, CheckerInfo *info, Entity *node) {
|
||||
if (node == NULL) {
|
||||
return;
|
||||
}
|
||||
if (map_get(map, hash_pointer(node)) != NULL) {
|
||||
if (map_entity_get(map, hash_pointer(node)) != NULL) {
|
||||
return;
|
||||
}
|
||||
map_set(map, hash_pointer(node), node);
|
||||
map_entity_set(map, hash_pointer(node), node);
|
||||
|
||||
|
||||
DeclInfo **found = map_get(&info->entities, hash_pointer(node));
|
||||
DeclInfo **found = map_decl_info_get(&info->entities, hash_pointer(node));
|
||||
if (found == NULL) {
|
||||
return;
|
||||
}
|
||||
@@ -895,9 +926,9 @@ void add_dependency_to_map(Map<Entity *> *map, CheckerInfo *info, Entity *node)
|
||||
}
|
||||
}
|
||||
|
||||
Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
|
||||
Map<Entity *> map = {}; // Key: Entity *
|
||||
map_init(&map, heap_allocator());
|
||||
MapEntity generate_minimum_dependency_map(CheckerInfo *info, Entity *start) {
|
||||
MapEntity map = {}; // Key: Entity *
|
||||
map_entity_init(&map, heap_allocator());
|
||||
|
||||
for_array(i, info->entities.entries) {
|
||||
auto *entry = &info->entities.entries.e[i];
|
||||
@@ -921,9 +952,6 @@ Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start)
|
||||
#include "stmt.cpp"
|
||||
|
||||
void init_preload_types(Checker *c) {
|
||||
PROF_PROC();
|
||||
|
||||
|
||||
if (t_type_info == NULL) {
|
||||
Entity *e = current_scope_lookup_entity(c->global_scope, str_lit("Type_Info"));
|
||||
if (e == NULL) {
|
||||
@@ -994,7 +1022,6 @@ void add_implicit_value(Checker *c, ImplicitValueId id, String name, String back
|
||||
|
||||
|
||||
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.e[i];
|
||||
Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
|
||||
@@ -1026,8 +1053,8 @@ void check_parsed_files(Checker *c) {
|
||||
AstNodeArray import_decls;
|
||||
array_init(&import_decls, heap_allocator());
|
||||
|
||||
Map<Scope *> file_scopes; // Key: String (fullpath)
|
||||
map_init(&file_scopes, heap_allocator());
|
||||
MapScope file_scopes; // Key: String (fullpath)
|
||||
map_scope_init(&file_scopes, heap_allocator());
|
||||
|
||||
// Map full filepaths to Scopes
|
||||
for_array(i, c->parser->files) {
|
||||
@@ -1050,14 +1077,12 @@ void check_parsed_files(Checker *c) {
|
||||
f->scope = scope;
|
||||
f->decl_info = make_declaration_info(c->allocator, f->scope);
|
||||
HashKey key = hash_string(f->tokenizer.fullpath);
|
||||
map_set(&file_scopes, key, scope);
|
||||
map_set(&c->info.files, key, f);
|
||||
map_scope_set(&file_scopes, key, scope);
|
||||
map_ast_file_set(&c->info.files, key, f);
|
||||
}
|
||||
|
||||
// Collect Entities
|
||||
for_array(i, c->parser->files) {
|
||||
PROF_SCOPED("Collect Entities");
|
||||
|
||||
AstFile *f = &c->parser->files.e[i];
|
||||
add_curr_ast_file(c, f);
|
||||
|
||||
@@ -1165,8 +1190,6 @@ void check_parsed_files(Checker *c) {
|
||||
}
|
||||
|
||||
for_array(i, c->parser->files) {
|
||||
PROF_SCOPED("Import Entities");
|
||||
|
||||
AstFile *f = &c->parser->files.e[i];
|
||||
add_curr_ast_file(c, f);
|
||||
|
||||
@@ -1180,7 +1203,7 @@ void check_parsed_files(Checker *c) {
|
||||
ast_node(id, ImportDecl, decl);
|
||||
|
||||
HashKey key = hash_string(id->fullpath);
|
||||
auto found = map_get(&file_scopes, key);
|
||||
auto found = map_scope_get(&file_scopes, key);
|
||||
GB_ASSERT_MSG(found != NULL, "Unable to find scope for file: %.*s", LIT(id->fullpath));
|
||||
Scope *scope = *found;
|
||||
|
||||
@@ -1189,7 +1212,7 @@ void check_parsed_files(Checker *c) {
|
||||
continue;
|
||||
}
|
||||
|
||||
b32 previously_added = false;
|
||||
bool previously_added = false;
|
||||
for_array(import_index, file_scope->imported) {
|
||||
Scope *prev = file_scope->imported.e[import_index];
|
||||
if (prev == scope) {
|
||||
@@ -1216,7 +1239,7 @@ void check_parsed_files(Checker *c) {
|
||||
add_entity(c, file_scope, NULL, e);
|
||||
if (!id->is_load) { // `#import`ed entities don't get exported
|
||||
HashKey key = hash_string(e->token.string);
|
||||
map_set(&file_scope->implicit, key, e);
|
||||
map_entity_set(&file_scope->implicit, key, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1295,8 +1318,8 @@ void check_parsed_files(Checker *c) {
|
||||
ProcedureInfo *pi = &c->procs.e[i];
|
||||
add_curr_ast_file(c, pi->file);
|
||||
|
||||
b32 bounds_check = (pi->tags & ProcTag_bounds_check) != 0;
|
||||
b32 no_bounds_check = (pi->tags & ProcTag_no_bounds_check) != 0;
|
||||
bool bounds_check = (pi->tags & ProcTag_bounds_check) != 0;
|
||||
bool no_bounds_check = (pi->tags & ProcTag_no_bounds_check) != 0;
|
||||
|
||||
CheckerContext prev_context = c->context;
|
||||
|
||||
@@ -1315,12 +1338,10 @@ void check_parsed_files(Checker *c) {
|
||||
|
||||
// Add untyped expression values
|
||||
for_array(i, c->info.untyped.entries) {
|
||||
PROF_SCOPED("Untyped expr values");
|
||||
|
||||
auto *entry = &c->info.untyped.entries.e[i];
|
||||
HashKey key = entry->key;
|
||||
AstNode *expr = cast(AstNode *)cast(uintptr)key.key;
|
||||
ExpressionInfo *info = &entry->value;
|
||||
ExprInfo *info = &entry->value;
|
||||
if (info != NULL && expr != NULL) {
|
||||
if (is_type_typed(info->type)) {
|
||||
compiler_error("%s (type %s) is typed!", expr_to_string(expr), type_to_string(info->type));
|
||||
@@ -1366,7 +1387,7 @@ void check_parsed_files(Checker *c) {
|
||||
// gb_printf("%td - %s\n", e->value, type_to_string(prev_type));
|
||||
// }
|
||||
|
||||
map_destroy(&file_scopes);
|
||||
map_scope_destroy(&file_scopes);
|
||||
array_free(&import_decls);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
b32 check_is_terminating(AstNode *node);
|
||||
bool check_is_terminating(AstNode *node);
|
||||
void check_stmt (Checker *c, AstNode *node, u32 flags);
|
||||
void check_stmt_list (Checker *c, AstNodeArray stmts, u32 flags);
|
||||
void check_type_decl (Checker *c, Entity *e, AstNode *type_expr, Type *def, CycleChecker *cycle_checker);
|
||||
@@ -8,8 +8,6 @@ void check_var_decl (Checker *c, Entity *e, Entity **entities, isize entity_
|
||||
|
||||
// NOTE(bill): `content_name` is for debugging and error messages
|
||||
Type *check_init_variable(Checker *c, Entity *e, Operand *operand, String context_name) {
|
||||
PROF_PROC();
|
||||
|
||||
if (operand->mode == Addressing_Invalid ||
|
||||
operand->type == t_invalid ||
|
||||
e->type == t_invalid) {
|
||||
@@ -58,8 +56,6 @@ Type *check_init_variable(Checker *c, Entity *e, Operand *operand, String contex
|
||||
}
|
||||
|
||||
void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArray inits, String context_name) {
|
||||
PROF_PROC();
|
||||
|
||||
if ((lhs == NULL || lhs_count == 0) && inits.count == 0) {
|
||||
return;
|
||||
}
|
||||
@@ -109,14 +105,12 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra
|
||||
|
||||
|
||||
void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type, CycleChecker *cycle_checker) {
|
||||
PROF_PROC();
|
||||
|
||||
if (e->type != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (d == NULL) {
|
||||
DeclInfo **found = map_get(&c->info.entities, hash_pointer(e));
|
||||
DeclInfo **found = map_decl_info_get(&c->info.entities, hash_pointer(e));
|
||||
if (found) {
|
||||
d = *found;
|
||||
} else {
|
||||
@@ -153,8 +147,6 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type, Cyc
|
||||
|
||||
|
||||
void check_var_decl_node(Checker *c, AstNode *node) {
|
||||
PROF_PROC();
|
||||
|
||||
ast_node(vd, VarDecl, node);
|
||||
isize entity_count = vd->names.count;
|
||||
isize entity_index = 0;
|
||||
@@ -224,8 +216,6 @@ void check_var_decl_node(Checker *c, AstNode *node) {
|
||||
|
||||
|
||||
void check_init_constant(Checker *c, Entity *e, Operand *operand) {
|
||||
PROF_PROC();
|
||||
|
||||
if (operand->mode == Addressing_Invalid ||
|
||||
operand->type == t_invalid ||
|
||||
e->type == t_invalid) {
|
||||
@@ -269,8 +259,6 @@ void check_init_constant(Checker *c, Entity *e, Operand *operand) {
|
||||
|
||||
|
||||
void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init_expr) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(e->type == NULL);
|
||||
|
||||
if (e->flags & EntityFlag_Visited) {
|
||||
@@ -300,8 +288,6 @@ void check_const_decl(Checker *c, Entity *e, AstNode *type_expr, AstNode *init_e
|
||||
}
|
||||
|
||||
void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, CycleChecker *cycle_checker) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(e->type == NULL);
|
||||
Type *named = make_type_named(c->allocator, e->token.string, NULL, e);
|
||||
named->Named.type_name = e;
|
||||
@@ -326,7 +312,7 @@ void check_type_decl(Checker *c, Entity *e, AstNode *type_expr, Type *def, Cycle
|
||||
}
|
||||
|
||||
|
||||
b32 are_signatures_similar_enough(Type *a_, Type *b_) {
|
||||
bool are_signatures_similar_enough(Type *a_, Type *b_) {
|
||||
GB_ASSERT(a_->kind == Type_Proc);
|
||||
GB_ASSERT(b_->kind == Type_Proc);
|
||||
auto *a = &a_->Proc;
|
||||
@@ -365,8 +351,6 @@ b32 are_signatures_similar_enough(Type *a_, Type *b_) {
|
||||
}
|
||||
|
||||
void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(e->type == NULL);
|
||||
|
||||
Type *proc_type = make_type_proc(c->allocator, e->scope, NULL, 0, NULL, 0, false);
|
||||
@@ -376,10 +360,10 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
check_open_scope(c, pd->type);
|
||||
check_procedure_type(c, proc_type, pd->type);
|
||||
|
||||
b32 is_foreign = (pd->tags & ProcTag_foreign) != 0;
|
||||
b32 is_link_name = (pd->tags & ProcTag_link_name) != 0;
|
||||
b32 is_inline = (pd->tags & ProcTag_inline) != 0;
|
||||
b32 is_no_inline = (pd->tags & ProcTag_no_inline) != 0;
|
||||
bool is_foreign = (pd->tags & ProcTag_foreign) != 0;
|
||||
bool is_link_name = (pd->tags & ProcTag_link_name) != 0;
|
||||
bool is_inline = (pd->tags & ProcTag_inline) != 0;
|
||||
bool is_no_inline = (pd->tags & ProcTag_no_inline) != 0;
|
||||
|
||||
if ((d->scope->is_file || d->scope->is_global) &&
|
||||
str_eq(e->token.string, str_lit("main"))) {
|
||||
@@ -425,7 +409,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
name = proc_decl->foreign_name;
|
||||
}
|
||||
HashKey key = hash_string(name);
|
||||
auto *found = map_get(fp, key);
|
||||
Entity **found = map_entity_get(fp, key);
|
||||
if (found) {
|
||||
Entity *f = *found;
|
||||
TokenPos pos = f->token.pos;
|
||||
@@ -438,7 +422,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
LIT(name), LIT(pos.file), pos.line, pos.column);
|
||||
}
|
||||
} else {
|
||||
map_set(fp, key, e);
|
||||
map_entity_set(fp, key, e);
|
||||
}
|
||||
} else if (is_link_name) {
|
||||
auto *fp = &c->info.foreign_procs;
|
||||
@@ -446,7 +430,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
String name = proc_decl->link_name;
|
||||
|
||||
HashKey key = hash_string(name);
|
||||
auto *found = map_get(fp, key);
|
||||
Entity **found = map_entity_get(fp, key);
|
||||
if (found) {
|
||||
Entity *f = *found;
|
||||
TokenPos pos = f->token.pos;
|
||||
@@ -455,7 +439,7 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
"\tother at %.*s(%td:%td)",
|
||||
LIT(name), LIT(pos.file), pos.line, pos.column);
|
||||
} else {
|
||||
map_set(fp, key, e);
|
||||
map_entity_set(fp, key, e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -463,8 +447,6 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d) {
|
||||
}
|
||||
|
||||
void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count, AstNode *type_expr, AstNode *init_expr) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(e->type == NULL);
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
|
||||
@@ -520,7 +502,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod
|
||||
String name = e->token.string;
|
||||
Type *t = base_type(type_deref(e->type));
|
||||
if (is_type_struct(t) || is_type_raw_union(t)) {
|
||||
Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
|
||||
Scope **found = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node));
|
||||
GB_ASSERT(found != NULL);
|
||||
for_array(i, (*found)->elements.entries) {
|
||||
Entity *f = (*found)->elements.entries.e[i].value;
|
||||
|
||||
@@ -66,7 +66,7 @@ struct Entity {
|
||||
String path;
|
||||
String name;
|
||||
Scope *scope;
|
||||
b32 used;
|
||||
bool used;
|
||||
} ImportName;
|
||||
struct {} Nil;
|
||||
struct {
|
||||
@@ -77,7 +77,7 @@ struct Entity {
|
||||
};
|
||||
};
|
||||
|
||||
b32 is_entity_exported(Entity *e) {
|
||||
bool is_entity_exported(Entity *e) {
|
||||
if (e->kind == Entity_ImportName) {
|
||||
return false;
|
||||
}
|
||||
@@ -125,7 +125,7 @@ Entity *make_entity_type_name(gbAllocator a, Scope *scope, Token token, Type *ty
|
||||
return entity;
|
||||
}
|
||||
|
||||
Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type, b32 anonymous) {
|
||||
Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type, bool anonymous) {
|
||||
Entity *entity = make_entity_variable(a, scope, token, type);
|
||||
entity->flags |= EntityFlag_Used;
|
||||
entity->flags |= EntityFlag_Anonymous*(anonymous != 0);
|
||||
@@ -133,7 +133,7 @@ Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type,
|
||||
return entity;
|
||||
}
|
||||
|
||||
Entity *make_entity_field(gbAllocator a, Scope *scope, Token token, Type *type, b32 anonymous, i32 field_src_index) {
|
||||
Entity *make_entity_field(gbAllocator a, Scope *scope, Token token, Type *type, bool anonymous, i32 field_src_index) {
|
||||
Entity *entity = make_entity_variable(a, scope, token, type);
|
||||
entity->Variable.field_src_index = field_src_index;
|
||||
entity->Variable.field_index = field_src_index;
|
||||
|
||||
@@ -6,22 +6,22 @@ Type * check_type (Checker *c, AstNode *expression, Type *named
|
||||
void check_type_decl (Checker *c, Entity *e, AstNode *type_expr, Type *def, CycleChecker *cycle_checker);
|
||||
Entity * check_selector (Checker *c, Operand *operand, AstNode *node);
|
||||
void check_not_tuple (Checker *c, Operand *operand);
|
||||
b32 check_value_is_expressible(Checker *c, ExactValue in_value, Type *type, ExactValue *out_value);
|
||||
bool check_value_is_expressible(Checker *c, ExactValue in_value, Type *type, ExactValue *out_value);
|
||||
void convert_to_typed (Checker *c, Operand *operand, Type *target_type, i32 level = 0);
|
||||
gbString expr_to_string (AstNode *expression);
|
||||
void check_entity_decl (Checker *c, Entity *e, DeclInfo *decl, Type *named_type, CycleChecker *cycle_checker = NULL);
|
||||
void check_proc_body (Checker *c, Token token, DeclInfo *decl, Type *type, AstNode *body);
|
||||
void update_expr_type (Checker *c, AstNode *e, Type *type, b32 final);
|
||||
void update_expr_type (Checker *c, AstNode *e, Type *type, bool final);
|
||||
|
||||
|
||||
|
||||
b32 check_is_assignable_to_using_subtype(Type *dst, Type *src) {
|
||||
bool check_is_assignable_to_using_subtype(Type *dst, Type *src) {
|
||||
Type *prev_src = src;
|
||||
// Type *prev_dst = dst;
|
||||
src = base_type(type_deref(src));
|
||||
// dst = base_type(type_deref(dst));
|
||||
b32 src_is_ptr = src != prev_src;
|
||||
// b32 dst_is_ptr = dst != prev_dst;
|
||||
bool src_is_ptr = src != prev_src;
|
||||
// bool dst_is_ptr = dst != prev_dst;
|
||||
|
||||
if (is_type_struct(src)) {
|
||||
for (isize i = 0; i < src->Record.field_count; i++) {
|
||||
@@ -35,7 +35,7 @@ b32 check_is_assignable_to_using_subtype(Type *dst, Type *src) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
b32 ok = check_is_assignable_to_using_subtype(dst, f->type);
|
||||
bool ok = check_is_assignable_to_using_subtype(dst, f->type);
|
||||
if (ok) {
|
||||
return true;
|
||||
}
|
||||
@@ -46,9 +46,7 @@ b32 check_is_assignable_to_using_subtype(Type *dst, Type *src) {
|
||||
}
|
||||
|
||||
|
||||
b32 check_is_assignable_to(Checker *c, Operand *operand, Type *type, b32 is_argument = false) {
|
||||
PROF_PROC();
|
||||
|
||||
bool check_is_assignable_to(Checker *c, Operand *operand, Type *type, bool is_argument = false) {
|
||||
if (operand->mode == Addressing_Invalid ||
|
||||
type == t_invalid) {
|
||||
return true;
|
||||
@@ -152,9 +150,7 @@ b32 check_is_assignable_to(Checker *c, Operand *operand, Type *type, b32 is_argu
|
||||
|
||||
|
||||
// NOTE(bill): `content_name` is for debugging and error messages
|
||||
void check_assignment(Checker *c, Operand *operand, Type *type, String context_name, b32 is_argument = false) {
|
||||
PROF_PROC();
|
||||
|
||||
void check_assignment(Checker *c, Operand *operand, Type *type, String context_name, bool is_argument = false) {
|
||||
check_not_tuple(c, operand);
|
||||
if (operand->mode == Addressing_Invalid) {
|
||||
return;
|
||||
@@ -211,9 +207,7 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
|
||||
}
|
||||
|
||||
|
||||
void populate_using_entity_map(Checker *c, AstNode *node, Type *t, Map<Entity *> *entity_map) {
|
||||
PROF_PROC();
|
||||
|
||||
void populate_using_entity_map(Checker *c, AstNode *node, Type *t, MapEntity *entity_map) {
|
||||
t = base_type(type_deref(t));
|
||||
gbString str = expr_to_string(node);
|
||||
|
||||
@@ -223,13 +217,13 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, Map<Entity *>
|
||||
GB_ASSERT(f->kind == Entity_Variable);
|
||||
String name = f->token.string;
|
||||
HashKey key = hash_string(name);
|
||||
Entity **found = map_get(entity_map, key);
|
||||
Entity **found = map_entity_get(entity_map, key);
|
||||
if (found != NULL) {
|
||||
Entity *e = *found;
|
||||
// TODO(bill): Better type error
|
||||
error(e->token, "`%.*s` is already declared in `%s`", LIT(name), str);
|
||||
} else {
|
||||
map_set(entity_map, key, f);
|
||||
map_entity_set(entity_map, key, f);
|
||||
add_entity(c, c->context.scope, NULL, f);
|
||||
if (f->flags & EntityFlag_Anonymous) {
|
||||
populate_using_entity_map(c, node, f->type, entity_map);
|
||||
@@ -247,12 +241,10 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
||||
Entity **fields, isize field_count,
|
||||
Entity **other_fields, isize other_field_count,
|
||||
CycleChecker *cycle_checker, String context) {
|
||||
PROF_PROC();
|
||||
|
||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||
|
||||
Map<Entity *> entity_map = {};
|
||||
map_init_with_reserve(&entity_map, c->tmp_allocator, 2*(field_count+other_field_count));
|
||||
MapEntity entity_map = {};
|
||||
map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*(field_count+other_field_count));
|
||||
|
||||
isize other_field_index = 0;
|
||||
Entity *using_index_expr = NULL;
|
||||
@@ -306,11 +298,11 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
||||
other_fields[other_field_index++] = e;
|
||||
} else {
|
||||
HashKey key = hash_string(name_token.string);
|
||||
if (map_get(&entity_map, key) != NULL) {
|
||||
if (map_entity_get(&entity_map, key) != NULL) {
|
||||
// TODO(bill): Scope checking already checks the declaration
|
||||
error(name_token, "`%.*s` is already declared in this structure", LIT(name_token.string));
|
||||
} else {
|
||||
map_set(&entity_map, key, e);
|
||||
map_entity_set(&entity_map, key, e);
|
||||
other_fields[other_field_index++] = e;
|
||||
}
|
||||
add_entity(c, c->context.scope, name, e);
|
||||
@@ -328,11 +320,11 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
||||
other_fields[other_field_index++] = e;
|
||||
} else {
|
||||
HashKey key = hash_string(name_token.string);
|
||||
if (map_get(&entity_map, key) != NULL) {
|
||||
if (map_entity_get(&entity_map, key) != NULL) {
|
||||
// TODO(bill): Scope checking already checks the declaration
|
||||
error(name_token, "`%.*s` is already declared in this structure", LIT(name_token.string));
|
||||
} else {
|
||||
map_set(&entity_map, key, e);
|
||||
map_entity_set(&entity_map, key, e);
|
||||
other_fields[other_field_index++] = e;
|
||||
}
|
||||
add_entity(c, c->context.scope, td->name, e);
|
||||
@@ -375,11 +367,11 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
||||
}
|
||||
|
||||
HashKey key = hash_string(name_token.string);
|
||||
if (map_get(&entity_map, key) != NULL) {
|
||||
if (map_entity_get(&entity_map, key) != NULL) {
|
||||
// TODO(bill): Scope checking already checks the declaration
|
||||
error(name_token, "`%.*s` is already declared in this union", LIT(name_token.string));
|
||||
} else {
|
||||
map_set(&entity_map, key, e);
|
||||
map_entity_set(&entity_map, key, e);
|
||||
fields[field_index++] = e;
|
||||
}
|
||||
add_entity_use(c, name, e);
|
||||
@@ -413,11 +405,11 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
||||
fields[field_index++] = e;
|
||||
} else {
|
||||
HashKey key = hash_string(name_token.string);
|
||||
if (map_get(&entity_map, key) != NULL) {
|
||||
if (map_entity_get(&entity_map, key) != NULL) {
|
||||
// TODO(bill): Scope checking already checks the declaration
|
||||
error(name_token, "`%.*s` is already declared in this type", LIT(name_token.string));
|
||||
} else {
|
||||
map_set(&entity_map, key, e);
|
||||
map_entity_set(&entity_map, key, e);
|
||||
fields[field_index++] = e;
|
||||
add_entity(c, c->context.scope, name, e);
|
||||
}
|
||||
@@ -431,7 +423,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
|
||||
if (!is_type_struct(t) && !is_type_raw_union(t)) {
|
||||
Token name_token = vd->names.e[0]->Ident;
|
||||
if (is_type_indexable(t)) {
|
||||
b32 ok = true;
|
||||
bool ok = true;
|
||||
for_array(emi, entity_map.entries) {
|
||||
Entity *e = entity_map.entries.e[emi].value;
|
||||
if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) {
|
||||
@@ -497,8 +489,6 @@ GB_COMPARE_PROC(cmp_struct_entity_size) {
|
||||
}
|
||||
|
||||
void check_struct_type(Checker *c, Type *struct_type, AstNode *node, CycleChecker *cycle_checker) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(is_type_struct(struct_type));
|
||||
ast_node(st, StructType, node);
|
||||
|
||||
@@ -563,8 +553,6 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, CycleChecke
|
||||
}
|
||||
|
||||
void check_union_type(Checker *c, Type *union_type, AstNode *node, CycleChecker *cycle_checker) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(is_type_union(union_type));
|
||||
ast_node(ut, UnionType, node);
|
||||
|
||||
@@ -599,8 +587,6 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node, CycleChecker
|
||||
}
|
||||
|
||||
void check_raw_union_type(Checker *c, Type *union_type, AstNode *node, CycleChecker *cycle_checker) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(node->kind == AstNode_RawUnionType);
|
||||
GB_ASSERT(is_type_raw_union(union_type));
|
||||
ast_node(ut, RawUnionType, node);
|
||||
@@ -657,8 +643,6 @@ GB_COMPARE_PROC(cmp_enum_order) {
|
||||
|
||||
|
||||
void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *node) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(node->kind == AstNode_EnumType);
|
||||
GB_ASSERT(is_type_enum(enum_type));
|
||||
ast_node(et, EnumType, node);
|
||||
@@ -693,8 +677,8 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
|
||||
|
||||
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));
|
||||
MapEntity entity_map = {};
|
||||
map_entity_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));;
|
||||
|
||||
@@ -749,11 +733,11 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
|
||||
}
|
||||
|
||||
HashKey key = hash_string(name_token.string);
|
||||
if (map_get(&entity_map, key)) {
|
||||
if (map_entity_get(&entity_map, key)) {
|
||||
// TODO(bill): Scope checking already checks the declaration
|
||||
error(name_token, "`%.*s` is already declared in this enumeration", LIT(name_token.string));
|
||||
} else {
|
||||
map_set(&entity_map, key, e);
|
||||
map_entity_set(&entity_map, key, e);
|
||||
add_entity(c, c->context.scope, NULL, e);
|
||||
fields[field_index++] = e;
|
||||
}
|
||||
@@ -777,14 +761,12 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod
|
||||
gb_temp_arena_memory_end(tmp);
|
||||
}
|
||||
|
||||
Type *check_get_params(Checker *c, Scope *scope, AstNodeArray params, b32 *is_variadic_) {
|
||||
PROF_PROC();
|
||||
|
||||
Type *check_get_params(Checker *c, Scope *scope, AstNodeArray params, bool *is_variadic_) {
|
||||
if (params.count == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b32 is_variadic = false;
|
||||
bool is_variadic = false;
|
||||
|
||||
Type *tuple = make_type_tuple(c->allocator);
|
||||
|
||||
@@ -843,8 +825,6 @@ Type *check_get_params(Checker *c, Scope *scope, AstNodeArray params, b32 *is_va
|
||||
}
|
||||
|
||||
Type *check_get_results(Checker *c, Scope *scope, AstNodeArray results) {
|
||||
PROF_PROC();
|
||||
|
||||
if (results.count == 0) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -870,11 +850,9 @@ Type *check_get_results(Checker *c, Scope *scope, AstNodeArray results) {
|
||||
|
||||
|
||||
void check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node) {
|
||||
PROF_PROC();
|
||||
|
||||
ast_node(pt, ProcType, proc_type_node);
|
||||
|
||||
b32 variadic = false;
|
||||
bool variadic = false;
|
||||
Type *params = check_get_params(c, c->context.scope, pt->params, &variadic);
|
||||
Type *results = check_get_results(c, c->context.scope, pt->results);
|
||||
|
||||
@@ -895,8 +873,6 @@ void check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node) {
|
||||
|
||||
|
||||
void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, CycleChecker *cycle_checker) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(n->kind == AstNode_Ident);
|
||||
o->mode = Addressing_Invalid;
|
||||
o->expr = n;
|
||||
@@ -1011,8 +987,6 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl
|
||||
}
|
||||
|
||||
i64 check_array_count(Checker *c, AstNode *e) {
|
||||
PROF_PROC();
|
||||
|
||||
if (e == NULL) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1040,8 +1014,6 @@ i64 check_array_count(Checker *c, AstNode *e) {
|
||||
}
|
||||
|
||||
Type *check_type(Checker *c, AstNode *e, Type *named_type, CycleChecker *cycle_checker) {
|
||||
PROF_PROC();
|
||||
|
||||
ExactValue null_value = {ExactValue_Invalid};
|
||||
Type *type = NULL;
|
||||
gbString err_str = NULL;
|
||||
@@ -1221,7 +1193,7 @@ end:
|
||||
}
|
||||
|
||||
|
||||
b32 check_unary_op(Checker *c, Operand *o, Token op) {
|
||||
bool 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;
|
||||
@@ -1257,7 +1229,7 @@ b32 check_unary_op(Checker *c, Operand *o, Token op) {
|
||||
return true;
|
||||
}
|
||||
|
||||
b32 check_binary_op(Checker *c, Operand *o, Token op) {
|
||||
bool check_binary_op(Checker *c, Operand *o, Token op) {
|
||||
// TODO(bill): Handle errors correctly
|
||||
Type *type = base_type(base_vector_type(o->type));
|
||||
switch (op.kind) {
|
||||
@@ -1331,9 +1303,7 @@ b32 check_binary_op(Checker *c, Operand *o, Token op) {
|
||||
return true;
|
||||
|
||||
}
|
||||
b32 check_value_is_expressible(Checker *c, ExactValue in_value, Type *type, ExactValue *out_value) {
|
||||
PROF_PROC();
|
||||
|
||||
bool check_value_is_expressible(Checker *c, ExactValue in_value, Type *type, ExactValue *out_value) {
|
||||
if (in_value.kind == ExactValue_Invalid) {
|
||||
// NOTE(bill): There's already been an error
|
||||
return true;
|
||||
@@ -1416,8 +1386,6 @@ b32 check_value_is_expressible(Checker *c, ExactValue in_value, Type *type, Exac
|
||||
}
|
||||
|
||||
void check_is_expressible(Checker *c, Operand *o, Type *type) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(type->kind == Type_Basic);
|
||||
GB_ASSERT(o->mode == Addressing_Constant);
|
||||
if (!check_value_is_expressible(c, o->value, type, &o->value)) {
|
||||
@@ -1439,7 +1407,7 @@ void check_is_expressible(Checker *c, Operand *o, Type *type) {
|
||||
}
|
||||
}
|
||||
|
||||
b32 check_is_expr_vector_index(Checker *c, AstNode *expr) {
|
||||
bool check_is_expr_vector_index(Checker *c, AstNode *expr) {
|
||||
// HACK(bill): Handle this correctly. Maybe with a custom AddressingMode
|
||||
expr = unparen_expr(expr);
|
||||
if (expr->kind == AstNode_IndexExpr) {
|
||||
@@ -1452,7 +1420,7 @@ b32 check_is_expr_vector_index(Checker *c, AstNode *expr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
b32 check_is_vector_elem(Checker *c, AstNode *expr) {
|
||||
bool check_is_vector_elem(Checker *c, AstNode *expr) {
|
||||
// HACK(bill): Handle this correctly. Maybe with a custom AddressingMode
|
||||
expr = unparen_expr(expr);
|
||||
if (expr->kind == AstNode_SelectorExpr) {
|
||||
@@ -1466,8 +1434,6 @@ b32 check_is_vector_elem(Checker *c, AstNode *expr) {
|
||||
}
|
||||
|
||||
void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
|
||||
PROF_PROC();
|
||||
|
||||
switch (op.kind) {
|
||||
case Token_Pointer: { // Pointer address
|
||||
if (o->mode != Addressing_Variable ||
|
||||
@@ -1487,7 +1453,7 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
|
||||
|
||||
case Token_Maybe: { // Make maybe
|
||||
Type *t = default_type(o->type);
|
||||
b32 is_value =
|
||||
bool is_value =
|
||||
o->mode == Addressing_Variable ||
|
||||
o->mode == Addressing_Value ||
|
||||
o->mode == Addressing_Constant;
|
||||
@@ -1543,8 +1509,6 @@ void check_unary_expr(Checker *c, Operand *o, Token op, AstNode *node) {
|
||||
}
|
||||
|
||||
void check_comparison(Checker *c, Operand *x, Operand *y, Token op) {
|
||||
PROF_PROC();
|
||||
|
||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||
|
||||
gbString err_str = NULL;
|
||||
@@ -1552,7 +1516,7 @@ void check_comparison(Checker *c, Operand *x, Operand *y, Token op) {
|
||||
if (check_is_assignable_to(c, x, y->type) ||
|
||||
check_is_assignable_to(c, y, x->type)) {
|
||||
Type *err_type = x->type;
|
||||
b32 defined = false;
|
||||
bool defined = false;
|
||||
switch (op.kind) {
|
||||
case Token_CmpEq:
|
||||
case Token_NotEq:
|
||||
@@ -1619,8 +1583,6 @@ void check_comparison(Checker *c, Operand *x, Operand *y, Token op) {
|
||||
}
|
||||
|
||||
void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(node->kind == AstNode_BinaryExpr);
|
||||
ast_node(be, BinaryExpr, node);
|
||||
|
||||
@@ -1629,7 +1591,7 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
|
||||
x_val = exact_value_to_integer(x->value);
|
||||
}
|
||||
|
||||
b32 x_is_untyped = is_type_untyped(x->type);
|
||||
bool 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);
|
||||
error(ast_node_token(node),
|
||||
@@ -1694,7 +1656,7 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
|
||||
}
|
||||
|
||||
if (x_is_untyped) {
|
||||
ExpressionInfo *info = map_get(&c->info.untyped, hash_pointer(x->expr));
|
||||
ExprInfo *info = map_expr_info_get(&c->info.untyped, hash_pointer(x->expr));
|
||||
if (info != NULL) {
|
||||
info->is_lhs = true;
|
||||
}
|
||||
@@ -1713,9 +1675,7 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
|
||||
x->mode = Addressing_Value;
|
||||
}
|
||||
|
||||
b32 check_is_castable_to(Checker *c, Operand *operand, Type *y) {
|
||||
PROF_PROC();
|
||||
|
||||
bool check_is_castable_to(Checker *c, Operand *operand, Type *y) {
|
||||
if (check_is_assignable_to(c, operand, y)) {
|
||||
return true;
|
||||
}
|
||||
@@ -1848,8 +1808,6 @@ Operand check_ptr_addition(Checker *c, TokenKind op, Operand *ptr, Operand *offs
|
||||
}
|
||||
|
||||
void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(node->kind == AstNode_BinaryExpr);
|
||||
Operand y_ = {}, *y = &y_;
|
||||
|
||||
@@ -1862,8 +1820,8 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
|
||||
return;
|
||||
}
|
||||
|
||||
b32 is_const_expr = x->mode == Addressing_Constant;
|
||||
b32 can_convert = false;
|
||||
bool is_const_expr = x->mode == Addressing_Constant;
|
||||
bool can_convert = false;
|
||||
|
||||
Type *bt = base_type(type);
|
||||
if (is_const_expr && is_type_constant_type(bt)) {
|
||||
@@ -2027,8 +1985,8 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
|
||||
return;
|
||||
}
|
||||
|
||||
b32 src_is_ptr = is_type_pointer(x->type);
|
||||
b32 dst_is_ptr = is_type_pointer(type);
|
||||
bool src_is_ptr = is_type_pointer(x->type);
|
||||
bool dst_is_ptr = is_type_pointer(type);
|
||||
Type *src = type_deref(x->type);
|
||||
Type *dst = type_deref(type);
|
||||
Type *bsrc = base_type(src);
|
||||
@@ -2050,7 +2008,7 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
|
||||
return;
|
||||
}
|
||||
|
||||
b32 ok = false;
|
||||
bool ok = false;
|
||||
for (isize i = 1; i < bsrc->Record.field_count; i++) {
|
||||
Entity *f = bsrc->Record.fields[i];
|
||||
if (are_types_identical(f->type, dst)) {
|
||||
@@ -2163,7 +2121,7 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
|
||||
case Token_ModEq:
|
||||
if ((x->mode == Addressing_Constant || is_type_integer(x->type)) &&
|
||||
y->mode == Addressing_Constant) {
|
||||
b32 fail = false;
|
||||
bool fail = false;
|
||||
switch (y->value.kind) {
|
||||
case ExactValue_Integer:
|
||||
if (y->value.value_integer == 0) {
|
||||
@@ -2226,11 +2184,9 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
|
||||
}
|
||||
|
||||
|
||||
void update_expr_type(Checker *c, AstNode *e, Type *type, b32 final) {
|
||||
PROF_PROC();
|
||||
|
||||
void update_expr_type(Checker *c, AstNode *e, Type *type, bool final) {
|
||||
HashKey key = hash_pointer(e);
|
||||
ExpressionInfo *found = map_get(&c->info.untyped, key);
|
||||
ExprInfo *found = map_expr_info_get(&c->info.untyped, key);
|
||||
if (found == NULL) {
|
||||
return;
|
||||
}
|
||||
@@ -2260,10 +2216,10 @@ void update_expr_type(Checker *c, AstNode *e, Type *type, b32 final) {
|
||||
|
||||
if (!final && is_type_untyped(type)) {
|
||||
found->type = base_type(type);
|
||||
map_set(&c->info.untyped, key, *found);
|
||||
map_expr_info_set(&c->info.untyped, key, *found);
|
||||
} else {
|
||||
ExpressionInfo old = *found;
|
||||
map_remove(&c->info.untyped, key);
|
||||
ExprInfo old = *found;
|
||||
map_expr_info_remove(&c->info.untyped, key);
|
||||
|
||||
if (old.is_lhs && !is_type_integer(type)) {
|
||||
gbString expr_str = expr_to_string(e);
|
||||
@@ -2279,7 +2235,7 @@ void update_expr_type(Checker *c, AstNode *e, Type *type, b32 final) {
|
||||
}
|
||||
|
||||
void update_expr_value(Checker *c, AstNode *e, ExactValue value) {
|
||||
ExpressionInfo *found = map_get(&c->info.untyped, hash_pointer(e));
|
||||
ExprInfo *found = map_expr_info_get(&c->info.untyped, hash_pointer(e));
|
||||
if (found) {
|
||||
found->value = value;
|
||||
}
|
||||
@@ -2306,8 +2262,6 @@ void convert_untyped_error(Checker *c, Operand *operand, Type *target_type) {
|
||||
}
|
||||
|
||||
void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT_NOT_NULL(target_type);
|
||||
if (operand->mode == Addressing_Invalid ||
|
||||
is_type_typed(operand->type) ||
|
||||
@@ -2386,9 +2340,7 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level
|
||||
operand->type = target_type;
|
||||
}
|
||||
|
||||
b32 check_index_value(Checker *c, AstNode *index_value, i64 max_count, i64 *value) {
|
||||
PROF_PROC();
|
||||
|
||||
bool check_index_value(Checker *c, AstNode *index_value, i64 max_count, i64 *value) {
|
||||
Operand operand = {Addressing_Invalid};
|
||||
check_expr(c, &operand, index_value);
|
||||
if (operand.mode == Addressing_Invalid) {
|
||||
@@ -2443,11 +2395,9 @@ b32 check_index_value(Checker *c, AstNode *index_value, i64 max_count, i64 *valu
|
||||
}
|
||||
|
||||
Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
|
||||
PROF_PROC();
|
||||
|
||||
ast_node(se, SelectorExpr, node);
|
||||
|
||||
b32 check_op_expr = true;
|
||||
bool check_op_expr = true;
|
||||
Entity *expr_entity = NULL;
|
||||
Entity *entity = NULL;
|
||||
Selection sel = {}; // NOTE(bill): Not used if it's an import name
|
||||
@@ -2478,11 +2428,11 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
|
||||
check_entity_decl(c, entity, NULL, NULL);
|
||||
}
|
||||
GB_ASSERT(entity->type != NULL);
|
||||
b32 is_not_exported = !is_entity_exported(entity);
|
||||
bool is_not_exported = !is_entity_exported(entity);
|
||||
|
||||
// TODO(bill): Fix this for `#import "file.odin" as .`
|
||||
if (is_not_exported) {
|
||||
auto found = map_get(&e->ImportName.scope->implicit, hash_string(sel_name));
|
||||
Entity **found = map_entity_get(&e->ImportName.scope->implicit, hash_string(sel_name));
|
||||
if (!found && e->ImportName.scope != entity->scope) {
|
||||
is_not_exported = false;
|
||||
}
|
||||
@@ -2577,9 +2527,7 @@ error:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) {
|
||||
PROF_PROC();
|
||||
|
||||
bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) {
|
||||
GB_ASSERT(call->kind == AstNode_CallExpr);
|
||||
ast_node(ce, CallExpr, call);
|
||||
BuiltinProc *bp = &builtin_procs[id];
|
||||
@@ -3416,15 +3364,13 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
|
||||
|
||||
|
||||
void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode *call) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(call->kind == AstNode_CallExpr);
|
||||
GB_ASSERT(proc_type->kind == Type_Proc);
|
||||
ast_node(ce, CallExpr, call);
|
||||
|
||||
isize param_count = 0;
|
||||
b32 variadic = proc_type->Proc.variadic;
|
||||
b32 vari_expand = (ce->ellipsis.pos.line != 0);
|
||||
bool variadic = proc_type->Proc.variadic;
|
||||
bool vari_expand = (ce->ellipsis.pos.line != 0);
|
||||
|
||||
if (proc_type->Proc.params != NULL) {
|
||||
param_count = proc_type->Proc.params->Tuple.variable_count;
|
||||
@@ -3501,7 +3447,7 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
|
||||
}
|
||||
|
||||
if (variadic) {
|
||||
b32 variadic_expand = false;
|
||||
bool variadic_expand = false;
|
||||
Type *slice = sig_params[param_count]->type;
|
||||
GB_ASSERT(is_type_slice(slice));
|
||||
Type *elem = base_type(slice)->Slice.elem;
|
||||
@@ -3548,8 +3494,6 @@ Entity *find_using_index_expr(Type *t) {
|
||||
}
|
||||
|
||||
ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
|
||||
PROF_PROC();
|
||||
|
||||
GB_ASSERT(call->kind == AstNode_CallExpr);
|
||||
ast_node(ce, CallExpr, call);
|
||||
check_expr_or_type(c, operand, ce->proc);
|
||||
@@ -3681,11 +3625,9 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
||||
case_end;
|
||||
|
||||
case_ast_node(cl, CompoundLit, node);
|
||||
PROF_SCOPED("check__expr_base - CompoundLit");
|
||||
|
||||
Type *type = type_hint;
|
||||
b32 ellipsis_array = false;
|
||||
b32 is_constant = true;
|
||||
bool ellipsis_array = false;
|
||||
bool is_constant = true;
|
||||
if (cl->type != NULL) {
|
||||
type = NULL;
|
||||
|
||||
@@ -3722,7 +3664,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
||||
{ // Checker values
|
||||
isize field_count = t->Record.field_count;
|
||||
if (cl->elems.e[0]->kind == AstNode_FieldValue) {
|
||||
b32 *fields_visited = gb_alloc_array(c->allocator, b32, field_count);
|
||||
bool *fields_visited = gb_alloc_array(c->allocator, bool, field_count);
|
||||
|
||||
for_array(i, cl->elems) {
|
||||
AstNode *elem = cl->elems.e[i];
|
||||
@@ -3942,18 +3884,16 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
||||
|
||||
|
||||
case_ast_node(ie, IndexExpr, node);
|
||||
PROF_SCOPED("check__expr_base - IndexExpr");
|
||||
|
||||
check_expr(c, o, ie->expr);
|
||||
if (o->mode == Addressing_Invalid) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
Type *t = base_type(type_deref(o->type));
|
||||
b32 is_const = o->mode == Addressing_Constant;
|
||||
bool is_const = o->mode == Addressing_Constant;
|
||||
|
||||
|
||||
auto set_index_data = [](Operand *o, Type *t, i64 *max_count) -> b32 {
|
||||
auto set_index_data = [](Operand *o, Type *t, i64 *max_count) -> bool {
|
||||
t = base_type(type_deref(t));
|
||||
|
||||
switch (t->kind) {
|
||||
@@ -3997,7 +3937,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
||||
};
|
||||
|
||||
i64 max_count = -1;
|
||||
b32 valid = set_index_data(o, t, &max_count);
|
||||
bool valid = set_index_data(o, t, &max_count);
|
||||
|
||||
if (is_const) {
|
||||
valid = false;
|
||||
@@ -4029,21 +3969,19 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
|
||||
}
|
||||
|
||||
i64 index = 0;
|
||||
b32 ok = check_index_value(c, ie->index, max_count, &index);
|
||||
bool ok = check_index_value(c, ie->index, max_count, &index);
|
||||
|
||||
case_end;
|
||||
|
||||
|
||||
|
||||
case_ast_node(se, SliceExpr, node);
|
||||
PROF_SCOPED("check__expr_base - SliceExpr");
|
||||
|
||||
check_expr(c, o, se->expr);
|
||||
if (o->mode == Addressing_Invalid) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
b32 valid = false;
|
||||
bool valid = false;
|
||||
i64 max_count = -1;
|
||||
Type *t = base_type(type_deref(o->type));
|
||||
switch (t->kind) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
b32 check_is_terminating(AstNode *node);
|
||||
b32 check_has_break (AstNode *stmt, b32 implicit);
|
||||
bool check_is_terminating(AstNode *node);
|
||||
bool check_has_break (AstNode *stmt, bool implicit);
|
||||
void check_stmt (Checker *c, AstNode *node, u32 flags);
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
|
||||
check_entity_decl(c, delayed_const.e[i].e, delayed_const.e[i].d, NULL);
|
||||
}
|
||||
|
||||
b32 ft_ok = (flags & Stmt_FallthroughAllowed) != 0;
|
||||
bool ft_ok = (flags & Stmt_FallthroughAllowed) != 0;
|
||||
u32 f = flags & (~Stmt_FallthroughAllowed);
|
||||
|
||||
for_array(i, stmts) {
|
||||
@@ -98,7 +98,7 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
|
||||
gb_temp_arena_memory_end(tmp);
|
||||
}
|
||||
|
||||
b32 check_is_terminating_list(AstNodeArray stmts) {
|
||||
bool check_is_terminating_list(AstNodeArray stmts) {
|
||||
|
||||
// Iterate backwards
|
||||
for (isize n = stmts.count-1; n >= 0; n--) {
|
||||
@@ -111,7 +111,7 @@ b32 check_is_terminating_list(AstNodeArray stmts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
b32 check_has_break_list(AstNodeArray stmts, b32 implicit) {
|
||||
bool check_has_break_list(AstNodeArray stmts, bool implicit) {
|
||||
for_array(i, stmts) {
|
||||
AstNode *stmt = stmts.e[i];
|
||||
if (check_has_break(stmt, implicit)) {
|
||||
@@ -122,9 +122,7 @@ b32 check_has_break_list(AstNodeArray stmts, b32 implicit) {
|
||||
}
|
||||
|
||||
|
||||
b32 check_has_break(AstNode *stmt, b32 implicit) {
|
||||
PROF_PROC();
|
||||
|
||||
bool check_has_break(AstNode *stmt, bool implicit) {
|
||||
switch (stmt->kind) {
|
||||
case AstNode_BranchStmt:
|
||||
if (stmt->BranchStmt.token.kind == Token_break) {
|
||||
@@ -153,9 +151,7 @@ b32 check_has_break(AstNode *stmt, b32 implicit) {
|
||||
// NOTE(bill): The last expression has to be a `return` statement
|
||||
// TODO(bill): This is a mild hack and should be probably handled properly
|
||||
// TODO(bill): Warn/err against code after `return` that it won't be executed
|
||||
b32 check_is_terminating(AstNode *node) {
|
||||
PROF_PROC();
|
||||
|
||||
bool check_is_terminating(AstNode *node) {
|
||||
switch (node->kind) {
|
||||
case_ast_node(rs, ReturnStmt, node);
|
||||
return true;
|
||||
@@ -185,7 +181,7 @@ b32 check_is_terminating(AstNode *node) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(ms, MatchStmt, node);
|
||||
b32 has_default = false;
|
||||
bool has_default = false;
|
||||
for_array(i, ms->body->BlockStmt.stmts) {
|
||||
AstNode *clause = ms->body->BlockStmt.stmts.e[i];
|
||||
ast_node(cc, CaseClause, clause);
|
||||
@@ -201,7 +197,7 @@ b32 check_is_terminating(AstNode *node) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(ms, TypeMatchStmt, node);
|
||||
b32 has_default = false;
|
||||
bool has_default = false;
|
||||
for_array(i, ms->body->BlockStmt.stmts) {
|
||||
AstNode *clause = ms->body->BlockStmt.stmts.e[i];
|
||||
ast_node(cc, CaseClause, clause);
|
||||
@@ -228,8 +224,6 @@ b32 check_is_terminating(AstNode *node) {
|
||||
}
|
||||
|
||||
Type *check_assignment_variable(Checker *c, Operand *op_a, AstNode *lhs) {
|
||||
PROF_PROC();
|
||||
|
||||
if (op_a->mode == Addressing_Invalid ||
|
||||
op_a->type == t_invalid) {
|
||||
return NULL;
|
||||
@@ -248,7 +242,7 @@ Type *check_assignment_variable(Checker *c, Operand *op_a, AstNode *lhs) {
|
||||
}
|
||||
|
||||
Entity *e = NULL;
|
||||
b32 used = false;
|
||||
bool used = false;
|
||||
if (node->kind == AstNode_Ident) {
|
||||
ast_node(i, Ident, node);
|
||||
e = scope_lookup_entity(c->context.scope, i->string);
|
||||
@@ -303,7 +297,7 @@ Type *check_assignment_variable(Checker *c, Operand *op_a, AstNode *lhs) {
|
||||
return op_a->type;
|
||||
}
|
||||
|
||||
b32 check_valid_type_match_type(Type *type, b32 *is_union_ptr, b32 *is_any) {
|
||||
bool check_valid_type_match_type(Type *type, bool *is_union_ptr, bool *is_any) {
|
||||
if (is_type_pointer(type)) {
|
||||
*is_union_ptr = is_type_union(type_deref(type));
|
||||
return *is_union_ptr;
|
||||
@@ -339,6 +333,16 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
|
||||
c->context.stmt_state_flags = prev_stmt_state_flags;
|
||||
}
|
||||
|
||||
typedef struct TypeAndToken {
|
||||
Type *type;
|
||||
Token token;
|
||||
} TypeAndToken;
|
||||
|
||||
#define MAP_TYPE TypeAndToken
|
||||
#define MAP_FUNC map_type_and_token_
|
||||
#define MAP_NAME MapTypeAndToken
|
||||
#include "../map.c"
|
||||
|
||||
void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
u32 mod_flags = flags & (~Stmt_FallthroughAllowed);
|
||||
switch (node->kind) {
|
||||
@@ -347,8 +351,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case_ast_node(_, BadDecl, node); case_end;
|
||||
|
||||
case_ast_node(es, ExprStmt, node)
|
||||
PROF_SCOPED("check_stmt - ExprStmt");
|
||||
|
||||
Operand operand = {Addressing_Invalid};
|
||||
ExprKind kind = check_expr_base(c, &operand, es->expr);
|
||||
switch (operand.mode) {
|
||||
@@ -378,8 +380,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(ids, IncDecStmt, node);
|
||||
PROF_SCOPED("check_stmt - IncDecStmt");
|
||||
|
||||
Token op = ids->op;
|
||||
switch (ids->op.kind) {
|
||||
case Token_Increment:
|
||||
@@ -419,8 +419,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(as, AssignStmt, node);
|
||||
PROF_SCOPED("check_stmt - AssignStmt");
|
||||
|
||||
switch (as->op.kind) {
|
||||
case Token_Eq: {
|
||||
// a, b, c = 1, 2, 3; // Multisided
|
||||
@@ -504,8 +502,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(is, IfStmt, node);
|
||||
PROF_SCOPED("check_stmt - IfStmt");
|
||||
|
||||
check_open_scope(c, node);
|
||||
|
||||
if (is->init != NULL) {
|
||||
@@ -539,8 +535,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(rs, ReturnStmt, node);
|
||||
PROF_SCOPED("check_stmt - ReturnStmt");
|
||||
|
||||
GB_ASSERT(c->proc_stack.count > 0);
|
||||
|
||||
if (c->in_defer) {
|
||||
@@ -574,8 +568,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(fs, ForStmt, node);
|
||||
PROF_SCOPED("check_stmt - ForStmt");
|
||||
|
||||
u32 new_flags = mod_flags | Stmt_BreakAllowed | Stmt_ContinueAllowed;
|
||||
check_open_scope(c, node);
|
||||
|
||||
@@ -600,8 +592,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(ms, MatchStmt, node);
|
||||
PROF_SCOPED("check_stmt - MatchStmt");
|
||||
|
||||
Operand x = {};
|
||||
|
||||
mod_flags |= Stmt_BreakAllowed;
|
||||
@@ -650,15 +640,10 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
}
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
|
||||
struct TypeAndToken {
|
||||
Type *type;
|
||||
Token token;
|
||||
};
|
||||
|
||||
Map<TypeAndToken> seen = {}; // NOTE(bill): Multimap
|
||||
map_init(&seen, heap_allocator());
|
||||
MapTypeAndToken seen = {}; // NOTE(bill): Multimap
|
||||
map_type_and_token_init(&seen, heap_allocator());
|
||||
|
||||
for_array(i, bs->stmts) {
|
||||
AstNode *stmt = bs->stmts.e[i];
|
||||
@@ -696,14 +681,14 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
if (y.value.kind != ExactValue_Invalid) {
|
||||
HashKey key = hash_exact_value(y.value);
|
||||
auto *found = map_get(&seen, key);
|
||||
TypeAndToken *found = map_type_and_token_get(&seen, key);
|
||||
if (found != NULL) {
|
||||
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
|
||||
isize count = multi_map_count(&seen, key);
|
||||
isize count = map_type_and_token_multi_count(&seen, key);
|
||||
TypeAndToken *taps = gb_alloc_array(c->tmp_allocator, TypeAndToken, count);
|
||||
|
||||
multi_map_get_all(&seen, key, taps);
|
||||
b32 continue_outer = false;
|
||||
map_type_and_token_multi_get_all(&seen, key, taps);
|
||||
bool continue_outer = false;
|
||||
|
||||
for (isize i = 0; i < count; i++) {
|
||||
TypeAndToken tap = taps[i];
|
||||
@@ -728,7 +713,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
}
|
||||
}
|
||||
TypeAndToken tap = {y.type, ast_node_token(y.expr)};
|
||||
multi_map_insert(&seen, key, tap);
|
||||
map_type_and_token_multi_insert(&seen, key, tap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,21 +726,19 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
check_close_scope(c);
|
||||
}
|
||||
|
||||
map_destroy(&seen);
|
||||
map_type_and_token_destroy(&seen);
|
||||
|
||||
check_close_scope(c);
|
||||
case_end;
|
||||
|
||||
case_ast_node(ms, TypeMatchStmt, node);
|
||||
PROF_SCOPED("check_stmt - TypeMatchStmt");
|
||||
|
||||
Operand x = {};
|
||||
|
||||
mod_flags |= Stmt_BreakAllowed;
|
||||
check_open_scope(c, node);
|
||||
|
||||
b32 is_union_ptr = false;
|
||||
b32 is_any = false;
|
||||
bool is_union_ptr = false;
|
||||
bool is_any = false;
|
||||
|
||||
check_expr(c, &x, ms->tag);
|
||||
check_assignment(c, &x, NULL, str_lit("type match expression"));
|
||||
@@ -800,8 +783,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
}
|
||||
|
||||
|
||||
Map<b32> seen = {};
|
||||
map_init(&seen, heap_allocator());
|
||||
MapBool seen = {};
|
||||
map_bool_init(&seen, heap_allocator());
|
||||
|
||||
for_array(i, bs->stmts) {
|
||||
AstNode *stmt = bs->stmts.e[i];
|
||||
@@ -823,7 +806,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
|
||||
if (is_union_ptr) {
|
||||
GB_ASSERT(is_type_union(bt));
|
||||
b32 tag_type_found = false;
|
||||
bool tag_type_found = false;
|
||||
for (isize i = 0; i < bt->Record.field_count; i++) {
|
||||
Entity *f = bt->Record.fields[i];
|
||||
if (are_types_identical(f->type, y.type)) {
|
||||
@@ -846,7 +829,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
}
|
||||
|
||||
HashKey key = hash_pointer(y.type);
|
||||
auto *found = map_get(&seen, key);
|
||||
bool *found = map_bool_get(&seen, key);
|
||||
if (found) {
|
||||
TokenPos pos = cc->token.pos;
|
||||
gbString expr_str = expr_to_string(y.expr);
|
||||
@@ -858,7 +841,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
gb_string_free(expr_str);
|
||||
break;
|
||||
}
|
||||
map_set(&seen, key, cast(b32)true);
|
||||
map_bool_set(&seen, key, cast(bool)true);
|
||||
}
|
||||
|
||||
check_open_scope(c, stmt);
|
||||
@@ -879,7 +862,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
check_stmt_list(c, cc->stmts, mod_flags);
|
||||
check_close_scope(c);
|
||||
}
|
||||
map_destroy(&seen);
|
||||
map_bool_destroy(&seen);
|
||||
|
||||
check_close_scope(c);
|
||||
case_end;
|
||||
@@ -889,7 +872,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
if (is_ast_node_decl(ds->stmt)) {
|
||||
error(ds->token, "You cannot defer a declaration");
|
||||
} else {
|
||||
b32 out_in_defer = c->in_defer;
|
||||
bool out_in_defer = c->in_defer;
|
||||
c->in_defer = true;
|
||||
check_stmt(c, ds->stmt, 0);
|
||||
c->in_defer = out_in_defer;
|
||||
@@ -921,14 +904,12 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(us, UsingStmt, node);
|
||||
PROF_SCOPED("check_stmt - UsingStmt");
|
||||
|
||||
switch (us->node->kind) {
|
||||
case_ast_node(es, ExprStmt, us->node);
|
||||
// TODO(bill): Allow for just a LHS expression list rather than this silly code
|
||||
Entity *e = NULL;
|
||||
|
||||
b32 is_selector = false;
|
||||
bool is_selector = false;
|
||||
AstNode *expr = unparen_expr(es->expr);
|
||||
if (expr->kind == AstNode_Ident) {
|
||||
String name = expr->Ident.string;
|
||||
@@ -1009,7 +990,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case Entity_Variable: {
|
||||
Type *t = base_type(type_deref(e->type));
|
||||
if (is_type_struct(t) || is_type_raw_union(t)) {
|
||||
Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
|
||||
Scope **found = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node));
|
||||
GB_ASSERT(found != NULL);
|
||||
for_array(i, (*found)->elements.entries) {
|
||||
Entity *f = (*found)->elements.entries.e[i].value;
|
||||
@@ -1060,8 +1041,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(vd, VarDecl, us->node);
|
||||
PROF_SCOPED("check_stmt - VarDecl");
|
||||
|
||||
if (vd->names.count > 1 && vd->type != NULL) {
|
||||
error(us->token, "`using` can only be applied to one variable of the same type");
|
||||
}
|
||||
@@ -1074,7 +1053,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
Entity *e = scope_lookup_entity(c->context.scope, name);
|
||||
Type *t = base_type(type_deref(e->type));
|
||||
if (is_type_struct(t) || is_type_raw_union(t)) {
|
||||
Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
|
||||
Scope **found = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node));
|
||||
GB_ASSERT(found != NULL);
|
||||
for_array(i, (*found)->elements.entries) {
|
||||
Entity *f = (*found)->elements.entries.e[i].value;
|
||||
@@ -1136,8 +1115,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) {
|
||||
case_end;
|
||||
|
||||
case_ast_node(pd, ProcDecl, node);
|
||||
PROF_SCOPED("check_stmt - ProcDecl");
|
||||
|
||||
// NOTE(bill): This must be handled here so it has access to the parent scope stuff
|
||||
// e.g. using
|
||||
Entity *e = make_entity_procedure(c->allocator, c->context.scope, pd->name->Ident, NULL);
|
||||
|
||||
@@ -136,9 +136,9 @@ struct Type {
|
||||
};
|
||||
struct { // struct only
|
||||
i64 * struct_offsets;
|
||||
b32 struct_are_offsets_set;
|
||||
b32 struct_is_packed;
|
||||
b32 struct_is_ordered;
|
||||
bool struct_are_offsets_set;
|
||||
bool struct_is_packed;
|
||||
bool struct_is_ordered;
|
||||
Entity **fields_in_src_order; // Entity_Variable
|
||||
};
|
||||
};
|
||||
@@ -155,7 +155,7 @@ struct Type {
|
||||
struct {
|
||||
Entity **variables; // Entity_Variable
|
||||
i32 variable_count;
|
||||
b32 are_offsets_set;
|
||||
bool are_offsets_set;
|
||||
i64 * offsets;
|
||||
} Tuple;
|
||||
struct {
|
||||
@@ -164,7 +164,7 @@ struct Type {
|
||||
Type * results; // Type_Tuple
|
||||
i32 param_count;
|
||||
i32 result_count;
|
||||
b32 variadic;
|
||||
bool variadic;
|
||||
} Proc;
|
||||
};
|
||||
};
|
||||
@@ -378,7 +378,7 @@ Type *make_type_tuple(gbAllocator a) {
|
||||
return t;
|
||||
}
|
||||
|
||||
Type *make_type_proc(gbAllocator a, Scope *scope, Type *params, isize param_count, Type *results, isize result_count, b32 variadic) {
|
||||
Type *make_type_proc(gbAllocator a, Scope *scope, Type *params, isize param_count, Type *results, isize result_count, bool variadic) {
|
||||
Type *t = alloc_type(a, Type_Proc);
|
||||
|
||||
if (variadic) {
|
||||
@@ -423,34 +423,34 @@ Type *get_enum_base_type(Type *t) {
|
||||
return t;
|
||||
}
|
||||
|
||||
b32 is_type_named(Type *t) {
|
||||
bool is_type_named(Type *t) {
|
||||
if (t->kind == Type_Basic) {
|
||||
return true;
|
||||
}
|
||||
return t->kind == Type_Named;
|
||||
}
|
||||
b32 is_type_boolean(Type *t) {
|
||||
bool is_type_boolean(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
return (t->Basic.flags & BasicFlag_Boolean) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_integer(Type *t) {
|
||||
bool is_type_integer(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
return (t->Basic.flags & BasicFlag_Integer) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_unsigned(Type *t) {
|
||||
bool is_type_unsigned(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
return (t->Basic.flags & BasicFlag_Unsigned) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_numeric(Type *t) {
|
||||
bool is_type_numeric(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
return (t->Basic.flags & BasicFlag_Numeric) != 0;
|
||||
@@ -460,28 +460,28 @@ b32 is_type_numeric(Type *t) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_string(Type *t) {
|
||||
bool is_type_string(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
return (t->Basic.flags & BasicFlag_String) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_typed(Type *t) {
|
||||
bool is_type_typed(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
return (t->Basic.flags & BasicFlag_Untyped) == 0;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
b32 is_type_untyped(Type *t) {
|
||||
bool is_type_untyped(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
return (t->Basic.flags & BasicFlag_Untyped) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_ordered(Type *t) {
|
||||
bool is_type_ordered(Type *t) {
|
||||
t = base_type(get_enum_base_type(t));
|
||||
if (t->kind == Type_Basic) {
|
||||
return (t->Basic.flags & BasicFlag_Ordered) != 0;
|
||||
@@ -491,7 +491,7 @@ b32 is_type_ordered(Type *t) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_constant_type(Type *t) {
|
||||
bool is_type_constant_type(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
return (t->Basic.flags & BasicFlag_ConstantType) != 0;
|
||||
@@ -501,82 +501,82 @@ b32 is_type_constant_type(Type *t) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_float(Type *t) {
|
||||
bool is_type_float(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
return (t->Basic.flags & BasicFlag_Float) != 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_f32(Type *t) {
|
||||
bool is_type_f32(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
return t->Basic.kind == Basic_f32;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_f64(Type *t) {
|
||||
bool is_type_f64(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
return t->Basic.kind == Basic_f64;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_pointer(Type *t) {
|
||||
bool is_type_pointer(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Basic) {
|
||||
return (t->Basic.flags & BasicFlag_Pointer) != 0;
|
||||
}
|
||||
return t->kind == Type_Pointer;
|
||||
}
|
||||
b32 is_type_maybe(Type *t) {
|
||||
bool is_type_maybe(Type *t) {
|
||||
t = base_type(t);
|
||||
return t->kind == Type_Maybe;
|
||||
}
|
||||
b32 is_type_tuple(Type *t) {
|
||||
bool is_type_tuple(Type *t) {
|
||||
t = base_type(t);
|
||||
return t->kind == Type_Tuple;
|
||||
}
|
||||
|
||||
|
||||
b32 is_type_int_or_uint(Type *t) {
|
||||
bool is_type_int_or_uint(Type *t) {
|
||||
if (t->kind == Type_Basic) {
|
||||
return (t->Basic.kind == Basic_int) || (t->Basic.kind == Basic_uint);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_rawptr(Type *t) {
|
||||
bool is_type_rawptr(Type *t) {
|
||||
if (t->kind == Type_Basic) {
|
||||
return t->Basic.kind == Basic_rawptr;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_u8(Type *t) {
|
||||
bool is_type_u8(Type *t) {
|
||||
if (t->kind == Type_Basic) {
|
||||
return t->Basic.kind == Basic_u8;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_array(Type *t) {
|
||||
bool is_type_array(Type *t) {
|
||||
t = base_type(t);
|
||||
return t->kind == Type_Array;
|
||||
}
|
||||
b32 is_type_slice(Type *t) {
|
||||
bool is_type_slice(Type *t) {
|
||||
t = base_type(t);
|
||||
return t->kind == Type_Slice;
|
||||
}
|
||||
b32 is_type_u8_slice(Type *t) {
|
||||
bool is_type_u8_slice(Type *t) {
|
||||
t = base_type(t);
|
||||
if (t->kind == Type_Slice) {
|
||||
return is_type_u8(t->Slice.elem);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
b32 is_type_vector(Type *t) {
|
||||
bool is_type_vector(Type *t) {
|
||||
t = base_type(t);
|
||||
return t->kind == Type_Vector;
|
||||
}
|
||||
b32 is_type_proc(Type *t) {
|
||||
bool is_type_proc(Type *t) {
|
||||
t = base_type(t);
|
||||
return t->kind == Type_Proc;
|
||||
}
|
||||
@@ -589,40 +589,40 @@ Type *base_vector_type(Type *t) {
|
||||
}
|
||||
|
||||
|
||||
b32 is_type_enum(Type *t) {
|
||||
bool is_type_enum(Type *t) {
|
||||
t = base_type(t);
|
||||
return (t->kind == Type_Record && t->Record.kind == TypeRecord_Enum);
|
||||
}
|
||||
b32 is_type_struct(Type *t) {
|
||||
bool is_type_struct(Type *t) {
|
||||
t = base_type(t);
|
||||
return (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct);
|
||||
}
|
||||
b32 is_type_union(Type *t) {
|
||||
bool is_type_union(Type *t) {
|
||||
t = base_type(t);
|
||||
return (t->kind == Type_Record && t->Record.kind == TypeRecord_Union);
|
||||
}
|
||||
b32 is_type_raw_union(Type *t) {
|
||||
bool is_type_raw_union(Type *t) {
|
||||
t = base_type(t);
|
||||
return (t->kind == Type_Record && t->Record.kind == TypeRecord_RawUnion);
|
||||
}
|
||||
|
||||
b32 is_type_any(Type *t) {
|
||||
bool is_type_any(Type *t) {
|
||||
t = base_type(t);
|
||||
return (t->kind == Type_Basic && t->Basic.kind == Basic_any);
|
||||
}
|
||||
b32 is_type_untyped_nil(Type *t) {
|
||||
bool is_type_untyped_nil(Type *t) {
|
||||
t = base_type(t);
|
||||
return (t->kind == Type_Basic && t->Basic.kind == Basic_UntypedNil);
|
||||
}
|
||||
|
||||
|
||||
|
||||
b32 is_type_indexable(Type *t) {
|
||||
bool is_type_indexable(Type *t) {
|
||||
return is_type_array(t) || is_type_slice(t) || is_type_vector(t) || is_type_string(t);
|
||||
}
|
||||
|
||||
|
||||
b32 type_has_nil(Type *t) {
|
||||
bool type_has_nil(Type *t) {
|
||||
t = base_type(t);
|
||||
switch (t->kind) {
|
||||
case Type_Basic:
|
||||
@@ -642,7 +642,7 @@ b32 type_has_nil(Type *t) {
|
||||
}
|
||||
|
||||
|
||||
b32 is_type_comparable(Type *t) {
|
||||
bool is_type_comparable(Type *t) {
|
||||
t = base_type(get_enum_base_type(t));
|
||||
switch (t->kind) {
|
||||
case Type_Basic:
|
||||
@@ -671,7 +671,7 @@ b32 is_type_comparable(Type *t) {
|
||||
return false;
|
||||
}
|
||||
|
||||
b32 are_types_identical(Type *x, Type *y) {
|
||||
bool are_types_identical(Type *x, Type *y) {
|
||||
if (x == y)
|
||||
return true;
|
||||
|
||||
@@ -810,11 +810,11 @@ typedef Array(isize) Array_isize;
|
||||
struct Selection {
|
||||
Entity * entity;
|
||||
Array_isize index;
|
||||
b32 indirect; // Set if there was a pointer deref anywhere down the line
|
||||
bool indirect; // Set if there was a pointer deref anywhere down the line
|
||||
};
|
||||
Selection empty_selection = {};
|
||||
|
||||
Selection make_selection(Entity *entity, Array_isize index, b32 indirect) {
|
||||
Selection make_selection(Entity *entity, Array_isize index, bool indirect) {
|
||||
Selection s = {entity, index, indirect};
|
||||
return s;
|
||||
}
|
||||
@@ -835,7 +835,7 @@ gb_global Entity *entity__string_count = NULL;
|
||||
gb_global Entity *entity__slice_count = NULL;
|
||||
gb_global Entity *entity__slice_capacity = NULL;
|
||||
|
||||
Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_type, Selection sel = empty_selection) {
|
||||
Selection lookup_field(gbAllocator a, Type *type_, String field_name, bool is_type, Selection sel = empty_selection) {
|
||||
GB_ASSERT(type_ != NULL);
|
||||
|
||||
if (str_eq(field_name, str_lit("_"))) {
|
||||
@@ -843,7 +843,7 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ
|
||||
}
|
||||
|
||||
Type *type = type_deref(type_);
|
||||
b32 is_ptr = type != type_;
|
||||
bool is_ptr = type != type_;
|
||||
sel.indirect = sel.indirect || is_ptr;
|
||||
|
||||
type = base_type(type);
|
||||
@@ -1131,7 +1131,7 @@ i64 type_align_of(BaseTypeSizes s, gbAllocator allocator, Type *t) {
|
||||
return gb_clamp(next_pow2(type_size_of(s, allocator, t)), 1, s.word_size);
|
||||
}
|
||||
|
||||
i64 *type_set_offsets_of(BaseTypeSizes s, gbAllocator allocator, Entity **fields, isize field_count, b32 is_packed) {
|
||||
i64 *type_set_offsets_of(BaseTypeSizes s, gbAllocator allocator, Entity **fields, isize field_count, bool is_packed) {
|
||||
i64 *offsets = gb_alloc_array(allocator, i64, field_count);
|
||||
i64 curr_offset = 0;
|
||||
if (is_packed) {
|
||||
@@ -1151,7 +1151,7 @@ i64 *type_set_offsets_of(BaseTypeSizes s, gbAllocator allocator, Entity **fields
|
||||
return offsets;
|
||||
}
|
||||
|
||||
b32 type_set_offsets(BaseTypeSizes s, gbAllocator allocator, Type *t) {
|
||||
bool type_set_offsets(BaseTypeSizes s, gbAllocator allocator, Type *t) {
|
||||
t = base_type(t);
|
||||
if (is_type_struct(t)) {
|
||||
if (!t->Record.struct_are_offsets_set) {
|
||||
|
||||
@@ -10,7 +10,7 @@ gbAllocator heap_allocator(void) {
|
||||
#include "array.cpp"
|
||||
|
||||
gb_global String global_module_path = {0};
|
||||
gb_global b32 global_module_path_set = false;
|
||||
gb_global bool global_module_path_set = false;
|
||||
|
||||
|
||||
String get_module_dir() {
|
||||
@@ -74,20 +74,20 @@ String path_to_fullpath(gbAllocator a, String s) {
|
||||
}
|
||||
|
||||
// Hasing
|
||||
enum HashKeyKind {
|
||||
typedef enum HashKeyKind {
|
||||
HashKey_Default,
|
||||
HashKey_String,
|
||||
HashKey_Pointer,
|
||||
};
|
||||
} HashKeyKind;
|
||||
|
||||
struct HashKey {
|
||||
typedef struct HashKey {
|
||||
HashKeyKind kind;
|
||||
u64 key;
|
||||
union {
|
||||
String string; // if String, s.len > 0
|
||||
void * ptr;
|
||||
};
|
||||
};
|
||||
} HashKey;
|
||||
|
||||
gb_inline HashKey hashing_proc(void const *data, isize len) {
|
||||
HashKey h = {HashKey_Default};
|
||||
@@ -112,7 +112,7 @@ gb_inline HashKey hash_pointer(void *ptr) {
|
||||
return h;
|
||||
}
|
||||
|
||||
b32 hash_key_equal(HashKey a, HashKey b) {
|
||||
bool hash_key_equal(HashKey a, HashKey b) {
|
||||
if (a.key == b.key) {
|
||||
// NOTE(bill): If two string's hashes collide, compare the strings themselves
|
||||
if (a.kind == HashKey_String) {
|
||||
@@ -232,13 +232,32 @@ i16 f32_to_f16(f32 value) {
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#define MAP_TYPE String
|
||||
#define MAP_FUNC map_string_
|
||||
#define MAP_NAME MapString
|
||||
#include "map.c"
|
||||
|
||||
#define MAP_TYPE bool
|
||||
#define MAP_FUNC map_bool_
|
||||
#define MAP_NAME MapBool
|
||||
#include "map.c"
|
||||
|
||||
#define MAP_TYPE isize
|
||||
#define MAP_FUNC map_isize_
|
||||
#define MAP_NAME MapIsize
|
||||
#include "map.c"
|
||||
|
||||
|
||||
struct MapFindResult {
|
||||
#if 0
|
||||
#ifndef MAP_FIND_RESULT
|
||||
#define MAP_FIND_RESULT
|
||||
typedef struct MapFindResult {
|
||||
isize hash_index;
|
||||
isize entry_prev;
|
||||
isize entry_index;
|
||||
};
|
||||
} MapFindResult;
|
||||
#endif
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct MapEntry {
|
||||
@@ -338,7 +357,7 @@ gb_internal MapFindResult map__find(Map<T> *h, MapEntry<T> *e) {
|
||||
|
||||
|
||||
template <typename T>
|
||||
gb_internal b32 map__full(Map<T> *h) {
|
||||
gb_internal bool map__full(Map<T> *h) {
|
||||
return 0.75f * h->hashes.count <= h->entries.count;
|
||||
}
|
||||
|
||||
@@ -529,3 +548,4 @@ void multi_map_remove_all(Map<T> *h, HashKey key) {
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,7 +21,7 @@ enum ExactValueKind {
|
||||
struct ExactValue {
|
||||
ExactValueKind kind;
|
||||
union {
|
||||
b32 value_bool;
|
||||
bool value_bool;
|
||||
String value_string;
|
||||
i64 value_integer; // NOTE(bill): This must be an integer and not a pointer
|
||||
f64 value_float;
|
||||
@@ -41,7 +41,7 @@ ExactValue make_exact_value_compound(AstNode *node) {
|
||||
return result;
|
||||
}
|
||||
|
||||
ExactValue make_exact_value_bool(b32 b) {
|
||||
ExactValue make_exact_value_bool(bool b) {
|
||||
ExactValue result = {ExactValue_Bool};
|
||||
result.value_bool = (b != 0);
|
||||
return result;
|
||||
@@ -339,7 +339,7 @@ i32 cmp_f64(f64 a, f64 b) {
|
||||
return (a > b) - (a < b);
|
||||
}
|
||||
|
||||
b32 compare_exact_values(Token op, ExactValue x, ExactValue y) {
|
||||
bool compare_exact_values(Token op, ExactValue x, ExactValue y) {
|
||||
match_exact_values(&x, &y);
|
||||
|
||||
switch (x.kind) {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#define VERSION_STRING "v0.0.3"
|
||||
|
||||
#include "common.cpp"
|
||||
#include "profiler.cpp"
|
||||
#include "timings.cpp"
|
||||
#include "unicode.cpp"
|
||||
#include "tokenizer.cpp"
|
||||
@@ -107,7 +106,6 @@ int main(int argc, char **argv) {
|
||||
usage(argv[0]);
|
||||
return 1;
|
||||
}
|
||||
prof_init();
|
||||
|
||||
Timings timings = {0};
|
||||
timings_init(&timings, str_lit("Total Time"), 128);
|
||||
@@ -122,7 +120,7 @@ int main(int argc, char **argv) {
|
||||
init_universal_scope();
|
||||
|
||||
char *init_filename = NULL;
|
||||
b32 run_output = false;
|
||||
bool run_output = false;
|
||||
String arg1 = make_string_c(argv[1]);
|
||||
if (str_eq(arg1, str_lit("run"))) {
|
||||
run_output = true;
|
||||
|
||||
@@ -32,7 +32,7 @@ struct AstFile {
|
||||
isize expr_level;
|
||||
|
||||
AstNodeArray decls;
|
||||
b32 is_global_scope;
|
||||
bool is_global_scope;
|
||||
|
||||
AstNode * curr_proc;
|
||||
isize scope_level;
|
||||
@@ -140,7 +140,7 @@ AST_NODE_KIND(_ExprBegin, "", struct{}) \
|
||||
AstNode *expr; \
|
||||
Token open, close; \
|
||||
AstNode *low, *high, *max; \
|
||||
b32 triple_indexed; \
|
||||
bool triple_indexed; \
|
||||
}) \
|
||||
AST_NODE_KIND(FieldValue, "field value", struct { Token eq; AstNode *field, *value; }) \
|
||||
AST_NODE_KIND(_ExprEnd, "", struct{}) \
|
||||
@@ -202,7 +202,7 @@ AST_NODE_KIND(_ComplexStmtBegin, "", struct{}) \
|
||||
}) \
|
||||
AST_NODE_KIND(AsmStmt, "assembly statement", struct { \
|
||||
Token token; \
|
||||
b32 is_volatile; \
|
||||
bool is_volatile; \
|
||||
Token open, close; \
|
||||
Token code_string; \
|
||||
AstNode *output_list; \
|
||||
@@ -227,7 +227,7 @@ AST_NODE_KIND(_DeclBegin, "", struct{}) \
|
||||
AST_NODE_KIND(BadDecl, "bad declaration", struct { Token begin, end; }) \
|
||||
AST_NODE_KIND(VarDecl, "variable declaration", struct { \
|
||||
u64 tags; \
|
||||
b32 is_using; \
|
||||
bool is_using; \
|
||||
AstNodeArray names; \
|
||||
AstNode * type; \
|
||||
AstNodeArray values; \
|
||||
@@ -258,19 +258,19 @@ AST_NODE_KIND(_DeclBegin, "", struct{}) \
|
||||
Token token, relpath; \
|
||||
String fullpath; \
|
||||
Token import_name; \
|
||||
b32 is_load; \
|
||||
bool is_load; \
|
||||
AstNode *note; \
|
||||
}) \
|
||||
AST_NODE_KIND(ForeignLibrary, "foreign library", struct { \
|
||||
Token token, filepath; \
|
||||
b32 is_system; \
|
||||
bool is_system; \
|
||||
}) \
|
||||
AST_NODE_KIND(_DeclEnd, "", struct{}) \
|
||||
AST_NODE_KIND(_TypeBegin, "", struct{}) \
|
||||
AST_NODE_KIND(Parameter, "parameter", struct { \
|
||||
AstNodeArray names; \
|
||||
AstNode *type; \
|
||||
b32 is_using; \
|
||||
bool is_using; \
|
||||
}) \
|
||||
AST_NODE_KIND(ProcType, "procedure type", struct { \
|
||||
Token token; \
|
||||
@@ -299,8 +299,8 @@ AST_NODE_KIND(_TypeBegin, "", struct{}) \
|
||||
Token token; \
|
||||
AstNodeArray decls; \
|
||||
isize decl_count; \
|
||||
b32 is_packed; \
|
||||
b32 is_ordered; \
|
||||
bool is_packed; \
|
||||
bool is_ordered; \
|
||||
}) \
|
||||
AST_NODE_KIND(UnionType, "union type", struct { \
|
||||
Token token; \
|
||||
@@ -355,19 +355,19 @@ struct AstNode {
|
||||
|
||||
|
||||
|
||||
gb_inline b32 is_ast_node_expr(AstNode *node) {
|
||||
gb_inline bool is_ast_node_expr(AstNode *node) {
|
||||
return gb_is_between(node->kind, AstNode__ExprBegin+1, AstNode__ExprEnd-1);
|
||||
}
|
||||
gb_inline b32 is_ast_node_stmt(AstNode *node) {
|
||||
gb_inline bool is_ast_node_stmt(AstNode *node) {
|
||||
return gb_is_between(node->kind, AstNode__StmtBegin+1, AstNode__StmtEnd-1);
|
||||
}
|
||||
gb_inline b32 is_ast_node_complex_stmt(AstNode *node) {
|
||||
gb_inline bool is_ast_node_complex_stmt(AstNode *node) {
|
||||
return gb_is_between(node->kind, AstNode__ComplexStmtBegin+1, AstNode__ComplexStmtEnd-1);
|
||||
}
|
||||
gb_inline b32 is_ast_node_decl(AstNode *node) {
|
||||
gb_inline bool is_ast_node_decl(AstNode *node) {
|
||||
return gb_is_between(node->kind, AstNode__DeclBegin+1, AstNode__DeclEnd-1);
|
||||
}
|
||||
gb_inline b32 is_ast_node_type(AstNode *node) {
|
||||
gb_inline bool is_ast_node_type(AstNode *node) {
|
||||
return gb_is_between(node->kind, AstNode__TypeBegin+1, AstNode__TypeEnd-1);
|
||||
}
|
||||
|
||||
@@ -598,7 +598,7 @@ AstNode *make_index_expr(AstFile *f, AstNode *expr, AstNode *index, Token open,
|
||||
}
|
||||
|
||||
|
||||
AstNode *make_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, AstNode *low, AstNode *high, AstNode *max, b32 triple_indexed) {
|
||||
AstNode *make_slice_expr(AstFile *f, AstNode *expr, Token open, Token close, AstNode *low, AstNode *high, AstNode *max, bool triple_indexed) {
|
||||
AstNode *result = make_node(f, AstNode_SliceExpr);
|
||||
result->SliceExpr.expr = expr;
|
||||
result->SliceExpr.open = open;
|
||||
@@ -796,7 +796,7 @@ AstNode *make_asm_operand(AstFile *f, Token string, AstNode *operand) {
|
||||
|
||||
}
|
||||
|
||||
AstNode *make_asm_stmt(AstFile *f, Token token, b32 is_volatile, Token open, Token close, Token code_string,
|
||||
AstNode *make_asm_stmt(AstFile *f, Token token, bool is_volatile, Token open, Token close, Token code_string,
|
||||
AstNode *output_list, AstNode *input_list, AstNode *clobber_list,
|
||||
isize output_count, isize input_count, isize clobber_count) {
|
||||
AstNode *result = make_node(f, AstNode_AsmStmt);
|
||||
@@ -856,7 +856,7 @@ AstNode *make_const_decl(AstFile *f, AstNodeArray names, AstNode *type, AstNodeA
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *make_parameter(AstFile *f, AstNodeArray names, AstNode *type, b32 is_using) {
|
||||
AstNode *make_parameter(AstFile *f, AstNodeArray names, AstNode *type, bool is_using) {
|
||||
AstNode *result = make_node(f, AstNode_Parameter);
|
||||
result->Parameter.names = names;
|
||||
result->Parameter.type = type;
|
||||
@@ -913,7 +913,7 @@ AstNode *make_vector_type(AstFile *f, Token token, AstNode *count, AstNode *elem
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *make_struct_type(AstFile *f, Token token, AstNodeArray decls, isize decl_count, b32 is_packed, b32 is_ordered) {
|
||||
AstNode *make_struct_type(AstFile *f, Token token, AstNodeArray decls, isize decl_count, bool is_packed, bool is_ordered) {
|
||||
AstNode *result = make_node(f, AstNode_StructType);
|
||||
result->StructType.token = token;
|
||||
result->StructType.decls = decls;
|
||||
@@ -957,7 +957,7 @@ AstNode *make_type_decl(AstFile *f, Token token, AstNode *name, AstNode *type) {
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *make_import_decl(AstFile *f, Token token, Token relpath, Token import_name, b32 is_load) {
|
||||
AstNode *make_import_decl(AstFile *f, Token token, Token relpath, Token import_name, bool is_load) {
|
||||
AstNode *result = make_node(f, AstNode_ImportDecl);
|
||||
result->ImportDecl.token = token;
|
||||
result->ImportDecl.relpath = relpath;
|
||||
@@ -966,7 +966,7 @@ AstNode *make_import_decl(AstFile *f, Token token, Token relpath, Token import_n
|
||||
return result;
|
||||
}
|
||||
|
||||
AstNode *make_foreign_library(AstFile *f, Token token, Token filepath, b32 is_system) {
|
||||
AstNode *make_foreign_library(AstFile *f, Token token, Token filepath, bool is_system) {
|
||||
AstNode *result = make_node(f, AstNode_ForeignLibrary);
|
||||
result->ForeignLibrary.token = token;
|
||||
result->ForeignLibrary.filepath = filepath;
|
||||
@@ -974,7 +974,7 @@ AstNode *make_foreign_library(AstFile *f, Token token, Token filepath, b32 is_sy
|
||||
return result;
|
||||
}
|
||||
|
||||
b32 next_token(AstFile *f) {
|
||||
bool next_token(AstFile *f) {
|
||||
if (f->curr_token_index+1 < f->tokens.count) {
|
||||
if (f->curr_token.kind != Token_Comment) {
|
||||
f->prev_token = f->curr_token;
|
||||
@@ -1035,7 +1035,7 @@ Token expect_keyword(AstFile *f) {
|
||||
return prev;
|
||||
}
|
||||
|
||||
b32 allow_token(AstFile *f, TokenKind kind) {
|
||||
bool allow_token(AstFile *f, TokenKind kind) {
|
||||
Token prev = f->curr_token;
|
||||
if (prev.kind == kind) {
|
||||
next_token(f);
|
||||
@@ -1045,7 +1045,7 @@ b32 allow_token(AstFile *f, TokenKind kind) {
|
||||
}
|
||||
|
||||
|
||||
b32 is_blank_ident(String str) {
|
||||
bool is_blank_ident(String str) {
|
||||
if (str.len == 1) {
|
||||
return str.text[0] == '_';
|
||||
}
|
||||
@@ -1099,7 +1099,7 @@ void fix_advance_to_next_stmt(AstFile *f) {
|
||||
#endif
|
||||
}
|
||||
|
||||
b32 expect_semicolon_after_stmt(AstFile *f, AstNode *s) {
|
||||
bool expect_semicolon_after_stmt(AstFile *f, AstNode *s) {
|
||||
if (allow_token(f, Token_Semicolon)) {
|
||||
return true;
|
||||
}
|
||||
@@ -1122,7 +1122,7 @@ b32 expect_semicolon_after_stmt(AstFile *f, AstNode *s) {
|
||||
}
|
||||
|
||||
|
||||
AstNode * parse_expr(AstFile *f, b32 lhs);
|
||||
AstNode * parse_expr(AstFile *f, bool lhs);
|
||||
AstNode * parse_proc_type(AstFile *f);
|
||||
AstNodeArray parse_stmt_list(AstFile *f);
|
||||
AstNode * parse_stmt(AstFile *f);
|
||||
@@ -1215,7 +1215,7 @@ void check_proc_add_tag(AstFile *f, AstNode *tag_expr, u64 *tags, ProcTag tag, S
|
||||
*tags |= tag;
|
||||
}
|
||||
|
||||
b32 is_foreign_name_valid(String name) {
|
||||
bool is_foreign_name_valid(String name) {
|
||||
// TODO(bill): is_foreign_name_valid
|
||||
if (name.len == 0)
|
||||
return false;
|
||||
@@ -1340,7 +1340,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name, String *link_n
|
||||
}
|
||||
}
|
||||
|
||||
AstNode *parse_operand(AstFile *f, b32 lhs) {
|
||||
AstNode *parse_operand(AstFile *f, bool lhs) {
|
||||
AstNode *operand = NULL; // Operand
|
||||
switch (f->curr_token.kind) {
|
||||
case Token_Identifier:
|
||||
@@ -1456,7 +1456,7 @@ AstNode *parse_operand(AstFile *f, b32 lhs) {
|
||||
return make_bad_expr(f, begin, f->curr_token);
|
||||
}
|
||||
|
||||
b32 is_literal_type(AstNode *node) {
|
||||
bool is_literal_type(AstNode *node) {
|
||||
switch (node->kind) {
|
||||
case AstNode_BadExpr:
|
||||
case AstNode_Ident:
|
||||
@@ -1505,10 +1505,10 @@ AstNode *parse_call_expr(AstFile *f, AstNode *operand) {
|
||||
return make_call_expr(f, operand, args, open_paren, close_paren, ellipsis);
|
||||
}
|
||||
|
||||
AstNode *parse_atom_expr(AstFile *f, b32 lhs) {
|
||||
AstNode *parse_atom_expr(AstFile *f, bool lhs) {
|
||||
AstNode *operand = parse_operand(f, lhs);
|
||||
|
||||
b32 loop = true;
|
||||
bool loop = true;
|
||||
while (loop) {
|
||||
switch (f->curr_token.kind) {
|
||||
|
||||
@@ -1580,7 +1580,7 @@ AstNode *parse_atom_expr(AstFile *f, b32 lhs) {
|
||||
if (colon_count == 0) {
|
||||
operand = make_index_expr(f, operand, indices[0], open, close);
|
||||
} else {
|
||||
b32 triple_indexed = false;
|
||||
bool triple_indexed = false;
|
||||
if (colon_count == 2) {
|
||||
triple_indexed = true;
|
||||
if (indices[1] == NULL) {
|
||||
@@ -1632,7 +1632,7 @@ AstNode *parse_atom_expr(AstFile *f, b32 lhs) {
|
||||
|
||||
AstNode *parse_type(AstFile *f);
|
||||
|
||||
AstNode *parse_unary_expr(AstFile *f, b32 lhs) {
|
||||
AstNode *parse_unary_expr(AstFile *f, bool lhs) {
|
||||
switch (f->curr_token.kind) {
|
||||
case Token_Pointer:
|
||||
case Token_Maybe:
|
||||
@@ -1690,7 +1690,7 @@ i32 token_precedence(Token t) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
AstNode *parse_binary_expr(AstFile *f, b32 lhs, i32 prec_in) {
|
||||
AstNode *parse_binary_expr(AstFile *f, bool lhs, i32 prec_in) {
|
||||
AstNode *expression = parse_unary_expr(f, lhs);
|
||||
for (i32 prec = token_precedence(f->curr_token); prec >= prec_in; prec--) {
|
||||
for (;;) {
|
||||
@@ -1748,12 +1748,12 @@ AstNode *parse_binary_expr(AstFile *f, b32 lhs, i32 prec_in) {
|
||||
return expression;
|
||||
}
|
||||
|
||||
AstNode *parse_expr(AstFile *f, b32 lhs) {
|
||||
AstNode *parse_expr(AstFile *f, bool lhs) {
|
||||
return parse_binary_expr(f, lhs, 0+1);
|
||||
}
|
||||
|
||||
|
||||
AstNodeArray parse_expr_list(AstFile *f, b32 lhs) {
|
||||
AstNodeArray parse_expr_list(AstFile *f, bool lhs) {
|
||||
AstNodeArray list = make_ast_node_array(f);
|
||||
do {
|
||||
AstNode *e = parse_expr(f, lhs);
|
||||
@@ -1916,7 +1916,7 @@ AstNodeArray parse_parameter_list(AstFile *f) {
|
||||
|
||||
while (f->curr_token.kind == Token_Identifier ||
|
||||
f->curr_token.kind == Token_using) {
|
||||
b32 is_using = false;
|
||||
bool is_using = false;
|
||||
if (allow_token(f, Token_using)) {
|
||||
is_using = true;
|
||||
}
|
||||
@@ -1968,13 +1968,13 @@ AstNodeArray parse_parameter_list(AstFile *f) {
|
||||
}
|
||||
|
||||
|
||||
AstNodeArray parse_struct_params(AstFile *f, isize *decl_count_, b32 using_allowed) {
|
||||
AstNodeArray parse_struct_params(AstFile *f, isize *decl_count_, bool using_allowed) {
|
||||
AstNodeArray decls = make_ast_node_array(f);
|
||||
isize decl_count = 0;
|
||||
|
||||
while (f->curr_token.kind == Token_Identifier ||
|
||||
f->curr_token.kind == Token_using) {
|
||||
b32 is_using = false;
|
||||
bool is_using = false;
|
||||
if (allow_token(f, Token_using)) {
|
||||
is_using = true;
|
||||
}
|
||||
@@ -2082,8 +2082,8 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
|
||||
|
||||
case Token_struct: {
|
||||
Token token = expect_token(f, Token_struct);
|
||||
b32 is_packed = false;
|
||||
b32 is_ordered = false;
|
||||
bool is_packed = false;
|
||||
bool is_ordered = false;
|
||||
while (allow_token(f, Token_Hash)) {
|
||||
Token tag = expect_token_after(f, Token_Identifier, "`#`");
|
||||
if (str_eq(tag.string, str_lit("packed"))) {
|
||||
@@ -2299,7 +2299,7 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) {
|
||||
syntax_error(f->curr_token, "Expected type separator `:` or `=`");
|
||||
}
|
||||
|
||||
b32 is_mutable = true;
|
||||
bool is_mutable = true;
|
||||
|
||||
if (f->curr_token.kind == Token_Eq ||
|
||||
f->curr_token.kind == Token_Colon) {
|
||||
@@ -2621,7 +2621,7 @@ AstNode *parse_defer_stmt(AstFile *f) {
|
||||
|
||||
AstNode *parse_asm_stmt(AstFile *f) {
|
||||
Token token = expect_token(f, Token_asm);
|
||||
b32 is_volatile = false;
|
||||
bool is_volatile = false;
|
||||
if (allow_token(f, Token_volatile)) {
|
||||
is_volatile = true;
|
||||
}
|
||||
@@ -2695,7 +2695,7 @@ AstNode *parse_stmt(AstFile *f) {
|
||||
next_token(f);
|
||||
node = parse_stmt(f);
|
||||
|
||||
b32 valid = false;
|
||||
bool valid = false;
|
||||
|
||||
switch (node->kind) {
|
||||
case AstNode_ExprStmt: {
|
||||
@@ -2876,7 +2876,6 @@ ParseFileError init_ast_file(AstFile *f, String fullpath) {
|
||||
if (err == TokenizerInit_None) {
|
||||
array_init(&f->tokens, heap_allocator());
|
||||
{
|
||||
PROF_SCOPED("Tokenize file");
|
||||
for (;;) {
|
||||
Token token = tokenizer_get_token(&f->tokenizer);
|
||||
if (token.kind == Token_Invalid) {
|
||||
@@ -2923,7 +2922,7 @@ void destroy_ast_file(AstFile *f) {
|
||||
destroy_tokenizer(&f->tokenizer);
|
||||
}
|
||||
|
||||
b32 init_parser(Parser *p) {
|
||||
bool init_parser(Parser *p) {
|
||||
array_init(&p->files, heap_allocator());
|
||||
array_init(&p->imports, heap_allocator());
|
||||
array_init(&p->foreign_libraries, heap_allocator());
|
||||
@@ -2948,7 +2947,7 @@ 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) {
|
||||
bool try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) {
|
||||
gb_mutex_lock(&p->mutex);
|
||||
|
||||
for_array(i, p->imports) {
|
||||
@@ -3005,7 +3004,7 @@ String get_fullpath_core(gbAllocator a, String path) {
|
||||
}
|
||||
|
||||
// NOTE(bill): Returns true if it's added
|
||||
b32 try_add_foreign_library_path(Parser *p, String import_file) {
|
||||
bool try_add_foreign_library_path(Parser *p, String import_file) {
|
||||
gb_mutex_lock(&p->mutex);
|
||||
|
||||
for_array(i, p->foreign_libraries) {
|
||||
@@ -3028,7 +3027,7 @@ gb_global Rune illegal_import_runes[] = {
|
||||
'|', ',', '<', '>', '?',
|
||||
};
|
||||
|
||||
b32 is_import_path_valid(String path) {
|
||||
bool is_import_path_valid(String path) {
|
||||
if (path.len > 0) {
|
||||
u8 *start = path.text;
|
||||
u8 *end = path.text + path.len;
|
||||
@@ -3060,7 +3059,7 @@ b32 is_import_path_valid(String path) {
|
||||
|
||||
String get_filepath_extension(String path) {
|
||||
isize dot = 0;
|
||||
b32 seen_slash = false;
|
||||
bool seen_slash = false;
|
||||
for (isize i = path.len-1; i >= 0; i--) {
|
||||
u8 c = path.text[i];
|
||||
if (c == '/' || c == '\\') {
|
||||
@@ -3080,8 +3079,6 @@ String get_filepath_extension(String path) {
|
||||
}
|
||||
|
||||
void parse_file(Parser *p, AstFile *f) {
|
||||
PROF_PROC();
|
||||
|
||||
String filepath = f->tokenizer.fullpath;
|
||||
String base_dir = filepath;
|
||||
for (isize i = filepath.len-1; i >= 0; i--) {
|
||||
|
||||
120
src/profiler.cpp
120
src/profiler.cpp
@@ -1,120 +0,0 @@
|
||||
// #define PROF_TIMINGS
|
||||
|
||||
struct ProfInfo {
|
||||
String name;
|
||||
HashKey hash;
|
||||
i32 count;
|
||||
i64 total_time;
|
||||
};
|
||||
|
||||
struct Profiler {
|
||||
Map<ProfInfo> info; // Key: String
|
||||
isize max_name_len;
|
||||
i64 start_time;
|
||||
};
|
||||
|
||||
gb_global Profiler global_profiler;
|
||||
|
||||
i64 prof_get_timestamp(void) {
|
||||
LARGE_INTEGER counter;
|
||||
QueryPerformanceCounter(&counter);
|
||||
return counter.QuadPart;
|
||||
}
|
||||
|
||||
void prof_init(void) {
|
||||
#if defined(PROF_TIMINGS)
|
||||
map_init(&global_profiler.info, heap_allocator());
|
||||
global_profiler.start_time = prof_get_timestamp();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
ProfInfo prof_begin(String name) {
|
||||
ProfInfo info = {};
|
||||
info.name = name;
|
||||
info.hash = hash_pointer(name.text); // NOTE(bill): Requires it to be unique
|
||||
|
||||
info.total_time = prof_get_timestamp();
|
||||
return info;
|
||||
}
|
||||
|
||||
void prof_end(ProfInfo info) {
|
||||
i64 dt = prof_get_timestamp() - info.total_time;
|
||||
info.total_time = dt;
|
||||
|
||||
auto *found = map_get(&global_profiler.info, info.hash);
|
||||
if (found) {
|
||||
found->count++;
|
||||
found->total_time += info.total_time;
|
||||
} else {
|
||||
info.count++;
|
||||
map_set(&global_profiler.info, info.hash, info);
|
||||
if (global_profiler.max_name_len < info.name.len) {
|
||||
global_profiler.max_name_len = info.name.len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct ScopedProfInfo {
|
||||
ProfInfo info;
|
||||
ScopedProfInfo(String name) {
|
||||
info = prof_begin(name);
|
||||
}
|
||||
~ScopedProfInfo() {
|
||||
prof_end(info);
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(PROF_TIMINGS)
|
||||
#define PROF_SCOPED(msg) ScopedProfInfo scoped_prof_info_##__COUNTER__ = ScopedProfInfo(make_string(cast(u8 *)msg, gb_size_of(msg)-1))
|
||||
#else
|
||||
#define PROF_SCOPED(msg) do {} while (0)
|
||||
#endif
|
||||
#define PROF_PROC() PROF_SCOPED(__FUNCTION__)
|
||||
|
||||
void prof_print_all(void) {
|
||||
#if defined(PROF_TIMINGS)
|
||||
LARGE_INTEGER win32_perf_count_freq = {0};
|
||||
QueryPerformanceFrequency(&win32_perf_count_freq);
|
||||
GB_ASSERT(win32_perf_count_freq.QuadPart != 0);
|
||||
|
||||
gb_printf("Profiler Timings\n");
|
||||
|
||||
i32 string_offset = cast(int)global_profiler.max_name_len;
|
||||
char spaces[] = " ";
|
||||
char dashses[] = "--------------------------------------------------------------------------------";
|
||||
isize pad_len = gb_size_of(spaces)-1;
|
||||
|
||||
isize info_count = global_profiler.info.entries.count;
|
||||
ProfInfo *info_data = gb_alloc_array(heap_allocator(), ProfInfo, info_count);
|
||||
defer (gb_free(heap_allocator(), info_data));
|
||||
for (isize i = 0; i < info_count; i++) {
|
||||
info_data[i] = global_profiler.info.entries[i].value;
|
||||
}
|
||||
|
||||
gb_sort_array(info_data, info_count, gb_i64_cmp(gb_offset_of(ProfInfo, total_time)));
|
||||
|
||||
for (isize i = info_count-1; i >= 0; i--) {
|
||||
auto entry = info_data + i;
|
||||
f64 dt = (1000.0*entry->total_time / cast(f64)win32_perf_count_freq.QuadPart);
|
||||
int pad = global_profiler.max_name_len - entry->name.len;
|
||||
pad = gb_max(pad, 0);
|
||||
gb_printf("%.*s%*.*s - %.3f ms - %.3f us\n",
|
||||
LIT(entry->name),
|
||||
pad, pad, spaces,
|
||||
dt, 1000.0*dt/cast(f64)entry->count);
|
||||
}
|
||||
|
||||
i64 total_time = prof_get_timestamp() - global_profiler.start_time;
|
||||
f64 total_time_ms = (1000.0*total_time / cast(f64)win32_perf_count_freq.QuadPart);
|
||||
|
||||
|
||||
gb_printf("%*.*s\n"
|
||||
"%*.*s %.3f ms\n",
|
||||
global_profiler.max_name_len, global_profiler.max_name_len, dashses,
|
||||
global_profiler.max_name_len, global_profiler.max_name_len, spaces,
|
||||
total_time_ms);
|
||||
#endif
|
||||
}
|
||||
216
src/ssa.cpp
216
src/ssa.cpp
@@ -5,6 +5,16 @@ typedef struct ssaDebugInfo ssaDebugInfo;
|
||||
|
||||
typedef Array(ssaValue *) ssaValueArray;
|
||||
|
||||
#define MAP_TYPE ssaValue *
|
||||
#define MAP_FUNC map_ssa_value_
|
||||
#define MAP_NAME MapSsaValue
|
||||
#include "map.c"
|
||||
|
||||
#define MAP_TYPE ssaDebugInfo *
|
||||
#define MAP_FUNC map_ssa_debug_info_
|
||||
#define MAP_NAME MapSsaDebugInfo
|
||||
#include "map.c"
|
||||
|
||||
struct ssaModule {
|
||||
CheckerInfo * info;
|
||||
BaseTypeSizes sizes;
|
||||
@@ -12,7 +22,7 @@ struct ssaModule {
|
||||
gbArena tmp_arena;
|
||||
gbAllocator allocator;
|
||||
gbAllocator tmp_allocator;
|
||||
b32 generate_debug_info;
|
||||
bool generate_debug_info;
|
||||
|
||||
u32 stmt_state_flags;
|
||||
|
||||
@@ -21,13 +31,13 @@ struct ssaModule {
|
||||
// String triple;
|
||||
|
||||
|
||||
Map<Entity *> min_dep_map; // Key: Entity *
|
||||
Map<ssaValue *> values; // Key: Entity *
|
||||
Map<ssaValue *> members; // Key: String
|
||||
Map<String> type_names; // Key: Type *
|
||||
Map<ssaDebugInfo *> debug_info; // Key: Unique pointer
|
||||
i32 global_string_index;
|
||||
i32 global_array_index; // For ConstantSlice
|
||||
MapEntity min_dep_map; // Key: Entity *
|
||||
MapSsaValue values; // Key: Entity *
|
||||
MapSsaValue members; // Key: String
|
||||
MapString type_names; // Key: Type *
|
||||
MapSsaDebugInfo debug_info; // Key: Unique pointer
|
||||
i32 global_string_index;
|
||||
i32 global_array_index; // For ConstantSlice
|
||||
|
||||
Array(ssaProcedure *) procs; // NOTE(bill): All procedures with bodies
|
||||
ssaValueArray procs_to_generate; // NOTE(bill): Procedures to generate
|
||||
@@ -199,7 +209,7 @@ struct ssaInstr {
|
||||
struct {
|
||||
Entity * entity;
|
||||
Type * type;
|
||||
b32 zero_initialized;
|
||||
bool zero_initialized;
|
||||
ssaValueArray referrers;
|
||||
} Local;
|
||||
struct {
|
||||
@@ -314,7 +324,7 @@ struct ssaInstr {
|
||||
ssaValue *low;
|
||||
ssaValue *high;
|
||||
ssaValue *max;
|
||||
b32 is_substring;
|
||||
bool is_substring;
|
||||
} SliceBoundsCheck;
|
||||
};
|
||||
};
|
||||
@@ -358,14 +368,14 @@ struct ssaValue {
|
||||
String name;
|
||||
} TypeName;
|
||||
struct {
|
||||
Entity * entity;
|
||||
Type * type;
|
||||
ssaValue * value;
|
||||
Entity * entity;
|
||||
Type * type;
|
||||
ssaValue * value;
|
||||
ssaValueArray referrers;
|
||||
b8 is_constant;
|
||||
b8 is_private;
|
||||
b8 is_thread_local;
|
||||
b8 is_unnamed_addr;
|
||||
bool is_constant;
|
||||
bool is_private;
|
||||
bool is_thread_local;
|
||||
bool is_unnamed_addr;
|
||||
} Global;
|
||||
struct {
|
||||
ssaProcedure * parent;
|
||||
@@ -540,11 +550,11 @@ struct ssaDebugInfo {
|
||||
struct ssaGen {
|
||||
ssaModule module;
|
||||
gbFile output_file;
|
||||
b32 opt_called;
|
||||
bool opt_called;
|
||||
};
|
||||
|
||||
ssaValue *ssa_lookup_member(ssaModule *m, String name) {
|
||||
ssaValue **v = map_get(&m->members, hash_string(name));
|
||||
ssaValue **v = map_ssa_value_get(&m->members, hash_string(name));
|
||||
if (v != NULL) {
|
||||
return *v;
|
||||
}
|
||||
@@ -638,7 +648,7 @@ Type *ssa_addr_type(ssaAddr lval) {
|
||||
|
||||
|
||||
|
||||
b32 ssa_is_blank_ident(AstNode *node) {
|
||||
bool ssa_is_blank_ident(AstNode *node) {
|
||||
if (node->kind == AstNode_Ident) {
|
||||
ast_node(i, Ident, node);
|
||||
return is_blank_ident(i->string);
|
||||
@@ -660,7 +670,7 @@ ssaInstr *ssa_get_last_instr(ssaBlock *block) {
|
||||
|
||||
}
|
||||
|
||||
b32 ssa_is_instr_terminating(ssaInstr *i) {
|
||||
bool ssa_is_instr_terminating(ssaInstr *i) {
|
||||
if (i != NULL) {
|
||||
switch (i->kind) {
|
||||
case ssaInstr_Return:
|
||||
@@ -786,7 +796,7 @@ ssaValue *ssa_make_value_nil(gbAllocator a, Type *type) {
|
||||
|
||||
|
||||
|
||||
ssaValue *ssa_make_instr_local(ssaProcedure *p, Entity *e, b32 zero_initialized) {
|
||||
ssaValue *ssa_make_instr_local(ssaProcedure *p, Entity *e, bool zero_initialized) {
|
||||
ssaValue *v = ssa_alloc_instr(p, ssaInstr_Local);
|
||||
ssaInstr *i = &v->Instr;
|
||||
i->Local.entity = e;
|
||||
@@ -1014,7 +1024,7 @@ ssaValue *ssa_make_instr_bounds_check(ssaProcedure *p, TokenPos pos, ssaValue *i
|
||||
v->Instr.BoundsCheck.len = len;
|
||||
return v;
|
||||
}
|
||||
ssaValue *ssa_make_instr_slice_bounds_check(ssaProcedure *p, TokenPos pos, ssaValue *low, ssaValue *high, ssaValue *max, b32 is_substring) {
|
||||
ssaValue *ssa_make_instr_slice_bounds_check(ssaProcedure *p, TokenPos pos, ssaValue *low, ssaValue *high, ssaValue *max, bool is_substring) {
|
||||
ssaValue *v = ssa_alloc_instr(p, ssaInstr_SliceBoundsCheck);
|
||||
v->Instr.SliceBoundsCheck.pos = pos;
|
||||
v->Instr.SliceBoundsCheck.low = low;
|
||||
@@ -1051,7 +1061,7 @@ ssaValue *ssa_make_const_i32(gbAllocator a, i64 i) {
|
||||
ssaValue *ssa_make_const_i64(gbAllocator a, i64 i) {
|
||||
return ssa_make_value_constant(a, t_i64, make_exact_value_integer(i));
|
||||
}
|
||||
ssaValue *ssa_make_const_bool(gbAllocator a, b32 b) {
|
||||
ssaValue *ssa_make_const_bool(gbAllocator a, bool b) {
|
||||
return ssa_make_value_constant(a, t_bool, make_exact_value_bool(b != 0));
|
||||
}
|
||||
ssaValue *ssa_make_const_string(gbAllocator a, String s) {
|
||||
@@ -1078,7 +1088,7 @@ ssaValue *ssa_make_value_procedure(gbAllocator a, ssaModule *m, Entity *entity,
|
||||
ssaBlock *ssa_add_block(ssaProcedure *proc, AstNode *node, char *label) {
|
||||
Scope *scope = NULL;
|
||||
if (node != NULL) {
|
||||
Scope **found = map_get(&proc->module->info->scopes, hash_pointer(node));
|
||||
Scope **found = map_scope_get(&proc->module->info->scopes, hash_pointer(node));
|
||||
if (found) {
|
||||
scope = *found;
|
||||
} else {
|
||||
@@ -1157,7 +1167,7 @@ ssaValue *ssa_add_module_constant(ssaModule *m, Type *type, ExactValue value) {
|
||||
Entity *e = make_entity_constant(a, NULL, make_token_ident(name), t, value);
|
||||
ssaValue *g = ssa_make_value_global(a, e, backing_array);
|
||||
ssa_module_add_value(m, e, g);
|
||||
map_set(&m->members, hash_string(name), g);
|
||||
map_ssa_value_set(&m->members, hash_string(name), g);
|
||||
|
||||
return ssa_make_value_constant_slice(a, type, g, count);
|
||||
}
|
||||
@@ -1188,7 +1198,7 @@ ssaValue *ssa_add_global_string_array(ssaModule *m, String string) {
|
||||
// g->Global.is_constant = true;
|
||||
|
||||
ssa_module_add_value(m, entity, g);
|
||||
map_set(&m->members, hash_string(name), g);
|
||||
map_ssa_value_set(&m->members, hash_string(name), g);
|
||||
|
||||
return g;
|
||||
}
|
||||
@@ -1196,7 +1206,7 @@ ssaValue *ssa_add_global_string_array(ssaModule *m, String string) {
|
||||
|
||||
|
||||
|
||||
ssaValue *ssa_add_local(ssaProcedure *proc, Entity *e, b32 zero_initialized = true) {
|
||||
ssaValue *ssa_add_local(ssaProcedure *proc, Entity *e, bool zero_initialized = true) {
|
||||
ssaBlock *b = proc->decl_block; // all variables must be in the first block
|
||||
ssaValue *instr = ssa_make_instr_local(proc, e, zero_initialized);
|
||||
instr->Instr.parent = b;
|
||||
@@ -1211,8 +1221,8 @@ ssaValue *ssa_add_local(ssaProcedure *proc, Entity *e, b32 zero_initialized = tr
|
||||
return instr;
|
||||
}
|
||||
|
||||
ssaValue *ssa_add_local_for_identifier(ssaProcedure *proc, AstNode *name, b32 zero_initialized) {
|
||||
Entity **found = map_get(&proc->module->info->definitions, hash_pointer(name));
|
||||
ssaValue *ssa_add_local_for_identifier(ssaProcedure *proc, AstNode *name, bool zero_initialized) {
|
||||
Entity **found = map_entity_get(&proc->module->info->definitions, hash_pointer(name));
|
||||
if (found) {
|
||||
Entity *e = *found;
|
||||
ssa_emit_comment(proc, e->token.string);
|
||||
@@ -1281,7 +1291,7 @@ ssaDebugInfo *ssa_add_debug_info_file(ssaProcedure *proc, AstFile *file) {
|
||||
di->File.filename = filename;
|
||||
di->File.directory = directory;
|
||||
|
||||
map_set(&proc->module->debug_info, hash_pointer(file), di);
|
||||
map_ssa_debug_info_set(&proc->module->debug_info, hash_pointer(file), di);
|
||||
return di;
|
||||
}
|
||||
|
||||
@@ -1298,7 +1308,7 @@ ssaDebugInfo *ssa_add_debug_info_proc(ssaProcedure *proc, Entity *entity, String
|
||||
di->Proc.file = file;
|
||||
di->Proc.pos = entity->token.pos;
|
||||
|
||||
map_set(&proc->module->debug_info, hash_pointer(entity), di);
|
||||
map_ssa_debug_info_set(&proc->module->debug_info, hash_pointer(entity), di);
|
||||
return di;
|
||||
}
|
||||
|
||||
@@ -1349,7 +1359,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_c(name_);
|
||||
ssaValue **found = map_get(&proc->module->members, hash_string(name));
|
||||
ssaValue **found = map_ssa_value_get(&proc->module->members, hash_string(name));
|
||||
GB_ASSERT_MSG(found != NULL, "%.*s", LIT(name));
|
||||
ssaValue *gp = *found;
|
||||
return ssa_emit_call(proc, gp, args, arg_count);
|
||||
@@ -1875,8 +1885,8 @@ String lookup_polymorphic_field(CheckerInfo *info, Type *dst, Type *src) {
|
||||
// Type *prev_dst = dst;
|
||||
src = base_type(type_deref(src));
|
||||
// dst = base_type(type_deref(dst));
|
||||
b32 src_is_ptr = src != prev_src;
|
||||
// b32 dst_is_ptr = dst != prev_dst;
|
||||
bool src_is_ptr = src != prev_src;
|
||||
// bool dst_is_ptr = dst != prev_dst;
|
||||
|
||||
GB_ASSERT(is_type_struct(src));
|
||||
for (isize i = 0; i < src->Record.field_count; i++) {
|
||||
@@ -2041,7 +2051,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) {
|
||||
// subtype polymorphism casting
|
||||
{
|
||||
Type *sb = base_type(type_deref(src));
|
||||
b32 src_is_ptr = src != sb;
|
||||
bool src_is_ptr = src != sb;
|
||||
if (is_type_struct(sb)) {
|
||||
String field_name = lookup_polymorphic_field(proc->module->info, t, src);
|
||||
// gb_printf("field_name: %.*s\n", LIT(field_name));
|
||||
@@ -2164,7 +2174,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b32 ssa_is_type_aggregate(Type *t) {
|
||||
bool ssa_is_type_aggregate(Type *t) {
|
||||
t = base_type(get_enum_base_type(t));
|
||||
switch (t->kind) {
|
||||
case Type_Basic:
|
||||
@@ -2245,7 +2255,7 @@ ssaValue *ssa_emit_union_cast(ssaProcedure *proc, ssaValue *value, Type *tuple)
|
||||
gbAllocator a = proc->module->allocator;
|
||||
|
||||
Type *src_type = ssa_type(value);
|
||||
b32 is_ptr = is_type_pointer(src_type);
|
||||
bool is_ptr = is_type_pointer(src_type);
|
||||
|
||||
ssaValue *v = ssa_add_local_generated(proc, tuple);
|
||||
|
||||
@@ -2330,7 +2340,7 @@ isize ssa_type_info_index(CheckerInfo *info, Type *type) {
|
||||
|
||||
isize entry_index = -1;
|
||||
HashKey key = hash_pointer(type);
|
||||
auto *found_entry_index = map_get(&info->type_info_map, key);
|
||||
isize *found_entry_index = map_isize_get(&info->type_info_map, key);
|
||||
if (found_entry_index) {
|
||||
entry_index = *found_entry_index;
|
||||
}
|
||||
@@ -2343,7 +2353,7 @@ isize ssa_type_info_index(CheckerInfo *info, Type *type) {
|
||||
if (are_types_identical(prev_type, type)) {
|
||||
entry_index = e->value;
|
||||
// NOTE(bill): Add it to the search map
|
||||
map_set(&info->type_info_map, key, entry_index);
|
||||
map_isize_set(&info->type_info_map, key, entry_index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -2356,7 +2366,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(str_lit(SSA_TYPE_INFO_DATA_NAME)));
|
||||
ssaValue **found = map_ssa_value_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;
|
||||
@@ -2456,7 +2466,7 @@ void ssa_emit_bounds_check(ssaProcedure *proc, Token token, ssaValue *index, ssa
|
||||
// ssa_emit_global_call(proc, "__bounds_check_error", args, 5);
|
||||
}
|
||||
|
||||
void ssa_emit_slice_bounds_check(ssaProcedure *proc, Token token, ssaValue *low, ssaValue *high, ssaValue *max, b32 is_substring) {
|
||||
void ssa_emit_slice_bounds_check(ssaProcedure *proc, Token token, ssaValue *low, ssaValue *high, ssaValue *max, bool is_substring) {
|
||||
if ((proc->module->stmt_state_flags & StmtStateFlag_no_bounds_check) != 0) {
|
||||
return;
|
||||
}
|
||||
@@ -2522,14 +2532,14 @@ void ssa_mangle_sub_type_name(ssaModule *m, Entity *field, String parent) {
|
||||
child.text[i++] = '.';
|
||||
gb_memmove(child.text+i, cn.text, cn.len);
|
||||
|
||||
map_set(&m->type_names, hash_pointer(field->type), child);
|
||||
map_string_set(&m->type_names, hash_pointer(field->type), child);
|
||||
ssa_gen_global_type_name(m, field, child);
|
||||
}
|
||||
|
||||
void ssa_gen_global_type_name(ssaModule *m, Entity *e, String name) {
|
||||
ssaValue *t = ssa_make_value_type_name(m->allocator, name, e->type);
|
||||
ssa_module_add_value(m, e, t);
|
||||
map_set(&m->members, hash_string(name), t);
|
||||
map_ssa_value_set(&m->members, hash_string(name), t);
|
||||
|
||||
Type *bt = base_type(e->type);
|
||||
if (bt->kind == Type_Record) {
|
||||
@@ -2572,7 +2582,7 @@ void ssa_build_defer_stmt(ssaProcedure *proc, ssaDefer d) {
|
||||
|
||||
|
||||
ssaValue *ssa_find_global_variable(ssaProcedure *proc, String name) {
|
||||
ssaValue **value = map_get(&proc->module->members, hash_string(name));
|
||||
ssaValue **value = map_ssa_value_get(&proc->module->members, hash_string(name));
|
||||
GB_ASSERT_MSG(value != NULL, "Unable to find global variable `%.*s`", LIT(name));
|
||||
return *value;
|
||||
}
|
||||
@@ -2581,7 +2591,7 @@ ssaValue *ssa_find_implicit_value_backing(ssaProcedure *proc, ImplicitValueId id
|
||||
Entity *e = proc->module->info->implicit_values[id];
|
||||
GB_ASSERT(e->kind == Entity_ImplicitValue);
|
||||
Entity *backing = e->ImplicitValue.backing;
|
||||
ssaValue **value = map_get(&proc->module->values, hash_pointer(backing));
|
||||
ssaValue **value = map_ssa_value_get(&proc->module->values, hash_pointer(backing));
|
||||
GB_ASSERT_MSG(value != NULL, "Unable to find implicit value backing `%.*s`", LIT(backing->token.string));
|
||||
return *value;
|
||||
}
|
||||
@@ -2596,7 +2606,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
||||
case_end;
|
||||
|
||||
case_ast_node(i, Ident, expr);
|
||||
Entity *e = *map_get(&proc->module->info->uses, hash_pointer(expr));
|
||||
Entity *e = *map_entity_get(&proc->module->info->uses, hash_pointer(expr));
|
||||
if (e->kind == Entity_Builtin) {
|
||||
Token token = ast_node_token(expr);
|
||||
GB_PANIC("TODO(bill): ssa_build_single_expr Entity_Builtin `%.*s`\n"
|
||||
@@ -2609,7 +2619,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
||||
return ssa_emit_load(proc, ssa_find_implicit_value_backing(proc, e->ImplicitValue.id));
|
||||
}
|
||||
|
||||
auto *found = map_get(&proc->module->values, hash_pointer(e));
|
||||
ssaValue **found = map_ssa_value_get(&proc->module->values, hash_pointer(e));
|
||||
if (found) {
|
||||
ssaValue *v = *found;
|
||||
if (v->kind == ssaValue_Proc) {
|
||||
@@ -2633,7 +2643,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
||||
case_end;
|
||||
|
||||
case_ast_node(se, SelectorExpr, expr);
|
||||
TypeAndValue *tav = map_get(&proc->module->info->types, hash_pointer(expr));
|
||||
TypeAndValue *tav = map_tav_get(&proc->module->info->types, hash_pointer(expr));
|
||||
GB_ASSERT(tav != NULL);
|
||||
return ssa_addr_load(proc, ssa_build_addr(proc, expr));
|
||||
case_end;
|
||||
@@ -2751,7 +2761,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
||||
case_ast_node(ce, CallExpr, expr);
|
||||
AstNode *p = unparen_expr(ce->proc);
|
||||
if (p->kind == AstNode_Ident) {
|
||||
Entity **found = map_get(&proc->module->info->uses, hash_pointer(p));
|
||||
Entity **found = map_entity_get(&proc->module->info->uses, hash_pointer(p));
|
||||
if (found && (*found)->kind == Entity_Builtin) {
|
||||
Entity *e = *found;
|
||||
switch (e->Builtin.id) {
|
||||
@@ -3136,8 +3146,8 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
||||
}
|
||||
}
|
||||
ssaValue **args = gb_alloc_array(proc->module->allocator, ssaValue *, arg_count);
|
||||
b32 variadic = proc_type_->Proc.variadic;
|
||||
b32 vari_expand = ce->ellipsis.pos.line != 0;
|
||||
bool variadic = proc_type_->Proc.variadic;
|
||||
bool vari_expand = ce->ellipsis.pos.line != 0;
|
||||
|
||||
for_array(i, ce->args) {
|
||||
ssaValue *a = ssa_build_expr(proc, ce->args.e[i]);
|
||||
@@ -3231,7 +3241,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
|
||||
ssaValue *ssa_build_expr(ssaProcedure *proc, AstNode *expr) {
|
||||
expr = unparen_expr(expr);
|
||||
|
||||
TypeAndValue *tv = map_get(&proc->module->info->types, hash_pointer(expr));
|
||||
TypeAndValue *tv = map_tav_get(&proc->module->info->types, hash_pointer(expr));
|
||||
GB_ASSERT_NOT_NULL(tv);
|
||||
|
||||
if (tv->value.kind != ExactValue_Invalid) {
|
||||
@@ -3254,7 +3264,7 @@ ssaValue *ssa_add_using_variable(ssaProcedure *proc, Entity *e) {
|
||||
Entity *parent = e->using_parent;
|
||||
Selection sel = lookup_field(proc->module->allocator, parent->type, name, false);
|
||||
GB_ASSERT(sel.entity != NULL);
|
||||
ssaValue **pv = map_get(&proc->module->values, hash_pointer(parent));
|
||||
ssaValue **pv = map_ssa_value_get(&proc->module->values, hash_pointer(parent));
|
||||
ssaValue *v = NULL;
|
||||
if (pv != NULL) {
|
||||
v = *pv;
|
||||
@@ -3263,7 +3273,7 @@ ssaValue *ssa_add_using_variable(ssaProcedure *proc, Entity *e) {
|
||||
}
|
||||
GB_ASSERT(v != NULL);
|
||||
ssaValue *var = ssa_emit_deep_field_gep(proc, parent->type, v, sel);
|
||||
map_set(&proc->module->values, hash_pointer(e), var);
|
||||
map_ssa_value_set(&proc->module->values, hash_pointer(e), var);
|
||||
return var;
|
||||
}
|
||||
|
||||
@@ -3276,12 +3286,12 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
|
||||
}
|
||||
|
||||
Entity *e = entity_of_ident(proc->module->info, expr);
|
||||
TypeAndValue *tv = map_get(&proc->module->info->types, hash_pointer(expr));
|
||||
TypeAndValue *tv = map_tav_get(&proc->module->info->types, hash_pointer(expr));
|
||||
|
||||
GB_ASSERT(e->kind != Entity_Constant);
|
||||
|
||||
ssaValue *v = NULL;
|
||||
ssaValue **found = map_get(&proc->module->values, hash_pointer(e));
|
||||
ssaValue **found = map_ssa_value_get(&proc->module->values, hash_pointer(e));
|
||||
if (found) {
|
||||
v = *found;
|
||||
} else if (e->kind == Entity_Variable && e->flags & EntityFlag_Anonymous) {
|
||||
@@ -3364,7 +3374,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
|
||||
gbAllocator a = proc->module->allocator;
|
||||
|
||||
|
||||
b32 deref = is_type_pointer(t);
|
||||
bool deref = is_type_pointer(t);
|
||||
t = type_deref(t);
|
||||
|
||||
ssaValue *using_addr = NULL;
|
||||
@@ -3435,7 +3445,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
|
||||
} break;
|
||||
|
||||
case Type_Basic: { // Basic_string
|
||||
TypeAndValue *tv = map_get(&proc->module->info->types, hash_pointer(ie->expr));
|
||||
TypeAndValue *tv = map_tav_get(&proc->module->info->types, hash_pointer(ie->expr));
|
||||
ssaValue *str;
|
||||
ssaValue *elem;
|
||||
ssaValue *len;
|
||||
@@ -3598,7 +3608,7 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
|
||||
case Type_Slice: et = bt->Slice.elem; break;
|
||||
}
|
||||
|
||||
auto is_elem_const = [](ssaModule *m, AstNode *elem, Type *elem_type) -> b32 {
|
||||
auto is_elem_const = [](ssaModule *m, AstNode *elem, Type *elem_type) -> bool {
|
||||
if (base_type(elem_type) == t_any) {
|
||||
return false;
|
||||
}
|
||||
@@ -3903,12 +3913,12 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
|
||||
if (pd->body != NULL) {
|
||||
auto *info = proc->module->info;
|
||||
|
||||
Entity **found = map_get(&info->definitions, hash_pointer(pd->name));
|
||||
Entity **found = map_entity_get(&info->definitions, hash_pointer(pd->name));
|
||||
GB_ASSERT_MSG(found != NULL, "Unable to find: %.*s", LIT(pd->name->Ident.string));
|
||||
Entity *e = *found;
|
||||
|
||||
|
||||
if (map_get(&proc->module->min_dep_map, hash_pointer(e)) == NULL) {
|
||||
if (map_entity_get(&proc->module->min_dep_map, hash_pointer(e)) == NULL) {
|
||||
// NOTE(bill): Nothing depends upon it so doesn't need to be built
|
||||
break;
|
||||
}
|
||||
@@ -3940,7 +3950,7 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
|
||||
} else {
|
||||
auto *info = proc->module->info;
|
||||
|
||||
Entity **found = map_get(&info->definitions, hash_pointer(pd->name));
|
||||
Entity **found = map_entity_get(&info->definitions, hash_pointer(pd->name));
|
||||
GB_ASSERT_MSG(found != NULL, "Unable to find: %.*s", LIT(pd->name->Ident.string));
|
||||
Entity *e = *found;
|
||||
|
||||
@@ -3961,10 +3971,10 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
|
||||
|
||||
if (value->Proc.tags & ProcTag_foreign) {
|
||||
HashKey key = hash_string(name);
|
||||
auto *prev_value = map_get(&proc->module->members, key);
|
||||
ssaValue **prev_value = map_ssa_value_get(&proc->module->members, key);
|
||||
if (prev_value == NULL) {
|
||||
// NOTE(bill): Don't do mutliple declarations in the IR
|
||||
map_set(&proc->module->members, key, value);
|
||||
map_ssa_value_set(&proc->module->members, key, value);
|
||||
}
|
||||
} else {
|
||||
array_add(&proc->children, &value->Proc);
|
||||
@@ -3983,12 +3993,12 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
|
||||
name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s.%.*s-%d", LIT(proc->name), LIT(td_name), guid);
|
||||
String name = make_string(name_text, name_len-1);
|
||||
|
||||
Entity **found = map_get(&proc->module->info->definitions, hash_pointer(td->name));
|
||||
Entity **found = map_entity_get(&proc->module->info->definitions, hash_pointer(td->name));
|
||||
GB_ASSERT(found != NULL);
|
||||
Entity *e = *found;
|
||||
ssaValue *value = ssa_make_value_type_name(proc->module->allocator,
|
||||
name, e->type);
|
||||
map_set(&proc->module->type_names, hash_pointer(e->type), name);
|
||||
map_string_set(&proc->module->type_names, hash_pointer(e->type), name);
|
||||
ssa_gen_global_type_name(proc->module, e, name);
|
||||
case_end;
|
||||
|
||||
@@ -4253,7 +4263,7 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
|
||||
ssaBlock *default_block = NULL;
|
||||
|
||||
ssaBlock *fall = NULL;
|
||||
b32 append_fall = false;
|
||||
bool append_fall = false;
|
||||
|
||||
isize case_count = body->stmts.count;
|
||||
for_array(i, body->stmts) {
|
||||
@@ -4329,8 +4339,8 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
|
||||
gbAllocator allocator = proc->module->allocator;
|
||||
|
||||
ssaValue *parent = ssa_build_expr(proc, ms->tag);
|
||||
b32 is_union_ptr = false;
|
||||
b32 is_any = false;
|
||||
bool is_union_ptr = false;
|
||||
bool is_any = false;
|
||||
GB_ASSERT(check_valid_type_match_type(ssa_type(parent), &is_union_ptr, &is_any));
|
||||
|
||||
ssaValue *tag_index = NULL;
|
||||
@@ -4370,7 +4380,7 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) {
|
||||
|
||||
ssaBlock *body = ssa_add_block(proc, clause, "type-match.case.body");
|
||||
|
||||
Scope *scope = *map_get(&proc->module->info->scopes, hash_pointer(clause));
|
||||
Scope *scope = *map_scope_get(&proc->module->info->scopes, hash_pointer(clause));
|
||||
Entity *tag_var_entity = current_scope_lookup_entity(scope, tag_var_name);
|
||||
GB_ASSERT_MSG(tag_var_entity != NULL, "%.*s", LIT(tag_var_name));
|
||||
|
||||
@@ -4599,12 +4609,12 @@ void ssa_build_proc(ssaValue *value, ssaProcedure *parent) {
|
||||
CheckerInfo *info = m->info;
|
||||
Entity *e = proc->entity;
|
||||
String filename = e->token.pos.file;
|
||||
AstFile **found = map_get(&info->files, hash_string(filename));
|
||||
AstFile **found = map_ast_file_get(&info->files, hash_string(filename));
|
||||
GB_ASSERT(found != NULL);
|
||||
AstFile *f = *found;
|
||||
ssaDebugInfo *di_file = NULL;
|
||||
|
||||
ssaDebugInfo **di_file_found = map_get(&m->debug_info, hash_pointer(f));
|
||||
ssaDebugInfo **di_file_found = map_ssa_debug_info_get(&m->debug_info, hash_pointer(f));
|
||||
if (di_file_found) {
|
||||
di_file = *di_file_found;
|
||||
GB_ASSERT(di_file->kind == ssaDebugInfo_File);
|
||||
@@ -4656,7 +4666,7 @@ void ssa_build_proc(ssaValue *value, ssaProcedure *parent) {
|
||||
|
||||
|
||||
void ssa_module_add_value(ssaModule *m, Entity *e, ssaValue *v) {
|
||||
map_set(&m->values, hash_pointer(e), v);
|
||||
map_ssa_value_set(&m->values, hash_pointer(e), v);
|
||||
}
|
||||
|
||||
void ssa_init_module(ssaModule *m, Checker *c) {
|
||||
@@ -4670,10 +4680,10 @@ void ssa_init_module(ssaModule *m, Checker *c) {
|
||||
m->info = &c->info;
|
||||
m->sizes = c->sizes;
|
||||
|
||||
map_init(&m->values, heap_allocator());
|
||||
map_init(&m->members, heap_allocator());
|
||||
map_init(&m->debug_info, heap_allocator());
|
||||
map_init(&m->type_names, heap_allocator());
|
||||
map_ssa_value_init(&m->values, heap_allocator());
|
||||
map_ssa_value_init(&m->members, heap_allocator());
|
||||
map_ssa_debug_info_init(&m->debug_info, heap_allocator());
|
||||
map_string_init(&m->type_names, heap_allocator());
|
||||
array_init(&m->procs, heap_allocator());
|
||||
array_init(&m->procs_to_generate, heap_allocator());
|
||||
|
||||
@@ -4690,7 +4700,7 @@ void ssa_init_module(ssaModule *m, Checker *c) {
|
||||
ssaValue *g = ssa_make_value_global(m->allocator, e, NULL);
|
||||
g->Global.is_private = true;
|
||||
ssa_module_add_value(m, e, g);
|
||||
map_set(&m->members, hash_string(name), g);
|
||||
map_ssa_value_set(&m->members, hash_string(name), g);
|
||||
}
|
||||
|
||||
// Type info member buffer
|
||||
@@ -4721,7 +4731,7 @@ void ssa_init_module(ssaModule *m, Checker *c) {
|
||||
make_type_array(m->allocator, t_type_info_member, count));
|
||||
ssaValue *g = ssa_make_value_global(m->allocator, e, NULL);
|
||||
ssa_module_add_value(m, e, g);
|
||||
map_set(&m->members, hash_string(name), g);
|
||||
map_ssa_value_set(&m->members, hash_string(name), g);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4730,15 +4740,15 @@ void ssa_init_module(ssaModule *m, Checker *c) {
|
||||
di->CompileUnit.file = m->info->files.entries.e[0].value; // Zeroth is the init file
|
||||
di->CompileUnit.producer = str_lit("odin");
|
||||
|
||||
map_set(&m->debug_info, hash_pointer(m), di);
|
||||
map_ssa_debug_info_set(&m->debug_info, hash_pointer(m), di);
|
||||
}
|
||||
}
|
||||
|
||||
void ssa_destroy_module(ssaModule *m) {
|
||||
map_destroy(&m->values);
|
||||
map_destroy(&m->members);
|
||||
map_destroy(&m->type_names);
|
||||
map_destroy(&m->debug_info);
|
||||
map_ssa_value_destroy(&m->values);
|
||||
map_ssa_value_destroy(&m->members);
|
||||
map_string_destroy(&m->type_names);
|
||||
map_ssa_debug_info_destroy(&m->debug_info);
|
||||
array_free(&m->procs_to_generate);
|
||||
gb_arena_free(&m->arena);
|
||||
}
|
||||
@@ -4752,7 +4762,7 @@ void ssa_destroy_module(ssaModule *m) {
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
b32 ssa_gen_init(ssaGen *s, Checker *c) {
|
||||
bool ssa_gen_init(ssaGen *s, Checker *c) {
|
||||
if (global_error_collector.count != 0) {
|
||||
return false;
|
||||
}
|
||||
@@ -4787,7 +4797,7 @@ String ssa_mangle_name(ssaGen *s, String path, String name) {
|
||||
ssaModule *m = &s->module;
|
||||
CheckerInfo *info = m->info;
|
||||
gbAllocator a = m->allocator;
|
||||
AstFile *file = *map_get(&info->files, hash_string(path));
|
||||
AstFile *file = *map_ast_file_get(&info->files, hash_string(path));
|
||||
|
||||
char *str = gb_alloc_array(a, char, path.len+1);
|
||||
gb_memmove(str, path.text, path.len);
|
||||
@@ -4866,7 +4876,7 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (map_get(&m->min_dep_map, hash_pointer(e)) == NULL) {
|
||||
if (map_entity_get(&m->min_dep_map, hash_pointer(e)) == NULL) {
|
||||
// NOTE(bill): Nothing depends upon it so doesn't need to be built
|
||||
continue;
|
||||
}
|
||||
@@ -4879,7 +4889,7 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
switch (e->kind) {
|
||||
case Entity_TypeName:
|
||||
GB_ASSERT(e->type->kind == Type_Named);
|
||||
map_set(&m->type_names, hash_pointer(e->type), name);
|
||||
map_string_set(&m->type_names, hash_pointer(e->type), name);
|
||||
ssa_gen_global_type_name(m, e, name);
|
||||
break;
|
||||
|
||||
@@ -4893,7 +4903,7 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
var.decl = decl;
|
||||
|
||||
if (decl->init_expr != NULL) {
|
||||
TypeAndValue *tav = map_get(&info->types, hash_pointer(decl->init_expr));
|
||||
TypeAndValue *tav = map_tav_get(&info->types, hash_pointer(decl->init_expr));
|
||||
if (tav != NULL) {
|
||||
if (tav->value.kind != ExactValue_Invalid) {
|
||||
ExactValue v = tav->value;
|
||||
@@ -4908,8 +4918,8 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
array_add(&global_variables, var);
|
||||
}
|
||||
|
||||
map_set(&m->values, hash_pointer(e), g);
|
||||
map_set(&m->members, hash_string(name), g);
|
||||
map_ssa_value_set(&m->values, hash_pointer(e), g);
|
||||
map_ssa_value_set(&m->members, hash_string(name), g);
|
||||
} break;
|
||||
|
||||
case Entity_Procedure: {
|
||||
@@ -4928,10 +4938,10 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
ssaValue *p = ssa_make_value_procedure(a, m, e, e->type, decl->type_expr, body, name);
|
||||
p->Proc.tags = pd->tags;
|
||||
|
||||
map_set(&m->values, hash_pointer(e), p);
|
||||
map_ssa_value_set(&m->values, hash_pointer(e), p);
|
||||
HashKey hash_name = hash_string(name);
|
||||
if (map_get(&m->members, hash_name) == NULL) {
|
||||
map_set(&m->members, hash_name, p);
|
||||
if (map_ssa_value_get(&m->members, hash_name) == NULL) {
|
||||
map_ssa_value_set(&m->members, hash_name, p);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
@@ -4959,7 +4969,7 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
}
|
||||
|
||||
array_init_reserve(&all_procs->AllProcs.procs, m->allocator, all_proc_max_count);
|
||||
map_set(&m->debug_info, hash_pointer(all_procs), all_procs); // NOTE(bill): This doesn't need to be mapped
|
||||
map_ssa_debug_info_set(&m->debug_info, hash_pointer(all_procs), all_procs); // NOTE(bill): This doesn't need to be mapped
|
||||
compile_unit->CompileUnit.all_procs = all_procs;
|
||||
|
||||
|
||||
@@ -4985,8 +4995,8 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
token.string = name;
|
||||
Entity *e = make_entity_procedure(a, NULL, token, proc_type);
|
||||
|
||||
map_set(&m->values, hash_pointer(e), p);
|
||||
map_set(&m->members, hash_string(name), p);
|
||||
map_ssa_value_set(&m->values, hash_pointer(e), p);
|
||||
map_ssa_value_set(&m->members, hash_string(name), p);
|
||||
|
||||
ssaProcedure *proc = &p->Proc;
|
||||
proc->tags = ProcTag_no_inline; // TODO(bill): is no_inline a good idea?
|
||||
@@ -5026,11 +5036,11 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
ssaValue *type_info_member_data = NULL;
|
||||
|
||||
ssaValue **found = NULL;
|
||||
found = map_get(&proc->module->members, hash_string(str_lit(SSA_TYPE_INFO_DATA_NAME)));
|
||||
found = map_ssa_value_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(str_lit(SSA_TYPE_INFO_DATA_MEMBER_NAME)));
|
||||
found = map_ssa_value_get(&proc->module->members, hash_string(str_lit(SSA_TYPE_INFO_DATA_MEMBER_NAME)));
|
||||
GB_ASSERT(found != NULL);
|
||||
type_info_member_data = *found;
|
||||
|
||||
@@ -5094,7 +5104,7 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
case Basic_int:
|
||||
case Basic_uint: {
|
||||
tag = ssa_add_local_generated(proc, t_type_info_integer);
|
||||
b32 is_unsigned = (t->Basic.flags & BasicFlag_Unsigned) != 0;
|
||||
bool is_unsigned = (t->Basic.flags & BasicFlag_Unsigned) != 0;
|
||||
ssaValue *bits = ssa_make_const_int(a, type_size_of(m->sizes, a, t));
|
||||
ssaValue *is_signed = ssa_make_const_bool(a, !is_unsigned);
|
||||
ssa_emit_store(proc, ssa_emit_struct_ep(proc, tag, 0), bits);
|
||||
@@ -5302,7 +5312,7 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
value_array = ssa_make_value_global(a, e, NULL);
|
||||
value_array->Global.is_private = true;
|
||||
ssa_module_add_value(m, e, value_array);
|
||||
map_set(&m->members, hash_string(token.string), value_array);
|
||||
map_ssa_value_set(&m->members, hash_string(token.string), value_array);
|
||||
}
|
||||
{
|
||||
Token token = {Token_Identifier};
|
||||
@@ -5316,7 +5326,7 @@ void ssa_gen_tree(ssaGen *s) {
|
||||
name_array = ssa_make_value_global(a, e, NULL);
|
||||
name_array->Global.is_private = true;
|
||||
ssa_module_add_value(m, e, name_array);
|
||||
map_set(&m->members, hash_string(token.string), name_array);
|
||||
map_ssa_value_set(&m->members, hash_string(token.string), name_array);
|
||||
}
|
||||
|
||||
for (isize i = 0; i < count; i++) {
|
||||
|
||||
@@ -115,7 +115,7 @@ void ssa_opt_block_replace_succ(ssaBlock *b, ssaBlock *from, ssaBlock *to) {
|
||||
}
|
||||
}
|
||||
|
||||
b32 ssa_opt_block_has_phi(ssaBlock *b) {
|
||||
bool ssa_opt_block_has_phi(ssaBlock *b) {
|
||||
return b->instrs.e[0]->Instr.kind == ssaInstr_Phi;
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ void ssa_remove_unreachable_blocks(ssaProcedure *proc) {
|
||||
ssa_remove_dead_blocks(proc);
|
||||
}
|
||||
|
||||
b32 ssa_opt_block_fusion(ssaProcedure *proc, ssaBlock *a) {
|
||||
bool ssa_opt_block_fusion(ssaProcedure *proc, ssaBlock *a) {
|
||||
if (a->succs.count != 1) {
|
||||
return false;
|
||||
}
|
||||
@@ -252,7 +252,7 @@ void ssa_opt_blocks(ssaProcedure *proc) {
|
||||
ssa_remove_unreachable_blocks(proc);
|
||||
|
||||
#if 1
|
||||
b32 changed = true;
|
||||
bool changed = true;
|
||||
while (changed) {
|
||||
changed = false;
|
||||
for_array(i, proc->blocks) {
|
||||
|
||||
@@ -51,7 +51,7 @@ void ssa_file_write(ssaFileBuffer *f, void *data, isize len) {
|
||||
}
|
||||
|
||||
|
||||
b32 ssa_valid_char(u8 c) {
|
||||
bool ssa_valid_char(u8 c) {
|
||||
if (c >= 0x80) {
|
||||
return false;
|
||||
}
|
||||
@@ -71,7 +71,7 @@ b32 ssa_valid_char(u8 c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ssa_print_escape_string(ssaFileBuffer *f, String name, b32 print_quotes) {
|
||||
void ssa_print_escape_string(ssaFileBuffer *f, String name, bool print_quotes) {
|
||||
isize extra = 0;
|
||||
for (isize i = 0; i < name.len; i++) {
|
||||
u8 c = name.text[i];
|
||||
@@ -127,7 +127,7 @@ void ssa_print_encoded_local(ssaFileBuffer *f, String name) {
|
||||
ssa_print_escape_string(f, name, true);
|
||||
}
|
||||
|
||||
void ssa_print_encoded_global(ssaFileBuffer *f, String name, b32 global_scope) {
|
||||
void ssa_print_encoded_global(ssaFileBuffer *f, String name, bool global_scope) {
|
||||
ssa_fprintf(f, "@");
|
||||
if (!global_scope && str_ne(name, str_lit("main"))) {
|
||||
ssa_fprintf(f, ".");
|
||||
@@ -239,7 +239,7 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) {
|
||||
|
||||
case Type_Named:
|
||||
if (is_type_struct(t) || is_type_union(t)) {
|
||||
String *name = map_get(&m->type_names, hash_pointer(t));
|
||||
String *name = map_string_get(&m->type_names, hash_pointer(t));
|
||||
GB_ASSERT_MSG(name != NULL, "%.*s", LIT(t->Named.name));
|
||||
ssa_print_encoded_local(f, *name);
|
||||
// ssa_print_encoded_local(f, t->Named.name);
|
||||
@@ -613,7 +613,7 @@ void ssa_print_value(ssaFileBuffer *f, ssaModule *m, ssaValue *value, Type *type
|
||||
break;
|
||||
case ssaValue_Global: {
|
||||
Scope *scope = value->Global.entity->scope;
|
||||
b32 in_global_scope = false;
|
||||
bool in_global_scope = false;
|
||||
if (scope != NULL) {
|
||||
in_global_scope = scope->is_global || scope->is_init;
|
||||
}
|
||||
@@ -1226,7 +1226,7 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
|
||||
|
||||
if (proc->module->generate_debug_info && proc->entity != NULL) {
|
||||
if (proc->body != NULL) {
|
||||
ssaDebugInfo *di = *map_get(&proc->module->debug_info, hash_pointer(proc->entity));
|
||||
ssaDebugInfo *di = *map_ssa_debug_info_get(&proc->module->debug_info, hash_pointer(proc->entity));
|
||||
GB_ASSERT(di->kind == ssaDebugInfo_Proc);
|
||||
ssa_fprintf(f, "!dbg !%d ", di->id);
|
||||
}
|
||||
@@ -1337,7 +1337,7 @@ void ssa_print_llvm_ir(ssaGen *ssa) {
|
||||
}
|
||||
auto *g = &v->Global;
|
||||
Scope *scope = g->entity->scope;
|
||||
b32 in_global_scope = false;
|
||||
bool in_global_scope = false;
|
||||
if (scope != NULL) {
|
||||
in_global_scope = scope->is_global || scope->is_init;
|
||||
}
|
||||
@@ -1383,7 +1383,7 @@ void ssa_print_llvm_ir(ssaGen *ssa) {
|
||||
switch (di->kind) {
|
||||
case ssaDebugInfo_CompileUnit: {
|
||||
auto *cu = &di->CompileUnit;
|
||||
ssaDebugInfo *file = *map_get(&m->debug_info, hash_pointer(cu->file));
|
||||
ssaDebugInfo *file = *map_ssa_debug_info_get(&m->debug_info, hash_pointer(cu->file));
|
||||
ssa_fprintf(f,
|
||||
"distinct !DICompileUnit("
|
||||
"language: DW_LANG_Go, " // Is this good enough?
|
||||
|
||||
@@ -49,14 +49,14 @@ gb_inline String make_string_c(char *text) {
|
||||
#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) {
|
||||
gb_inline bool are_strings_equal(String a, String b) {
|
||||
if (a.len == b.len) {
|
||||
return gb_memcompare(a.text, b.text, a.len) == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
gb_inline b32 str_eq_ignore_case(String a, String b) {
|
||||
gb_inline bool 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];
|
||||
@@ -137,7 +137,7 @@ gb_inline bool str_ge(String a, String b) { return string_compare(a, b) >= 0;
|
||||
gb_inline isize string_extension_position(String str) {
|
||||
isize dot_pos = -1;
|
||||
isize i = str.len;
|
||||
b32 seen_dot = false;
|
||||
bool seen_dot = false;
|
||||
while (i --> 0) {
|
||||
if (str.text[i] == GB_PATH_SEPARATOR)
|
||||
break;
|
||||
@@ -150,7 +150,7 @@ gb_inline isize string_extension_position(String str) {
|
||||
return dot_pos;
|
||||
}
|
||||
|
||||
gb_inline b32 string_has_extension(String str, String ext) {
|
||||
gb_inline bool string_has_extension(String str, String ext) {
|
||||
if (str.len > ext.len+1) {
|
||||
u8 *s = str.text+str.len - ext.len-1;
|
||||
if (s[0] == '.') {
|
||||
@@ -162,7 +162,7 @@ gb_inline b32 string_has_extension(String str, String ext) {
|
||||
return false;
|
||||
}
|
||||
|
||||
b32 string_contains_char(String s, u8 c) {
|
||||
bool string_contains_char(String s, u8 c) {
|
||||
for (isize i = 0; i < s.len; i++) {
|
||||
if (s.text[i] == c)
|
||||
return true;
|
||||
@@ -238,7 +238,7 @@ String string16_to_string(gbAllocator a, String16 s) {
|
||||
|
||||
|
||||
|
||||
b32 unquote_char(String s, u8 quote, Rune *rune, b32 *multiple_bytes, String *tail_string) {
|
||||
bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *tail_string) {
|
||||
if (s.text[0] == quote &&
|
||||
(quote == '$' || quote == '"')) {
|
||||
return false;
|
||||
@@ -396,8 +396,8 @@ i32 unquote_string(gbAllocator a, String *s_) {
|
||||
while (s.len > 0) {
|
||||
String tail_string = {0};
|
||||
Rune r = 0;
|
||||
b32 multiple_bytes = false;
|
||||
b32 success = unquote_char(s, quote, &r, &multiple_bytes, &tail_string);
|
||||
bool multiple_bytes = false;
|
||||
bool success = unquote_char(s, quote, &r, &multiple_bytes, &tail_string);
|
||||
if (!success) {
|
||||
gb_free(a, buf);
|
||||
return 0;
|
||||
|
||||
@@ -144,7 +144,7 @@ i32 token_pos_cmp(TokenPos a, TokenPos b) {
|
||||
return (a.line < b.line) ? -1 : +1;
|
||||
}
|
||||
|
||||
b32 token_pos_are_equal(TokenPos a, TokenPos b) {
|
||||
bool token_pos_are_equal(TokenPos a, TokenPos b) {
|
||||
return token_pos_cmp(a, b) == 0;
|
||||
}
|
||||
|
||||
@@ -253,19 +253,19 @@ void compiler_error(char *fmt, ...) {
|
||||
|
||||
|
||||
|
||||
gb_inline b32 token_is_literal(Token t) {
|
||||
gb_inline bool token_is_literal(Token t) {
|
||||
return gb_is_between(t.kind, Token__LiteralBegin+1, Token__LiteralEnd-1);
|
||||
}
|
||||
gb_inline b32 token_is_operator(Token t) {
|
||||
gb_inline bool token_is_operator(Token t) {
|
||||
return gb_is_between(t.kind, Token__OperatorBegin+1, Token__OperatorEnd-1);
|
||||
}
|
||||
gb_inline b32 token_is_keyword(Token t) {
|
||||
gb_inline bool token_is_keyword(Token t) {
|
||||
return gb_is_between(t.kind, Token__KeywordBegin+1, Token__KeywordEnd-1);
|
||||
}
|
||||
gb_inline b32 token_is_comparison(Token t) {
|
||||
gb_inline bool token_is_comparison(Token t) {
|
||||
return gb_is_between(t.kind, Token__ComparisonBegin+1, Token__ComparisonEnd-1);
|
||||
}
|
||||
gb_inline b32 token_is_shift(Token t) {
|
||||
gb_inline bool token_is_shift(Token t) {
|
||||
return t.kind == Token_Shl || t.kind == Token_Shr;
|
||||
}
|
||||
|
||||
@@ -350,8 +350,6 @@ 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);
|
||||
@@ -432,7 +430,7 @@ gb_inline void scan_mantissa(Tokenizer *t, i32 base) {
|
||||
}
|
||||
|
||||
|
||||
Token scan_number_to_token(Tokenizer *t, b32 seen_decimal_point) {
|
||||
Token scan_number_to_token(Tokenizer *t, bool seen_decimal_point) {
|
||||
Token token = {};
|
||||
token.kind = Token_Integer;
|
||||
token.string = make_string(t->curr, 1);
|
||||
@@ -507,7 +505,7 @@ exponent:
|
||||
}
|
||||
|
||||
// Quote == " for string
|
||||
b32 scan_escape(Tokenizer *t, Rune quote) {
|
||||
bool scan_escape(Tokenizer *t, Rune quote) {
|
||||
isize len = 0;
|
||||
u32 base = 0, max = 0, x = 0;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
b32 rune_is_letter(Rune r) {
|
||||
bool rune_is_letter(Rune r) {
|
||||
if ((r < 0x80 && gb_char_is_alpha(cast(char)r)) ||
|
||||
r == '_') {
|
||||
return true;
|
||||
@@ -22,14 +22,14 @@ b32 rune_is_letter(Rune r) {
|
||||
return false;
|
||||
}
|
||||
|
||||
b32 rune_is_digit(Rune r) {
|
||||
bool rune_is_digit(Rune r) {
|
||||
if (r < 0x80 && gb_is_between(r, '0', '9')) {
|
||||
return true;
|
||||
}
|
||||
return utf8proc_category(r) == UTF8PROC_CATEGORY_ND;
|
||||
}
|
||||
|
||||
b32 rune_is_whitespace(Rune r) {
|
||||
bool rune_is_whitespace(Rune r) {
|
||||
switch (r) {
|
||||
case ' ':
|
||||
case '\t':
|
||||
@@ -41,13 +41,13 @@ b32 rune_is_whitespace(Rune r) {
|
||||
}
|
||||
|
||||
|
||||
b32 is_string_an_identifier(String s) {
|
||||
bool is_string_an_identifier(String s) {
|
||||
if (s.len < 1) {
|
||||
return false;
|
||||
}
|
||||
isize offset = 0;
|
||||
while (offset < s.len) {
|
||||
b32 ok = false;
|
||||
bool ok = false;
|
||||
Rune r = -1;
|
||||
isize size = gb_utf8_decode(s.text+offset, s.len-offset, &r);
|
||||
if (offset == 0) {
|
||||
|
||||
Reference in New Issue
Block a user