Remove templated Map; replace with #include macro "templates" trick

This commit is contained in:
Ginger Bill
2016-11-23 10:36:48 +00:00
parent cb7b9a413d
commit 8ecfca0c9b
17 changed files with 519 additions and 698 deletions
+122 -101
View File
@@ -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);
}
+12 -30
View File
@@ -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;
+4 -4
View File
@@ -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;
+67 -129
View File
@@ -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) {
+42 -65
View File
@@ -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);
+46 -46
View File
@@ -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) {