diff --git a/src/array.cpp b/src/array.cpp new file mode 100644 index 000000000..d8b8e9ef3 --- /dev/null +++ b/src/array.cpp @@ -0,0 +1,116 @@ +#define ARRAY_GROW_FORMULA(x) (2*(x) + 8) + +template +struct Array { + gbAllocator allocator; + T *data; + isize count; + isize capacity; + + T &operator[](isize index) { + if (count > 0) { + GB_ASSERT_MSG(0 <= index && index < count, "Index out of bounds"); + } + return data[index]; + } + + T const &operator[](isize index) const { + if (count > 0) { + GB_ASSERT_MSG(0 <= index && index < count, "Index out of bounds"); + } + return data[index]; + } +}; + +template void array_init (Array *array, gbAllocator a, isize init_capacity = 8); +template void array_free (Array *array); +template void array_add (Array *array, T const &t); +template T array_pop (Array *array); +template void array_clear (Array *array); +template void array_reserve (Array *array, isize capacity); +template void array_resize (Array *array, isize count); +template void array_set_capacity(Array *array, isize capacity); + + +template +void array_init(Array *array, gbAllocator a, isize init_capacity) { + array->allocator = a; + array->data = gb_alloc_array(a, T, init_capacity); + array->count = 0; + array->capacity = init_capacity; +} + +template +void array_free(Array *array) { + gb_free(array->allocator, array->data); + array->count = 0; + array->capacity = 0; +} + +template +void array__grow(Array *array, isize min_capacity) { + isize new_capacity = ARRAY_GROW_FORMULA(array->capacity); + if (new_capacity < min_capacity) { + new_capacity = min_capacity; + } + array_set_capacity(array, new_capacity); +} + +template +void array_add(Array *array, T const &t) { + if (array->capacity < array->count+1) { + array__grow(array, 0); + } + array->data[array->count] = t; + array->count++; +} + +template +T array_pop(Array *array) { + GB_ASSERT(array->count > 0); + array->count--; + return array->data[array->count]; +} + +template +void array_clear(Array *array) { + array->count = 0; +} + +template +void array_reserve(Array *array, isize capacity) { + if (array->capacity < capacity) { + array_set_capacity(array, capacity); + } +} + +template +void array_resize(Array *array, isize count) { + if (array->capacity < count) { + array__grow(array, count); + } + array->count = count; +} + +template +void array_set_capacity(Array *array, isize capacity) { + if (capacity == array->capacity) { + return; + } + + if (capacity < array->count) { + array_resize(array, capacity); + } + + T *new_data = NULL; + if (capacity > 0) { + new_data = gb_alloc_array(array->allocator, T, capacity); + gb_memmove(new_data, array->data, gb_size_of(T) * array->capacity); + } + gb_free(array->allocator, array->data); + array->data = new_data; + array->capacity = capacity; +} + + + diff --git a/src/checker/checker.cpp b/src/checker/checker.cpp index 9e1295b9a..53ae0ae9f 100644 --- a/src/checker/checker.cpp +++ b/src/checker/checker.cpp @@ -118,8 +118,8 @@ struct Scope { Map elements; // Key: String Map implicit; // Key: String - gbArray(Scope *) shared; - gbArray(Scope *) imported; + Array shared; + Array imported; b32 is_proc; b32 is_global; b32 is_file; @@ -240,7 +240,7 @@ struct Checker { AstFile * curr_ast_file; BaseTypeSizes sizes; Scope * global_scope; - gbArray(ProcedureInfo) procs; // NOTE(bill): Procedures to check + Array procs; // NOTE(bill): Procedures to check gbArena arena; gbArena tmp_arena; @@ -249,31 +249,31 @@ struct Checker { CheckerContext context; - gbArray(Type *) proc_stack; + Array proc_stack; b32 in_defer; // TODO(bill): Actually handle correctly }; gb_global Scope *universal_scope = NULL; struct CycleChecker { - gbArray(Entity *) path; // Entity_TypeName + Array path; // Entity_TypeName }; CycleChecker *cycle_checker_add(CycleChecker *cc, Entity *e) { if (cc == NULL) { return NULL; } - if (cc->path == NULL) { - gb_array_init(cc->path, gb_heap_allocator()); + if (cc->path.data == NULL) { + array_init(&cc->path, gb_heap_allocator()); } GB_ASSERT(e != NULL && e->kind == Entity_TypeName); - gb_array_append(cc->path, e); + array_add(&cc->path, e); return cc; } void cycle_checker_destroy(CycleChecker *cc) { - if (cc != NULL && cc->path != NULL) { - gb_array_free(cc->path); + if (cc != NULL && cc->path.data != NULL) { + array_free(&cc->path); } } @@ -282,10 +282,10 @@ void cycle_checker_destroy(CycleChecker *cc) { Scope *make_scope(Scope *parent, gbAllocator allocator) { Scope *s = gb_alloc_item(allocator, Scope); s->parent = parent; - map_init(&s->elements, gb_heap_allocator()); - map_init(&s->implicit, gb_heap_allocator()); - gb_array_init(s->shared, gb_heap_allocator()); - gb_array_init(s->imported, gb_heap_allocator()); + map_init(&s->elements, gb_heap_allocator()); + map_init(&s->implicit, gb_heap_allocator()); + array_init(&s->shared, gb_heap_allocator()); + array_init(&s->imported, gb_heap_allocator()); if (parent != NULL && parent != universal_scope) { DLIST_APPEND(parent->first_child, parent->last_child, s); @@ -294,7 +294,7 @@ Scope *make_scope(Scope *parent, gbAllocator allocator) { } void destroy_scope(Scope *scope) { - gb_for_array(i, scope->elements.entries) { + for_array(i, scope->elements.entries) { Entity *e =scope->elements.entries[i].value; if (e->kind == Entity_Variable) { if (!e->Variable.used) { @@ -311,8 +311,8 @@ void destroy_scope(Scope *scope) { map_destroy(&scope->elements); map_destroy(&scope->implicit); - gb_array_free(scope->shared); - gb_array_free(scope->imported); + array_free(&scope->shared); + array_free(&scope->imported); // NOTE(bill): No need to free scope as it "should" be allocated in an arena (except for the global scope) } @@ -366,7 +366,7 @@ void scope_lookup_parent_entity(Scope *scope, String name, Scope **scope_, Entit gone_thru_proc = true; } else { // Check shared scopes - i.e. other files @ global scope - gb_for_array(i, s->shared) { + for_array(i, s->shared) { Scope *shared = s->shared[i]; Entity **found = map_get(&shared->elements, key); if (found) { @@ -409,7 +409,7 @@ Entity *current_scope_lookup_entity(Scope *s, String name) { if (found) { return *found; } - gb_for_array(i, s->shared) { + for_array(i, s->shared) { Entity **found = map_get(&s->shared[i]->elements, key); if (found) { return *found; @@ -436,7 +436,7 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) { void check_scope_usage(Checker *c, Scope *scope) { // TODO(bill): Use this? #if 0 - gb_for_array(i, scope->elements.entries) { + for_array(i, scope->elements.entries) { auto *entry = scope->elements.entries + i; Entity *e = entry->value; if (e->kind == Entity_Variable) { @@ -557,15 +557,15 @@ void init_checker(Checker *c, Parser *parser, BaseTypeSizes sizes) { init_checker_info(&c->info); c->sizes = sizes; - gb_array_init(c->proc_stack, a); - gb_array_init(c->procs, a); + array_init(&c->proc_stack, a); + array_init(&c->procs, a); // NOTE(bill): Is this big enough or too small? isize item_size = gb_max(gb_max(gb_size_of(Entity), gb_size_of(Type)), gb_size_of(Scope)); isize total_token_count = 0; - gb_for_array(i, c->parser->files) { + for_array(i, c->parser->files) { AstFile *f = &c->parser->files[i]; - total_token_count += gb_array_count(f->tokens); + total_token_count += f->tokens.count; } isize arena_size = 2 * item_size * total_token_count; gb_arena_init_from_allocator(&c->arena, a, arena_size); @@ -581,8 +581,8 @@ void init_checker(Checker *c, Parser *parser, BaseTypeSizes sizes) { void destroy_checker(Checker *c) { destroy_checker_info(&c->info); destroy_scope(c->global_scope); - gb_array_free(c->proc_stack); - gb_array_free(c->procs); + array_free(&c->proc_stack); + array_free(&c->procs); gb_arena_free(&c->arena); } @@ -723,7 +723,7 @@ void add_type_info_type(Checker *c, Type *t) { } isize ti_index = -1; - gb_for_array(i, c->info.type_info_map.entries) { + for_array(i, c->info.type_info_map.entries) { auto *e = &c->info.type_info_map.entries[i]; Type *prev_type = cast(Type *)cast(uintptr)e->key.key; if (are_types_identical(t, prev_type)) { @@ -814,19 +814,19 @@ void check_procedure_later(Checker *c, AstFile *file, Token token, DeclInfo *dec info.type = type; info.body = body; info.tags = tags; - gb_array_append(c->procs, info); + array_add(&c->procs, info); } void push_procedure(Checker *c, Type *type) { - gb_array_append(c->proc_stack, type); + array_add(&c->proc_stack, type); } void pop_procedure(Checker *c) { - gb_array_pop(c->proc_stack); + array_pop(&c->proc_stack); } Type *const curr_procedure(Checker *c) { - isize count = gb_array_count(c->proc_stack); + isize count = c->proc_stack.count; if (count > 0) { return c->proc_stack[count-1]; } @@ -859,7 +859,7 @@ void add_dependency_to_map(Map *map, CheckerInfo *info, Entity *node) } DeclInfo *decl = *found; - gb_for_array(i, decl->deps.entries) { + for_array(i, decl->deps.entries) { Entity *e = cast(Entity *)cast(uintptr)decl->deps.entries[i].key.key; add_dependency_to_map(map, info, e); } @@ -869,7 +869,7 @@ Map generate_minimum_dependency_map(CheckerInfo *info, Entity *start) Map map = {}; // Key: Entity * map_init(&map, gb_heap_allocator()); - gb_for_array(i, info->entities.entries) { + for_array(i, info->entities.entries) { auto *entry = &info->entities.entries[i]; Entity *e = cast(Entity *)cast(uintptr)entry->key.key; if (e->scope->is_global) { @@ -948,16 +948,16 @@ void init_preload_types(Checker *c) { void check_parsed_files(Checker *c) { - gbArray(AstNode *) import_decls; - gb_array_init(import_decls, gb_heap_allocator()); - defer (gb_array_free(import_decls)); + Array import_decls; + array_init(&import_decls, gb_heap_allocator()); + defer (array_free(&import_decls)); Map file_scopes; // Key: String (fullpath) map_init(&file_scopes, gb_heap_allocator()); defer (map_destroy(&file_scopes)); // Map full filepaths to Scopes - gb_for_array(i, c->parser->files) { + for_array(i, c->parser->files) { AstFile *f = &c->parser->files[i]; Scope *scope = NULL; scope = make_scope(c->global_scope, c->allocator); @@ -971,7 +971,7 @@ void check_parsed_files(Checker *c) { } if (scope->is_global) { - gb_array_append(c->global_scope->shared, scope); + array_add(&c->global_scope->shared, scope); } f->scope = scope; @@ -982,13 +982,13 @@ void check_parsed_files(Checker *c) { } // Collect Entities - gb_for_array(i, c->parser->files) { + for_array(i, c->parser->files) { AstFile *f = &c->parser->files[i]; add_curr_ast_file(c, f); Scope *file_scope = f->scope; - gb_for_array(decl_index, f->decls) { + for_array(decl_index, f->decls) { AstNode *decl = f->decls[decl_index]; if (!is_ast_node_decl(decl)) { continue; @@ -1005,7 +1005,7 @@ void check_parsed_files(Checker *c) { case_end; case_ast_node(cd, ConstDecl, decl); - gb_for_array(i, cd->values) { + for_array(i, cd->values) { AstNode *name = cd->names[i]; AstNode *value = cd->values[i]; ExactValue v = {ExactValue_Invalid}; @@ -1017,8 +1017,8 @@ void check_parsed_files(Checker *c) { add_entity_and_decl_info(c, name, e, di); } - isize lhs_count = gb_array_count(cd->names); - isize rhs_count = gb_array_count(cd->values); + isize lhs_count = cd->names.count; + isize rhs_count = cd->values.count; if (rhs_count == 0 && cd->type == NULL) { error(ast_node_token(decl), "Missing type or initial expression"); @@ -1028,11 +1028,11 @@ void check_parsed_files(Checker *c) { case_end; case_ast_node(vd, VarDecl, decl); - isize entity_count = gb_array_count(vd->names); + isize entity_count = vd->names.count; isize entity_index = 0; Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count); DeclInfo *di = NULL; - if (gb_array_count(vd->values) > 0) { + if (vd->values.count > 0) { di = make_declaration_info(gb_heap_allocator(), file_scope); di->entities = entities; di->entity_count = entity_count; @@ -1040,10 +1040,10 @@ void check_parsed_files(Checker *c) { di->init_expr = vd->values[0]; } - gb_for_array(i, vd->names) { + for_array(i, vd->names) { AstNode *name = vd->names[i]; AstNode *value = NULL; - if (i < gb_array_count(vd->values)) { + if (i < vd->values.count) { value = vd->values[i]; } Entity *e = make_entity_variable(c->allocator, file_scope, name->Ident, NULL); @@ -1089,13 +1089,13 @@ void check_parsed_files(Checker *c) { } } - gb_for_array(i, c->parser->files) { + for_array(i, c->parser->files) { AstFile *f = &c->parser->files[i]; add_curr_ast_file(c, f); Scope *file_scope = f->scope; - gb_for_array(decl_index, f->decls) { + for_array(decl_index, f->decls) { AstNode *decl = f->decls[decl_index]; if (decl->kind != AstNode_ImportDecl) { continue; @@ -1107,7 +1107,7 @@ void check_parsed_files(Checker *c) { GB_ASSERT_MSG(found != NULL, "Unable to find scope for file: %.*s", LIT(id->fullpath)); Scope *scope = *found; b32 previously_added = false; - gb_for_array(import_index, file_scope->imported) { + for_array(import_index, file_scope->imported) { Scope *prev = file_scope->imported[import_index]; if (prev == scope) { previously_added = true; @@ -1115,14 +1115,14 @@ void check_parsed_files(Checker *c) { } } if (!previously_added) { - gb_array_append(file_scope->imported, scope); + array_add(&file_scope->imported, scope); } else { warning(id->token, "Multiple #import of the same file within this scope"); } if (id->import_name.string == ".") { // NOTE(bill): Add imported entities to this file's scope - gb_for_array(elem_index, scope->elements.entries) { + for_array(elem_index, scope->elements.entries) { Entity *e = scope->elements.entries[elem_index].value; if (e->scope == file_scope) { continue; @@ -1186,7 +1186,7 @@ void check_parsed_files(Checker *c) { } auto check_global_entity = [](Checker *c, EntityKind kind) { - gb_for_array(i, c->info.entities.entries) { + for_array(i, c->info.entities.entries) { auto *entry = &c->info.entities.entries[i]; Entity *e = cast(Entity *)cast(uintptr)entry->key.key; if (e->kind == kind) { @@ -1222,7 +1222,7 @@ void check_parsed_files(Checker *c) { check_global_entity(c, Entity_Variable); // Check procedure bodies - gb_for_array(i, c->procs) { + for_array(i, c->procs) { ProcedureInfo *pi = &c->procs[i]; add_curr_ast_file(c, pi->file); @@ -1244,13 +1244,13 @@ void check_parsed_files(Checker *c) { if (false) { gb_printf("Dependency graph:\n"); - gb_for_array(i, c->info.entities.entries) { + for_array(i, c->info.entities.entries) { auto *entry = &c->info.entities.entries[i]; Entity *e = cast(Entity *)cast(uintptr)entry->key.key; DeclInfo *d = entry->value; - if (gb_array_count(d->deps.entries) > 0) { + if (d->deps.entries.count > 0) { gb_printf("\t%.*s depends on\n", LIT(e->token.string)); - gb_for_array(j, d->deps.entries) { + for_array(j, d->deps.entries) { Entity *e = cast(Entity *)cast(uintptr)d->deps.entries[j].key.key; gb_printf("\t\t%.*s\n", LIT(e->token.string)); } @@ -1259,7 +1259,7 @@ void check_parsed_files(Checker *c) { } // Add untyped expression values - gb_for_array(i, c->info.untyped.entries) { + for_array(i, c->info.untyped.entries) { auto *entry = &c->info.untyped.entries[i]; HashKey key = entry->key; AstNode *expr = cast(AstNode *)cast(uintptr)key.key; diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp index 23d877bd9..48359b434 100644 --- a/src/checker/expr.cpp +++ b/src/checker/expr.cpp @@ -254,19 +254,19 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, Entity *e; AstNode *t; }; - gbArray(Delay) delayed_const; gb_array_init_reserve(delayed_const, c->tmp_allocator, other_field_count); - gbArray(Delay) delayed_type; gb_array_init_reserve(delayed_type, c->tmp_allocator, other_field_count); + Array delayed_const; array_init(&delayed_const, c->tmp_allocator, other_field_count); + Array delayed_type; array_init(&delayed_type, c->tmp_allocator, other_field_count); - gb_for_array(decl_index, decls) { + for_array(decl_index, decls) { AstNode *decl = decls[decl_index]; if (decl->kind == AstNode_ConstDecl) { ast_node(cd, ConstDecl, decl); - isize entity_count = gb_array_count(cd->names); + isize entity_count = cd->names.count; isize entity_index = 0; Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count); - gb_for_array(i, cd->values) { + for_array(i, cd->values) { AstNode *name = cd->names[i]; AstNode *value = cd->values[i]; @@ -277,11 +277,11 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, entities[entity_index++] = e; Delay delay = {e, cd->type}; - gb_array_append(delayed_const, delay); + array_add(&delayed_const, delay); } - isize lhs_count = gb_array_count(cd->names); - isize rhs_count = gb_array_count(cd->values); + isize lhs_count = cd->names.count; + isize rhs_count = cd->values.count; // TODO(bill): Better error messages or is this good enough? if (rhs_count == 0 && cd->type == NULL) { @@ -290,7 +290,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, error(ast_node_token(node), "Extra initial expression"); } - gb_for_array(i, cd->names) { + for_array(i, cd->names) { AstNode *name = cd->names[i]; Entity *e = entities[i]; Token name_token = name->Ident; @@ -314,7 +314,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, Entity *e = make_entity_type_name(c->allocator, c->context.scope, name_token, NULL); Delay delay = {e, td->type}; - gb_array_append(delayed_type, delay); + array_add(&delayed_type, delay); if (name_token.string == "_") { other_fields[other_field_index++] = e; @@ -333,17 +333,17 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, } } - gb_for_array(i, delayed_type) { + for_array(i, delayed_type) { check_const_decl(c, delayed_type[i].e, delayed_type[i].t, NULL); } - gb_for_array(i, delayed_const) { + for_array(i, delayed_const) { check_type_decl(c, delayed_const[i].e, delayed_const[i].t, NULL, NULL); } if (node->kind == AstNode_UnionType) { isize field_index = 0; fields[field_index++] = make_entity_type_name(c->allocator, c->context.scope, empty_token, NULL); - gb_for_array(decl_index, decls) { + for_array(decl_index, decls) { AstNode *decl = decls[decl_index]; if (decl->kind != AstNode_VarDecl) { continue; @@ -352,7 +352,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, ast_node(vd, VarDecl, decl); Type *base_type = check_type(c, vd->type, NULL, cycle_checker); - gb_for_array(name_index, vd->names) { + for_array(name_index, vd->names) { AstNode *name = vd->names[name_index]; Token name_token = name->Ident; @@ -379,7 +379,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, } } else { isize field_index = 0; - gb_for_array(decl_index, decls) { + for_array(decl_index, decls) { AstNode *decl = decls[decl_index]; if (decl->kind != AstNode_VarDecl) { continue; @@ -389,13 +389,13 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, Type *type = check_type(c, vd->type, NULL, cycle_checker); if (vd->is_using) { - if (gb_array_count(vd->names) > 1) { + if (vd->names.count > 1) { error(ast_node_token(vd->names[0]), "Cannot apply `using` to more than one of the same type"); } } - gb_for_array(name_index, vd->names) { + for_array(name_index, vd->names) { AstNode *name = vd->names[name_index]; Token name_token = name->Ident; @@ -424,7 +424,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls, Token name_token = vd->names[0]->Ident; if (is_type_indexable(t)) { b32 ok = true; - gb_for_array(emi, entity_map.entries) { + for_array(emi, entity_map.entries) { Entity *e = entity_map.entries[emi].value; if (e->kind == Entity_Variable && e->Variable.anonymous) { if (is_type_indexable(e->type)) { @@ -492,15 +492,15 @@ void check_struct_type(Checker *c, Type *struct_type, AstNode *node, CycleChecke isize field_count = 0; isize other_field_count = 0; - gb_for_array(decl_index, st->decls) { + for_array(decl_index, st->decls) { AstNode *decl = st->decls[decl_index]; switch (decl->kind) { case_ast_node(vd, VarDecl, decl); - field_count += gb_array_count(vd->names); + field_count += vd->names.count; case_end; case_ast_node(cd, ConstDecl, decl); - other_field_count += gb_array_count(cd->names); + other_field_count += cd->names.count; case_end; case_ast_node(td, TypeDecl, decl); @@ -554,15 +554,15 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node, CycleChecker isize field_count = 1; isize other_field_count = 0; - gb_for_array(decl_index, ut->decls) { + for_array(decl_index, ut->decls) { AstNode *decl = ut->decls[decl_index]; switch (decl->kind) { case_ast_node(vd, VarDecl, decl); - field_count += gb_array_count(vd->names); + field_count += vd->names.count; case_end; case_ast_node(cd, ConstDecl, decl); - other_field_count += gb_array_count(cd->names); + other_field_count += cd->names.count; case_end; case_ast_node(td, TypeDecl, decl); @@ -589,15 +589,15 @@ void check_raw_union_type(Checker *c, Type *union_type, AstNode *node, CycleChec isize field_count = 0; isize other_field_count = 0; - gb_for_array(decl_index, ut->decls) { + for_array(decl_index, ut->decls) { AstNode *decl = ut->decls[decl_index]; switch (decl->kind) { case_ast_node(vd, VarDecl, decl); - field_count += gb_array_count(vd->names); + field_count += vd->names.count; case_end; case_ast_node(cd, ConstDecl, decl); - other_field_count += gb_array_count(cd->names); + other_field_count += cd->names.count; case_end; case_ast_node(td, TypeDecl, decl); @@ -661,7 +661,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod } enum_type->Record.enum_base = base_type; - Entity **fields = gb_alloc_array(c->allocator, Entity *, gb_array_count(et->fields)); + Entity **fields = gb_alloc_array(c->allocator, Entity *, et->fields.count); isize field_index = 0; ExactValue iota = make_exact_value_integer(-1); i64 min_value = 0; @@ -673,7 +673,7 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod } Entity *blank_entity = make_entity_constant(c->allocator, c->context.scope, blank_token, constant_type, make_exact_value_integer(0));; - gb_for_array(i, et->fields) { + for_array(i, et->fields) { AstNode *field = et->fields[i]; ast_node(f, FieldValue, field); @@ -735,10 +735,10 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod add_entity_use(c, f->field, e); } - gb_sort_array(fields, gb_array_count(et->fields), cmp_enum_order); + gb_sort_array(fields, et->fields.count, cmp_enum_order); enum_type->Record.other_fields = fields; - enum_type->Record.other_field_count = gb_array_count(et->fields); + enum_type->Record.other_field_count = et->fields.count; enum_type->Record.enum_count = make_entity_constant(c->allocator, NULL, make_token_ident(make_string("count")), t_int, make_exact_value_integer(enum_type->Record.other_field_count)); @@ -749,29 +749,30 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod } Type *check_get_params(Checker *c, Scope *scope, AstNodeArray params, b32 *is_variadic_) { - if (params == NULL || gb_array_count(params) == 0) + if (params.count == 0) { return NULL; + } b32 is_variadic = false; Type *tuple = make_type_tuple(c->allocator); isize variable_count = 0; - gb_for_array(i, params) { + for_array(i, params) { AstNode *field = params[i]; ast_node(p, Parameter, field); - variable_count += gb_array_count(p->names); + variable_count += p->names.count; } Entity **variables = gb_alloc_array(c->allocator, Entity *, variable_count); isize variable_index = 0; - gb_for_array(i, params) { + for_array(i, params) { ast_node(p, Parameter, params[i]); AstNode *type_expr = p->type; if (type_expr) { if (type_expr->kind == AstNode_Ellipsis) { type_expr = type_expr->Ellipsis.expr; - if (i+1 == gb_array_count(params)) { + if (i+1 == params.count) { is_variadic = true; } else { error(ast_node_token(params[i]), "Invalid AST: Invalid variadic parameter"); @@ -779,7 +780,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNodeArray params, b32 *is_va } Type *type = check_type(c, type_expr); - gb_for_array(j, p->names) { + for_array(j, p->names) { AstNode *name = p->names[j]; if (name->kind == AstNode_Ident) { Entity *param = make_entity_param(c->allocator, scope, name->Ident, type, p->is_using); @@ -792,10 +793,10 @@ Type *check_get_params(Checker *c, Scope *scope, AstNodeArray params, b32 *is_va } } - if (is_variadic && gb_array_count(params) > 0) { + if (is_variadic && params.count > 0) { // NOTE(bill): Change last variadic parameter to be a slice // Custom Calling convention for variadic parameters - Entity *end = variables[gb_array_count(params)-1]; + Entity *end = variables[params.count-1]; end->type = make_type_slice(c->allocator, end->type); } @@ -808,14 +809,14 @@ Type *check_get_params(Checker *c, Scope *scope, AstNodeArray params, b32 *is_va } Type *check_get_results(Checker *c, Scope *scope, AstNodeArray results) { - if (results == NULL || gb_array_count(results) == 0) { + if (results.count == 0) { return NULL; } Type *tuple = make_type_tuple(c->allocator); - Entity **variables = gb_alloc_array(c->allocator, Entity *, gb_array_count(results)); + Entity **variables = gb_alloc_array(c->allocator, Entity *, results.count); isize variable_index = 0; - gb_for_array(i, results) { + for_array(i, results) { AstNode *item = results[i]; Type *type = check_type(c, item); Token token = ast_node_token(item); @@ -826,7 +827,7 @@ Type *check_get_results(Checker *c, Scope *scope, AstNodeArray results) { variables[variable_index++] = param; } tuple->Tuple.variables = variables; - tuple->Tuple.variable_count = gb_array_count(results); + tuple->Tuple.variable_count = results.count; return tuple; } @@ -915,7 +916,7 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl #if 0 // TODO(bill): Fix cyclical dependancy checker if (cycle_checker != NULL) { - gb_for_array(i, cycle_checker->path) { + for_array(i, cycle_checker->path) { Entity *prev = cycle_checker->path[i]; if (prev == e) { error(e->token, "Illegal declaration cycle for %.*s", LIT(e->token.string)); @@ -2270,15 +2271,17 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) BuiltinProc *bp = &builtin_procs[id]; { char *err = NULL; - if (gb_array_count(ce->args) < bp->arg_count) + if (ce->args.count < bp->arg_count) { err = "Too few"; - if (gb_array_count(ce->args) > bp->arg_count && !bp->variadic) + } else if (ce->args.count > bp->arg_count && !bp->variadic) { err = "Too many"; + } + if (err) { ast_node(proc, Ident, ce->proc); error(ce->close, "`%s` arguments for `%.*s`, expected %td, got %td", err, LIT(proc->string), - bp->arg_count, gb_array_count(ce->args)); + bp->arg_count, ce->args.count); return false; } } @@ -2321,7 +2324,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) AstNode *len = ce->args[1]; AstNode *cap = NULL; - if (gb_array_count(ce->args) > 2) { + if (ce->args.count > 2) { cap = ce->args[2]; } @@ -2349,7 +2352,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) type_str); return false; } - if (ce->args[3] != NULL) { + if (ce->args.count > 3) { error(ast_node_token(call), "Too many arguments to `new_slice`, expected either 2 or 3"); return false; @@ -2666,7 +2669,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) isize max_count = vector_type->Vector.count; isize arg_count = 0; - gb_for_array(i, ce->args) { + for_array(i, ce->args) { if (i == 0) continue; AstNode *arg = ce->args[i]; Operand op = {}; @@ -2826,7 +2829,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) AstNode *len = ce->args[1]; AstNode *cap = NULL; - if (gb_array_count(ce->args) > 2) { + if (ce->args.count > 2) { cap = ce->args[2]; } @@ -2855,7 +2858,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id) type_str); return false; } - if (ce->args[2] != NULL) { + if (ce->args.count > 3) { error(ast_node_token(call), "Too many arguments to `slice_ptr`, expected either 2 or 3"); return false; @@ -3083,7 +3086,7 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode return; } - if (gb_array_count(ce->args) == 0 && param_count == 0) { + if (ce->args.count == 0 && param_count == 0) { return; } @@ -3091,14 +3094,14 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode defer (gb_temp_arena_memory_end(tmp)); isize operand_count = 0; - gbArray(Operand) operands; - gb_array_init_reserve(operands, c->tmp_allocator, 2*param_count); + Array operands; + array_init(&operands, c->tmp_allocator, 2*param_count); - gb_for_array(i, ce->args) { + for_array(i, ce->args) { Operand o = {}; check_multi_expr(c, &o, ce->args[i]); if (o.type->kind != Type_Tuple) { - gb_array_append(operands, o); + array_add(&operands, o); } else { auto *tuple = &o.type->Tuple; if (variadic && i >= param_count) { @@ -3109,12 +3112,12 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode } for (isize j = 0; j < tuple->variable_count; j++) { o.type = tuple->variables[j]->type; - gb_array_append(operands, o); + array_add(&operands, o); } } } - operand_count = gb_array_count(operands); + operand_count = operands.count; i32 error_code = 0; if (operand_count < param_count) { error_code = -1; @@ -3190,7 +3193,7 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) { check_expr_or_type(c, operand, ce->proc); if (operand->mode == Addressing_Invalid) { - gb_for_array(i, ce->args) { + for_array(i, ce->args) { check_expr_base(c, operand, ce->args[i]); } operand->mode = Addressing_Invalid; @@ -3342,9 +3345,10 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint Type *t = base_type(type); switch (t->kind) { case Type_Record: { - if (!is_type_struct(t)) + if (!is_type_struct(t)) { break; - if (cl->elems == NULL || gb_array_count(cl->elems) == 0) { + } + if (cl->elems.count == 0) { break; // NOTE(bill): No need to init } { // Checker values @@ -3352,7 +3356,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint if (cl->elems[0]->kind == AstNode_FieldValue) { b32 *fields_visited = gb_alloc_array(c->allocator, b32, field_count); - gb_for_array(i, cl->elems) { + for_array(i, cl->elems) { AstNode *elem = cl->elems[i]; if (elem->kind != AstNode_FieldValue) { error(ast_node_token(elem), @@ -3376,7 +3380,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint continue; } - if (gb_array_count(sel.index) > 1) { + if (sel.index.count > 1) { error(ast_node_token(elem), "Cannot assign to an anonymous field `%.*s` in a structure literal (at the moment)", LIT(name)); continue; @@ -3401,7 +3405,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint check_assignment(c, o, field->type, make_string("structure literal")); } } else { - gb_for_array(index, cl->elems) { + for_array(index, cl->elems) { AstNode *elem = cl->elems[index]; if (elem->kind == AstNode_FieldValue) { error(ast_node_token(elem), @@ -3422,8 +3426,8 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint check_assignment(c, o, field->type, make_string("structure literal")); } - if (gb_array_count(cl->elems) < field_count) { - error(cl->close, "Too few values in structure literal, expected %td, got %td", field_count, gb_array_count(cl->elems)); + if (cl->elems.count < field_count) { + error(cl->close, "Too few values in structure literal, expected %td, got %td", field_count, cl->elems.count); } } } @@ -3450,10 +3454,8 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint i64 max = 0; isize index = 0; - isize elem_count = 0; - if (cl->elems != NULL) { - elem_count = gb_array_count(cl->elems); - } + isize elem_count = cl->elems.count; + for (; index < elem_count; index++) { AstNode *e = cl->elems[index]; if (e->kind == AstNode_FieldValue) { @@ -3871,7 +3873,7 @@ void check_expr_or_type(Checker *c, Operand *o, AstNode *e) { gbString write_expr_to_string(gbString str, AstNode *node); gbString write_params_to_string(gbString str, AstNodeArray params, char *sep) { - gb_for_array(i, params) { + for_array(i, params) { ast_node(p, Parameter, params[i]); if (i > 0) { str = gb_string_appendc(str, sep); @@ -3918,7 +3920,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_ast_node(cl, CompoundLit, node); str = write_expr_to_string(str, cl->type); str = gb_string_appendc(str, "{"); - gb_for_array(i, cl->elems) { + for_array(i, cl->elems) { if (i > 0) { str = gb_string_appendc(str, ", "); } @@ -4021,7 +4023,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { if (p->is_using) { str = gb_string_appendc(str, "using "); } - gb_for_array(i, p->names) { + for_array(i, p->names) { AstNode *name = p->names[i]; if (i > 0) str = gb_string_appendc(str, ", "); @@ -4036,7 +4038,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { str = write_expr_to_string(str, ce->proc); str = gb_string_appendc(str, "("); - gb_for_array(i, ce->args) { + for_array(i, ce->args) { AstNode *arg = ce->args[i]; if (i > 0) { str = gb_string_appendc(str, ", "); @@ -4056,7 +4058,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { str = gb_string_appendc(str, "struct "); if (st->is_packed) str = gb_string_appendc(str, "#packed "); if (st->is_ordered) str = gb_string_appendc(str, "#ordered "); - gb_for_array(i, st->decls) { + for_array(i, st->decls) { if (i > 0) { str = gb_string_appendc(str, "; "); } @@ -4068,7 +4070,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_ast_node(st, RawUnionType, node); str = gb_string_appendc(str, "raw_union {"); - gb_for_array(i, st->decls) { + for_array(i, st->decls) { if (i > 0) { str = gb_string_appendc(str, "; "); } @@ -4080,7 +4082,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_ast_node(st, UnionType, node); str = gb_string_appendc(str, "union {"); - gb_for_array(i, st->decls) { + for_array(i, st->decls) { if (i > 0) { str = gb_string_appendc(str, "; "); } diff --git a/src/checker/stmt.cpp b/src/checker/stmt.cpp index e4d9115d7..7dddf00e7 100644 --- a/src/checker/stmt.cpp +++ b/src/checker/stmt.cpp @@ -11,7 +11,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags); void check_proc_decl(Checker *c, Entity *e, DeclInfo *d); void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) { - if (stmts == NULL) { + if (stmts.count == 0) { return; } @@ -22,14 +22,14 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) { Entity *e; DeclInfo *d; }; - gbArray(Delay) delayed_const; gb_array_init_reserve(delayed_const, c->tmp_allocator, gb_array_count(stmts)); - gbArray(Delay) delayed_type; gb_array_init_reserve(delayed_type, c->tmp_allocator, gb_array_count(stmts)); + Array delayed_const; array_init(&delayed_const, c->tmp_allocator, stmts.count); + Array delayed_type; array_init(&delayed_type, c->tmp_allocator, stmts.count); - gb_for_array(i, stmts) { + for_array(i, stmts) { AstNode *node = stmts[i]; switch (node->kind) { case_ast_node(cd, ConstDecl, node); - gb_for_array(i, cd->values) { + for_array(i, cd->values) { AstNode *name = cd->names[i]; AstNode *value = cd->values[i]; ExactValue v = {ExactValue_Invalid}; @@ -44,11 +44,11 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) { add_entity_and_decl_info(c, name, e, d); Delay delay = {e, d}; - gb_array_append(delayed_const, delay); + array_add(&delayed_const, delay); } - isize lhs_count = gb_array_count(cd->names); - isize rhs_count = gb_array_count(cd->values); + isize lhs_count = cd->names.count; + isize rhs_count = cd->values.count; if (rhs_count == 0 && cd->type == NULL) { error(ast_node_token(node), "Missing type or initial expression"); @@ -67,28 +67,28 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) { add_entity_and_decl_info(c, td->name, e, d); Delay delay = {e, d}; - gb_array_append(delayed_type, delay); + array_add(&delayed_type, delay); case_end; } } - gb_for_array(i, delayed_type) { + for_array(i, delayed_type) { check_entity_decl(c, delayed_type[i].e, delayed_type[i].d, NULL); } - gb_for_array(i, delayed_const) { + for_array(i, delayed_const) { check_entity_decl(c, delayed_const[i].e, delayed_const[i].d, NULL); } b32 ft_ok = (flags & Stmt_FallthroughAllowed) != 0; u32 f = flags & (~Stmt_FallthroughAllowed); - gb_for_array(i, stmts) { + for_array(i, stmts) { AstNode *n = stmts[i]; if (n->kind == AstNode_EmptyStmt) { continue; } u32 new_flags = f; - if (ft_ok && i+1 == gb_array_count(stmts)) { + if (ft_ok && i+1 == stmts.count) { new_flags |= Stmt_FallthroughAllowed; } check_stmt(c, n, new_flags); @@ -101,7 +101,7 @@ b32 check_has_break(AstNode *stmt, b32 implicit); b32 check_is_terminating_list(AstNodeArray stmts) { // Iterate backwards - for (isize n = gb_array_count(stmts)-1; n >= 0; n--) { + for (isize n = stmts.count-1; n >= 0; n--) { AstNode *stmt = stmts[n]; if (stmt->kind != AstNode_EmptyStmt) { return check_is_terminating(stmt); @@ -112,7 +112,7 @@ b32 check_is_terminating_list(AstNodeArray stmts) { } b32 check_has_break_list(AstNodeArray stmts, b32 implicit) { - gb_for_array(i, stmts) { + for_array(i, stmts) { AstNode *stmt = stmts[i]; if (check_has_break(stmt, implicit)) { return true; @@ -182,10 +182,10 @@ b32 check_is_terminating(AstNode *node) { case_ast_node(ms, MatchStmt, node); b32 has_default = false; - gb_for_array(i, ms->body->BlockStmt.stmts) { + for_array(i, ms->body->BlockStmt.stmts) { AstNode *clause = ms->body->BlockStmt.stmts[i]; ast_node(cc, CaseClause, clause); - if (cc->list == NULL) { + if (cc->list.count == 0) { has_default = true; } if (!check_is_terminating_list(cc->stmts) || @@ -198,10 +198,10 @@ b32 check_is_terminating(AstNode *node) { case_ast_node(ms, TypeMatchStmt, node); b32 has_default = false; - gb_for_array(i, ms->body->BlockStmt.stmts) { + for_array(i, ms->body->BlockStmt.stmts) { AstNode *clause = ms->body->BlockStmt.stmts[i]; ast_node(cc, CaseClause, clause); - if (cc->list == NULL) { + if (cc->list.count == 0) { has_default = true; } if (!check_is_terminating_list(cc->stmts) || @@ -336,7 +336,7 @@ 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) { - if ((lhs == NULL || lhs_count == 0) && (inits == NULL || gb_array_count(inits) == 0)) { + if ((lhs == NULL || lhs_count == 0) && inits.count == 0) { return; } @@ -345,26 +345,26 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra // NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be // an extra allocation - gbArray(Operand) operands; - gb_array_init_reserve(operands, c->tmp_allocator, 2*lhs_count); + Array operands; + array_init(&operands, c->tmp_allocator, 2*lhs_count); - gb_for_array(i, inits) { + for_array(i, inits) { AstNode *rhs = inits[i]; Operand o = {}; check_multi_expr(c, &o, rhs); if (o.type->kind != Type_Tuple) { - gb_array_append(operands, o); + array_add(&operands, o); } else { auto *tuple = &o.type->Tuple; for (isize j = 0; j < tuple->variable_count; j++) { o.type = tuple->variables[j]->type; - gb_array_append(operands, o); + array_add(&operands, o); } } } - isize rhs_count = gb_array_count(operands); - gb_for_array(i, operands) { + isize rhs_count = operands.count; + for_array(i, operands) { if (operands[i].mode == Addressing_Invalid) { rhs_count--; } @@ -498,7 +498,7 @@ void check_proc_body(Checker *c, Token token, DeclInfo *decl, Type *type, AstNod if (is_type_struct(t) || is_type_raw_union(t)) { Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node)); GB_ASSERT(found != NULL); - gb_for_array(i, (*found)->elements.entries) { + for_array(i, (*found)->elements.entries) { Entity *f = (*found)->elements.entries[i].value; if (f->kind == Entity_Variable) { Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type); @@ -696,8 +696,8 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count } AstNodeArray inits; - gb_array_init_reserve(inits, c->allocator, 1); - gb_array_append(inits, init_expr); + array_init(&inits, c->allocator, 1); + array_add(&inits, init_expr); check_init_variables(c, entities, entity_count, inits, make_string("variable declaration")); } @@ -746,11 +746,11 @@ void check_entity_decl(Checker *c, Entity *e, DeclInfo *d, Type *named_type, Cyc void check_var_decl_node(Checker *c, AstNode *node) { ast_node(vd, VarDecl, node); - isize entity_count = gb_array_count(vd->names); + isize entity_count = vd->names.count; isize entity_index = 0; Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count); - gb_for_array(i, vd->names) { + for_array(i, vd->names) { AstNode *name = vd->names[i]; Entity *entity = NULL; if (name->kind == AstNode_Ident) { @@ -803,7 +803,7 @@ void check_var_decl_node(Checker *c, AstNode *node) { check_init_variables(c, entities, entity_count, vd->values, make_string("variable declaration")); - gb_for_array(i, vd->names) { + for_array(i, vd->names) { if (entities[i] != NULL) { add_entity(c, c->context.scope, vd->names[i], entities[i]); } @@ -911,7 +911,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { switch (as->op.kind) { case Token_Eq: { // a, b, c = 1, 2, 3; // Multisided - if (gb_array_count(as->lhs) == 0) { + if (as->lhs.count == 0) { error(as->op, "Missing lhs in assignment statement"); return; } @@ -921,29 +921,29 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { // NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be // an extra allocation - gbArray(Operand) operands; - gb_array_init_reserve(operands, c->tmp_allocator, 2 * gb_array_count(as->lhs)); + Array operands; + array_init(&operands, c->tmp_allocator, 2 * as->lhs.count); - gb_for_array(i, as->rhs) { + for_array(i, as->rhs) { AstNode *rhs = as->rhs[i]; Operand o = {}; check_multi_expr(c, &o, rhs); if (o.type->kind != Type_Tuple) { - gb_array_append(operands, o); + array_add(&operands, o); } else { auto *tuple = &o.type->Tuple; for (isize j = 0; j < tuple->variable_count; j++) { o.type = tuple->variables[j]->type; - gb_array_append(operands, o); + array_add(&operands, o); } } } - isize lhs_count = gb_array_count(as->lhs); - isize rhs_count = gb_array_count(operands); + isize lhs_count = as->lhs.count; + isize rhs_count = operands.count; isize operand_index = 0; - gb_for_array(i, as->lhs) { + for_array(i, as->lhs) { AstNode *lhs = as->lhs[i]; check_assignment_variable(c, &operands[i], lhs); } @@ -955,7 +955,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { default: { // a += 1; // Single-sided Token op = as->op; - if (gb_array_count(as->lhs) != 1 || gb_array_count(as->rhs) != 1) { + if (as->lhs.count != 1 || as->rhs.count != 1) { error(op, "Assignment operation `%.*s` requires single-valued expressions", LIT(op.string)); return; } @@ -1019,7 +1019,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { case_end; case_ast_node(rs, ReturnStmt, node); - GB_ASSERT(gb_array_count(c->proc_stack) > 0); + GB_ASSERT(c->proc_stack.count > 0); if (c->in_defer) { error(rs->token, "You cannot `return` within a defer statement"); @@ -1028,7 +1028,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { } - Type *proc_type = c->proc_stack[gb_array_count(c->proc_stack)-1]; + Type *proc_type = c->proc_stack[c->proc_stack.count-1]; isize result_count = 0; if (proc_type->Proc.results) { result_count = proc_type->Proc.results->Tuple.variable_count; @@ -1040,13 +1040,13 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { auto *tuple = &proc_type->Proc.results->Tuple; variables = tuple->variables; } - if (gb_array_count(rs->results) == 0) { + if (rs->results.count == 0) { error(ast_node_token(node), "Expected %td return values, got 0", result_count); } else { check_init_variables(c, variables, result_count, rs->results, make_string("return statement")); } - } else if (gb_array_count(rs->results) > 0) { + } else if (rs->results.count > 0) { error(ast_node_token(rs->results[0]), "No return values expected"); } case_end; @@ -1099,12 +1099,12 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { // NOTE(bill): Check for multiple defaults AstNode *first_default = NULL; ast_node(bs, BlockStmt, ms->body); - gb_for_array(i, bs->stmts) { + for_array(i, bs->stmts) { AstNode *stmt = bs->stmts[i]; AstNode *default_stmt = NULL; if (stmt->kind == AstNode_CaseClause) { ast_node(cc, CaseClause, stmt); - if (gb_array_count(cc->list) == 0) { + if (cc->list.count == 0) { default_stmt = stmt; } } else { @@ -1132,7 +1132,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { Map seen = {}; // Multimap map_init(&seen, gb_heap_allocator()); defer (map_destroy(&seen)); - gb_for_array(i, bs->stmts) { + for_array(i, bs->stmts) { AstNode *stmt = bs->stmts[i]; if (stmt->kind != AstNode_CaseClause) { // NOTE(bill): error handled by above multiple default checker @@ -1141,7 +1141,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { ast_node(cc, CaseClause, stmt); - gb_for_array(j, cc->list) { + for_array(j, cc->list) { AstNode *expr = cc->list[j]; Operand y = {}; Operand z = {}; @@ -1206,7 +1206,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { check_open_scope(c, stmt); u32 ft_flags = mod_flags; - if (i+1 < gb_array_count(bs->stmts)) { + if (i+1 < bs->stmts.count) { ft_flags |= Stmt_FallthroughAllowed; } check_stmt_list(c, cc->stmts, ft_flags); @@ -1237,12 +1237,12 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { // NOTE(bill): Check for multiple defaults AstNode *first_default = NULL; ast_node(bs, BlockStmt, ms->body); - gb_for_array(i, bs->stmts) { + for_array(i, bs->stmts) { AstNode *stmt = bs->stmts[i]; AstNode *default_stmt = NULL; if (stmt->kind == AstNode_CaseClause) { ast_node(cc, CaseClause, stmt); - if (gb_array_count(cc->list) == 0) { + if (cc->list.count == 0) { default_stmt = stmt; } } else { @@ -1271,7 +1271,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { defer (map_destroy(&seen)); - gb_for_array(i, bs->stmts) { + for_array(i, bs->stmts) { AstNode *stmt = bs->stmts[i]; if (stmt->kind != AstNode_CaseClause) { // NOTE(bill): error handled by above multiple default checker @@ -1428,7 +1428,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { case Entity_ImportName: { Scope *scope = e->ImportName.scope; - gb_for_array(i, scope->elements.entries) { + for_array(i, scope->elements.entries) { Entity *decl = scope->elements.entries[i].value; Entity *found = scope_insert_entity(c->context.scope, decl); if (found != NULL) { @@ -1459,7 +1459,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { if (is_type_struct(t) || is_type_raw_union(t)) { Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node)); GB_ASSERT(found != NULL); - gb_for_array(i, (*found)->elements.entries) { + for_array(i, (*found)->elements.entries) { Entity *f = (*found)->elements.entries[i].value; if (f->kind == Entity_Variable) { Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type); @@ -1485,12 +1485,12 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { case_end; case_ast_node(vd, VarDecl, us->node); - if (gb_array_count(vd->names) > 1 && vd->type != NULL) { + if (vd->names.count > 1 && vd->type != NULL) { error(us->token, "`using` can only be applied to one variable of the same type"); } check_var_decl_node(c, us->node); - gb_for_array(name_index, vd->names) { + for_array(name_index, vd->names) { AstNode *item = vd->names[name_index]; ast_node(i, Ident, item); String name = i->string; @@ -1499,7 +1499,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { if (is_type_struct(t) || is_type_raw_union(t)) { Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node)); GB_ASSERT(found != NULL); - gb_for_array(i, (*found)->elements.entries) { + for_array(i, (*found)->elements.entries) { Entity *f = (*found)->elements.entries[i].value; if (f->kind == Entity_Variable) { Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type); diff --git a/src/checker/type.cpp b/src/checker/type.cpp index 901a467f7..8e1367f95 100644 --- a/src/checker/type.cpp +++ b/src/checker/type.cpp @@ -777,12 +777,12 @@ gb_global i64 basic_type_sizes[] = { struct Selection { Entity *entity; - gbArray(isize) index; + Array index; b32 indirect; // Set if there was a pointer deref anywhere down the line }; Selection empty_selection = {}; -Selection make_selection(Entity *entity, gbArray(isize) index, b32 indirect) { +Selection make_selection(Entity *entity, Array index, b32 indirect) { Selection s = {entity, index, indirect}; return s; } @@ -790,10 +790,10 @@ Selection make_selection(Entity *entity, gbArray(isize) index, b32 indirect) { void selection_add_index(Selection *s, isize index) { // IMPORTANT NOTE(bill): this requires a stretchy buffer/dynamic array so it requires some form // of heap allocation - if (s->index == NULL) { - gb_array_init(s->index, gb_heap_allocator()); + if (s->index.data == NULL) { + array_init(&s->index, gb_heap_allocator()); } - gb_array_append(s->index, index); + array_add(&s->index, index); } gb_global Entity *entity__any_type_info = NULL; @@ -918,7 +918,8 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ String str = f->token.string; if (field_name == str) { - return make_selection(f, NULL, i); + Selection sel = {f, {}, i}; + return sel; } } } @@ -929,7 +930,8 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ String str = f->token.string; if (field_name == str) { - return make_selection(f, NULL, i); + Selection sel = {f, {}, i}; + return sel; } } @@ -958,10 +960,7 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ } if (f->Variable.anonymous) { - isize prev_count = 0; - if (sel.index != NULL) { - prev_count = gb_array_count(sel.index); - } + isize prev_count = sel.index.count; selection_add_index(&sel, i); // HACK(bill): Leaky memory sel = lookup_field(a, f->type, field_name, is_type, sel); @@ -971,7 +970,7 @@ Selection lookup_field(gbAllocator a, Type *type_, String field_name, b32 is_typ sel.indirect = true; return sel; } - gb_array_count(sel.index) = prev_count; + sel.index.count = prev_count; } } } @@ -1208,7 +1207,7 @@ i64 type_offset_of(BaseTypeSizes s, gbAllocator allocator, Type *t, isize index) i64 type_offset_of_from_selection(BaseTypeSizes s, gbAllocator allocator, Type *t, Selection sel) { i64 offset = 0; - for (isize i = 0; i < gb_array_count(sel.index); i++) { + for_array(i, sel.index) { isize index = sel.index[i]; t = base_type(t); if (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct) { diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index cf9e561b1..95727e519 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -87,7 +87,7 @@ void ssa_gen_tree(ssaGen *s) { isize global_variable_max_count = 0; Entity *entry_point = NULL; - gb_for_array(i, info->entities.entries) { + for_array(i, info->entities.entries) { auto *entry = &info->entities.entries[i]; Entity *e = cast(Entity *)cast(uintptr)entry->key.key; String name = e->token.string; @@ -104,13 +104,13 @@ void ssa_gen_tree(ssaGen *s) { ssaValue *var, *init; DeclInfo *decl; }; - gbArray(ssaGlobalVariable) global_variables; - gb_array_init_reserve(global_variables, m->tmp_allocator, global_variable_max_count); + Array global_variables; + array_init(&global_variables, m->tmp_allocator, global_variable_max_count); auto min_dep_map = generate_minimum_dependency_map(info, entry_point); defer (map_destroy(&min_dep_map)); - gb_for_array(i, info->entities.entries) { + for_array(i, info->entities.entries) { auto *entry = &info->entities.entries[i]; Entity *e = cast(Entity *)cast(uintptr)entry->key.key; String name = e->token.string; @@ -160,7 +160,7 @@ void ssa_gen_tree(ssaGen *s) { } if (g->Global.value == NULL) { - gb_array_append(global_variables, var); + array_add(&global_variables, var); } map_set(&m->values, hash_pointer(e), g); @@ -192,7 +192,7 @@ void ssa_gen_tree(ssaGen *s) { } } - gb_for_array(i, m->members.entries) { + for_array(i, m->members.entries) { auto *entry = &m->members.entries[i]; ssaValue *v = entry->value; if (v->kind == ssaValue_Proc) @@ -204,7 +204,7 @@ void ssa_gen_tree(ssaGen *s) { ssaDebugInfo *all_procs = ssa_alloc_debug_info(m->allocator, ssaDebugInfo_AllProcs); isize all_proc_max_count = 0; - gb_for_array(i, m->debug_info.entries) { + for_array(i, m->debug_info.entries) { auto *entry = &m->debug_info.entries[i]; ssaDebugInfo *di = entry->value; di->id = i; @@ -213,17 +213,17 @@ void ssa_gen_tree(ssaGen *s) { } } - gb_array_init_reserve(all_procs->AllProcs.procs, m->allocator, all_proc_max_count); + array_init(&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 compile_unit->CompileUnit.all_procs = all_procs; - gb_for_array(i, m->debug_info.entries) { + for_array(i, m->debug_info.entries) { auto *entry = &m->debug_info.entries[i]; ssaDebugInfo *di = entry->value; di->id = i; if (di->kind == ssaDebugInfo_Proc) { - gb_array_append(all_procs->AllProcs.procs, di); + array_add(&all_procs->AllProcs.procs, di); } } @@ -249,7 +249,7 @@ void ssa_gen_tree(ssaGen *s) { ssa_begin_procedure_body(proc); // TODO(bill): Should do a dependency graph do check which order to initialize them in? - gb_for_array(i, global_variables) { + for_array(i, global_variables) { ssaGlobalVariable *var = &global_variables[i]; if (var->decl->init_expr != NULL) { var->init = ssa_build_expr(proc, var->decl->init_expr); @@ -257,7 +257,7 @@ void ssa_gen_tree(ssaGen *s) { } // NOTE(bill): Initialize constants first - gb_for_array(i, global_variables) { + for_array(i, global_variables) { ssaGlobalVariable *var = &global_variables[i]; if (var->init != NULL) { if (var->init->kind == ssaValue_Constant) { @@ -266,7 +266,7 @@ void ssa_gen_tree(ssaGen *s) { } } - gb_for_array(i, global_variables) { + for_array(i, global_variables) { ssaGlobalVariable *var = &global_variables[i]; if (var->init != NULL) { if (var->init->kind != ssaValue_Constant) { @@ -315,7 +315,7 @@ void ssa_gen_tree(ssaGen *s) { }; - gb_for_array(type_info_map_index, info->type_info_map.entries) { + for_array(type_info_map_index, info->type_info_map.entries) { auto *entry = &info->type_info_map.entries[type_info_map_index]; Type *t = cast(Type *)cast(uintptr)entry->key.key; t = default_type(t); @@ -673,7 +673,7 @@ void ssa_gen_tree(ssaGen *s) { ssa_end_procedure_body(proc); } - gb_for_array(i, m->procs) { + for_array(i, m->procs) { ssa_build_proc(m->procs[i], m->procs[i]->Proc.parent); } diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index 1abbdb0d1..0d8a5e51f 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -354,7 +354,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ type = base_type(type); if (is_type_array(type)) { ast_node(cl, CompoundLit, value.value_compound); - isize elem_count = cl->elems != NULL ? gb_array_count(cl->elems) : 0; + isize elem_count = cl->elems.count; if (elem_count == 0) { ssa_fprintf(f, "zeroinitializer"); break; @@ -385,7 +385,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ ssa_fprintf(f, "]"); } else if (is_type_vector(type)) { ast_node(cl, CompoundLit, value.value_compound); - isize elem_count = cl->elems != NULL ? gb_array_count(cl->elems) : 0; + isize elem_count = cl->elems.count; if (elem_count == 0) { ssa_fprintf(f, "zeroinitializer"); break; @@ -427,7 +427,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ ast_node(cl, CompoundLit, value.value_compound); - if (cl->elems == NULL || gb_array_count(cl->elems) == 0) { + if (cl->elems.count == 0) { ssa_fprintf(f, "zeroinitializer"); break; } @@ -438,7 +438,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ if (cl->elems[0]->kind == AstNode_FieldValue) { - isize elem_count = cl->elems != NULL ? gb_array_count(cl->elems) : 0; + isize elem_count = cl->elems.count; for (isize i = 0; i < elem_count; i++) { ast_node(fv, FieldValue, cl->elems[i]); String name = fv->field->Ident.string; @@ -1009,14 +1009,14 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) { // ssa_fprintf(f, "nounwind uwtable {\n"); ssa_fprintf(f, "{\n"); - gb_for_array(i, proc->blocks) { + for_array(i, proc->blocks) { ssaBlock *block = proc->blocks[i]; if (i > 0) ssa_fprintf(f, "\n"); ssa_print_block_name(f, block); ssa_fprintf(f, ":\n"); - gb_for_array(j, block->instrs) { + for_array(j, block->instrs) { ssaValue *value = block->instrs[j]; ssa_print_instr(f, m, value); } @@ -1026,7 +1026,7 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) { ssa_fprintf(f, "\n"); } - gb_for_array(i, proc->children) { + for_array(i, proc->children) { ssa_print_proc(f, m, proc->children[i]); } } @@ -1063,7 +1063,7 @@ void ssa_print_llvm_ir(ssaFileBuffer *f, ssaModule *m) { ssa_fprintf(f, "} ; Basic_any\n"); - gb_for_array(member_index, m->members.entries) { + for_array(member_index, m->members.entries) { auto *entry = &m->members.entries[member_index]; ssaValue *v = entry->value; if (v->kind != ssaValue_TypeName) { @@ -1072,7 +1072,7 @@ void ssa_print_llvm_ir(ssaFileBuffer *f, ssaModule *m) { ssa_print_type_name(f, m, v); } - gb_for_array(member_index, m->members.entries) { + for_array(member_index, m->members.entries) { auto *entry = &m->members.entries[member_index]; ssaValue *v = entry->value; if (v->kind != ssaValue_Proc) { @@ -1083,7 +1083,7 @@ void ssa_print_llvm_ir(ssaFileBuffer *f, ssaModule *m) { } } - gb_for_array(member_index, m->members.entries) { + for_array(member_index, m->members.entries) { auto *entry = &m->members.entries[member_index]; ssaValue *v = entry->value; if (v->kind != ssaValue_Proc) { @@ -1095,7 +1095,7 @@ void ssa_print_llvm_ir(ssaFileBuffer *f, ssaModule *m) { } - gb_for_array(member_index, m->members.entries) { + for_array(member_index, m->members.entries) { auto *entry = &m->members.entries[member_index]; ssaValue *v = entry->value; if (v->kind != ssaValue_Global) { @@ -1137,7 +1137,7 @@ void ssa_print_llvm_ir(ssaFileBuffer *f, ssaModule *m) { ssa_fprintf(f, "\n"); ssa_fprintf(f, "!llvm.dbg.cu = !{!0}\n"); - gb_for_array(di_index, m->debug_info.entries) { + for_array(di_index, m->debug_info.entries) { auto *entry = &m->debug_info.entries[di_index]; ssaDebugInfo *di = entry->value; ssa_fprintf(f, "!%d = ", di->id); @@ -1184,7 +1184,7 @@ void ssa_print_llvm_ir(ssaFileBuffer *f, ssaModule *m) { case ssaDebugInfo_AllProcs: ssa_fprintf(f, "!{"); - gb_for_array(proc_index, di->AllProcs.procs) { + for_array(proc_index, di->AllProcs.procs) { ssaDebugInfo *p = di->AllProcs.procs[proc_index]; if (proc_index > 0) {ssa_fprintf(f, ",");} ssa_fprintf(f, "!%d", p->id); diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index 5d66b222e..5875c4b35 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -37,7 +37,7 @@ struct ssaDebugInfo { TokenPos pos; } Proc; struct { - gbArray(ssaDebugInfo *) procs; + Array procs; } AllProcs; }; }; @@ -64,7 +64,7 @@ struct ssaModule { i32 global_string_index; i32 global_array_index; // For ConstantSlice - gbArray(ssaValue *) procs; // NOTE(bill): Procedures to generate + Array procs; // NOTE(bill): Procedures to generate }; @@ -77,8 +77,11 @@ struct ssaBlock { ssaProcedure *parent; b32 added; - gbArray(ssaValue *) instrs; - gbArray(ssaValue *) values; + Array instrs; + Array locals; + + Array preds; + Array succs; }; struct ssaTargetList { @@ -111,7 +114,7 @@ struct ssaDefer { struct ssaProcedure { ssaProcedure *parent; - gbArray(ssaProcedure *) children; + Array children; Entity * entity; ssaModule * module; @@ -122,8 +125,8 @@ struct ssaProcedure { u64 tags; isize scope_index; - gbArray(ssaDefer) defer_stmts; - gbArray(ssaBlock *) blocks; + Array defer_stmts; + Array blocks; ssaBlock * decl_block; ssaBlock * entry_block; ssaBlock * curr_block; @@ -149,6 +152,7 @@ struct ssaProcedure { SSA_INSTR_KIND(Br), \ SSA_INSTR_KIND(Ret), \ SSA_INSTR_KIND(Select), \ + SSA_INSTR_KIND(Phi), \ SSA_INSTR_KIND(Unreachable), \ SSA_INSTR_KIND(BinaryOp), \ SSA_INSTR_KIND(Call), \ @@ -261,6 +265,10 @@ struct ssaInstr { ssaValue *true_value; ssaValue *false_value; } Select; + struct { + String comment; + Array edges; + } Phi; struct { Type *type; Token op; @@ -396,7 +404,7 @@ ssaDefer ssa_add_defer_node(ssaProcedure *proc, isize scope_index, AstNode *stmt d.scope_index = scope_index; d.block = proc->curr_block; d.stmt = stmt; - gb_array_append(proc->defer_stmts, d); + array_add(&proc->defer_stmts, d); return d; } @@ -406,7 +414,7 @@ ssaDefer ssa_add_defer_instr(ssaProcedure *proc, isize scope_index, ssaValue *in d.scope_index = proc->scope_index; d.block = proc->curr_block; d.instr = instr; // NOTE(bill): It will make a copy everytime it is called - gb_array_append(proc->defer_stmts, d); + array_add(&proc->defer_stmts, d); return d; } @@ -425,7 +433,7 @@ void ssa_init_module(ssaModule *m, Checker *c) { map_init(&m->members, gb_heap_allocator()); map_init(&m->debug_info, gb_heap_allocator()); map_init(&m->type_names, gb_heap_allocator()); - gb_array_init(m->procs, gb_heap_allocator()); + array_init(&m->procs, gb_heap_allocator()); // Default states m->stmt_state_flags = 0; @@ -435,7 +443,7 @@ void ssa_init_module(ssaModule *m, Checker *c) { // Add type info data { String name = make_string(SSA_TYPE_INFO_DATA_NAME); - isize count = gb_array_count(c->info.type_info_map.entries); + isize count = c->info.type_info_map.entries.count; Entity *e = make_entity_variable(m->allocator, NULL, make_token_ident(name), make_type_array(m->allocator, t_type_info, count)); ssaValue *g = ssa_make_value_global(m->allocator, e, NULL); g->Global.is_private = true; @@ -448,7 +456,7 @@ void ssa_init_module(ssaModule *m, Checker *c) { // NOTE(bill): Removes need for heap allocation by making it global memory isize count = 0; - gb_for_array(entry_index, m->info->type_info_map.entries) { + for_array(entry_index, m->info->type_info_map.entries) { auto *entry = &m->info->type_info_map.entries[entry_index]; Type *t = cast(Type *)cast(uintptr)entry->key.key; @@ -489,7 +497,7 @@ void ssa_destroy_module(ssaModule *m) { map_destroy(&m->members); map_destroy(&m->type_names); map_destroy(&m->debug_info); - gb_array_free(m->procs); + array_free(&m->procs); gb_arena_free(&m->arena); } @@ -630,9 +638,6 @@ ssaValue *ssa_alloc_value(gbAllocator a, ssaValueKind kind) { ssaValue *ssa_alloc_instr(ssaProcedure *proc, ssaInstrKind kind) { ssaValue *v = ssa_alloc_value(proc->module->allocator, ssaValue_Instr); v->Instr.kind = kind; - if (proc->curr_block) { - gb_array_append(proc->curr_block->values, v); - } return v; } @@ -868,10 +873,7 @@ ssaValue *ssa_add_module_constant(ssaModule *m, Type *type, ExactValue value) { ast_node(cl, CompoundLit, value.value_compound); gbAllocator a = m->allocator; - isize count = 0; - if (cl->elems) { - count = gb_array_count(cl->elems); - } + isize count = cl->elems.count; if (count > 0) { Type *elem = base_type(type)->Slice.elem; Type *t = make_type_array(a, elem, count); @@ -918,8 +920,11 @@ ssaValue *ssa_make_value_block(ssaProcedure *proc, AstNode *node, Scope *scope, v->Block.scope = scope; v->Block.parent = proc; - gb_array_init(v->Block.instrs, gb_heap_allocator()); - gb_array_init(v->Block.values, gb_heap_allocator()); + array_init(&v->Block.instrs, gb_heap_allocator()); + array_init(&v->Block.locals, gb_heap_allocator()); + + array_init(&v->Block.preds, gb_heap_allocator()); + array_init(&v->Block.succs, gb_heap_allocator()); return v; } @@ -935,10 +940,7 @@ b32 ssa_is_blank_ident(AstNode *node) { ssaInstr *ssa_get_last_instr(ssaBlock *block) { if (block != NULL) { - isize len = 0; - if (block->instrs != NULL) { - len = gb_array_count(block->instrs); - } + isize len = block->instrs.count; if (len > 0) { ssaValue *v = block->instrs[len-1]; GB_ASSERT(v->kind == ssaValue_Instr); @@ -968,7 +970,7 @@ ssaValue *ssa_emit(ssaProcedure *proc, ssaValue *instr) { if (b != NULL) { ssaInstr *i = ssa_get_last_instr(b); if (!ssa_is_instr_terminating(i)) { - gb_array_append(b->instrs, instr); + array_add(&b->instrs, instr); } } return instr; @@ -996,7 +998,8 @@ ssaValue *ssa_add_local(ssaProcedure *proc, Entity *e, b32 zero_initialized = tr 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; - gb_array_append(b->instrs, instr); + array_add(&b->instrs, instr); + array_add(&b->locals, instr); // if (zero_initialized) { ssa_emit_zero_init(proc, instr); @@ -1079,7 +1082,7 @@ ssaBlock *ssa__make_block(ssaProcedure *proc, AstNode *node, String label) { ssaBlock *ssa_add_block(ssaProcedure *proc, AstNode *node, String label) { ssaBlock *block = ssa__make_block(proc, node, label); - gb_array_append(proc->blocks, block); + array_add(&proc->blocks, block); return block; } @@ -1094,7 +1097,7 @@ void ssa_build_defer_stmt(ssaProcedure *proc, ssaDefer d) { if (last_instr == NULL || !ssa_is_instr_terminating(last_instr)) { ssa_emit_jump(proc, b); } - gb_array_append(proc->blocks, b); + array_add(&proc->blocks, b); proc->curr_block = b; ssa_emit_comment(proc, make_string("defer")); if (d.kind == ssaDefer_Node) { @@ -1107,7 +1110,7 @@ void ssa_build_defer_stmt(ssaProcedure *proc, ssaDefer d) { } void ssa_emit_defer_stmts(ssaProcedure *proc, ssaDeferExitKind kind, ssaBlock *block) { - isize count = gb_array_count(proc->defer_stmts); + isize count = proc->defer_stmts.count; isize i = count; while (i --> 0) { ssaDefer d = proc->defer_stmts[i]; @@ -1115,7 +1118,7 @@ void ssa_emit_defer_stmts(ssaProcedure *proc, ssaDeferExitKind kind, ssaBlock *b if (proc->scope_index == d.scope_index && d.scope_index > 1) { ssa_build_defer_stmt(proc, d); - gb_array_pop(proc->defer_stmts); + array_pop(&proc->defer_stmts); continue; } else { break; @@ -1143,6 +1146,10 @@ void ssa_close_scope(ssaProcedure *proc, ssaDeferExitKind kind, ssaBlock *block) proc->scope_index--; } +void ssa_add_edge(ssaBlock *from, ssaBlock *to) { + array_add(&from->succs, to); + array_add(&to->preds, from); +} @@ -1155,15 +1162,24 @@ void ssa_emit_ret(ssaProcedure *proc, ssaValue *v) { ssa_emit(proc, ssa_make_instr_ret(proc, v)); } -void ssa_emit_jump(ssaProcedure *proc, ssaBlock *block) { - ssa_emit(proc, ssa_make_instr_br(proc, NULL, block, NULL)); - proc->curr_block = NULL; +void ssa_emit_jump(ssaProcedure *proc, ssaBlock *target_block) { + ssaBlock *b = proc->curr_block; + if (b != NULL) { + ssa_emit(proc, ssa_make_instr_br(proc, NULL, target_block, NULL)); + ssa_add_edge(b, target_block); + proc->curr_block = NULL; + } } void ssa_emit_if(ssaProcedure *proc, ssaValue *cond, ssaBlock *true_block, ssaBlock *false_block) { - ssaValue *br = ssa_make_instr_br(proc, cond, true_block, false_block); - ssa_emit(proc, br); - proc->curr_block = NULL; + ssaBlock *b = proc->curr_block; + if (b != NULL) { + ssaValue *br = ssa_make_instr_br(proc, cond, true_block, false_block); + ssa_emit(proc, br); + ssa_add_edge(b, true_block); + ssa_add_edge(b, false_block); + proc->curr_block = NULL; + } } void ssa_emit_no_op(ssaProcedure *proc) { @@ -1208,9 +1224,9 @@ ssaValue *ssa_lvalue_load(ssaProcedure *proc, ssaAddr lval) { void ssa_begin_procedure_body(ssaProcedure *proc) { - gb_array_init(proc->blocks, gb_heap_allocator()); - gb_array_init(proc->defer_stmts, gb_heap_allocator()); - gb_array_init(proc->children, gb_heap_allocator()); + array_init(&proc->blocks, gb_heap_allocator()); + array_init(&proc->defer_stmts, gb_heap_allocator()); + array_init(&proc->children, gb_heap_allocator()); proc->decl_block = ssa_add_block(proc, proc->type_expr, make_string("decls")); proc->entry_block = ssa_add_block(proc, proc->type_expr, make_string("entry")); @@ -1230,7 +1246,7 @@ void ssa_end_procedure_body(ssaProcedure *proc) { ssa_emit_ret(proc, NULL); } - if (gb_array_count(proc->curr_block->instrs) == 0) { + if (proc->curr_block->instrs.count == 0) { ssa_emit_unreachable(proc); } @@ -1240,10 +1256,10 @@ void ssa_end_procedure_body(ssaProcedure *proc) { // Number blocks and registers i32 reg_id = 0; - gb_for_array(i, proc->blocks) { + for_array(i, proc->blocks) { ssaBlock *b = proc->blocks[i]; b->id = i; - gb_for_array(j, b->instrs) { + for_array(j, b->instrs) { ssaValue *value = b->instrs[j]; GB_ASSERT(value->kind == ssaValue_Instr); ssaInstr *instr = &value->Instr; @@ -1370,9 +1386,9 @@ ssaValue *ssa_emit_struct_ev(ssaProcedure *proc, ssaValue *s, i32 index, Type *r ssaValue *ssa_emit_deep_field_gep(ssaProcedure *proc, Type *type, ssaValue *e, Selection sel) { - GB_ASSERT(gb_array_count(sel.index) > 0); + GB_ASSERT(sel.index.count > 0); - gb_for_array(i, sel.index) { + for_array(i, sel.index) { isize index = sel.index[i]; if (is_type_pointer(type)) { type = type_deref(type); @@ -1419,9 +1435,9 @@ ssaValue *ssa_emit_deep_field_gep(ssaProcedure *proc, Type *type, ssaValue *e, S ssaValue *ssa_emit_deep_field_ev(ssaProcedure *proc, Type *type, ssaValue *e, Selection sel) { - GB_ASSERT(gb_array_count(sel.index) > 0); + GB_ASSERT(sel.index.count > 0); - gb_for_array(i, sel.index) { + for_array(i, sel.index) { isize index = sel.index[i]; if (is_type_pointer(type)) { type = type_deref(type); @@ -1480,7 +1496,7 @@ isize ssa_type_info_index(CheckerInfo *info, Type *type) { if (entry_index < 0) { // NOTE(bill): Do manual search // TODO(bill): This is O(n) and can be very slow - gb_for_array(i, info->type_info_map.entries){ + for_array(i, info->type_info_map.entries){ auto *e = &info->type_info_map.entries[i]; Type *prev_type = cast(Type *)cast(uintptr)e->key.key; if (are_types_identical(prev_type, type)) { @@ -2012,7 +2028,7 @@ ssaValue *ssa_emit_logical_binary_expr(ssaProcedure *proc, AstNode *expr) { ssa_emit_store(proc, result, v_false); ssa_emit_jump(proc, done); - gb_array_append(proc->blocks, done); + array_add(&proc->blocks, done); proc->curr_block = done; return ssa_emit_load(proc, result); @@ -2182,7 +2198,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue // parent$count isize name_len = proc->name.len + 1 + 8 + 1; u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len); - name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s$%d", LIT(proc->name), cast(i32)gb_array_count(proc->children)); + name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s$%d", LIT(proc->name), cast(i32)proc->children.count); String name = make_string(name_text, name_len-1); Type *type = type_of_expr(proc->module->info, expr); @@ -2191,7 +2207,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue value->Proc.tags = pl->tags; - gb_array_append(proc->children, &value->Proc); + array_add(&proc->children, &value->Proc); ssa_build_proc(value, proc); return value; @@ -2225,30 +2241,28 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case Type_Vector: { ssaValue *result = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)); - if (cl->elems != NULL) { - for (isize index = 0; index < gb_array_count(cl->elems); index++) { - AstNode *elem = cl->elems[index]; - if (is_elem_const(proc->module, elem)) { - continue; - } - ssaValue *field_elem = ssa_build_expr(proc, elem); - Type *t = ssa_type(field_elem); - GB_ASSERT(t->kind != Type_Tuple); - ssaValue *ev = ssa_emit_conv(proc, field_elem, et); - ssaValue *i = ssa_make_const_int(proc->module->allocator, index); - result = ssa_emit(proc, ssa_make_instr_insert_element(proc, result, ev, i)); + for_array(index, cl->elems) { + AstNode *elem = cl->elems[index]; + if (is_elem_const(proc->module, elem)) { + continue; } + ssaValue *field_elem = ssa_build_expr(proc, elem); + Type *t = ssa_type(field_elem); + GB_ASSERT(t->kind != Type_Tuple); + ssaValue *ev = ssa_emit_conv(proc, field_elem, et); + ssaValue *i = ssa_make_const_int(proc->module->allocator, index); + result = ssa_emit(proc, ssa_make_instr_insert_element(proc, result, ev, i)); + } - if (gb_array_count(cl->elems) == 1 && bt->Vector.count > 1) { - isize index_count = bt->Vector.count; - i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count); - for (isize i = 0; i < index_count; i++) { - indices[i] = 0; - } - ssaValue *sv = ssa_emit(proc, ssa_make_instr_shuffle_vector(proc, result, indices, index_count)); - ssa_emit_store(proc, v, sv); - return ssa_emit_load(proc, v); + if (cl->elems.count == 1 && bt->Vector.count > 1) { + isize index_count = bt->Vector.count; + i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count); + for (isize i = 0; i < index_count; i++) { + indices[i] = 0; } + ssaValue *sv = ssa_emit(proc, ssa_make_instr_shuffle_vector(proc, result, indices, index_count)); + ssa_emit_store(proc, v, sv); + return ssa_emit_load(proc, v); } return result; } break; @@ -2256,9 +2270,9 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case Type_Record: { GB_ASSERT(is_type_struct(bt)); auto *st = &bt->Record; - if (cl->elems != NULL && gb_array_count(cl->elems) > 0) { + if (cl->elems.count > 0) { ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr))); - gb_for_array(field_index, cl->elems) { + for_array(field_index, cl->elems) { AstNode *elem = cl->elems[field_index]; if (is_elem_const(proc->module, elem)) { continue; @@ -2292,9 +2306,9 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue } } break; case Type_Array: { - if (cl->elems != NULL && gb_array_count(cl->elems) > 0) { + if (cl->elems.count > 0) { ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr))); - gb_for_array(i, cl->elems) { + for_array(i, cl->elems) { AstNode *elem = cl->elems[i]; if (is_elem_const(proc->module, elem)) { continue; @@ -2309,7 +2323,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue } } break; case Type_Slice: { - if (cl->elems != NULL && gb_array_count(cl->elems) > 0) { + if (cl->elems.count > 0) { Type *elem_type = bt->Slice.elem; Type *elem_ptr_type = make_type_pointer(proc->module->allocator, elem_type); Type *elem_ptr_ptr_type = make_type_pointer(proc->module->allocator, elem_ptr_type); @@ -2319,7 +2333,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue ssaValue *data = ssa_emit_struct_gep(proc, slice->ConstantSlice.backing_array, v_zero32, elem_ptr_type); - gb_for_array(i, cl->elems) { + for_array(i, cl->elems) { AstNode *elem = cl->elems[i]; if (is_elem_const(proc->module,elem)) { continue; @@ -2400,7 +2414,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue ssaValue *len =ssa_emit_conv(proc, ssa_build_expr(proc, ce->args[1]), t_int); ssaValue *cap = len; - if (gb_array_count(ce->args) == 3) { + if (ce->args.count == 3) { cap = ssa_emit_conv(proc, ssa_build_expr(proc, ce->args[2]), t_int); } @@ -2457,7 +2471,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue ssa_emit_global_call(proc, "__assert", args, 4); ssa_emit_jump(proc, done); - gb_array_append(proc->blocks, done); + array_add(&proc->blocks, done); proc->curr_block = done; return NULL; @@ -2571,7 +2585,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue ssa_emit_store(proc, gep, new_len); ssa_emit_jump(proc, done); - gb_array_append(proc->blocks, done); + array_add(&proc->blocks, done); proc->curr_block = done; return ssa_emit_conv(proc, cond, t_bool, true); @@ -2580,14 +2594,14 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue case BuiltinProc_swizzle: { ssa_emit_comment(proc, make_string("swizzle")); ssaValue *vector = ssa_build_expr(proc, ce->args[0]); - isize index_count = gb_array_count(ce->args)-1; + isize index_count = ce->args.count-1; if (index_count == 0) { return vector; } i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count); isize index = 0; - gb_for_array(i, ce->args) { + for_array(i, ce->args) { if (i == 0) continue; TypeAndValue *tv = type_and_value_of_expression(proc->module->info, ce->args[i]); GB_ASSERT(is_type_integer(tv->type)); @@ -2632,7 +2646,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue len = ssa_emit_conv(proc, len, t_int, true); - if (gb_array_count(ce->args) == 3) { + if (ce->args.count == 3) { cap = ssa_build_expr(proc, ce->args[2]); cap = ssa_emit_conv(proc, cap, t_int, true); } @@ -2705,7 +2719,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue isize arg_index = 0; isize arg_count = 0; - gb_for_array(i, ce->args) { + for_array(i, ce->args) { AstNode *a = ce->args[i]; Type *at = base_type(type_of_expr(proc->module->info, a)); if (at->kind == Type_Tuple) { @@ -2718,7 +2732,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue b32 variadic = proc_type_->Proc.variadic; b32 vari_expand = ce->ellipsis.pos.line != 0; - gb_for_array(i, ce->args) { + for_array(i, ce->args) { ssaValue *a = ssa_build_expr(proc, ce->args[i]); Type *at = ssa_type(a); if (at->kind == Type_Tuple) { @@ -3308,7 +3322,7 @@ void ssa_gen_global_type_name(ssaModule *m, Entity *e, String name) { void ssa_build_stmt_list(ssaProcedure *proc, AstNodeArray stmts) { - gb_for_array(i, stmts) { + for_array(i, stmts) { ssa_build_stmt(proc, stmts[i]); } } @@ -3348,20 +3362,20 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena); defer (gb_temp_arena_memory_end(tmp)); - if (gb_array_count(vd->values) == 0) { // declared and zero-initialized - gb_for_array(i, vd->names) { + if (vd->values.count == 0) { // declared and zero-initialized + for_array(i, vd->names) { AstNode *name = vd->names[i]; if (!ssa_is_blank_ident(name)) { ssa_add_local_for_identifier(proc, name, true); } } } else { // Tuple(s) - gbArray(ssaAddr) lvals; - gbArray(ssaValue *) inits; - gb_array_init_reserve(lvals, m->tmp_allocator, gb_array_count(vd->names)); - gb_array_init_reserve(inits, m->tmp_allocator, gb_array_count(vd->names)); + Array lvals; + Array inits; + array_init(&lvals, m->tmp_allocator, vd->names.count); + array_init(&inits, m->tmp_allocator, vd->names.count); - gb_for_array(i, vd->names) { + for_array(i, vd->names) { AstNode *name = vd->names[i]; ssaAddr lval = ssa_make_addr(NULL, NULL); if (!ssa_is_blank_ident(name)) { @@ -3369,25 +3383,25 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { lval = ssa_build_addr(proc, name); } - gb_array_append(lvals, lval); + array_add(&lvals, lval); } - gb_for_array(i, vd->values) { + for_array(i, vd->values) { ssaValue *init = ssa_build_expr(proc, vd->values[i]); Type *t = ssa_type(init); if (t->kind == Type_Tuple) { for (isize i = 0; i < t->Tuple.variable_count; i++) { Entity *e = t->Tuple.variables[i]; ssaValue *v = ssa_emit_struct_ev(proc, init, i, e->type); - gb_array_append(inits, v); + array_add(&inits, v); } } else { - gb_array_append(inits, init); + array_add(&inits, init); } } - gb_for_array(i, inits) { + for_array(i, inits) { ssaValue *v = ssa_emit_conv(proc, inits[i], ssa_addr_type(lvals[i])); ssa_lvalue_store(proc, lvals[i], v); } @@ -3412,7 +3426,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { isize name_len = proc->name.len + 1 + pd_name.len + 1 + 10 + 1; u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len); - i32 guid = cast(i32)gb_array_count(proc->children); + i32 guid = cast(i32)proc->children.count; name_len = gb_snprintf(cast(char *)name_text, name_len, "%.*s.%.*s-%d", LIT(proc->name), LIT(pd_name), guid); String name = make_string(name_text, name_len-1); @@ -3424,8 +3438,8 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { value->Proc.parent = proc; ssa_module_add_value(proc->module, e, value); - gb_array_append(proc->children, &value->Proc); - gb_array_append(proc->module->procs, value); + array_add(&proc->children, &value->Proc); + array_add(&proc->module->procs, value); } else { auto *info = proc->module->info; @@ -3456,7 +3470,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { map_set(&proc->module->members, key, value); } } else { - gb_array_append(proc->children, &value->Proc); + array_add(&proc->children, &value->Proc); } } case_end; @@ -3468,7 +3482,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { String td_name = td->name->Ident.string; isize name_len = proc->name.len + 1 + td_name.len + 1 + 10 + 1; u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len); - i32 guid = cast(i32)gb_array_count(proc->module->members.entries); + i32 guid = cast(i32)proc->module->members.entries.count; 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); @@ -3504,41 +3518,41 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { switch (as->op.kind) { case Token_Eq: { - gbArray(ssaAddr) lvals; - gb_array_init(lvals, m->tmp_allocator); + Array lvals; + array_init(&lvals, m->tmp_allocator); - gb_for_array(i, as->lhs) { + for_array(i, as->lhs) { AstNode *lhs = as->lhs[i]; ssaAddr lval = {}; if (!ssa_is_blank_ident(lhs)) { lval = ssa_build_addr(proc, lhs); } - gb_array_append(lvals, lval); + array_add(&lvals, lval); } - if (gb_array_count(as->lhs) == gb_array_count(as->rhs)) { - if (gb_array_count(as->lhs) == 1) { + if (as->lhs.count == as->rhs.count) { + if (as->lhs.count == 1) { AstNode *rhs = as->rhs[0]; ssaValue *init = ssa_build_expr(proc, rhs); ssa_lvalue_store(proc, lvals[0], init); } else { - gbArray(ssaValue *) inits; - gb_array_init_reserve(inits, m->tmp_allocator, gb_array_count(lvals)); + Array inits; + array_init(&inits, m->tmp_allocator, lvals.count); - gb_for_array(i, as->rhs) { + for_array(i, as->rhs) { ssaValue *init = ssa_build_expr(proc, as->rhs[i]); - gb_array_append(inits, init); + array_add(&inits, init); } - gb_for_array(i, inits) { + for_array(i, inits) { ssa_lvalue_store(proc, lvals[i], inits[i]); } } } else { - gbArray(ssaValue *) inits; - gb_array_init_reserve(inits, m->tmp_allocator, gb_array_count(lvals)); + Array inits; + array_init(&inits, m->tmp_allocator, lvals.count); - gb_for_array(i, as->rhs) { + for_array(i, as->rhs) { ssaValue *init = ssa_build_expr(proc, as->rhs[i]); Type *t = ssa_type(init); // TODO(bill): refactor for code reuse as this is repeated a bit @@ -3546,14 +3560,14 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { for (isize i = 0; i < t->Tuple.variable_count; i++) { Entity *e = t->Tuple.variables[i]; ssaValue *v = ssa_emit_struct_ev(proc, init, i, e->type); - gb_array_append(inits, v); + array_add(&inits, v); } } else { - gb_array_append(inits, init); + array_add(&inits, init); } } - gb_for_array(i, inits) { + for_array(i, inits) { ssa_lvalue_store(proc, lvals[i], inits[i]); } } @@ -3608,26 +3622,26 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena); defer (gb_temp_arena_memory_end(tmp)); - gbArray(ssaValue *) results; - gb_array_init_reserve(results, proc->module->tmp_allocator, return_count); + Array results; + array_init(&results, proc->module->tmp_allocator, return_count); - gb_for_array(res_index, rs->results) { + for_array(res_index, rs->results) { ssaValue *res = ssa_build_expr(proc, rs->results[res_index]); Type *t = ssa_type(res); if (t->kind == Type_Tuple) { for (isize i = 0; i < t->Tuple.variable_count; i++) { Entity *e = t->Tuple.variables[i]; ssaValue *v = ssa_emit_struct_ev(proc, res, i, e->type); - gb_array_append(results, v); + array_add(&results, v); } } else { - gb_array_append(results, res); + array_add(&results, res); } } Type *ret_type = proc->type->Proc.results; v = ssa_add_local_generated(proc, ret_type); - gb_for_array(i, results) { + for_array(i, results) { Entity *e = return_type_tuple->variables[i]; ssaValue *res = ssa_emit_conv(proc, results[i], e->type); ssaValue *field = ssa_emit_struct_gep(proc, v, i, make_type_pointer(proc->module->allocator, e->type)); @@ -3674,7 +3688,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { ssa_emit_jump(proc, done); } - gb_array_append(proc->blocks, done); + array_add(&proc->blocks, done); proc->curr_block = done; case_end; @@ -3722,7 +3736,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { } - gb_array_append(proc->blocks, done); + array_add(&proc->blocks, done); proc->curr_block = done; case_end; @@ -3741,15 +3755,15 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { ast_node(body, BlockStmt, ms->body); - AstNodeArray default_stmts = NULL; + AstNodeArray default_stmts = {}; ssaBlock *default_fall = NULL; ssaBlock *default_block = NULL; ssaBlock *fall = NULL; b32 append_fall = false; - isize case_count = gb_array_count(body->stmts); - gb_for_array(i, body->stmts) { + isize case_count = body->stmts.count; + for_array(i, body->stmts) { AstNode *clause = body->stmts[i]; ssaBlock *body = fall; b32 append_body = false; @@ -3759,7 +3773,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { if (body == NULL) { append_body = true; - if (gb_array_count(cc->list)) { + if (cc->list.count == 0) { body = ssa__make_block(proc, clause, make_string("match.dflt.body")); } else { body = ssa__make_block(proc, clause, make_string("match.case.body")); @@ -3776,7 +3790,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { fall = ssa__make_block(proc, clause, make_string("match.fall.body")); } - if (gb_array_count(cc->list) == 0) { + if (cc->list.count == 0) { // default case default_stmts = cc->stmts; default_fall = fall; @@ -3786,17 +3800,17 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { ssaBlock *next_cond = NULL; Token eq = {Token_CmpEq}; - gb_for_array(j, cc->list) { + for_array(j, cc->list) { AstNode *expr = cc->list[j]; next_cond = ssa__make_block(proc, clause, make_string("match.case.next")); ssaValue *cond = ssa_emit_comp(proc, eq, tag, ssa_build_expr(proc, expr)); ssa_emit_if(proc, cond, body, next_cond); - gb_array_append(proc->blocks, next_cond); + array_add(&proc->blocks, next_cond); proc->curr_block = next_cond; } if (append_body) { - gb_array_append(proc->blocks, body); + array_add(&proc->blocks, body); } proc->curr_block = body; @@ -3812,7 +3826,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { if (default_block != NULL) { ssa_emit_jump(proc, default_block); - gb_array_append(proc->blocks, default_block); + array_add(&proc->blocks, default_block); proc->curr_block = default_block; ssa_push_target_list(proc, done, NULL, default_fall); @@ -3823,7 +3837,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { } ssa_emit_jump(proc, done); - gb_array_append(proc->blocks, done); + array_add(&proc->blocks, done); proc->curr_block = done; case_end; @@ -3853,15 +3867,15 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { String tag_var_name = ms->var->Ident.string; - AstNodeArray default_stmts = NULL; + AstNodeArray default_stmts = {}; ssaBlock *default_block = NULL; - isize case_count = gb_array_count(body->stmts); - gb_for_array(i, body->stmts) { + isize case_count = body->stmts.count; + for_array(i, body->stmts) { AstNode *clause = body->stmts[i]; ast_node(cc, CaseClause, clause); - if (gb_array_count(cc->list) == 0) { + if (cc->list.count == 0) { // default case default_stmts = cc->stmts; default_block = ssa__make_block(proc, clause, make_string("type-match.dflt.body")); @@ -3897,10 +3911,10 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { Token eq = {Token_CmpEq}; ssaValue *cond = ssa_emit_comp(proc, eq, tag_index, index); ssa_emit_if(proc, cond, body, next_cond); - gb_array_append(proc->blocks, next_cond); + array_add(&proc->blocks, next_cond); proc->curr_block = next_cond; - gb_array_append(proc->blocks, body); + array_add(&proc->blocks, body); proc->curr_block = body; ssa_push_target_list(proc, done, NULL, NULL); @@ -3915,7 +3929,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { if (default_block != NULL) { ssa_emit_jump(proc, default_block); - gb_array_append(proc->blocks, default_block); + array_add(&proc->blocks, default_block); proc->curr_block = default_block; ssa_push_target_list(proc, done, NULL, NULL); @@ -3926,7 +3940,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { } ssa_emit_jump(proc, done); - gb_array_append(proc->blocks, done); + array_add(&proc->blocks, done); proc->curr_block = done; case_end; diff --git a/src/common.cpp b/src/common.cpp index 73f11b172..dc66efb1f 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -2,7 +2,9 @@ #define GB_IMPLEMENTATION #include "gb/gb.h" + #include "string.cpp" +#include "array.cpp" gb_global String global_module_path = {}; gb_global b32 global_module_path_set = false; @@ -12,21 +14,21 @@ String get_module_dir() { return global_module_path; } - gbArray(wchar_t) path_buf; - gb_array_init_reserve(path_buf, gb_heap_allocator(), 300); - defer (gb_array_free(path_buf)); - gb_array_resize(path_buf, 300); + Array path_buf; + array_init(&path_buf, gb_heap_allocator(), 300); + defer (array_free(&path_buf)); + array_resize(&path_buf, 300); isize len = 0; for (;;) { - len = GetModuleFileNameW(NULL, path_buf, gb_array_count(path_buf)); + len = GetModuleFileNameW(NULL, &path_buf[0], path_buf.count); if (len == 0) { return make_string(NULL, 0); } - if (len < gb_array_count(path_buf)) { + if (len < path_buf.count) { break; } - gb_array_resize(path_buf, 2*gb_array_count(path_buf) + 300); + array_resize(&path_buf, 2*path_buf.count + 300); } gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&string_buffer_arena); @@ -155,6 +157,7 @@ i64 prev_pow2(i64 n) { #define gb_for_array(index_, array_) for (isize index_ = 0; (array_) != NULL && index_ < gb_array_count(array_); index_++) +#define for_array(index_, array_) for (isize index_ = 0; index_ < (array_).count; index_++) // Doubly Linked Lists @@ -179,6 +182,8 @@ i64 prev_pow2(i64 n) { //////////////////////////////////////////////////////////////// + + struct MapFindResult { isize hash_index; isize entry_prev; @@ -194,8 +199,8 @@ struct MapEntry { template struct Map { - gbArray(isize) hashes; - gbArray(MapEntry) entries; + Array hashes; + Array > entries; }; template void map_init (Map *h, gbAllocator a); @@ -221,14 +226,14 @@ template void multi_map_remove_all(Map *h, HashKey key); template gb_inline void map_init(Map *h, gbAllocator a) { - gb_array_init(h->hashes, a); - gb_array_init(h->entries, a); + array_init(&h->hashes, a); + array_init(&h->entries, a); } template gb_inline void map_destroy(Map *h) { - if (h->entries) gb_array_free(h->entries); - if (h->hashes) gb_array_free(h->hashes); + array_free(&h->entries); + array_free(&h->hashes); } template @@ -236,15 +241,15 @@ gb_internal isize map__add_entry(Map *h, HashKey key) { MapEntry e = {}; e.key = key; e.next = -1; - gb_array_append(h->entries, e); - return gb_array_count(h->entries)-1; + array_add(&h->entries, e); + return h->entries.count-1; } template gb_internal MapFindResult map__find(Map *h, HashKey key) { MapFindResult fr = {-1, -1, -1}; - if (gb_array_count(h->hashes) > 0) { - fr.hash_index = key.key % gb_array_count(h->hashes); + if (h->hashes.count > 0) { + fr.hash_index = key.key % h->hashes.count; fr.entry_index = h->hashes[fr.hash_index]; while (fr.entry_index >= 0) { if (hash_key_equal(h->entries[fr.entry_index].key, key)) { @@ -260,8 +265,8 @@ gb_internal MapFindResult map__find(Map *h, HashKey key) { template gb_internal MapFindResult map__find(Map *h, MapEntry *e) { MapFindResult fr = {-1, -1, -1}; - if (gb_array_count(h->hashes) > 0) { - fr.hash_index = e->key.key % gb_array_count(h->hashes); + if (h->hashes.count > 0) { + fr.hash_index = e->key.key % h->hashes.count; fr.entry_index = h->hashes[fr.hash_index]; while (fr.entry_index >= 0) { if (&h->entries[fr.entry_index] == e) { @@ -277,12 +282,12 @@ gb_internal MapFindResult map__find(Map *h, MapEntry *e) { template gb_internal b32 map__full(Map *h) { - return 0.75f * gb_array_count(h->hashes) <= gb_array_count(h->entries); + return 0.75f * h->hashes.count <= h->entries.count; } template gb_inline void map_grow(Map *h) { - isize new_count = GB_ARRAY_GROW_FORMULA(gb_array_count(h->entries)); + isize new_count = GB_ARRAY_GROW_FORMULA(h->entries.count); map_rehash(h, new_count); } @@ -290,16 +295,18 @@ template void map_rehash(Map *h, isize new_count) { isize i, j; Map nh = {}; - map_init(&nh, gb_array_allocator(h->hashes)); - gb_array_resize(nh.hashes, new_count); - gb_array_reserve(nh.entries, gb_array_count(h->entries)); - for (i = 0; i < new_count; i++) + map_init(&nh, h->hashes.allocator); + array_resize(&nh.hashes, new_count); + array_reserve(&nh.entries, h->entries.count); + for (i = 0; i < new_count; i++) { nh.hashes[i] = -1; - for (i = 0; i < gb_array_count(h->entries); i++) { + } + for (i = 0; i < h->entries.count; i++) { MapEntry *e = &h->entries[i]; MapFindResult fr; - if (gb_array_count(nh.hashes) == 0) + if (nh.hashes.count == 0) { map_grow(&nh); + } fr = map__find(&nh, e->key); j = map__add_entry(&nh, e->key); if (fr.entry_prev < 0) @@ -327,7 +334,7 @@ template void map_set(Map *h, HashKey key, T value) { isize index; MapFindResult fr; - if (gb_array_count(h->hashes) == 0) + if (h->hashes.count == 0) map_grow(h); fr = map__find(h, key); if (fr.entry_index >= 0) { @@ -355,11 +362,11 @@ void map__erase(Map *h, MapFindResult fr) { } else { h->entries[fr.entry_prev].next = h->entries[fr.entry_index].next; } - if (fr.entry_index == gb_array_count(h->entries)-1) { - gb_array_pop(h->entries); + if (fr.entry_index == h->entries.count-1) { + array_pop(&h->entries); return; } - h->entries[fr.entry_index] = h->entries[gb_array_count(h->entries)-1]; + h->entries[fr.entry_index] = h->entries[h->entries.count-1]; MapFindResult last = map__find(h, h->entries[fr.entry_index].key); if (last.entry_prev >= 0) { h->entries[last.entry_prev].next = fr.entry_index; @@ -428,7 +435,7 @@ void multi_map_get_all(Map *h, HashKey key, T *items) { template void multi_map_insert(Map *h, HashKey key, T value) { - if (gb_array_count(h->hashes) == 0) { + if (h->hashes.count == 0) { map_grow(h); } MapFindResult fr = map__find(h, key); diff --git a/src/main.cpp b/src/main.cpp index a464eb7e0..32f9e2ebe 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -189,7 +189,6 @@ int main(int argc, char **argv) { // "-dse " // "-dce " // "-S " - // "-debug-pass=Arguments " "", LIT(module_dir), output_name, LIT(output)); @@ -203,6 +202,7 @@ int main(int argc, char **argv) { exit_code = win32_exec_command_line_app( "%.*sbin/llc %.*s.bc -filetype=obj -O%d " "%.*s " + // "-debug-pass=Arguments " "", LIT(module_dir), LIT(output), @@ -217,7 +217,7 @@ int main(int argc, char **argv) { gbString lib_str = gb_string_make(gb_heap_allocator(), "Kernel32.lib"); // defer (gb_string_free(lib_str)); char lib_str_buf[1024] = {}; - gb_for_array(i, parser.system_libraries) { + for_array(i, parser.system_libraries) { String lib = parser.system_libraries[i]; isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf), " %.*s.lib", LIT(lib)); diff --git a/src/parser.cpp b/src/parser.cpp index d44a199ae..fb93c4609 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -15,13 +15,13 @@ enum ParseFileError { ParseFile_Count, }; -typedef gbArray(AstNode *) AstNodeArray; +typedef Array AstNodeArray; struct AstFile { u32 id; gbArena arena; Tokenizer tokenizer; - gbArray(Token) tokens; + Array tokens; isize curr_token_index; Token curr_token; Token prev_token; // previous non-comment @@ -54,10 +54,10 @@ struct ImportedFile { struct Parser { String init_fullpath; - gbArray(AstFile) files; - gbArray(ImportedFile) imports; + Array files; + Array imports; gbAtomic32 import_index; - gbArray(String) system_libraries; + Array system_libraries; isize total_token_count; gbMutex mutex; }; @@ -96,8 +96,7 @@ enum CallExprKind { AstNodeArray make_ast_node_array(AstFile *f) { AstNodeArray a; - gb_array_init(a, gb_arena_allocator(&f->arena)); - GB_ASSERT(a != NULL); + array_init(&a, gb_arena_allocator(&f->arena)); return a; } @@ -452,10 +451,11 @@ Token ast_node_token(AstNode *node) { case AstNode_ForeignSystemLibrary: return node->ForeignSystemLibrary.token; case AstNode_Parameter: { - if (node->Parameter.names) + if (node->Parameter.names.count > 0) { return ast_node_token(node->Parameter.names[0]); - else + } else { return ast_node_token(node->Parameter.type); + } } case AstNode_ProcType: return node->ProcType.token; @@ -957,7 +957,7 @@ AstNode *make_foreign_system_library(AstFile *f, Token token, Token filepath) { } b32 next_token(AstFile *f) { - if (f->curr_token_index+1 < gb_array_count(f->tokens)) { + if (f->curr_token_index+1 < f->tokens.count) { if (f->curr_token.kind != Token_Comment) { f->prev_token = f->curr_token; } @@ -1155,7 +1155,7 @@ AstNodeArray parse_element_list(AstFile *f) { elem = make_field_value(f, elem, value, eq); } - gb_array_append(elems, elem); + array_add(&elems, elem); if (f->curr_token.kind != Token_Comma) { break; @@ -1167,7 +1167,7 @@ AstNodeArray parse_element_list(AstFile *f) { } AstNode *parse_literal_value(AstFile *f, AstNode *type) { - AstNodeArray elems = NULL; + AstNodeArray elems = {}; Token open = expect_token(f, Token_OpenBrace); f->expr_level++; if (f->curr_token.kind != Token_CloseBrace) { @@ -1464,7 +1464,7 @@ AstNode *parse_call_expr(AstFile *f, AstNode *operand) { } AstNode *arg = parse_expr(f, false); - gb_array_append(args, arg); + array_add(&args, arg); if (f->curr_token.kind != Token_Comma) { if (f->curr_token.kind == Token_CloseParen) @@ -1493,9 +1493,9 @@ AstNode *parse_atom_expr(AstFile *f, b32 lhs) { // TODO(bill): Handle this } AstNode *proc = parse_identifier(f); - gbArray(AstNode *) args; - gb_array_init_reserve(args, gb_arena_allocator(&f->arena), 1); - gb_array_append(args, operand); + Array args; + array_init(&args, gb_arena_allocator(&f->arena), 1); + array_add(&args, operand); operand = make_call_expr(f, proc, args, ast_node_token(operand), op, empty_token); } break; @@ -1685,7 +1685,7 @@ AstNode *parse_binary_expr(AstFile *f, b32 lhs, i32 prec_in) { AstNode *proc = parse_identifier(f); /* if (f->curr_token.kind == Token_OpenParen) { AstNode *call = parse_call_expr(f, proc); - gb_array_append(call->CallExpr.args, expression); + array_add(&call->CallExpr.args, expression); for (isize i = gb_array_count(call->CallExpr.args)-1; i > 0; i--) { gb_swap(AstNode *, call->CallExpr.args[i], call->CallExpr.args[i-1]); } @@ -1693,10 +1693,10 @@ AstNode *parse_binary_expr(AstFile *f, b32 lhs, i32 prec_in) { expression = call; } else */{ right = parse_binary_expr(f, false, prec+1); - gbArray(AstNode *) args; - gb_array_init_reserve(args, gb_arena_allocator(&f->arena), 2); - gb_array_append(args, expression); - gb_array_append(args, right); + Array args = {}; + array_init(&args, gb_arena_allocator(&f->arena), 2); + array_add(&args, expression); + array_add(&args, right); expression = make_call_expr(f, proc, args, op, ast_node_token(right), empty_token); } continue; @@ -1730,7 +1730,7 @@ AstNodeArray parse_expr_list(AstFile *f, b32 lhs) { AstNodeArray list = make_ast_node_array(f); do { AstNode *e = parse_expr(f, lhs); - gb_array_append(list, e); + array_add(&list, e); if (f->curr_token.kind != Token_Comma || f->curr_token.kind == Token_EOF) { break; @@ -1780,7 +1780,7 @@ AstNode *parse_simple_stmt(AstFile *f) { } next_token(f); AstNodeArray rhs = parse_rhs_expr_list(f); - if (gb_array_count(rhs) == 0) { + if (rhs.count == 0) { syntax_error(token, "No right-hand side in assignment statement."); return make_bad_stmt(f, token, f->curr_token); } @@ -1838,7 +1838,7 @@ AstNodeArray parse_identfier_list(AstFile *f) { AstNodeArray list = make_ast_node_array(f); do { - gb_array_append(list, parse_identifier(f)); + array_add(&list, parse_identifier(f)); if (f->curr_token.kind != Token_Comma || f->curr_token.kind == Token_EOF) { break; @@ -1875,8 +1875,8 @@ Token parse_procedure_signature(AstFile *f, AstNodeArray *params, AstNodeArray *results); AstNode *parse_proc_type(AstFile *f) { - AstNodeArray params = NULL; - AstNodeArray results = NULL; + AstNodeArray params = {}; + AstNodeArray results = {}; Token proc_token = parse_procedure_signature(f, ¶ms, &results); @@ -1895,11 +1895,11 @@ AstNodeArray parse_parameter_list(AstFile *f) { } AstNodeArray names = parse_lhs_expr_list(f); - if (gb_array_count(names) == 0) { + if (names.count == 0) { syntax_error(f->curr_token, "Empty parameter declaration"); } - if (gb_array_count(names) > 1 && is_using) { + if (names.count > 1 && is_using) { syntax_error(f->curr_token, "Cannot apply `using` to more than one of the same type"); is_using = false; } @@ -1915,7 +1915,7 @@ AstNodeArray parse_parameter_list(AstFile *f) { syntax_error(f->curr_token, "variadic parameter is missing a type after `..`"); type = make_bad_expr(f, ellipsis, f->curr_token); } else { - if (gb_array_count(names) > 1) { + if (names.count > 1) { syntax_error(f->curr_token, "mutliple variadic parameters, only `..`"); } else { type = make_ellipsis(f, ellipsis, type); @@ -1930,7 +1930,7 @@ AstNodeArray parse_parameter_list(AstFile *f) { syntax_error(f->curr_token, "Expected a type for this parameter declaration"); } - gb_array_append(params, make_parameter(f, names, type, is_using)); + array_add(¶ms, make_parameter(f, names, type, is_using)); if (f->curr_token.kind != Token_Comma) { break; } @@ -1952,7 +1952,7 @@ AstNodeArray parse_struct_params(AstFile *f, isize *decl_count_, b32 using_allow is_using = true; } AstNodeArray names = parse_lhs_expr_list(f); - if (gb_array_count(names) == 0) { + if (names.count == 0) { syntax_error(f->curr_token, "Empty field declaration"); } @@ -1960,7 +1960,7 @@ AstNodeArray parse_struct_params(AstFile *f, isize *decl_count_, b32 using_allow syntax_error(f->curr_token, "Cannot apply `using` to members of a union"); is_using = false; } - if (gb_array_count(names) > 1 && is_using) { + if (names.count > 1 && is_using) { syntax_error(f->curr_token, "Cannot apply `using` to more than one of the same type"); } @@ -1981,10 +1981,10 @@ AstNodeArray parse_struct_params(AstFile *f, isize *decl_count_, b32 using_allow expect_semicolon_after_stmt(f, decl); if (decl != NULL && is_ast_node_decl(decl)) { - gb_array_append(decls, decl); + array_add(&decls, decl); if (decl->kind == AstNode_VarDecl) { decl->VarDecl.is_using = is_using && using_allowed; - if (gb_array_count(decl->VarDecl.values) > 0) { + if (decl->VarDecl.values.count > 0) { syntax_error(f->curr_token, "Default variable assignments within a structure will be ignored (at the moment)"); } } else { @@ -2129,7 +2129,7 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) { value = parse_value(f); } AstNode *field = make_field_value(f, name, value, eq); - gb_array_append(fields, field); + array_add(&fields, field); if (f->curr_token.kind != Token_Comma) { break; } @@ -2185,7 +2185,7 @@ AstNodeArray parse_results(AstFile *f) { expect_token(f, Token_OpenParen); while (f->curr_token.kind != Token_CloseParen && f->curr_token.kind != Token_EOF) { - gb_array_append(results, parse_type(f)); + array_add(&results, parse_type(f)); if (f->curr_token.kind != Token_Comma) { break; } @@ -2196,7 +2196,7 @@ AstNodeArray parse_results(AstFile *f) { return results; } - gb_array_append(results, parse_type(f)); + array_add(&results, parse_type(f)); return results; } return results; @@ -2214,7 +2214,7 @@ Token parse_procedure_signature(AstFile *f, } AstNode *parse_body(AstFile *f) { - AstNodeArray stmts = NULL; + AstNodeArray stmts = {}; Token open, close; open = expect_token(f, Token_OpenBrace); stmts = parse_stmt_list(f); @@ -2226,8 +2226,8 @@ AstNode *parse_body(AstFile *f) { AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) { - AstNodeArray params = NULL; - AstNodeArray results = NULL; + AstNodeArray params = {}; + AstNodeArray results = {}; parse_procedure_signature(f, ¶ms, &results); AstNode *proc_type = make_proc_type(f, proc_token, params, results); @@ -2254,10 +2254,10 @@ AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) { } AstNode *parse_decl(AstFile *f, AstNodeArray names) { - AstNodeArray values = NULL; + AstNodeArray values = {}; AstNode *type = NULL; - // gb_for_array(i, names) { + // for_array(i, names) { // AstNode *name = names[i]; // if (name->kind == AstNode_Ident) { // String n = name->Ident.string; @@ -2295,7 +2295,7 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) { if (token.kind == Token_type) { next_token(f); } - if (gb_array_count(names) != 1) { + if (names.count != 1) { syntax_error(ast_node_token(names[0]), "You can only declare one type at a time"); return make_bad_decl(f, names[0]->Ident, token); } @@ -2311,7 +2311,7 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) { // NOTE(bill): Procedure declarations Token proc_token = f->curr_token; AstNode *name = names[0]; - if (gb_array_count(names) != 1) { + if (names.count != 1) { syntax_error(proc_token, "You can only declare one procedure at a time"); return make_bad_decl(f, name->Ident, proc_token); } @@ -2320,29 +2320,29 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) { } else { values = parse_rhs_expr_list(f); - if (gb_array_count(values) > gb_array_count(names)) { + if (values.count > names.count) { syntax_error(f->curr_token, "Too many values on the right hand side of the declaration"); - } else if (gb_array_count(values) < gb_array_count(names) && !is_mutable) { + } else if (values.count < names.count && !is_mutable) { syntax_error(f->curr_token, "All constant declarations must be defined"); - } else if (gb_array_count(values) == 0) { + } else if (values.count == 0) { syntax_error(f->curr_token, "Expected an expression for this declaration"); } } } if (is_mutable) { - if (type == NULL && gb_array_count(values) == 0) { + if (type == NULL && values.count == 0) { syntax_error(f->curr_token, "Missing variable type or initialization"); return make_bad_decl(f, f->curr_token, f->curr_token); } } else { - if (type == NULL && gb_array_count(values) == 0 && gb_array_count(names) > 0) { + if (type == NULL && values.count == 0 && names.count > 0) { syntax_error(f->curr_token, "Missing constant value"); return make_bad_decl(f, f->curr_token, f->curr_token); } } - if (values == NULL) { + if (values.data == NULL) { values = make_ast_node_array(f); } @@ -2421,7 +2421,7 @@ AstNode *parse_return_stmt(AstFile *f) { results = parse_rhs_expr_list(f); } if (f->curr_token.kind != Token_CloseBrace) { - expect_semicolon_after_stmt(f, results ? results[0] : NULL); + expect_semicolon_after_stmt(f, results[0]); } return make_return_stmt(f, token, results); @@ -2491,7 +2491,7 @@ AstNode *parse_type_case_clause(AstFile *f) { Token token = f->curr_token; AstNodeArray clause = make_ast_node_array(f); if (allow_token(f, Token_case)) { - gb_array_append(clause, parse_expr(f, false)); + array_add(&clause, parse_expr(f, false)); } else { expect_token(f, Token_default); } @@ -2532,7 +2532,7 @@ AstNode *parse_match_stmt(AstFile *f) { while (f->curr_token.kind == Token_case || f->curr_token.kind == Token_default) { - gb_array_append(list, parse_type_case_clause(f)); + array_add(&list, parse_type_case_clause(f)); } close = expect_token(f, Token_CloseBrace); @@ -2563,7 +2563,7 @@ AstNode *parse_match_stmt(AstFile *f) { while (f->curr_token.kind == Token_case || f->curr_token.kind == Token_default) { - gb_array_append(list, parse_case_clause(f)); + array_add(&list, parse_case_clause(f)); } close = expect_token(f, Token_CloseBrace); @@ -2833,7 +2833,7 @@ AstNodeArray parse_stmt_list(AstFile *f) { f->curr_token.kind != Token_EOF) { AstNode *stmt = parse_stmt(f); if (stmt && stmt->kind != AstNode_EmptyStmt) { - gb_array_append(list, stmt); + array_add(&list, stmt); } } @@ -2847,13 +2847,13 @@ ParseFileError init_ast_file(AstFile *f, String fullpath) { } TokenizerInitError err = init_tokenizer(&f->tokenizer, fullpath); if (err == TokenizerInit_None) { - gb_array_init(f->tokens, gb_heap_allocator()); + array_init(&f->tokens, gb_heap_allocator()); for (;;) { Token token = tokenizer_get_token(&f->tokenizer); if (token.kind == Token_Invalid) { return ParseFile_InvalidToken; } - gb_array_append(f->tokens, token); + array_add(&f->tokens, token); if (token.kind == Token_EOF) { break; @@ -2866,7 +2866,7 @@ ParseFileError init_ast_file(AstFile *f, String fullpath) { // NOTE(bill): Is this big enough or too small? isize arena_size = gb_size_of(AstNode); - arena_size *= 2*gb_array_count(f->tokens); + arena_size *= 2*f->tokens.count; gb_arena_init_from_allocator(&f->arena, gb_heap_allocator(), arena_size); f->curr_proc = NULL; @@ -2888,32 +2888,32 @@ ParseFileError init_ast_file(AstFile *f, String fullpath) { void destroy_ast_file(AstFile *f) { gb_arena_free(&f->arena); - gb_array_free(f->tokens); + array_free(&f->tokens); gb_free(gb_heap_allocator(), f->tokenizer.fullpath.text); destroy_tokenizer(&f->tokenizer); } b32 init_parser(Parser *p) { - gb_array_init(p->files, gb_heap_allocator()); - gb_array_init(p->imports, gb_heap_allocator()); - gb_array_init(p->system_libraries, gb_heap_allocator()); + array_init(&p->files, gb_heap_allocator()); + array_init(&p->imports, gb_heap_allocator()); + array_init(&p->system_libraries, gb_heap_allocator()); gb_mutex_init(&p->mutex); return true; } void destroy_parser(Parser *p) { // TODO(bill): Fix memory leak - gb_for_array(i, p->files) { + for_array(i, p->files) { destroy_ast_file(&p->files[i]); } #if 1 - gb_for_array(i, p->imports) { + for_array(i, p->imports) { // gb_free(gb_heap_allocator(), p->imports[i].text); } #endif - gb_array_free(p->files); - gb_array_free(p->imports); - gb_array_free(p->system_libraries); + array_free(&p->files); + array_free(&p->imports); + array_free(&p->system_libraries); gb_mutex_destroy(&p->mutex); } @@ -2922,7 +2922,7 @@ b32 try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) { gb_mutex_lock(&p->mutex); defer (gb_mutex_unlock(&p->mutex)); - gb_for_array(i, p->imports) { + for_array(i, p->imports) { String import = p->imports[i].path; if (import == path) { return false; @@ -2933,7 +2933,7 @@ b32 try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) { item.path = path; item.rel_path = rel_path; item.pos = pos; - gb_array_append(p->imports, item); + array_add(&p->imports, item); return true; } @@ -2973,13 +2973,13 @@ b32 try_add_foreign_system_library_path(Parser *p, String import_file) { gb_mutex_lock(&p->mutex); defer (gb_mutex_unlock(&p->mutex)); - gb_for_array(i, p->system_libraries) { + for_array(i, p->system_libraries) { String import = p->system_libraries[i]; if (import == import_file) { return false; } } - gb_array_append(p->system_libraries, import_file); + array_add(&p->system_libraries, import_file); return true; } @@ -3057,7 +3057,7 @@ void parse_file(Parser *p, AstFile *f) { f->decls = parse_stmt_list(f); - gb_for_array(i, f->decls) { + for_array(i, f->decls) { AstNode *node = f->decls[i]; if (!is_ast_node_decl(node) && node->kind != AstNode_BadStmt && @@ -3118,16 +3118,16 @@ ParseFileError parse_files(Parser *p, char *init_filename) { String init_fullpath = make_string(fullpath_str); TokenPos init_pos = {}; ImportedFile init_imported_file = {init_fullpath, init_fullpath, init_pos}; - gb_array_append(p->imports, init_imported_file); + array_add(&p->imports, init_imported_file); p->init_fullpath = init_fullpath; { String s = get_fullpath_core(gb_heap_allocator(), make_string("_preload.odin")); ImportedFile runtime_file = {s, s, init_pos}; - gb_array_append(p->imports, runtime_file); + array_add(&p->imports, runtime_file); } - gb_for_array(i, p->imports) { + for_array(i, p->imports) { ImportedFile imported_file = p->imports[i]; String import_path = imported_file.path; String import_rel_path = imported_file.rel_path; @@ -3169,13 +3169,13 @@ ParseFileError parse_files(Parser *p, char *init_filename) { gb_mutex_lock(&p->mutex); defer (gb_mutex_unlock(&p->mutex)); - file.id = gb_array_count(p->files); - gb_array_append(p->files, file); + file.id = p->files.count; + array_add(&p->files, file); } } - gb_for_array(i, p->files) { - p->total_token_count += gb_array_count(p->files[i].tokens); + for_array(i, p->files) { + p->total_token_count += p->files[i].tokens.count; } diff --git a/src/printer.cpp b/src/printer.cpp index d27fbf48c..4d7184631 100644 --- a/src/printer.cpp +++ b/src/printer.cpp @@ -29,7 +29,7 @@ void print_ast(AstNode *node, isize indent) { print_indent(indent); gb_printf("(compound lit)\n"); print_ast(node->CompoundLit.type, indent+1); - gb_for_array(i, node->CompoundLit.elems) { + for_array(i, node->CompoundLit.elems) { print_ast(node->CompoundLit.elems[i], indent+1); } break; @@ -58,7 +58,7 @@ void print_ast(AstNode *node, isize indent) { print_indent(indent); gb_printf("(call)\n"); print_ast(node->CallExpr.proc, indent+1); - gb_for_array(i, node->CallExpr.args) { + for_array(i, node->CallExpr.args) { print_ast(node->CallExpr.args[i], indent+1); } break; @@ -92,17 +92,17 @@ void print_ast(AstNode *node, isize indent) { case AstNode_AssignStmt: print_indent(indent); print_token(node->AssignStmt.op); - gb_for_array(i, node->AssignStmt.lhs) { + for_array(i, node->AssignStmt.lhs) { print_ast(node->AssignStmt.lhs[i], indent+1); } - gb_for_array(i, node->AssignStmt.rhs) { + for_array(i, node->AssignStmt.rhs) { print_ast(node->AssignStmt.rhs[i], indent+1); } break; case AstNode_BlockStmt: print_indent(indent); gb_printf("(block)\n"); - gb_for_array(i, node->BlockStmt.stmts) { + for_array(i, node->BlockStmt.stmts) { print_ast(node->BlockStmt.stmts[i], indent+1); } break; @@ -121,7 +121,7 @@ void print_ast(AstNode *node, isize indent) { case AstNode_ReturnStmt: print_indent(indent); gb_printf("(return)\n"); - gb_for_array(i, node->ReturnStmt.results) { + for_array(i, node->ReturnStmt.results) { print_ast(node->ReturnStmt.results[i], indent+1); } break; @@ -143,22 +143,22 @@ void print_ast(AstNode *node, isize indent) { case AstNode_VarDecl: print_indent(indent); gb_printf("(decl:var)\n"); - gb_for_array(i, node->VarDecl.names) { + for_array(i, node->VarDecl.names) { print_ast(node->VarDecl.names[i], indent+1); } print_ast(node->VarDecl.type, indent+1); - gb_for_array(i, node->VarDecl.values) { + for_array(i, node->VarDecl.values) { print_ast(node->VarDecl.values[i], indent+1); } break; case AstNode_ConstDecl: print_indent(indent); gb_printf("(decl:const)\n"); - gb_for_array(i, node->VarDecl.names) { + for_array(i, node->VarDecl.names) { print_ast(node->VarDecl.names[i], indent+1); } print_ast(node->VarDecl.type, indent+1); - gb_for_array(i, node->VarDecl.values) { + for_array(i, node->VarDecl.values) { print_ast(node->VarDecl.values[i], indent+1); } break; @@ -178,20 +178,20 @@ void print_ast(AstNode *node, isize indent) { case AstNode_ProcType: print_indent(indent); - gb_printf("(type:proc)(%td -> %td)\n", gb_array_count(node->ProcType.params), gb_array_count(node->ProcType.results)); - gb_for_array(i, node->ProcType.params) { + gb_printf("(type:proc)(%td -> %td)\n", node->ProcType.params.count, node->ProcType.results.count); + for_array(i, node->ProcType.params) { print_ast(node->ProcType.params[i], indent+1); } - if (gb_array_count(node->ProcType.results) > 0) { + if (node->ProcType.results.count > 0) { print_indent(indent+1); gb_printf("->\n"); - gb_for_array(i, node->ProcType.results) { + for_array(i, node->ProcType.results) { print_ast(node->ProcType.results[i], indent+1); } } break; case AstNode_Parameter: - gb_for_array(i, node->Parameter.names) { + for_array(i, node->Parameter.names) { print_ast(node->Parameter.names[i], indent+1); } print_ast(node->Parameter.type, indent); @@ -210,7 +210,7 @@ void print_ast(AstNode *node, isize indent) { case AstNode_StructType: print_indent(indent); gb_printf("(struct)\n"); - gb_for_array(i, node->StructType.decls) { + for_array(i, node->StructType.decls) { print_ast(node->StructType.decls[i], indent+1); } break; diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 224d9bc51..c7c423512 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -292,7 +292,7 @@ struct Tokenizer { isize line_count; isize error_count; - gbArray(String) allocated_strings; + Array allocated_strings; }; @@ -368,7 +368,7 @@ TokenizerInitError init_tokenizer(Tokenizer *t, String fullpath) { if (t->curr_rune == GB_RUNE_BOM) advance_to_next_rune(t); // Ignore BOM at file beginning - gb_array_init(t->allocated_strings, gb_heap_allocator()); + array_init(&t->allocated_strings, gb_heap_allocator()); return TokenizerInit_None; } @@ -397,12 +397,10 @@ gb_inline void destroy_tokenizer(Tokenizer *t) { if (t->start != NULL) { gb_free(gb_heap_allocator(), t->start); } - if (t->allocated_strings != NULL) { - gb_for_array(i, t->allocated_strings) { - gb_free(gb_heap_allocator(), t->allocated_strings[i].text); - } - gb_array_free(t->allocated_strings); + for_array(i, t->allocated_strings) { + gb_free(gb_heap_allocator(), t->allocated_strings[i].text); } + array_free(&t->allocated_strings); } void tokenizer_skip_whitespace(Tokenizer *t) { @@ -696,7 +694,7 @@ Token tokenizer_get_token(Tokenizer *t) { i32 success = unquote_string(gb_heap_allocator(), &token.string); if (success > 0) { if (success == 2) { - gb_array_append(t->allocated_strings, token.string); + array_add(&t->allocated_strings, token.string); } return token; } else {