Browse Source

Change from gbArray(T) to Array<T>

Ginger Bill 8 years ago
parent
commit
b705fa7f22
13 changed files with 658 additions and 522 deletions
  1. 116 0
      src/array.cpp
  2. 58 58
      src/checker/checker.cpp
  3. 80 78
      src/checker/expr.cpp
  4. 60 60
      src/checker/stmt.cpp
  5. 12 13
      src/checker/type.cpp
  6. 15 15
      src/codegen/codegen.cpp
  7. 13 13
      src/codegen/print_llvm.cpp
  8. 162 148
      src/codegen/ssa.cpp
  9. 39 32
      src/common.cpp
  10. 2 2
      src/main.cpp
  11. 79 79
      src/parser.cpp
  12. 16 16
      src/printer.cpp
  13. 6 8
      src/tokenizer.cpp

+ 116 - 0
src/array.cpp

@@ -0,0 +1,116 @@
+#define ARRAY_GROW_FORMULA(x) (2*(x) + 8)
+
+template <typename T>
+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 <typename T> void array_init        (Array<T> *array, gbAllocator a, isize init_capacity = 8);
+template <typename T> void array_free        (Array<T> *array);
+template <typename T> void array_add         (Array<T> *array, T const &t);
+template <typename T> T    array_pop         (Array<T> *array);
+template <typename T> void array_clear       (Array<T> *array);
+template <typename T> void array_reserve     (Array<T> *array, isize capacity);
+template <typename T> void array_resize      (Array<T> *array, isize count);
+template <typename T> void array_set_capacity(Array<T> *array, isize capacity);
+
+
+template <typename T>
+void array_init(Array<T> *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 <typename T>
+void array_free(Array<T> *array) {
+	gb_free(array->allocator, array->data);
+	array->count = 0;
+	array->capacity = 0;
+}
+
+template <typename T>
+void array__grow(Array<T> *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 <typename T>
+void array_add(Array<T> *array, T const &t) {
+	if (array->capacity < array->count+1) {
+		array__grow(array, 0);
+	}
+	array->data[array->count] = t;
+	array->count++;
+}
+
+template <typename T>
+T array_pop(Array<T> *array) {
+	GB_ASSERT(array->count > 0);
+	array->count--;
+	return array->data[array->count];
+}
+
+template <typename T>
+void array_clear(Array<T> *array) {
+	array->count = 0;
+}
+
+template <typename T>
+void array_reserve(Array<T> *array, isize capacity) {
+	if (array->capacity < capacity) {
+		array_set_capacity(array, capacity);
+	}
+}
+
+template <typename T>
+void array_resize(Array<T> *array, isize count) {
+	if (array->capacity < count) {
+		array__grow(array, count);
+	}
+	array->count = count;
+}
+
+template <typename T>
+void array_set_capacity(Array<T> *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;
+}
+
+
+

+ 58 - 58
src/checker/checker.cpp

@@ -118,8 +118,8 @@ struct Scope {
 	Map<Entity *> elements; // Key: String
 	Map<Entity *> elements; // Key: String
 	Map<Entity *> implicit; // Key: String
 	Map<Entity *> implicit; // Key: String
 
 
-	gbArray(Scope *) shared;
-	gbArray(Scope *) imported;
+	Array<Scope *> shared;
+	Array<Scope *> imported;
 	b32 is_proc;
 	b32 is_proc;
 	b32 is_global;
 	b32 is_global;
 	b32 is_file;
 	b32 is_file;
@@ -240,7 +240,7 @@ struct Checker {
 	AstFile *              curr_ast_file;
 	AstFile *              curr_ast_file;
 	BaseTypeSizes          sizes;
 	BaseTypeSizes          sizes;
 	Scope *                global_scope;
 	Scope *                global_scope;
-	gbArray(ProcedureInfo) procs; // NOTE(bill): Procedures to check
+	Array<ProcedureInfo> procs; // NOTE(bill): Procedures to check
 
 
 	gbArena     arena;
 	gbArena     arena;
 	gbArena     tmp_arena;
 	gbArena     tmp_arena;
@@ -249,31 +249,31 @@ struct Checker {
 
 
 	CheckerContext context;
 	CheckerContext context;
 
 
-	gbArray(Type *) proc_stack;
+	Array<Type *> proc_stack;
 	b32 in_defer; // TODO(bill): Actually handle correctly
 	b32 in_defer; // TODO(bill): Actually handle correctly
 };
 };
 
 
 gb_global Scope *universal_scope = NULL;
 gb_global Scope *universal_scope = NULL;
 
 
 struct CycleChecker {
 struct CycleChecker {
-	gbArray(Entity *) path; // Entity_TypeName
+	Array<Entity *> path; // Entity_TypeName
 };
 };
 
 
 CycleChecker *cycle_checker_add(CycleChecker *cc, Entity *e) {
 CycleChecker *cycle_checker_add(CycleChecker *cc, Entity *e) {
 	if (cc == NULL) {
 	if (cc == NULL) {
 		return 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_ASSERT(e != NULL && e->kind == Entity_TypeName);
-	gb_array_append(cc->path, e);
+	array_add(&cc->path, e);
 	return cc;
 	return cc;
 }
 }
 
 
 void cycle_checker_destroy(CycleChecker *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 *make_scope(Scope *parent, gbAllocator allocator) {
 	Scope *s = gb_alloc_item(allocator, Scope);
 	Scope *s = gb_alloc_item(allocator, Scope);
 	s->parent = parent;
 	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) {
 	if (parent != NULL && parent != universal_scope) {
 		DLIST_APPEND(parent->first_child, parent->last_child, s);
 		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) {
 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;
 		Entity *e =scope->elements.entries[i].value;
 		if (e->kind == Entity_Variable) {
 		if (e->kind == Entity_Variable) {
 			if (!e->Variable.used) {
 			if (!e->Variable.used) {
@@ -311,8 +311,8 @@ void destroy_scope(Scope *scope) {
 
 
 	map_destroy(&scope->elements);
 	map_destroy(&scope->elements);
 	map_destroy(&scope->implicit);
 	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)
 	// 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;
 			gone_thru_proc = true;
 		} else {
 		} else {
 			// Check shared scopes - i.e. other files @ global scope
 			// 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];
 				Scope *shared = s->shared[i];
 				Entity **found = map_get(&shared->elements, key);
 				Entity **found = map_get(&shared->elements, key);
 				if (found) {
 				if (found) {
@@ -409,7 +409,7 @@ Entity *current_scope_lookup_entity(Scope *s, String name) {
 	if (found) {
 	if (found) {
 		return *found;
 		return *found;
 	}
 	}
-	gb_for_array(i, s->shared) {
+	for_array(i, s->shared) {
 		Entity **found = map_get(&s->shared[i]->elements, key);
 		Entity **found = map_get(&s->shared[i]->elements, key);
 		if (found) {
 		if (found) {
 			return *found;
 			return *found;
@@ -436,7 +436,7 @@ Entity *scope_insert_entity(Scope *s, Entity *entity) {
 void check_scope_usage(Checker *c, Scope *scope) {
 void check_scope_usage(Checker *c, Scope *scope) {
 	// TODO(bill): Use this?
 	// TODO(bill): Use this?
 #if 0
 #if 0
-	gb_for_array(i, scope->elements.entries) {
+	for_array(i, scope->elements.entries) {
 		auto *entry = scope->elements.entries + i;
 		auto *entry = scope->elements.entries + i;
 		Entity *e = entry->value;
 		Entity *e = entry->value;
 		if (e->kind == Entity_Variable) {
 		if (e->kind == Entity_Variable) {
@@ -557,15 +557,15 @@ void init_checker(Checker *c, Parser *parser, BaseTypeSizes sizes) {
 	init_checker_info(&c->info);
 	init_checker_info(&c->info);
 	c->sizes = sizes;
 	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?
 	// 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 item_size = gb_max(gb_max(gb_size_of(Entity), gb_size_of(Type)), gb_size_of(Scope));
 	isize total_token_count = 0;
 	isize total_token_count = 0;
-	gb_for_array(i, c->parser->files) {
+	for_array(i, c->parser->files) {
 		AstFile *f = &c->parser->files[i];
 		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;
 	isize arena_size = 2 * item_size * total_token_count;
 	gb_arena_init_from_allocator(&c->arena, a, arena_size);
 	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) {
 void destroy_checker(Checker *c) {
 	destroy_checker_info(&c->info);
 	destroy_checker_info(&c->info);
 	destroy_scope(c->global_scope);
 	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);
 	gb_arena_free(&c->arena);
 }
 }
@@ -723,7 +723,7 @@ void add_type_info_type(Checker *c, Type *t) {
 	}
 	}
 
 
 	isize ti_index = -1;
 	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];
 		auto *e = &c->info.type_info_map.entries[i];
 		Type *prev_type = cast(Type *)cast(uintptr)e->key.key;
 		Type *prev_type = cast(Type *)cast(uintptr)e->key.key;
 		if (are_types_identical(t, prev_type)) {
 		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.type  = type;
 	info.body  = body;
 	info.body  = body;
 	info.tags  = tags;
 	info.tags  = tags;
-	gb_array_append(c->procs, info);
+	array_add(&c->procs, info);
 }
 }
 
 
 void push_procedure(Checker *c, Type *type) {
 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) {
 void pop_procedure(Checker *c) {
-	gb_array_pop(c->proc_stack);
+	array_pop(&c->proc_stack);
 }
 }
 
 
 Type *const curr_procedure(Checker *c) {
 Type *const curr_procedure(Checker *c) {
-	isize count = gb_array_count(c->proc_stack);
+	isize count = c->proc_stack.count;
 	if (count > 0) {
 	if (count > 0) {
 		return c->proc_stack[count-1];
 		return c->proc_stack[count-1];
 	}
 	}
@@ -859,7 +859,7 @@ void add_dependency_to_map(Map<Entity *> *map, CheckerInfo *info, Entity *node)
 	}
 	}
 
 
 	DeclInfo *decl = *found;
 	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;
 		Entity *e = cast(Entity *)cast(uintptr)decl->deps.entries[i].key.key;
 		add_dependency_to_map(map, info, e);
 		add_dependency_to_map(map, info, e);
 	}
 	}
@@ -869,7 +869,7 @@ Map<Entity *> generate_minimum_dependency_map(CheckerInfo *info, Entity *start)
 	Map<Entity *> map = {}; // Key: Entity *
 	Map<Entity *> map = {}; // Key: Entity *
 	map_init(&map, gb_heap_allocator());
 	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];
 		auto *entry = &info->entities.entries[i];
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		if (e->scope->is_global) {
 		if (e->scope->is_global) {
@@ -948,16 +948,16 @@ void init_preload_types(Checker *c) {
 
 
 void check_parsed_files(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<AstNode *> import_decls;
+	array_init(&import_decls, gb_heap_allocator());
+	defer (array_free(&import_decls));
 
 
 	Map<Scope *> file_scopes; // Key: String (fullpath)
 	Map<Scope *> file_scopes; // Key: String (fullpath)
 	map_init(&file_scopes, gb_heap_allocator());
 	map_init(&file_scopes, gb_heap_allocator());
 	defer (map_destroy(&file_scopes));
 	defer (map_destroy(&file_scopes));
 
 
 	// Map full filepaths to 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];
 		AstFile *f = &c->parser->files[i];
 		Scope *scope = NULL;
 		Scope *scope = NULL;
 		scope = make_scope(c->global_scope, c->allocator);
 		scope = make_scope(c->global_scope, c->allocator);
@@ -971,7 +971,7 @@ void check_parsed_files(Checker *c) {
 		}
 		}
 
 
 		if (scope->is_global) {
 		if (scope->is_global) {
-			gb_array_append(c->global_scope->shared, scope);
+			array_add(&c->global_scope->shared, scope);
 		}
 		}
 
 
 		f->scope = scope;
 		f->scope = scope;
@@ -982,13 +982,13 @@ void check_parsed_files(Checker *c) {
 	}
 	}
 
 
 	// Collect Entities
 	// Collect Entities
-	gb_for_array(i, c->parser->files) {
+	for_array(i, c->parser->files) {
 		AstFile *f = &c->parser->files[i];
 		AstFile *f = &c->parser->files[i];
 		add_curr_ast_file(c, f);
 		add_curr_ast_file(c, f);
 
 
 		Scope *file_scope = f->scope;
 		Scope *file_scope = f->scope;
 
 
-		gb_for_array(decl_index, f->decls) {
+		for_array(decl_index, f->decls) {
 			AstNode *decl = f->decls[decl_index];
 			AstNode *decl = f->decls[decl_index];
 			if (!is_ast_node_decl(decl)) {
 			if (!is_ast_node_decl(decl)) {
 				continue;
 				continue;
@@ -1005,7 +1005,7 @@ void check_parsed_files(Checker *c) {
 			case_end;
 			case_end;
 
 
 			case_ast_node(cd, ConstDecl, decl);
 			case_ast_node(cd, ConstDecl, decl);
-				gb_for_array(i, cd->values) {
+				for_array(i, cd->values) {
 					AstNode *name = cd->names[i];
 					AstNode *name = cd->names[i];
 					AstNode *value = cd->values[i];
 					AstNode *value = cd->values[i];
 					ExactValue v = {ExactValue_Invalid};
 					ExactValue v = {ExactValue_Invalid};
@@ -1017,8 +1017,8 @@ void check_parsed_files(Checker *c) {
 					add_entity_and_decl_info(c, name, e, di);
 					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) {
 				if (rhs_count == 0 && cd->type == NULL) {
 					error(ast_node_token(decl), "Missing type or initial expression");
 					error(ast_node_token(decl), "Missing type or initial expression");
@@ -1028,11 +1028,11 @@ void check_parsed_files(Checker *c) {
 			case_end;
 			case_end;
 
 
 			case_ast_node(vd, VarDecl, decl);
 			case_ast_node(vd, VarDecl, decl);
-				isize entity_count = gb_array_count(vd->names);
+				isize entity_count = vd->names.count;
 				isize entity_index = 0;
 				isize entity_index = 0;
 				Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
 				Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
 				DeclInfo *di = NULL;
 				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 = make_declaration_info(gb_heap_allocator(), file_scope);
 					di->entities = entities;
 					di->entities = entities;
 					di->entity_count = entity_count;
 					di->entity_count = entity_count;
@@ -1040,10 +1040,10 @@ void check_parsed_files(Checker *c) {
 					di->init_expr = vd->values[0];
 					di->init_expr = vd->values[0];
 				}
 				}
 
 
-				gb_for_array(i, vd->names) {
+				for_array(i, vd->names) {
 					AstNode *name = vd->names[i];
 					AstNode *name = vd->names[i];
 					AstNode *value = NULL;
 					AstNode *value = NULL;
-					if (i < gb_array_count(vd->values)) {
+					if (i < vd->values.count) {
 						value = vd->values[i];
 						value = vd->values[i];
 					}
 					}
 					Entity *e = make_entity_variable(c->allocator, file_scope, name->Ident, NULL);
 					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];
 		AstFile *f = &c->parser->files[i];
 		add_curr_ast_file(c, f);
 		add_curr_ast_file(c, f);
 
 
 		Scope *file_scope = f->scope;
 		Scope *file_scope = f->scope;
 
 
-		gb_for_array(decl_index, f->decls) {
+		for_array(decl_index, f->decls) {
 			AstNode *decl = f->decls[decl_index];
 			AstNode *decl = f->decls[decl_index];
 			if (decl->kind != AstNode_ImportDecl) {
 			if (decl->kind != AstNode_ImportDecl) {
 				continue;
 				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));
 			GB_ASSERT_MSG(found != NULL, "Unable to find scope for file: %.*s", LIT(id->fullpath));
 			Scope *scope = *found;
 			Scope *scope = *found;
 			b32 previously_added = false;
 			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];
 				Scope *prev = file_scope->imported[import_index];
 				if (prev == scope) {
 				if (prev == scope) {
 					previously_added = true;
 					previously_added = true;
@@ -1115,14 +1115,14 @@ void check_parsed_files(Checker *c) {
 				}
 				}
 			}
 			}
 			if (!previously_added) {
 			if (!previously_added) {
-				gb_array_append(file_scope->imported, scope);
+				array_add(&file_scope->imported, scope);
 			} else {
 			} else {
 				warning(id->token, "Multiple #import of the same file within this scope");
 				warning(id->token, "Multiple #import of the same file within this scope");
 			}
 			}
 
 
 			if (id->import_name.string == ".") {
 			if (id->import_name.string == ".") {
 				// NOTE(bill): Add imported entities to this file's scope
 				// 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;
 					Entity *e = scope->elements.entries[elem_index].value;
 					if (e->scope == file_scope) {
 					if (e->scope == file_scope) {
 						continue;
 						continue;
@@ -1186,7 +1186,7 @@ void check_parsed_files(Checker *c) {
 	}
 	}
 
 
 	auto check_global_entity = [](Checker *c, EntityKind kind) {
 	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];
 			auto *entry = &c->info.entities.entries[i];
 			Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 			Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 			if (e->kind == kind) {
 			if (e->kind == kind) {
@@ -1222,7 +1222,7 @@ void check_parsed_files(Checker *c) {
 	check_global_entity(c, Entity_Variable);
 	check_global_entity(c, Entity_Variable);
 
 
 	// Check procedure bodies
 	// Check procedure bodies
-	gb_for_array(i, c->procs) {
+	for_array(i, c->procs) {
 		ProcedureInfo *pi = &c->procs[i];
 		ProcedureInfo *pi = &c->procs[i];
 		add_curr_ast_file(c, pi->file);
 		add_curr_ast_file(c, pi->file);
 
 
@@ -1244,13 +1244,13 @@ void check_parsed_files(Checker *c) {
 
 
 	if (false) {
 	if (false) {
 		gb_printf("Dependency graph:\n");
 		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];
 			auto *entry = &c->info.entities.entries[i];
 			Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 			Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 			DeclInfo *d = entry->value;
 			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_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;
 					Entity *e = cast(Entity *)cast(uintptr)d->deps.entries[j].key.key;
 					gb_printf("\t\t%.*s\n", LIT(e->token.string));
 					gb_printf("\t\t%.*s\n", LIT(e->token.string));
 				}
 				}
@@ -1259,7 +1259,7 @@ void check_parsed_files(Checker *c) {
 	}
 	}
 
 
 	// Add untyped expression values
 	// 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];
 		auto *entry = &c->info.untyped.entries[i];
 		HashKey key = entry->key;
 		HashKey key = entry->key;
 		AstNode *expr = cast(AstNode *)cast(uintptr)key.key;
 		AstNode *expr = cast(AstNode *)cast(uintptr)key.key;

+ 80 - 78
src/checker/expr.cpp

@@ -254,19 +254,19 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
 		Entity *e;
 		Entity *e;
 		AstNode *t;
 		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<Delay> delayed_const; array_init(&delayed_const, c->tmp_allocator, other_field_count);
+	Array<Delay> 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];
 		AstNode *decl = decls[decl_index];
 		if (decl->kind == AstNode_ConstDecl) {
 		if (decl->kind == AstNode_ConstDecl) {
 			ast_node(cd, ConstDecl, decl);
 			ast_node(cd, ConstDecl, decl);
 
 
-			isize entity_count = gb_array_count(cd->names);
+			isize entity_count = cd->names.count;
 			isize entity_index = 0;
 			isize entity_index = 0;
 			Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
 			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 *name = cd->names[i];
 				AstNode *value = cd->values[i];
 				AstNode *value = cd->values[i];
 
 
@@ -277,11 +277,11 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
 				entities[entity_index++] = e;
 				entities[entity_index++] = e;
 
 
 				Delay delay = {e, cd->type};
 				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?
 			// TODO(bill): Better error messages or is this good enough?
 			if (rhs_count == 0 && cd->type == NULL) {
 			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");
 				error(ast_node_token(node), "Extra initial expression");
 			}
 			}
 
 
-			gb_for_array(i, cd->names) {
+			for_array(i, cd->names) {
 				AstNode *name = cd->names[i];
 				AstNode *name = cd->names[i];
 				Entity *e = entities[i];
 				Entity *e = entities[i];
 				Token name_token = name->Ident;
 				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);
 			Entity *e = make_entity_type_name(c->allocator, c->context.scope, name_token, NULL);
 			Delay delay = {e, td->type};
 			Delay delay = {e, td->type};
-			gb_array_append(delayed_type, delay);
+			array_add(&delayed_type, delay);
 
 
 			if (name_token.string == "_") {
 			if (name_token.string == "_") {
 				other_fields[other_field_index++] = e;
 				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);
 		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);
 		check_type_decl(c, delayed_const[i].e, delayed_const[i].t, NULL, NULL);
 	}
 	}
 
 
 	if (node->kind == AstNode_UnionType) {
 	if (node->kind == AstNode_UnionType) {
 		isize field_index = 0;
 		isize field_index = 0;
 		fields[field_index++] = make_entity_type_name(c->allocator, c->context.scope, empty_token, NULL);
 		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];
 			AstNode *decl = decls[decl_index];
 			if (decl->kind != AstNode_VarDecl) {
 			if (decl->kind != AstNode_VarDecl) {
 				continue;
 				continue;
@@ -352,7 +352,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
 			ast_node(vd, VarDecl, decl);
 			ast_node(vd, VarDecl, decl);
 			Type *base_type = check_type(c, vd->type, NULL, cycle_checker);
 			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];
 				AstNode *name = vd->names[name_index];
 				Token name_token = name->Ident;
 				Token name_token = name->Ident;
 
 
@@ -379,7 +379,7 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
 		}
 		}
 	} else {
 	} else {
 		isize field_index = 0;
 		isize field_index = 0;
-		gb_for_array(decl_index, decls) {
+		for_array(decl_index, decls) {
 			AstNode *decl = decls[decl_index];
 			AstNode *decl = decls[decl_index];
 			if (decl->kind != AstNode_VarDecl) {
 			if (decl->kind != AstNode_VarDecl) {
 				continue;
 				continue;
@@ -389,13 +389,13 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
 			Type *type = check_type(c, vd->type, NULL, cycle_checker);
 			Type *type = check_type(c, vd->type, NULL, cycle_checker);
 
 
 			if (vd->is_using) {
 			if (vd->is_using) {
-				if (gb_array_count(vd->names) > 1) {
+				if (vd->names.count > 1) {
 					error(ast_node_token(vd->names[0]),
 					error(ast_node_token(vd->names[0]),
 					      "Cannot apply `using` to more than one of the same type");
 					      "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];
 				AstNode *name = vd->names[name_index];
 				Token name_token = name->Ident;
 				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;
 					Token name_token = vd->names[0]->Ident;
 					if (is_type_indexable(t)) {
 					if (is_type_indexable(t)) {
 						b32 ok = true;
 						b32 ok = true;
-						gb_for_array(emi, entity_map.entries) {
+						for_array(emi, entity_map.entries) {
 							Entity *e = entity_map.entries[emi].value;
 							Entity *e = entity_map.entries[emi].value;
 							if (e->kind == Entity_Variable && e->Variable.anonymous) {
 							if (e->kind == Entity_Variable && e->Variable.anonymous) {
 								if (is_type_indexable(e->type)) {
 								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 field_count = 0;
 	isize other_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];
 		AstNode *decl = st->decls[decl_index];
 		switch (decl->kind) {
 		switch (decl->kind) {
 		case_ast_node(vd, VarDecl, decl);
 		case_ast_node(vd, VarDecl, decl);
-			field_count += gb_array_count(vd->names);
+			field_count += vd->names.count;
 		case_end;
 		case_end;
 
 
 		case_ast_node(cd, ConstDecl, decl);
 		case_ast_node(cd, ConstDecl, decl);
-			other_field_count += gb_array_count(cd->names);
+			other_field_count += cd->names.count;
 		case_end;
 		case_end;
 
 
 		case_ast_node(td, TypeDecl, decl);
 		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 field_count = 1;
 	isize other_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];
 		AstNode *decl = ut->decls[decl_index];
 		switch (decl->kind) {
 		switch (decl->kind) {
 		case_ast_node(vd, VarDecl, decl);
 		case_ast_node(vd, VarDecl, decl);
-			field_count += gb_array_count(vd->names);
+			field_count += vd->names.count;
 		case_end;
 		case_end;
 
 
 		case_ast_node(cd, ConstDecl, decl);
 		case_ast_node(cd, ConstDecl, decl);
-			other_field_count += gb_array_count(cd->names);
+			other_field_count += cd->names.count;
 		case_end;
 		case_end;
 
 
 		case_ast_node(td, TypeDecl, decl);
 		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 field_count = 0;
 	isize other_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];
 		AstNode *decl = ut->decls[decl_index];
 		switch (decl->kind) {
 		switch (decl->kind) {
 		case_ast_node(vd, VarDecl, decl);
 		case_ast_node(vd, VarDecl, decl);
-			field_count += gb_array_count(vd->names);
+			field_count += vd->names.count;
 		case_end;
 		case_end;
 
 
 		case_ast_node(cd, ConstDecl, decl);
 		case_ast_node(cd, ConstDecl, decl);
-			other_field_count += gb_array_count(cd->names);
+			other_field_count += cd->names.count;
 		case_end;
 		case_end;
 
 
 		case_ast_node(td, TypeDecl, decl);
 		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;
 	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;
 	isize field_index = 0;
 	ExactValue iota = make_exact_value_integer(-1);
 	ExactValue iota = make_exact_value_integer(-1);
 	i64 min_value = 0;
 	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));;
 	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];
 		AstNode *field = et->fields[i];
 
 
 		ast_node(f, FieldValue, field);
 		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);
 		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_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,
 	enum_type->Record.enum_count = make_entity_constant(c->allocator, NULL,
 		make_token_ident(make_string("count")), t_int, make_exact_value_integer(enum_type->Record.other_field_count));
 		make_token_ident(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_) {
 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;
 		return NULL;
+	}
 
 
 	b32 is_variadic = false;
 	b32 is_variadic = false;
 
 
 	Type *tuple = make_type_tuple(c->allocator);
 	Type *tuple = make_type_tuple(c->allocator);
 
 
 	isize variable_count = 0;
 	isize variable_count = 0;
-	gb_for_array(i, params) {
+	for_array(i, params) {
 		AstNode *field = params[i];
 		AstNode *field = params[i];
 		ast_node(p, Parameter, field);
 		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);
 	Entity **variables = gb_alloc_array(c->allocator, Entity *, variable_count);
 	isize variable_index = 0;
 	isize variable_index = 0;
-	gb_for_array(i, params) {
+	for_array(i, params) {
 		ast_node(p, Parameter, params[i]);
 		ast_node(p, Parameter, params[i]);
 		AstNode *type_expr = p->type;
 		AstNode *type_expr = p->type;
 		if (type_expr) {
 		if (type_expr) {
 			if (type_expr->kind == AstNode_Ellipsis) {
 			if (type_expr->kind == AstNode_Ellipsis) {
 				type_expr = type_expr->Ellipsis.expr;
 				type_expr = type_expr->Ellipsis.expr;
-				if (i+1 == gb_array_count(params)) {
+				if (i+1 == params.count) {
 					is_variadic = true;
 					is_variadic = true;
 				} else {
 				} else {
 					error(ast_node_token(params[i]), "Invalid AST: Invalid variadic parameter");
 					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);
 			Type *type = check_type(c, type_expr);
-			gb_for_array(j, p->names) {
+			for_array(j, p->names) {
 				AstNode *name = p->names[j];
 				AstNode *name = p->names[j];
 				if (name->kind == AstNode_Ident) {
 				if (name->kind == AstNode_Ident) {
 					Entity *param = make_entity_param(c->allocator, scope, name->Ident, type, p->is_using);
 					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
 		// NOTE(bill): Change last variadic parameter to be a slice
 		// Custom Calling convention for variadic parameters
 		// 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);
 		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) {
 Type *check_get_results(Checker *c, Scope *scope, AstNodeArray results) {
-	if (results == NULL || gb_array_count(results) == 0) {
+	if (results.count == 0) {
 		return NULL;
 		return NULL;
 	}
 	}
 	Type *tuple = make_type_tuple(c->allocator);
 	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;
 	isize variable_index = 0;
-	gb_for_array(i, results) {
+	for_array(i, results) {
 		AstNode *item = results[i];
 		AstNode *item = results[i];
 		Type *type = check_type(c, item);
 		Type *type = check_type(c, item);
 		Token token = ast_node_token(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;
 		variables[variable_index++] = param;
 	}
 	}
 	tuple->Tuple.variables = variables;
 	tuple->Tuple.variables = variables;
-	tuple->Tuple.variable_count = gb_array_count(results);
+	tuple->Tuple.variable_count = results.count;
 
 
 	return tuple;
 	return tuple;
 }
 }
@@ -915,7 +916,7 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl
 #if 0
 #if 0
 	// TODO(bill): Fix cyclical dependancy checker
 	// TODO(bill): Fix cyclical dependancy checker
 		if (cycle_checker != NULL) {
 		if (cycle_checker != NULL) {
-			gb_for_array(i, cycle_checker->path) {
+			for_array(i, cycle_checker->path) {
 				Entity *prev = cycle_checker->path[i];
 				Entity *prev = cycle_checker->path[i];
 				if (prev == e) {
 				if (prev == e) {
 					error(e->token, "Illegal declaration cycle for %.*s", LIT(e->token.string));
 					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];
 	BuiltinProc *bp = &builtin_procs[id];
 	{
 	{
 		char *err = NULL;
 		char *err = NULL;
-		if (gb_array_count(ce->args) < bp->arg_count)
+		if (ce->args.count < bp->arg_count) {
 			err = "Too few";
 			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";
 			err = "Too many";
+		}
+
 		if (err) {
 		if (err) {
 			ast_node(proc, Ident, ce->proc);
 			ast_node(proc, Ident, ce->proc);
 			error(ce->close, "`%s` arguments for `%.*s`, expected %td, got %td",
 			error(ce->close, "`%s` arguments for `%.*s`, expected %td, got %td",
 			      err, LIT(proc->string),
 			      err, LIT(proc->string),
-			      bp->arg_count, gb_array_count(ce->args));
+			      bp->arg_count, ce->args.count);
 			return false;
 			return false;
 		}
 		}
 	}
 	}
@@ -2321,7 +2324,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
 
 
 		AstNode *len = ce->args[1];
 		AstNode *len = ce->args[1];
 		AstNode *cap = NULL;
 		AstNode *cap = NULL;
-		if (gb_array_count(ce->args) > 2) {
+		if (ce->args.count > 2) {
 			cap = ce->args[2];
 			cap = ce->args[2];
 		}
 		}
 
 
@@ -2349,7 +2352,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
 				      type_str);
 				      type_str);
 				return false;
 				return false;
 			}
 			}
-			if (ce->args[3] != NULL) {
+			if (ce->args.count > 3) {
 				error(ast_node_token(call),
 				error(ast_node_token(call),
 				      "Too many arguments to `new_slice`, expected either 2 or 3");
 				      "Too many arguments to `new_slice`, expected either 2 or 3");
 				return false;
 				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 max_count = vector_type->Vector.count;
 		isize arg_count = 0;
 		isize arg_count = 0;
-		gb_for_array(i, ce->args) {
+		for_array(i, ce->args) {
 			if (i == 0) continue;
 			if (i == 0) continue;
 			AstNode *arg = ce->args[i];
 			AstNode *arg = ce->args[i];
 			Operand op = {};
 			Operand op = {};
@@ -2826,7 +2829,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
 
 
 		AstNode *len = ce->args[1];
 		AstNode *len = ce->args[1];
 		AstNode *cap = NULL;
 		AstNode *cap = NULL;
-		if (gb_array_count(ce->args) > 2) {
+		if (ce->args.count > 2) {
 			cap = ce->args[2];
 			cap = ce->args[2];
 		}
 		}
 
 
@@ -2855,7 +2858,7 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
 				      type_str);
 				      type_str);
 				return false;
 				return false;
 			}
 			}
-			if (ce->args[2] != NULL) {
+			if (ce->args.count > 3) {
 				error(ast_node_token(call),
 				error(ast_node_token(call),
 				      "Too many arguments to `slice_ptr`, expected either 2 or 3");
 				      "Too many arguments to `slice_ptr`, expected either 2 or 3");
 				return false;
 				return false;
@@ -3083,7 +3086,7 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
 		return;
 		return;
 	}
 	}
 
 
-	if (gb_array_count(ce->args) == 0 && param_count == 0) {
+	if (ce->args.count == 0 && param_count == 0) {
 		return;
 		return;
 	}
 	}
 
 
@@ -3091,14 +3094,14 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
 	defer (gb_temp_arena_memory_end(tmp));
 	defer (gb_temp_arena_memory_end(tmp));
 
 
 	isize operand_count = 0;
 	isize operand_count = 0;
-	gbArray(Operand) operands;
-	gb_array_init_reserve(operands, c->tmp_allocator, 2*param_count);
+	Array<Operand> operands;
+	array_init(&operands, c->tmp_allocator, 2*param_count);
 
 
-	gb_for_array(i, ce->args) {
+	for_array(i, ce->args) {
 		Operand o = {};
 		Operand o = {};
 		check_multi_expr(c, &o, ce->args[i]);
 		check_multi_expr(c, &o, ce->args[i]);
 		if (o.type->kind != Type_Tuple) {
 		if (o.type->kind != Type_Tuple) {
-			gb_array_append(operands, o);
+			array_add(&operands, o);
 		} else {
 		} else {
 			auto *tuple = &o.type->Tuple;
 			auto *tuple = &o.type->Tuple;
 			if (variadic && i >= param_count) {
 			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++) {
 			for (isize j = 0; j < tuple->variable_count; j++) {
 				o.type = tuple->variables[j]->type;
 				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;
 	i32 error_code = 0;
 	if (operand_count < param_count) {
 	if (operand_count < param_count) {
 		error_code = -1;
 		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);
 	check_expr_or_type(c, operand, ce->proc);
 
 
 	if (operand->mode == Addressing_Invalid) {
 	if (operand->mode == Addressing_Invalid) {
-		gb_for_array(i, ce->args) {
+		for_array(i, ce->args) {
 			check_expr_base(c, operand, ce->args[i]);
 			check_expr_base(c, operand, ce->args[i]);
 		}
 		}
 		operand->mode = Addressing_Invalid;
 		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);
 		Type *t = base_type(type);
 		switch (t->kind) {
 		switch (t->kind) {
 		case Type_Record: {
 		case Type_Record: {
-			if (!is_type_struct(t))
+			if (!is_type_struct(t)) {
 				break;
 				break;
-			if (cl->elems == NULL || gb_array_count(cl->elems) == 0) {
+			}
+			if (cl->elems.count == 0) {
 				break; // NOTE(bill): No need to init
 				break; // NOTE(bill): No need to init
 			}
 			}
 			{ // Checker values
 			{ // 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) {
 				if (cl->elems[0]->kind == AstNode_FieldValue) {
 					b32 *fields_visited = gb_alloc_array(c->allocator, b32, field_count);
 					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];
 						AstNode *elem = cl->elems[i];
 						if (elem->kind != AstNode_FieldValue) {
 						if (elem->kind != AstNode_FieldValue) {
 							error(ast_node_token(elem),
 							error(ast_node_token(elem),
@@ -3376,7 +3380,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
 							continue;
 							continue;
 						}
 						}
 
 
-						if (gb_array_count(sel.index) > 1) {
+						if (sel.index.count > 1) {
 							error(ast_node_token(elem),
 							error(ast_node_token(elem),
 							      "Cannot assign to an anonymous field `%.*s` in a structure literal (at the moment)", LIT(name));
 							      "Cannot assign to an anonymous field `%.*s` in a structure literal (at the moment)", LIT(name));
 							continue;
 							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"));
 						check_assignment(c, o, field->type, make_string("structure literal"));
 					}
 					}
 				} else {
 				} else {
-					gb_for_array(index, cl->elems) {
+					for_array(index, cl->elems) {
 						AstNode *elem = cl->elems[index];
 						AstNode *elem = cl->elems[index];
 						if (elem->kind == AstNode_FieldValue) {
 						if (elem->kind == AstNode_FieldValue) {
 							error(ast_node_token(elem),
 							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"));
 						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;
 			i64 max = 0;
 			isize index = 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++) {
 			for (; index < elem_count; index++) {
 				AstNode *e = cl->elems[index];
 				AstNode *e = cl->elems[index];
 				if (e->kind == AstNode_FieldValue) {
 				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_expr_to_string(gbString str, AstNode *node);
 
 
 gbString write_params_to_string(gbString str, AstNodeArray params, char *sep) {
 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]);
 		ast_node(p, Parameter, params[i]);
 		if (i > 0) {
 		if (i > 0) {
 			str = gb_string_appendc(str, sep);
 			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);
 	case_ast_node(cl, CompoundLit, node);
 		str = write_expr_to_string(str, cl->type);
 		str = write_expr_to_string(str, cl->type);
 		str = gb_string_appendc(str, "{");
 		str = gb_string_appendc(str, "{");
-		gb_for_array(i, cl->elems) {
+		for_array(i, cl->elems) {
 			if (i > 0) {
 			if (i > 0) {
 				str = gb_string_appendc(str, ", ");
 				str = gb_string_appendc(str, ", ");
 			}
 			}
@@ -4021,7 +4023,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 		if (p->is_using) {
 		if (p->is_using) {
 			str = gb_string_appendc(str, "using ");
 			str = gb_string_appendc(str, "using ");
 		}
 		}
-		gb_for_array(i, p->names) {
+		for_array(i, p->names) {
 			AstNode *name = p->names[i];
 			AstNode *name = p->names[i];
 			if (i > 0)
 			if (i > 0)
 				str = gb_string_appendc(str, ", ");
 				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 = write_expr_to_string(str, ce->proc);
 		str = gb_string_appendc(str, "(");
 		str = gb_string_appendc(str, "(");
 
 
-		gb_for_array(i, ce->args) {
+		for_array(i, ce->args) {
 			AstNode *arg = ce->args[i];
 			AstNode *arg = ce->args[i];
 			if (i > 0) {
 			if (i > 0) {
 				str = gb_string_appendc(str, ", ");
 				str = gb_string_appendc(str, ", ");
@@ -4056,7 +4058,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 		str = gb_string_appendc(str, "struct ");
 		str = gb_string_appendc(str, "struct ");
 		if (st->is_packed)  str = gb_string_appendc(str, "#packed ");
 		if (st->is_packed)  str = gb_string_appendc(str, "#packed ");
 		if (st->is_ordered) str = gb_string_appendc(str, "#ordered ");
 		if (st->is_ordered) str = gb_string_appendc(str, "#ordered ");
-		gb_for_array(i, st->decls) {
+		for_array(i, st->decls) {
 			if (i > 0) {
 			if (i > 0) {
 				str = gb_string_appendc(str, "; ");
 				str = gb_string_appendc(str, "; ");
 			}
 			}
@@ -4068,7 +4070,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 
 
 	case_ast_node(st, RawUnionType, node);
 	case_ast_node(st, RawUnionType, node);
 		str = gb_string_appendc(str, "raw_union {");
 		str = gb_string_appendc(str, "raw_union {");
-		gb_for_array(i, st->decls) {
+		for_array(i, st->decls) {
 			if (i > 0) {
 			if (i > 0) {
 				str = gb_string_appendc(str, "; ");
 				str = gb_string_appendc(str, "; ");
 			}
 			}
@@ -4080,7 +4082,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
 
 
 	case_ast_node(st, UnionType, node);
 	case_ast_node(st, UnionType, node);
 		str = gb_string_appendc(str, "union {");
 		str = gb_string_appendc(str, "union {");
-		gb_for_array(i, st->decls) {
+		for_array(i, st->decls) {
 			if (i > 0) {
 			if (i > 0) {
 				str = gb_string_appendc(str, "; ");
 				str = gb_string_appendc(str, "; ");
 			}
 			}

+ 60 - 60
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_proc_decl(Checker *c, Entity *e, DeclInfo *d);
 
 
 void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
 void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
-	if (stmts == NULL) {
+	if (stmts.count == 0) {
 		return;
 		return;
 	}
 	}
 
 
@@ -22,14 +22,14 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
 		Entity *e;
 		Entity *e;
 		DeclInfo *d;
 		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<Delay> delayed_const; array_init(&delayed_const, c->tmp_allocator, stmts.count);
+	Array<Delay> delayed_type;  array_init(&delayed_type,  c->tmp_allocator, stmts.count);
 
 
-	gb_for_array(i, stmts) {
+	for_array(i, stmts) {
 		AstNode *node = stmts[i];
 		AstNode *node = stmts[i];
 		switch (node->kind) {
 		switch (node->kind) {
 		case_ast_node(cd, ConstDecl, node);
 		case_ast_node(cd, ConstDecl, node);
-			gb_for_array(i, cd->values) {
+			for_array(i, cd->values) {
 				AstNode *name = cd->names[i];
 				AstNode *name = cd->names[i];
 				AstNode *value = cd->values[i];
 				AstNode *value = cd->values[i];
 				ExactValue v = {ExactValue_Invalid};
 				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);
 				add_entity_and_decl_info(c, name, e, d);
 
 
 				Delay delay = {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) {
 			if (rhs_count == 0 && cd->type == NULL) {
 				error(ast_node_token(node), "Missing type or initial expression");
 				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);
 			add_entity_and_decl_info(c, td->name, e, d);
 
 
 			Delay delay = {e, d};
 			Delay delay = {e, d};
-			gb_array_append(delayed_type, delay);
+			array_add(&delayed_type, delay);
 		case_end;
 		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);
 		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);
 		check_entity_decl(c, delayed_const[i].e, delayed_const[i].d, NULL);
 	}
 	}
 
 
 	b32 ft_ok = (flags & Stmt_FallthroughAllowed) != 0;
 	b32 ft_ok = (flags & Stmt_FallthroughAllowed) != 0;
 	u32 f = flags & (~Stmt_FallthroughAllowed);
 	u32 f = flags & (~Stmt_FallthroughAllowed);
 
 
-	gb_for_array(i, stmts) {
+	for_array(i, stmts) {
 		AstNode *n = stmts[i];
 		AstNode *n = stmts[i];
 		if (n->kind == AstNode_EmptyStmt) {
 		if (n->kind == AstNode_EmptyStmt) {
 			continue;
 			continue;
 		}
 		}
 		u32 new_flags = f;
 		u32 new_flags = f;
-		if (ft_ok && i+1 == gb_array_count(stmts)) {
+		if (ft_ok && i+1 == stmts.count) {
 			new_flags |= Stmt_FallthroughAllowed;
 			new_flags |= Stmt_FallthroughAllowed;
 		}
 		}
 		check_stmt(c, n, new_flags);
 		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) {
 b32 check_is_terminating_list(AstNodeArray stmts) {
 
 
 	// Iterate backwards
 	// 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];
 		AstNode *stmt = stmts[n];
 		if (stmt->kind != AstNode_EmptyStmt) {
 		if (stmt->kind != AstNode_EmptyStmt) {
 			return check_is_terminating(stmt);
 			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) {
 b32 check_has_break_list(AstNodeArray stmts, b32 implicit) {
-	gb_for_array(i, stmts) {
+	for_array(i, stmts) {
 		AstNode *stmt = stmts[i];
 		AstNode *stmt = stmts[i];
 		if (check_has_break(stmt, implicit)) {
 		if (check_has_break(stmt, implicit)) {
 			return true;
 			return true;
@@ -182,10 +182,10 @@ b32 check_is_terminating(AstNode *node) {
 
 
 	case_ast_node(ms, MatchStmt, node);
 	case_ast_node(ms, MatchStmt, node);
 		b32 has_default = false;
 		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];
 			AstNode *clause = ms->body->BlockStmt.stmts[i];
 			ast_node(cc, CaseClause, clause);
 			ast_node(cc, CaseClause, clause);
-			if (cc->list == NULL) {
+			if (cc->list.count == 0) {
 				has_default = true;
 				has_default = true;
 			}
 			}
 			if (!check_is_terminating_list(cc->stmts) ||
 			if (!check_is_terminating_list(cc->stmts) ||
@@ -198,10 +198,10 @@ b32 check_is_terminating(AstNode *node) {
 
 
 	case_ast_node(ms, TypeMatchStmt, node);
 	case_ast_node(ms, TypeMatchStmt, node);
 		b32 has_default = false;
 		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];
 			AstNode *clause = ms->body->BlockStmt.stmts[i];
 			ast_node(cc, CaseClause, clause);
 			ast_node(cc, CaseClause, clause);
-			if (cc->list == NULL) {
+			if (cc->list.count == 0) {
 				has_default = true;
 				has_default = true;
 			}
 			}
 			if (!check_is_terminating_list(cc->stmts) ||
 			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) {
 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;
 		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
 	// NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
 	// an extra allocation
 	// an extra allocation
-	gbArray(Operand) operands;
-	gb_array_init_reserve(operands, c->tmp_allocator, 2*lhs_count);
+	Array<Operand> operands;
+	array_init(&operands, c->tmp_allocator, 2*lhs_count);
 
 
-	gb_for_array(i, inits) {
+	for_array(i, inits) {
 		AstNode *rhs = inits[i];
 		AstNode *rhs = inits[i];
 		Operand o = {};
 		Operand o = {};
 		check_multi_expr(c, &o, rhs);
 		check_multi_expr(c, &o, rhs);
 		if (o.type->kind != Type_Tuple) {
 		if (o.type->kind != Type_Tuple) {
-			gb_array_append(operands, o);
+			array_add(&operands, o);
 		} else {
 		} else {
 			auto *tuple = &o.type->Tuple;
 			auto *tuple = &o.type->Tuple;
 			for (isize j = 0; j < tuple->variable_count; j++) {
 			for (isize j = 0; j < tuple->variable_count; j++) {
 				o.type = tuple->variables[j]->type;
 				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) {
 		if (operands[i].mode == Addressing_Invalid) {
 			rhs_count--;
 			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)) {
 			if (is_type_struct(t) || is_type_raw_union(t)) {
 				Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
 				Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
 				GB_ASSERT(found != NULL);
 				GB_ASSERT(found != NULL);
-				gb_for_array(i, (*found)->elements.entries) {
+				for_array(i, (*found)->elements.entries) {
 					Entity *f = (*found)->elements.entries[i].value;
 					Entity *f = (*found)->elements.entries[i].value;
 					if (f->kind == Entity_Variable) {
 					if (f->kind == Entity_Variable) {
 						Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type);
 						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;
 	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"));
 	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) {
 void check_var_decl_node(Checker *c, AstNode *node) {
 	ast_node(vd, VarDecl, node);
 	ast_node(vd, VarDecl, node);
-	isize entity_count = gb_array_count(vd->names);
+	isize entity_count = vd->names.count;
 	isize entity_index = 0;
 	isize entity_index = 0;
 	Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count);
 	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];
 		AstNode *name = vd->names[i];
 		Entity *entity = NULL;
 		Entity *entity = NULL;
 		if (name->kind == AstNode_Ident) {
 		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"));
 	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) {
 		if (entities[i] != NULL) {
 			add_entity(c, c->context.scope, vd->names[i], entities[i]);
 			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) {
 		switch (as->op.kind) {
 		case Token_Eq: {
 		case Token_Eq: {
 			// a, b, c = 1, 2, 3;  // Multisided
 			// 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");
 				error(as->op, "Missing lhs in assignment statement");
 				return;
 				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
 			// NOTE(bill): If there is a bad syntax error, rhs > lhs which would mean there would need to be
 			// an extra allocation
 			// an extra allocation
-			gbArray(Operand) operands;
-			gb_array_init_reserve(operands, c->tmp_allocator, 2 * gb_array_count(as->lhs));
+			Array<Operand> 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];
 				AstNode *rhs = as->rhs[i];
 				Operand o = {};
 				Operand o = {};
 				check_multi_expr(c, &o, rhs);
 				check_multi_expr(c, &o, rhs);
 				if (o.type->kind != Type_Tuple) {
 				if (o.type->kind != Type_Tuple) {
-					gb_array_append(operands, o);
+					array_add(&operands, o);
 				} else {
 				} else {
 					auto *tuple = &o.type->Tuple;
 					auto *tuple = &o.type->Tuple;
 					for (isize j = 0; j < tuple->variable_count; j++) {
 					for (isize j = 0; j < tuple->variable_count; j++) {
 						o.type = tuple->variables[j]->type;
 						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;
 			isize operand_index = 0;
-			gb_for_array(i, as->lhs) {
+			for_array(i, as->lhs) {
 				AstNode *lhs = as->lhs[i];
 				AstNode *lhs = as->lhs[i];
 				check_assignment_variable(c, &operands[i], lhs);
 				check_assignment_variable(c, &operands[i], lhs);
 			}
 			}
@@ -955,7 +955,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
 		default: {
 		default: {
 			// a += 1; // Single-sided
 			// a += 1; // Single-sided
 			Token op = as->op;
 			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));
 				error(op, "Assignment operation `%.*s` requires single-valued expressions", LIT(op.string));
 				return;
 				return;
 			}
 			}
@@ -1019,7 +1019,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
 	case_end;
 	case_end;
 
 
 	case_ast_node(rs, ReturnStmt, node);
 	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) {
 		if (c->in_defer) {
 			error(rs->token, "You cannot `return` within a defer statement");
 			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;
 		isize result_count = 0;
 		if (proc_type->Proc.results) {
 		if (proc_type->Proc.results) {
 			result_count = proc_type->Proc.results->Tuple.variable_count;
 			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;
 				auto *tuple = &proc_type->Proc.results->Tuple;
 				variables = tuple->variables;
 				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);
 				error(ast_node_token(node), "Expected %td return values, got 0", result_count);
 			} else {
 			} else {
 				check_init_variables(c, variables, result_count,
 				check_init_variables(c, variables, result_count,
 				                     rs->results, make_string("return statement"));
 				                     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");
 			error(ast_node_token(rs->results[0]), "No return values expected");
 		}
 		}
 	case_end;
 	case_end;
@@ -1099,12 +1099,12 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
 		// NOTE(bill): Check for multiple defaults
 		// NOTE(bill): Check for multiple defaults
 		AstNode *first_default = NULL;
 		AstNode *first_default = NULL;
 		ast_node(bs, BlockStmt, ms->body);
 		ast_node(bs, BlockStmt, ms->body);
-		gb_for_array(i, bs->stmts) {
+		for_array(i, bs->stmts) {
 			AstNode *stmt = bs->stmts[i];
 			AstNode *stmt = bs->stmts[i];
 			AstNode *default_stmt = NULL;
 			AstNode *default_stmt = NULL;
 			if (stmt->kind == AstNode_CaseClause) {
 			if (stmt->kind == AstNode_CaseClause) {
 				ast_node(cc, CaseClause, stmt);
 				ast_node(cc, CaseClause, stmt);
-				if (gb_array_count(cc->list) == 0) {
+				if (cc->list.count == 0) {
 					default_stmt = stmt;
 					default_stmt = stmt;
 				}
 				}
 			} else {
 			} else {
@@ -1132,7 +1132,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
 		Map<TypeAndToken> seen = {}; // Multimap
 		Map<TypeAndToken> seen = {}; // Multimap
 		map_init(&seen, gb_heap_allocator());
 		map_init(&seen, gb_heap_allocator());
 		defer (map_destroy(&seen));
 		defer (map_destroy(&seen));
-		gb_for_array(i, bs->stmts) {
+		for_array(i, bs->stmts) {
 			AstNode *stmt = bs->stmts[i];
 			AstNode *stmt = bs->stmts[i];
 			if (stmt->kind != AstNode_CaseClause) {
 			if (stmt->kind != AstNode_CaseClause) {
 				// NOTE(bill): error handled by above multiple default checker
 				// 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);
 			ast_node(cc, CaseClause, stmt);
 
 
 
 
-			gb_for_array(j, cc->list) {
+			for_array(j, cc->list) {
 				AstNode *expr = cc->list[j];
 				AstNode *expr = cc->list[j];
 				Operand y = {};
 				Operand y = {};
 				Operand z = {};
 				Operand z = {};
@@ -1206,7 +1206,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
 
 
 			check_open_scope(c, stmt);
 			check_open_scope(c, stmt);
 			u32 ft_flags = mod_flags;
 			u32 ft_flags = mod_flags;
-			if (i+1 < gb_array_count(bs->stmts)) {
+			if (i+1 < bs->stmts.count) {
 				ft_flags |= Stmt_FallthroughAllowed;
 				ft_flags |= Stmt_FallthroughAllowed;
 			}
 			}
 			check_stmt_list(c, cc->stmts, ft_flags);
 			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
 		// NOTE(bill): Check for multiple defaults
 		AstNode *first_default = NULL;
 		AstNode *first_default = NULL;
 		ast_node(bs, BlockStmt, ms->body);
 		ast_node(bs, BlockStmt, ms->body);
-		gb_for_array(i, bs->stmts) {
+		for_array(i, bs->stmts) {
 			AstNode *stmt = bs->stmts[i];
 			AstNode *stmt = bs->stmts[i];
 			AstNode *default_stmt = NULL;
 			AstNode *default_stmt = NULL;
 			if (stmt->kind == AstNode_CaseClause) {
 			if (stmt->kind == AstNode_CaseClause) {
 				ast_node(cc, CaseClause, stmt);
 				ast_node(cc, CaseClause, stmt);
-				if (gb_array_count(cc->list) == 0) {
+				if (cc->list.count == 0) {
 					default_stmt = stmt;
 					default_stmt = stmt;
 				}
 				}
 			} else {
 			} else {
@@ -1271,7 +1271,7 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
 		defer (map_destroy(&seen));
 		defer (map_destroy(&seen));
 
 
 
 
-		gb_for_array(i, bs->stmts) {
+		for_array(i, bs->stmts) {
 			AstNode *stmt = bs->stmts[i];
 			AstNode *stmt = bs->stmts[i];
 			if (stmt->kind != AstNode_CaseClause) {
 			if (stmt->kind != AstNode_CaseClause) {
 				// NOTE(bill): error handled by above multiple default checker
 				// 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: {
 			case Entity_ImportName: {
 				Scope *scope = e->ImportName.scope;
 				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 *decl = scope->elements.entries[i].value;
 					Entity *found = scope_insert_entity(c->context.scope, decl);
 					Entity *found = scope_insert_entity(c->context.scope, decl);
 					if (found != NULL) {
 					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)) {
 				if (is_type_struct(t) || is_type_raw_union(t)) {
 					Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
 					Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
 					GB_ASSERT(found != NULL);
 					GB_ASSERT(found != NULL);
-					gb_for_array(i, (*found)->elements.entries) {
+					for_array(i, (*found)->elements.entries) {
 						Entity *f = (*found)->elements.entries[i].value;
 						Entity *f = (*found)->elements.entries[i].value;
 						if (f->kind == Entity_Variable) {
 						if (f->kind == Entity_Variable) {
 							Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type);
 							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_end;
 
 
 		case_ast_node(vd, VarDecl, us->node);
 		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");
 				error(us->token, "`using` can only be applied to one variable of the same type");
 			}
 			}
 			check_var_decl_node(c, us->node);
 			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];
 				AstNode *item = vd->names[name_index];
 				ast_node(i, Ident, item);
 				ast_node(i, Ident, item);
 				String name = i->string;
 				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)) {
 				if (is_type_struct(t) || is_type_raw_union(t)) {
 					Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
 					Scope **found = map_get(&c->info.scopes, hash_pointer(t->Record.node));
 					GB_ASSERT(found != NULL);
 					GB_ASSERT(found != NULL);
-					gb_for_array(i, (*found)->elements.entries) {
+					for_array(i, (*found)->elements.entries) {
 						Entity *f = (*found)->elements.entries[i].value;
 						Entity *f = (*found)->elements.entries[i].value;
 						if (f->kind == Entity_Variable) {
 						if (f->kind == Entity_Variable) {
 							Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type);
 							Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type);

+ 12 - 13
src/checker/type.cpp

@@ -777,12 +777,12 @@ gb_global i64 basic_type_sizes[] = {
 
 
 struct Selection {
 struct Selection {
 	Entity *entity;
 	Entity *entity;
-	gbArray(isize) index;
+	Array<isize> index;
 	b32 indirect; // Set if there was a pointer deref anywhere down the line
 	b32 indirect; // Set if there was a pointer deref anywhere down the line
 };
 };
 Selection empty_selection = {};
 Selection empty_selection = {};
 
 
-Selection make_selection(Entity *entity, gbArray(isize) index, b32 indirect) {
+Selection make_selection(Entity *entity, Array<isize> index, b32 indirect) {
 	Selection s = {entity, index, indirect};
 	Selection s = {entity, index, indirect};
 	return s;
 	return s;
 }
 }
@@ -790,10 +790,10 @@ Selection make_selection(Entity *entity, gbArray(isize) index, b32 indirect) {
 void selection_add_index(Selection *s, isize index) {
 void selection_add_index(Selection *s, isize index) {
 	// IMPORTANT NOTE(bill): this requires a stretchy buffer/dynamic array so it requires some form
 	// IMPORTANT NOTE(bill): this requires a stretchy buffer/dynamic array so it requires some form
 	// of heap allocation
 	// 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;
 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;
 				String str = f->token.string;
 
 
 				if (field_name == str) {
 				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;
 			String str = f->token.string;
 
 
 			if (field_name == str) {
 			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) {
 			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
 				selection_add_index(&sel, i); // HACK(bill): Leaky memory
 
 
 				sel = lookup_field(a, f->type, field_name, is_type, sel);
 				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;
 						sel.indirect = true;
 					return sel;
 					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 type_offset_of_from_selection(BaseTypeSizes s, gbAllocator allocator, Type *t, Selection sel) {
 	i64 offset = 0;
 	i64 offset = 0;
-	for (isize i = 0; i < gb_array_count(sel.index); i++) {
+	for_array(i, sel.index) {
 		isize index = sel.index[i];
 		isize index = sel.index[i];
 		t = base_type(t);
 		t = base_type(t);
 		if (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct) {
 		if (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct) {

+ 15 - 15
src/codegen/codegen.cpp

@@ -87,7 +87,7 @@ void ssa_gen_tree(ssaGen *s) {
 	isize global_variable_max_count = 0;
 	isize global_variable_max_count = 0;
 	Entity *entry_point = NULL;
 	Entity *entry_point = NULL;
 
 
-	gb_for_array(i, info->entities.entries) {
+	for_array(i, info->entities.entries) {
 		auto *entry = &info->entities.entries[i];
 		auto *entry = &info->entities.entries[i];
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		String name = e->token.string;
 		String name = e->token.string;
@@ -104,13 +104,13 @@ void ssa_gen_tree(ssaGen *s) {
 		ssaValue *var, *init;
 		ssaValue *var, *init;
 		DeclInfo *decl;
 		DeclInfo *decl;
 	};
 	};
-	gbArray(ssaGlobalVariable) global_variables;
-	gb_array_init_reserve(global_variables, m->tmp_allocator, global_variable_max_count);
+	Array<ssaGlobalVariable> global_variables;
+	array_init(&global_variables, m->tmp_allocator, global_variable_max_count);
 
 
 	auto min_dep_map = generate_minimum_dependency_map(info, entry_point);
 	auto min_dep_map = generate_minimum_dependency_map(info, entry_point);
 	defer (map_destroy(&min_dep_map));
 	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];
 		auto *entry = &info->entities.entries[i];
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		Entity *e = cast(Entity *)cast(uintptr)entry->key.key;
 		String name = e->token.string;
 		String name = e->token.string;
@@ -160,7 +160,7 @@ void ssa_gen_tree(ssaGen *s) {
 			}
 			}
 
 
 			if (g->Global.value == NULL) {
 			if (g->Global.value == NULL) {
-				gb_array_append(global_variables, var);
+				array_add(&global_variables, var);
 			}
 			}
 
 
 			map_set(&m->values, hash_pointer(e), g);
 			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];
 		auto *entry = &m->members.entries[i];
 		ssaValue *v = entry->value;
 		ssaValue *v = entry->value;
 		if (v->kind == ssaValue_Proc)
 		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);
 	ssaDebugInfo *all_procs = ssa_alloc_debug_info(m->allocator, ssaDebugInfo_AllProcs);
 
 
 	isize all_proc_max_count = 0;
 	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];
 		auto *entry = &m->debug_info.entries[i];
 		ssaDebugInfo *di = entry->value;
 		ssaDebugInfo *di = entry->value;
 		di->id = i;
 		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
 	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;
 	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];
 		auto *entry = &m->debug_info.entries[i];
 		ssaDebugInfo *di = entry->value;
 		ssaDebugInfo *di = entry->value;
 		di->id = i;
 		di->id = i;
 		if (di->kind == ssaDebugInfo_Proc) {
 		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);
 		ssa_begin_procedure_body(proc);
 
 
 		// TODO(bill): Should do a dependency graph do check which order to initialize them in?
 		// 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];
 			ssaGlobalVariable *var = &global_variables[i];
 			if (var->decl->init_expr != NULL) {
 			if (var->decl->init_expr != NULL) {
 				var->init = ssa_build_expr(proc, var->decl->init_expr);
 				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
 		// NOTE(bill): Initialize constants first
-		gb_for_array(i, global_variables) {
+		for_array(i, global_variables) {
 			ssaGlobalVariable *var = &global_variables[i];
 			ssaGlobalVariable *var = &global_variables[i];
 			if (var->init != NULL) {
 			if (var->init != NULL) {
 				if (var->init->kind == ssaValue_Constant) {
 				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];
 			ssaGlobalVariable *var = &global_variables[i];
 			if (var->init != NULL) {
 			if (var->init != NULL) {
 				if (var->init->kind != ssaValue_Constant) {
 				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];
 				auto *entry = &info->type_info_map.entries[type_info_map_index];
 				Type *t = cast(Type *)cast(uintptr)entry->key.key;
 				Type *t = cast(Type *)cast(uintptr)entry->key.key;
 				t = default_type(t);
 				t = default_type(t);
@@ -673,7 +673,7 @@ void ssa_gen_tree(ssaGen *s) {
 		ssa_end_procedure_body(proc);
 		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);
 		ssa_build_proc(m->procs[i], m->procs[i]->Proc.parent);
 	}
 	}
 
 

+ 13 - 13
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);
 		type = base_type(type);
 		if (is_type_array(type)) {
 		if (is_type_array(type)) {
 			ast_node(cl, CompoundLit, value.value_compound);
 			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) {
 			if (elem_count == 0) {
 				ssa_fprintf(f, "zeroinitializer");
 				ssa_fprintf(f, "zeroinitializer");
 				break;
 				break;
@@ -385,7 +385,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ
 			ssa_fprintf(f, "]");
 			ssa_fprintf(f, "]");
 		} else if (is_type_vector(type)) {
 		} else if (is_type_vector(type)) {
 			ast_node(cl, CompoundLit, value.value_compound);
 			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) {
 			if (elem_count == 0) {
 				ssa_fprintf(f, "zeroinitializer");
 				ssa_fprintf(f, "zeroinitializer");
 				break;
 				break;
@@ -427,7 +427,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ
 
 
 			ast_node(cl, CompoundLit, value.value_compound);
 			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");
 				ssa_fprintf(f, "zeroinitializer");
 				break;
 				break;
 			}
 			}
@@ -438,7 +438,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ
 
 
 
 
 			if (cl->elems[0]->kind == AstNode_FieldValue) {
 			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++) {
 				for (isize i = 0; i < elem_count; i++) {
 					ast_node(fv, FieldValue, cl->elems[i]);
 					ast_node(fv, FieldValue, cl->elems[i]);
 					String name = fv->field->Ident.string;
 					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, "nounwind uwtable {\n");
 
 
 		ssa_fprintf(f, "{\n");
 		ssa_fprintf(f, "{\n");
-		gb_for_array(i, proc->blocks) {
+		for_array(i, proc->blocks) {
 			ssaBlock *block = proc->blocks[i];
 			ssaBlock *block = proc->blocks[i];
 
 
 			if (i > 0) ssa_fprintf(f, "\n");
 			if (i > 0) ssa_fprintf(f, "\n");
 			ssa_print_block_name(f, block);
 			ssa_print_block_name(f, block);
 			ssa_fprintf(f, ":\n");
 			ssa_fprintf(f, ":\n");
 
 
-			gb_for_array(j, block->instrs) {
+			for_array(j, block->instrs) {
 				ssaValue *value = block->instrs[j];
 				ssaValue *value = block->instrs[j];
 				ssa_print_instr(f, m, value);
 				ssa_print_instr(f, m, value);
 			}
 			}
@@ -1026,7 +1026,7 @@ void ssa_print_proc(ssaFileBuffer *f, ssaModule *m, ssaProcedure *proc) {
 		ssa_fprintf(f, "\n");
 		ssa_fprintf(f, "\n");
 	}
 	}
 
 
-	gb_for_array(i, proc->children) {
+	for_array(i, proc->children) {
 		ssa_print_proc(f, m, proc->children[i]);
 		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");
 	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];
 		auto *entry = &m->members.entries[member_index];
 		ssaValue *v = entry->value;
 		ssaValue *v = entry->value;
 		if (v->kind != ssaValue_TypeName) {
 		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);
 		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];
 		auto *entry = &m->members.entries[member_index];
 		ssaValue *v = entry->value;
 		ssaValue *v = entry->value;
 		if (v->kind != ssaValue_Proc) {
 		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];
 		auto *entry = &m->members.entries[member_index];
 		ssaValue *v = entry->value;
 		ssaValue *v = entry->value;
 		if (v->kind != ssaValue_Proc) {
 		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];
 		auto *entry = &m->members.entries[member_index];
 		ssaValue *v = entry->value;
 		ssaValue *v = entry->value;
 		if (v->kind != ssaValue_Global) {
 		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, "\n");
 		ssa_fprintf(f, "!llvm.dbg.cu = !{!0}\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];
 			auto *entry = &m->debug_info.entries[di_index];
 			ssaDebugInfo *di = entry->value;
 			ssaDebugInfo *di = entry->value;
 			ssa_fprintf(f, "!%d = ", di->id);
 			ssa_fprintf(f, "!%d = ", di->id);
@@ -1184,7 +1184,7 @@ void ssa_print_llvm_ir(ssaFileBuffer *f, ssaModule *m) {
 
 
 			case ssaDebugInfo_AllProcs:
 			case ssaDebugInfo_AllProcs:
 				ssa_fprintf(f, "!{");
 				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];
 					ssaDebugInfo *p = di->AllProcs.procs[proc_index];
 					if (proc_index > 0) {ssa_fprintf(f, ",");}
 					if (proc_index > 0) {ssa_fprintf(f, ",");}
 					ssa_fprintf(f, "!%d", p->id);
 					ssa_fprintf(f, "!%d", p->id);

+ 162 - 148
src/codegen/ssa.cpp

@@ -37,7 +37,7 @@ struct ssaDebugInfo {
 			TokenPos      pos;
 			TokenPos      pos;
 		} Proc;
 		} Proc;
 		struct {
 		struct {
-			gbArray(ssaDebugInfo *) procs;
+			Array<ssaDebugInfo *> procs;
 		} AllProcs;
 		} AllProcs;
 	};
 	};
 };
 };
@@ -64,7 +64,7 @@ struct ssaModule {
 	i32                 global_string_index;
 	i32                 global_string_index;
 	i32                 global_array_index; // For ConstantSlice
 	i32                 global_array_index; // For ConstantSlice
 
 
-	gbArray(ssaValue *) procs; // NOTE(bill): Procedures to generate
+	Array<ssaValue *> procs; // NOTE(bill): Procedures to generate
 };
 };
 
 
 
 
@@ -77,8 +77,11 @@ struct ssaBlock {
 	ssaProcedure *parent;
 	ssaProcedure *parent;
 	b32 added;
 	b32 added;
 
 
-	gbArray(ssaValue *) instrs;
-	gbArray(ssaValue *) values;
+	Array<ssaValue *> instrs;
+	Array<ssaValue *> locals;
+
+	Array<ssaBlock *> preds;
+	Array<ssaBlock *> succs;
 };
 };
 
 
 struct ssaTargetList {
 struct ssaTargetList {
@@ -111,7 +114,7 @@ struct ssaDefer {
 
 
 struct ssaProcedure {
 struct ssaProcedure {
 	ssaProcedure *parent;
 	ssaProcedure *parent;
-	gbArray(ssaProcedure *) children;
+	Array<ssaProcedure *> children;
 
 
 	Entity *      entity;
 	Entity *      entity;
 	ssaModule *   module;
 	ssaModule *   module;
@@ -122,8 +125,8 @@ struct ssaProcedure {
 	u64           tags;
 	u64           tags;
 
 
 	isize               scope_index;
 	isize               scope_index;
-	gbArray(ssaDefer)   defer_stmts;
-	gbArray(ssaBlock *) blocks;
+	Array<ssaDefer>     defer_stmts;
+	Array<ssaBlock *>   blocks;
 	ssaBlock *          decl_block;
 	ssaBlock *          decl_block;
 	ssaBlock *          entry_block;
 	ssaBlock *          entry_block;
 	ssaBlock *          curr_block;
 	ssaBlock *          curr_block;
@@ -149,6 +152,7 @@ struct ssaProcedure {
 	SSA_INSTR_KIND(Br), \
 	SSA_INSTR_KIND(Br), \
 	SSA_INSTR_KIND(Ret), \
 	SSA_INSTR_KIND(Ret), \
 	SSA_INSTR_KIND(Select), \
 	SSA_INSTR_KIND(Select), \
+	SSA_INSTR_KIND(Phi), \
 	SSA_INSTR_KIND(Unreachable), \
 	SSA_INSTR_KIND(Unreachable), \
 	SSA_INSTR_KIND(BinaryOp), \
 	SSA_INSTR_KIND(BinaryOp), \
 	SSA_INSTR_KIND(Call), \
 	SSA_INSTR_KIND(Call), \
@@ -261,6 +265,10 @@ struct ssaInstr {
 			ssaValue *true_value;
 			ssaValue *true_value;
 			ssaValue *false_value;
 			ssaValue *false_value;
 		} Select;
 		} Select;
+		struct {
+			String comment;
+			Array<ssaValue *> edges;
+		} Phi;
 		struct {
 		struct {
 			Type *type;
 			Type *type;
 			Token op;
 			Token op;
@@ -396,7 +404,7 @@ ssaDefer ssa_add_defer_node(ssaProcedure *proc, isize scope_index, AstNode *stmt
 	d.scope_index = scope_index;
 	d.scope_index = scope_index;
 	d.block = proc->curr_block;
 	d.block = proc->curr_block;
 	d.stmt = stmt;
 	d.stmt = stmt;
-	gb_array_append(proc->defer_stmts, d);
+	array_add(&proc->defer_stmts, d);
 	return 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.scope_index = proc->scope_index;
 	d.block = proc->curr_block;
 	d.block = proc->curr_block;
 	d.instr = instr; // NOTE(bill): It will make a copy everytime it is called
 	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;
 	return d;
 }
 }
 
 
@@ -425,7 +433,7 @@ void ssa_init_module(ssaModule *m, Checker *c) {
 	map_init(&m->members,    gb_heap_allocator());
 	map_init(&m->members,    gb_heap_allocator());
 	map_init(&m->debug_info, gb_heap_allocator());
 	map_init(&m->debug_info, gb_heap_allocator());
 	map_init(&m->type_names, 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
 	// Default states
 	m->stmt_state_flags = 0;
 	m->stmt_state_flags = 0;
@@ -435,7 +443,7 @@ void ssa_init_module(ssaModule *m, Checker *c) {
 		// Add type info data
 		// Add type info data
 		{
 		{
 			String name = make_string(SSA_TYPE_INFO_DATA_NAME);
 			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));
 			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);
 			ssaValue *g = ssa_make_value_global(m->allocator, e, NULL);
 			g->Global.is_private  = true;
 			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
 			// NOTE(bill): Removes need for heap allocation by making it global memory
 			isize count = 0;
 			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];
 				auto *entry = &m->info->type_info_map.entries[entry_index];
 				Type *t = cast(Type *)cast(uintptr)entry->key.key;
 				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->members);
 	map_destroy(&m->type_names);
 	map_destroy(&m->type_names);
 	map_destroy(&m->debug_info);
 	map_destroy(&m->debug_info);
-	gb_array_free(m->procs);
+	array_free(&m->procs);
 	gb_arena_free(&m->arena);
 	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 *ssa_alloc_instr(ssaProcedure *proc, ssaInstrKind kind) {
 	ssaValue *v = ssa_alloc_value(proc->module->allocator, ssaValue_Instr);
 	ssaValue *v = ssa_alloc_value(proc->module->allocator, ssaValue_Instr);
 	v->Instr.kind = kind;
 	v->Instr.kind = kind;
-	if (proc->curr_block) {
-		gb_array_append(proc->curr_block->values, v);
-	}
 	return 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);
 		ast_node(cl, CompoundLit, value.value_compound);
 		gbAllocator a = m->allocator;
 		gbAllocator a = m->allocator;
 
 
-		isize count = 0;
-		if (cl->elems) {
-			count = gb_array_count(cl->elems);
-		}
+		isize count = cl->elems.count;
 		if (count > 0) {
 		if (count > 0) {
 			Type *elem = base_type(type)->Slice.elem;
 			Type *elem = base_type(type)->Slice.elem;
 			Type *t = make_type_array(a, elem, count);
 			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.scope  = scope;
 	v->Block.parent = proc;
 	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;
 	return v;
 }
 }
@@ -935,10 +940,7 @@ b32 ssa_is_blank_ident(AstNode *node) {
 
 
 ssaInstr *ssa_get_last_instr(ssaBlock *block) {
 ssaInstr *ssa_get_last_instr(ssaBlock *block) {
 	if (block != NULL) {
 	if (block != NULL) {
-		isize len = 0;
-		if (block->instrs != NULL) {
-			len = gb_array_count(block->instrs);
-		}
+		isize len = block->instrs.count;
 		if (len > 0) {
 		if (len > 0) {
 			ssaValue *v = block->instrs[len-1];
 			ssaValue *v = block->instrs[len-1];
 			GB_ASSERT(v->kind == ssaValue_Instr);
 			GB_ASSERT(v->kind == ssaValue_Instr);
@@ -968,7 +970,7 @@ ssaValue *ssa_emit(ssaProcedure *proc, ssaValue *instr) {
 	if (b != NULL) {
 	if (b != NULL) {
 		ssaInstr *i = ssa_get_last_instr(b);
 		ssaInstr *i = ssa_get_last_instr(b);
 		if (!ssa_is_instr_terminating(i)) {
 		if (!ssa_is_instr_terminating(i)) {
-			gb_array_append(b->instrs, instr);
+			array_add(&b->instrs, instr);
 		}
 		}
 	}
 	}
 	return 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
 	ssaBlock *b = proc->decl_block; // all variables must be in the first block
 	ssaValue *instr = ssa_make_instr_local(proc, e, zero_initialized);
 	ssaValue *instr = ssa_make_instr_local(proc, e, zero_initialized);
 	instr->Instr.parent = b;
 	instr->Instr.parent = b;
-	gb_array_append(b->instrs, instr);
+	array_add(&b->instrs, instr);
+	array_add(&b->locals, instr);
 
 
 	// if (zero_initialized) {
 	// if (zero_initialized) {
 		ssa_emit_zero_init(proc, instr);
 		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 *ssa_add_block(ssaProcedure *proc, AstNode *node, String label) {
 	ssaBlock *block = ssa__make_block(proc, node, label);
 	ssaBlock *block = ssa__make_block(proc, node, label);
-	gb_array_append(proc->blocks, block);
+	array_add(&proc->blocks, block);
 	return 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)) {
 	if (last_instr == NULL || !ssa_is_instr_terminating(last_instr)) {
 		ssa_emit_jump(proc, b);
 		ssa_emit_jump(proc, b);
 	}
 	}
-	gb_array_append(proc->blocks, b);
+	array_add(&proc->blocks, b);
 	proc->curr_block = b;
 	proc->curr_block = b;
 	ssa_emit_comment(proc, make_string("defer"));
 	ssa_emit_comment(proc, make_string("defer"));
 	if (d.kind == ssaDefer_Node) {
 	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) {
 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;
 	isize i = count;
 	while (i --> 0) {
 	while (i --> 0) {
 		ssaDefer d = proc->defer_stmts[i];
 		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 &&
 			if (proc->scope_index == d.scope_index &&
 			    d.scope_index > 1) {
 			    d.scope_index > 1) {
 				ssa_build_defer_stmt(proc, d);
 				ssa_build_defer_stmt(proc, d);
-				gb_array_pop(proc->defer_stmts);
+				array_pop(&proc->defer_stmts);
 				continue;
 				continue;
 			} else {
 			} else {
 				break;
 				break;
@@ -1143,6 +1146,10 @@ void ssa_close_scope(ssaProcedure *proc, ssaDeferExitKind kind, ssaBlock *block)
 	proc->scope_index--;
 	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));
 	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) {
 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) {
 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) {
 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->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"));
 	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);
 		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);
 		ssa_emit_unreachable(proc);
 	}
 	}
 
 
@@ -1240,10 +1256,10 @@ void ssa_end_procedure_body(ssaProcedure *proc) {
 
 
 // Number blocks and registers
 // Number blocks and registers
 	i32 reg_id = 0;
 	i32 reg_id = 0;
-	gb_for_array(i, proc->blocks) {
+	for_array(i, proc->blocks) {
 		ssaBlock *b = proc->blocks[i];
 		ssaBlock *b = proc->blocks[i];
 		b->id = i;
 		b->id = i;
-		gb_for_array(j, b->instrs) {
+		for_array(j, b->instrs) {
 			ssaValue *value = b->instrs[j];
 			ssaValue *value = b->instrs[j];
 			GB_ASSERT(value->kind == ssaValue_Instr);
 			GB_ASSERT(value->kind == ssaValue_Instr);
 			ssaInstr *instr = &value->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) {
 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];
 		isize index = sel.index[i];
 		if (is_type_pointer(type)) {
 		if (is_type_pointer(type)) {
 			type = type_deref(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) {
 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];
 		isize index = sel.index[i];
 		if (is_type_pointer(type)) {
 		if (is_type_pointer(type)) {
 			type = type_deref(type);
 			type = type_deref(type);
@@ -1480,7 +1496,7 @@ isize ssa_type_info_index(CheckerInfo *info, Type *type) {
 	if (entry_index < 0) {
 	if (entry_index < 0) {
 		// NOTE(bill): Do manual search
 		// NOTE(bill): Do manual search
 		// TODO(bill): This is O(n) and can be very slow
 		// 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];
 			auto *e = &info->type_info_map.entries[i];
 			Type *prev_type = cast(Type *)cast(uintptr)e->key.key;
 			Type *prev_type = cast(Type *)cast(uintptr)e->key.key;
 			if (are_types_identical(prev_type, type)) {
 			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_store(proc, result, v_false);
 	ssa_emit_jump(proc, done);
 	ssa_emit_jump(proc, done);
 
 
-	gb_array_append(proc->blocks, done);
+	array_add(&proc->blocks, done);
 	proc->curr_block = done;
 	proc->curr_block = done;
 
 
 	return ssa_emit_load(proc, result);
 	return ssa_emit_load(proc, result);
@@ -2182,7 +2198,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 		// parent$count
 		// parent$count
 		isize name_len = proc->name.len + 1 + 8 + 1;
 		isize name_len = proc->name.len + 1 + 8 + 1;
 		u8 *name_text = gb_alloc_array(proc->module->allocator, u8, name_len);
 		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);
 		String name = make_string(name_text, name_len-1);
 
 
 		Type *type = type_of_expr(proc->module->info, expr);
 		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;
 		value->Proc.tags = pl->tags;
 
 
-		gb_array_append(proc->children, &value->Proc);
+		array_add(&proc->children, &value->Proc);
 		ssa_build_proc(value, proc);
 		ssa_build_proc(value, proc);
 
 
 		return value;
 		return value;
@@ -2225,30 +2241,28 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 
 
 		case Type_Vector: {
 		case Type_Vector: {
 			ssaValue *result = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr));
 			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;
 			return result;
 		} break;
 		} break;
@@ -2256,9 +2270,9 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 		case Type_Record: {
 		case Type_Record: {
 			GB_ASSERT(is_type_struct(bt));
 			GB_ASSERT(is_type_struct(bt));
 			auto *st = &bt->Record;
 			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)));
 				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];
 					AstNode *elem = cl->elems[field_index];
 					if (is_elem_const(proc->module, elem)) {
 					if (is_elem_const(proc->module, elem)) {
 						continue;
 						continue;
@@ -2292,9 +2306,9 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 			}
 			}
 		} break;
 		} break;
 		case Type_Array: {
 		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)));
 				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];
 					AstNode *elem = cl->elems[i];
 					if (is_elem_const(proc->module, elem)) {
 					if (is_elem_const(proc->module, elem)) {
 						continue;
 						continue;
@@ -2309,7 +2323,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
 			}
 			}
 		} break;
 		} break;
 		case Type_Slice: {
 		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_type = bt->Slice.elem;
 				Type *elem_ptr_type = make_type_pointer(proc->module->allocator, elem_type);
 				Type *elem_ptr_type = make_type_pointer(proc->module->allocator, elem_type);
 				Type *elem_ptr_ptr_type = make_type_pointer(proc->module->allocator, elem_ptr_type);
 				Type *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);
 				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];
 					AstNode *elem = cl->elems[i];
 					if (is_elem_const(proc->module,elem)) {
 					if (is_elem_const(proc->module,elem)) {
 						continue;
 						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 *len =ssa_emit_conv(proc, ssa_build_expr(proc, ce->args[1]), t_int);
 					ssaValue *cap = len;
 					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);
 						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_global_call(proc, "__assert", args, 4);
 
 
 					ssa_emit_jump(proc, done);
 					ssa_emit_jump(proc, done);
-					gb_array_append(proc->blocks, done);
+					array_add(&proc->blocks, done);
 					proc->curr_block = done;
 					proc->curr_block = done;
 
 
 					return NULL;
 					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_store(proc, gep, new_len);
 
 
 					ssa_emit_jump(proc, done);
 					ssa_emit_jump(proc, done);
-					gb_array_append(proc->blocks, done);
+					array_add(&proc->blocks, done);
 					proc->curr_block = done;
 					proc->curr_block = done;
 
 
 					return ssa_emit_conv(proc, cond, t_bool, true);
 					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: {
 				case BuiltinProc_swizzle: {
 					ssa_emit_comment(proc, make_string("swizzle"));
 					ssa_emit_comment(proc, make_string("swizzle"));
 					ssaValue *vector = ssa_build_expr(proc, ce->args[0]);
 					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) {
 					if (index_count == 0) {
 						return vector;
 						return vector;
 					}
 					}
 
 
 					i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count);
 					i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count);
 					isize index = 0;
 					isize index = 0;
-					gb_for_array(i, ce->args) {
+					for_array(i, ce->args) {
 						if (i == 0) continue;
 						if (i == 0) continue;
 						TypeAndValue *tv = type_and_value_of_expression(proc->module->info, ce->args[i]);
 						TypeAndValue *tv = type_and_value_of_expression(proc->module->info, ce->args[i]);
 						GB_ASSERT(is_type_integer(tv->type));
 						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);
 					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_build_expr(proc, ce->args[2]);
 						cap = ssa_emit_conv(proc, cap, t_int, true);
 						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_index = 0;
 
 
 		isize arg_count = 0;
 		isize arg_count = 0;
-		gb_for_array(i, ce->args) {
+		for_array(i, ce->args) {
 			AstNode *a = ce->args[i];
 			AstNode *a = ce->args[i];
 			Type *at = base_type(type_of_expr(proc->module->info, a));
 			Type *at = base_type(type_of_expr(proc->module->info, a));
 			if (at->kind == Type_Tuple) {
 			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 variadic = proc_type_->Proc.variadic;
 		b32 vari_expand = ce->ellipsis.pos.line != 0;
 		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]);
 			ssaValue *a = ssa_build_expr(proc, ce->args[i]);
 			Type *at = ssa_type(a);
 			Type *at = ssa_type(a);
 			if (at->kind == Type_Tuple) {
 			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) {
 void ssa_build_stmt_list(ssaProcedure *proc, AstNodeArray stmts) {
-	gb_for_array(i, stmts) {
+	for_array(i, stmts) {
 		ssa_build_stmt(proc, stmts[i]);
 		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);
 		gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);
 		defer (gb_temp_arena_memory_end(tmp));
 		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];
 				AstNode *name = vd->names[i];
 				if (!ssa_is_blank_ident(name)) {
 				if (!ssa_is_blank_ident(name)) {
 					ssa_add_local_for_identifier(proc, name, true);
 					ssa_add_local_for_identifier(proc, name, true);
 				}
 				}
 			}
 			}
 		} else { // Tuple(s)
 		} 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<ssaAddr>  lvals;
+			Array<ssaValue *> 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];
 				AstNode *name = vd->names[i];
 				ssaAddr lval = ssa_make_addr(NULL, NULL);
 				ssaAddr lval = ssa_make_addr(NULL, NULL);
 				if (!ssa_is_blank_ident(name)) {
 				if (!ssa_is_blank_ident(name)) {
@@ -3369,25 +3383,25 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 					lval = ssa_build_addr(proc, name);
 					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]);
 				ssaValue *init = ssa_build_expr(proc, vd->values[i]);
 				Type *t = ssa_type(init);
 				Type *t = ssa_type(init);
 				if (t->kind == Type_Tuple) {
 				if (t->kind == Type_Tuple) {
 					for (isize i = 0; i < t->Tuple.variable_count; i++) {
 					for (isize i = 0; i < t->Tuple.variable_count; i++) {
 						Entity *e = t->Tuple.variables[i];
 						Entity *e = t->Tuple.variables[i];
 						ssaValue *v = ssa_emit_struct_ev(proc, init, i, e->type);
 						ssaValue *v = ssa_emit_struct_ev(proc, init, i, e->type);
-						gb_array_append(inits, v);
+						array_add(&inits, v);
 					}
 					}
 				} else {
 				} 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]));
 				ssaValue *v = ssa_emit_conv(proc, inits[i], ssa_addr_type(lvals[i]));
 				ssa_lvalue_store(proc, lvals[i], v);
 				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;
 			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);
 			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);
 			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);
 			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;
 			value->Proc.parent = proc;
 
 
 			ssa_module_add_value(proc->module, e, value);
 			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 {
 		} else {
 			auto *info = proc->module->info;
 			auto *info = proc->module->info;
 
 
@@ -3456,7 +3470,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 					map_set(&proc->module->members, key, value);
 					map_set(&proc->module->members, key, value);
 				}
 				}
 			} else {
 			} else {
-				gb_array_append(proc->children, &value->Proc);
+				array_add(&proc->children, &value->Proc);
 			}
 			}
 		}
 		}
 	case_end;
 	case_end;
@@ -3468,7 +3482,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 		String td_name = td->name->Ident.string;
 		String td_name = td->name->Ident.string;
 		isize name_len = proc->name.len + 1 + td_name.len + 1 + 10 + 1;
 		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);
 		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);
 		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);
 		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) {
 		switch (as->op.kind) {
 		case Token_Eq: {
 		case Token_Eq: {
-			gbArray(ssaAddr) lvals;
-			gb_array_init(lvals, m->tmp_allocator);
+			Array<ssaAddr> lvals;
+			array_init(&lvals, m->tmp_allocator);
 
 
-			gb_for_array(i, as->lhs) {
+			for_array(i, as->lhs) {
 				AstNode *lhs = as->lhs[i];
 				AstNode *lhs = as->lhs[i];
 				ssaAddr lval = {};
 				ssaAddr lval = {};
 				if (!ssa_is_blank_ident(lhs)) {
 				if (!ssa_is_blank_ident(lhs)) {
 					lval = ssa_build_addr(proc, 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];
 					AstNode *rhs = as->rhs[0];
 					ssaValue *init = ssa_build_expr(proc, rhs);
 					ssaValue *init = ssa_build_expr(proc, rhs);
 					ssa_lvalue_store(proc, lvals[0], init);
 					ssa_lvalue_store(proc, lvals[0], init);
 				} else {
 				} else {
-					gbArray(ssaValue *) inits;
-					gb_array_init_reserve(inits, m->tmp_allocator, gb_array_count(lvals));
+					Array<ssaValue *> 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]);
 						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]);
 						ssa_lvalue_store(proc, lvals[i], inits[i]);
 					}
 					}
 				}
 				}
 			} else {
 			} else {
-				gbArray(ssaValue *) inits;
-				gb_array_init_reserve(inits, m->tmp_allocator, gb_array_count(lvals));
+				Array<ssaValue *> 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]);
 					ssaValue *init = ssa_build_expr(proc, as->rhs[i]);
 					Type *t = ssa_type(init);
 					Type *t = ssa_type(init);
 					// TODO(bill): refactor for code reuse as this is repeated a bit
 					// 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++) {
 						for (isize i = 0; i < t->Tuple.variable_count; i++) {
 							Entity *e = t->Tuple.variables[i];
 							Entity *e = t->Tuple.variables[i];
 							ssaValue *v = ssa_emit_struct_ev(proc, init, i, e->type);
 							ssaValue *v = ssa_emit_struct_ev(proc, init, i, e->type);
-							gb_array_append(inits, v);
+							array_add(&inits, v);
 						}
 						}
 					} else {
 					} 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]);
 					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);
 			gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena);
 			defer (gb_temp_arena_memory_end(tmp));
 			defer (gb_temp_arena_memory_end(tmp));
 
 
-			gbArray(ssaValue *) results;
-			gb_array_init_reserve(results, proc->module->tmp_allocator, return_count);
+			Array<ssaValue *> 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]);
 				ssaValue *res = ssa_build_expr(proc, rs->results[res_index]);
 				Type *t = ssa_type(res);
 				Type *t = ssa_type(res);
 				if (t->kind == Type_Tuple) {
 				if (t->kind == Type_Tuple) {
 					for (isize i = 0; i < t->Tuple.variable_count; i++) {
 					for (isize i = 0; i < t->Tuple.variable_count; i++) {
 						Entity *e = t->Tuple.variables[i];
 						Entity *e = t->Tuple.variables[i];
 						ssaValue *v = ssa_emit_struct_ev(proc, res, i, e->type);
 						ssaValue *v = ssa_emit_struct_ev(proc, res, i, e->type);
-						gb_array_append(results, v);
+						array_add(&results, v);
 					}
 					}
 				} else {
 				} else {
-					gb_array_append(results, res);
+					array_add(&results, res);
 				}
 				}
 			}
 			}
 
 
 			Type *ret_type = proc->type->Proc.results;
 			Type *ret_type = proc->type->Proc.results;
 			v = ssa_add_local_generated(proc, ret_type);
 			v = ssa_add_local_generated(proc, ret_type);
-			gb_for_array(i, results) {
+			for_array(i, results) {
 				Entity *e = return_type_tuple->variables[i];
 				Entity *e = return_type_tuple->variables[i];
 				ssaValue *res = ssa_emit_conv(proc, results[i], e->type);
 				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));
 				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);
 			ssa_emit_jump(proc, done);
 		}
 		}
-		gb_array_append(proc->blocks, done);
+		array_add(&proc->blocks, done);
 		proc->curr_block = done;
 		proc->curr_block = done;
 	case_end;
 	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;
 		proc->curr_block = done;
 
 
 	case_end;
 	case_end;
@@ -3741,15 +3755,15 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 		ast_node(body, BlockStmt, ms->body);
 		ast_node(body, BlockStmt, ms->body);
 
 
 
 
-		AstNodeArray default_stmts = NULL;
+		AstNodeArray default_stmts = {};
 		ssaBlock *default_fall = NULL;
 		ssaBlock *default_fall = NULL;
 		ssaBlock *default_block = NULL;
 		ssaBlock *default_block = NULL;
 
 
 		ssaBlock *fall = NULL;
 		ssaBlock *fall = NULL;
 		b32 append_fall = false;
 		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];
 			AstNode *clause = body->stmts[i];
 			ssaBlock *body = fall;
 			ssaBlock *body = fall;
 			b32 append_body = false;
 			b32 append_body = false;
@@ -3759,7 +3773,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 
 
 			if (body == NULL) {
 			if (body == NULL) {
 				append_body = true;
 				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"));
 					body = ssa__make_block(proc, clause, make_string("match.dflt.body"));
 				} else {
 				} else {
 					body = ssa__make_block(proc, clause, make_string("match.case.body"));
 					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"));
 				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 case
 				default_stmts = cc->stmts;
 				default_stmts = cc->stmts;
 				default_fall  = fall;
 				default_fall  = fall;
@@ -3786,17 +3800,17 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 
 
 			ssaBlock *next_cond = NULL;
 			ssaBlock *next_cond = NULL;
 			Token eq = {Token_CmpEq};
 			Token eq = {Token_CmpEq};
-			gb_for_array(j, cc->list) {
+			for_array(j, cc->list) {
 				AstNode *expr = cc->list[j];
 				AstNode *expr = cc->list[j];
 				next_cond = ssa__make_block(proc, clause, make_string("match.case.next"));
 				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));
 				ssaValue *cond = ssa_emit_comp(proc, eq, tag, ssa_build_expr(proc, expr));
 				ssa_emit_if(proc, cond, body, next_cond);
 				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;
 				proc->curr_block = next_cond;
 			}
 			}
 			if (append_body) {
 			if (append_body) {
-				gb_array_append(proc->blocks, body);
+				array_add(&proc->blocks, body);
 			}
 			}
 			proc->curr_block = body;
 			proc->curr_block = body;
 
 
@@ -3812,7 +3826,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 
 
 		if (default_block != NULL) {
 		if (default_block != NULL) {
 			ssa_emit_jump(proc, default_block);
 			ssa_emit_jump(proc, default_block);
-			gb_array_append(proc->blocks, default_block);
+			array_add(&proc->blocks, default_block);
 			proc->curr_block = default_block;
 			proc->curr_block = default_block;
 
 
 			ssa_push_target_list(proc, done, NULL, default_fall);
 			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);
 		ssa_emit_jump(proc, done);
-		gb_array_append(proc->blocks, done);
+		array_add(&proc->blocks, done);
 		proc->curr_block = done;
 		proc->curr_block = done;
 	case_end;
 	case_end;
 
 
@@ -3853,15 +3867,15 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 
 
 		String tag_var_name = ms->var->Ident.string;
 		String tag_var_name = ms->var->Ident.string;
 
 
-		AstNodeArray default_stmts = NULL;
+		AstNodeArray default_stmts = {};
 		ssaBlock *default_block = NULL;
 		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];
 			AstNode *clause = body->stmts[i];
 			ast_node(cc, CaseClause, clause);
 			ast_node(cc, CaseClause, clause);
 
 
-			if (gb_array_count(cc->list) == 0) {
+			if (cc->list.count == 0) {
 				// default case
 				// default case
 				default_stmts = cc->stmts;
 				default_stmts = cc->stmts;
 				default_block = ssa__make_block(proc, clause, make_string("type-match.dflt.body"));
 				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};
 			Token eq = {Token_CmpEq};
 			ssaValue *cond = ssa_emit_comp(proc, eq, tag_index, index);
 			ssaValue *cond = ssa_emit_comp(proc, eq, tag_index, index);
 			ssa_emit_if(proc, cond, body, next_cond);
 			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;
 			proc->curr_block = next_cond;
 
 
-			gb_array_append(proc->blocks, body);
+			array_add(&proc->blocks, body);
 			proc->curr_block = body;
 			proc->curr_block = body;
 
 
 			ssa_push_target_list(proc, done, NULL, NULL);
 			ssa_push_target_list(proc, done, NULL, NULL);
@@ -3915,7 +3929,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
 
 
 		if (default_block != NULL) {
 		if (default_block != NULL) {
 			ssa_emit_jump(proc, default_block);
 			ssa_emit_jump(proc, default_block);
-			gb_array_append(proc->blocks, default_block);
+			array_add(&proc->blocks, default_block);
 			proc->curr_block = default_block;
 			proc->curr_block = default_block;
 
 
 			ssa_push_target_list(proc, done, NULL, NULL);
 			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);
 		ssa_emit_jump(proc, done);
-		gb_array_append(proc->blocks, done);
+		array_add(&proc->blocks, done);
 		proc->curr_block = done;
 		proc->curr_block = done;
 	case_end;
 	case_end;
 
 

+ 39 - 32
src/common.cpp

@@ -2,7 +2,9 @@
 #define GB_IMPLEMENTATION
 #define GB_IMPLEMENTATION
 #include "gb/gb.h"
 #include "gb/gb.h"
 
 
+
 #include "string.cpp"
 #include "string.cpp"
+#include "array.cpp"
 
 
 gb_global String global_module_path = {};
 gb_global String global_module_path = {};
 gb_global b32 global_module_path_set = false;
 gb_global b32 global_module_path_set = false;
@@ -12,21 +14,21 @@ String get_module_dir() {
 		return global_module_path;
 		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<wchar_t> path_buf;
+	array_init(&path_buf, gb_heap_allocator(), 300);
+	defer (array_free(&path_buf));
+	array_resize(&path_buf, 300);
 
 
 	isize len = 0;
 	isize len = 0;
 	for (;;) {
 	for (;;) {
-		len = GetModuleFileNameW(NULL, path_buf, gb_array_count(path_buf));
+		len = GetModuleFileNameW(NULL, &path_buf[0], path_buf.count);
 		if (len == 0) {
 		if (len == 0) {
 			return make_string(NULL, 0);
 			return make_string(NULL, 0);
 		}
 		}
-		if (len < gb_array_count(path_buf)) {
+		if (len < path_buf.count) {
 			break;
 			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);
 	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 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
 // Doubly Linked Lists
@@ -179,6 +182,8 @@ i64 prev_pow2(i64 n) {
 ////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////
 
 
 
 
+
+
 struct MapFindResult {
 struct MapFindResult {
 	isize hash_index;
 	isize hash_index;
 	isize entry_prev;
 	isize entry_prev;
@@ -194,8 +199,8 @@ struct MapEntry {
 
 
 template <typename T>
 template <typename T>
 struct Map {
 struct Map {
-	gbArray(isize) hashes;
-	gbArray(MapEntry<T>) entries;
+	Array<isize> hashes;
+	Array<MapEntry<T> > entries;
 };
 };
 
 
 template <typename T> void map_init   (Map<T> *h, gbAllocator a);
 template <typename T> void map_init   (Map<T> *h, gbAllocator a);
@@ -221,14 +226,14 @@ template <typename T> void  multi_map_remove_all(Map<T> *h, HashKey key);
 
 
 template <typename T>
 template <typename T>
 gb_inline void map_init(Map<T> *h, gbAllocator a) {
 gb_inline void map_init(Map<T> *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 <typename T>
 template <typename T>
 gb_inline void map_destroy(Map<T> *h) {
 gb_inline void map_destroy(Map<T> *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 <typename T>
 template <typename T>
@@ -236,15 +241,15 @@ gb_internal isize map__add_entry(Map<T> *h, HashKey key) {
 	MapEntry<T> e = {};
 	MapEntry<T> e = {};
 	e.key = key;
 	e.key = key;
 	e.next = -1;
 	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 <typename T>
 template <typename T>
 gb_internal MapFindResult map__find(Map<T> *h, HashKey key) {
 gb_internal MapFindResult map__find(Map<T> *h, HashKey key) {
 	MapFindResult fr = {-1, -1, -1};
 	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];
 		fr.entry_index = h->hashes[fr.hash_index];
 		while (fr.entry_index >= 0) {
 		while (fr.entry_index >= 0) {
 			if (hash_key_equal(h->entries[fr.entry_index].key, key)) {
 			if (hash_key_equal(h->entries[fr.entry_index].key, key)) {
@@ -260,8 +265,8 @@ gb_internal MapFindResult map__find(Map<T> *h, HashKey key) {
 template <typename T>
 template <typename T>
 gb_internal MapFindResult map__find(Map<T> *h, MapEntry<T> *e) {
 gb_internal MapFindResult map__find(Map<T> *h, MapEntry<T> *e) {
 	MapFindResult fr = {-1, -1, -1};
 	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];
 		fr.entry_index = h->hashes[fr.hash_index];
 		while (fr.entry_index >= 0) {
 		while (fr.entry_index >= 0) {
 			if (&h->entries[fr.entry_index] == e) {
 			if (&h->entries[fr.entry_index] == e) {
@@ -277,12 +282,12 @@ gb_internal MapFindResult map__find(Map<T> *h, MapEntry<T> *e) {
 
 
 template <typename T>
 template <typename T>
 gb_internal b32 map__full(Map<T> *h) {
 gb_internal b32 map__full(Map<T> *h) {
-	return 0.75f * gb_array_count(h->hashes) <= gb_array_count(h->entries);
+	return 0.75f * h->hashes.count <= h->entries.count;
 }
 }
 
 
 template <typename T>
 template <typename T>
 gb_inline void map_grow(Map<T> *h) {
 gb_inline void map_grow(Map<T> *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);
 	map_rehash(h, new_count);
 }
 }
 
 
@@ -290,16 +295,18 @@ template <typename T>
 void map_rehash(Map<T> *h, isize new_count) {
 void map_rehash(Map<T> *h, isize new_count) {
 	isize i, j;
 	isize i, j;
 	Map<T> nh = {};
 	Map<T> 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;
 		nh.hashes[i] = -1;
-	for (i = 0; i < gb_array_count(h->entries); i++) {
+	}
+	for (i = 0; i < h->entries.count; i++) {
 		MapEntry<T> *e = &h->entries[i];
 		MapEntry<T> *e = &h->entries[i];
 		MapFindResult fr;
 		MapFindResult fr;
-		if (gb_array_count(nh.hashes) == 0)
+		if (nh.hashes.count == 0) {
 			map_grow(&nh);
 			map_grow(&nh);
+		}
 		fr = map__find(&nh, e->key);
 		fr = map__find(&nh, e->key);
 		j = map__add_entry(&nh, e->key);
 		j = map__add_entry(&nh, e->key);
 		if (fr.entry_prev < 0)
 		if (fr.entry_prev < 0)
@@ -327,7 +334,7 @@ template <typename T>
 void map_set(Map<T> *h, HashKey key, T value) {
 void map_set(Map<T> *h, HashKey key, T value) {
 	isize index;
 	isize index;
 	MapFindResult fr;
 	MapFindResult fr;
-	if (gb_array_count(h->hashes) == 0)
+	if (h->hashes.count == 0)
 		map_grow(h);
 		map_grow(h);
 	fr = map__find(h, key);
 	fr = map__find(h, key);
 	if (fr.entry_index >= 0) {
 	if (fr.entry_index >= 0) {
@@ -355,11 +362,11 @@ void map__erase(Map<T> *h, MapFindResult fr) {
 	} else {
 	} else {
 		h->entries[fr.entry_prev].next = h->entries[fr.entry_index].next;
 		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;
 		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);
 	MapFindResult last = map__find(h, h->entries[fr.entry_index].key);
 	if (last.entry_prev >= 0) {
 	if (last.entry_prev >= 0) {
 		h->entries[last.entry_prev].next = fr.entry_index;
 		h->entries[last.entry_prev].next = fr.entry_index;
@@ -428,7 +435,7 @@ void multi_map_get_all(Map<T> *h, HashKey key, T *items) {
 
 
 template <typename T>
 template <typename T>
 void multi_map_insert(Map<T> *h, HashKey key, T value) {
 void multi_map_insert(Map<T> *h, HashKey key, T value) {
-	if (gb_array_count(h->hashes) == 0) {
+	if (h->hashes.count == 0) {
 		map_grow(h);
 		map_grow(h);
 	}
 	}
 	MapFindResult fr = map__find(h, key);
 	MapFindResult fr = map__find(h, key);

+ 2 - 2
src/main.cpp

@@ -189,7 +189,6 @@ int main(int argc, char **argv) {
 		// "-dse "
 		// "-dse "
 		// "-dce "
 		// "-dce "
 		// "-S "
 		// "-S "
-		// "-debug-pass=Arguments "
 		"",
 		"",
 		LIT(module_dir),
 		LIT(module_dir),
 		output_name, LIT(output));
 		output_name, LIT(output));
@@ -203,6 +202,7 @@ int main(int argc, char **argv) {
 	exit_code = win32_exec_command_line_app(
 	exit_code = win32_exec_command_line_app(
 		"%.*sbin/llc %.*s.bc -filetype=obj -O%d "
 		"%.*sbin/llc %.*s.bc -filetype=obj -O%d "
 		"%.*s "
 		"%.*s "
+		// "-debug-pass=Arguments "
 		"",
 		"",
 		LIT(module_dir),
 		LIT(module_dir),
 		LIT(output),
 		LIT(output),
@@ -217,7 +217,7 @@ int main(int argc, char **argv) {
 	gbString lib_str = gb_string_make(gb_heap_allocator(), "Kernel32.lib");
 	gbString lib_str = gb_string_make(gb_heap_allocator(), "Kernel32.lib");
 	// defer (gb_string_free(lib_str));
 	// defer (gb_string_free(lib_str));
 	char lib_str_buf[1024] = {};
 	char lib_str_buf[1024] = {};
-	gb_for_array(i, parser.system_libraries) {
+	for_array(i, parser.system_libraries) {
 		String lib = parser.system_libraries[i];
 		String lib = parser.system_libraries[i];
 		isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
 		isize len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf),
 		                        " %.*s.lib", LIT(lib));
 		                        " %.*s.lib", LIT(lib));

+ 79 - 79
src/parser.cpp

@@ -15,13 +15,13 @@ enum ParseFileError {
 	ParseFile_Count,
 	ParseFile_Count,
 };
 };
 
 
-typedef gbArray(AstNode *) AstNodeArray;
+typedef Array<AstNode *> AstNodeArray;
 
 
 struct AstFile {
 struct AstFile {
 	u32            id;
 	u32            id;
 	gbArena        arena;
 	gbArena        arena;
 	Tokenizer      tokenizer;
 	Tokenizer      tokenizer;
-	gbArray(Token) tokens;
+	Array<Token>   tokens;
 	isize          curr_token_index;
 	isize          curr_token_index;
 	Token          curr_token;
 	Token          curr_token;
 	Token          prev_token; // previous non-comment
 	Token          prev_token; // previous non-comment
@@ -54,10 +54,10 @@ struct ImportedFile {
 
 
 struct Parser {
 struct Parser {
 	String init_fullpath;
 	String init_fullpath;
-	gbArray(AstFile)      files;
-	gbArray(ImportedFile) imports;
+	Array<AstFile>      files;
+	Array<ImportedFile> imports;
 	gbAtomic32 import_index;
 	gbAtomic32 import_index;
-	gbArray(String)       system_libraries;
+	Array<String>       system_libraries;
 	isize total_token_count;
 	isize total_token_count;
 	gbMutex mutex;
 	gbMutex mutex;
 };
 };
@@ -96,8 +96,7 @@ enum CallExprKind {
 
 
 AstNodeArray make_ast_node_array(AstFile *f) {
 AstNodeArray make_ast_node_array(AstFile *f) {
 	AstNodeArray a;
 	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;
 	return a;
 }
 }
 
 
@@ -452,10 +451,11 @@ Token ast_node_token(AstNode *node) {
 	case AstNode_ForeignSystemLibrary:
 	case AstNode_ForeignSystemLibrary:
 		return node->ForeignSystemLibrary.token;
 		return node->ForeignSystemLibrary.token;
 	case AstNode_Parameter: {
 	case AstNode_Parameter: {
-		if (node->Parameter.names)
+		if (node->Parameter.names.count > 0) {
 			return ast_node_token(node->Parameter.names[0]);
 			return ast_node_token(node->Parameter.names[0]);
-		else
+		} else {
 			return ast_node_token(node->Parameter.type);
 			return ast_node_token(node->Parameter.type);
+		}
 	}
 	}
 	case AstNode_ProcType:
 	case AstNode_ProcType:
 		return node->ProcType.token;
 		return node->ProcType.token;
@@ -957,7 +957,7 @@ AstNode *make_foreign_system_library(AstFile *f, Token token, Token filepath) {
 }
 }
 
 
 b32 next_token(AstFile *f) {
 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) {
 		if (f->curr_token.kind != Token_Comment) {
 			f->prev_token = f->curr_token;
 			f->prev_token = f->curr_token;
 		}
 		}
@@ -1155,7 +1155,7 @@ AstNodeArray parse_element_list(AstFile *f) {
 			elem = make_field_value(f, elem, value, eq);
 			elem = make_field_value(f, elem, value, eq);
 		}
 		}
 
 
-		gb_array_append(elems, elem);
+		array_add(&elems, elem);
 
 
 		if (f->curr_token.kind != Token_Comma) {
 		if (f->curr_token.kind != Token_Comma) {
 			break;
 			break;
@@ -1167,7 +1167,7 @@ AstNodeArray parse_element_list(AstFile *f) {
 }
 }
 
 
 AstNode *parse_literal_value(AstFile *f, AstNode *type) {
 AstNode *parse_literal_value(AstFile *f, AstNode *type) {
-	AstNodeArray elems = NULL;
+	AstNodeArray elems = {};
 	Token open = expect_token(f, Token_OpenBrace);
 	Token open = expect_token(f, Token_OpenBrace);
 	f->expr_level++;
 	f->expr_level++;
 	if (f->curr_token.kind != Token_CloseBrace) {
 	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);
 		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_Comma) {
 			if (f->curr_token.kind == Token_CloseParen)
 			if (f->curr_token.kind == Token_CloseParen)
@@ -1493,9 +1493,9 @@ AstNode *parse_atom_expr(AstFile *f, b32 lhs) {
 				// TODO(bill): Handle this
 				// TODO(bill): Handle this
 			}
 			}
 			AstNode *proc = parse_identifier(f);
 			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<AstNode *> 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);
 			operand = make_call_expr(f, proc, args, ast_node_token(operand), op, empty_token);
 		} break;
 		} break;
 
 
@@ -1685,7 +1685,7 @@ AstNode *parse_binary_expr(AstFile *f, b32 lhs, i32 prec_in) {
 				AstNode *proc = parse_identifier(f);
 				AstNode *proc = parse_identifier(f);
 				/* if (f->curr_token.kind == Token_OpenParen) {
 				/* if (f->curr_token.kind == Token_OpenParen) {
 					AstNode *call = parse_call_expr(f, proc);
 					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--) {
 					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]);
 						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;
 					expression = call;
 				} else  */{
 				} else  */{
 					right = parse_binary_expr(f, false, prec+1);
 					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<AstNode *> 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);
 					expression = make_call_expr(f, proc, args, op, ast_node_token(right), empty_token);
 				}
 				}
 				continue;
 				continue;
@@ -1730,7 +1730,7 @@ AstNodeArray parse_expr_list(AstFile *f, b32 lhs) {
 	AstNodeArray list = make_ast_node_array(f);
 	AstNodeArray list = make_ast_node_array(f);
 	do {
 	do {
 		AstNode *e = parse_expr(f, lhs);
 		AstNode *e = parse_expr(f, lhs);
-		gb_array_append(list, e);
+		array_add(&list, e);
 		if (f->curr_token.kind != Token_Comma ||
 		if (f->curr_token.kind != Token_Comma ||
 		    f->curr_token.kind == Token_EOF) {
 		    f->curr_token.kind == Token_EOF) {
 		    break;
 		    break;
@@ -1780,7 +1780,7 @@ AstNode *parse_simple_stmt(AstFile *f) {
 		}
 		}
 		next_token(f);
 		next_token(f);
 		AstNodeArray rhs = parse_rhs_expr_list(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.");
 			syntax_error(token, "No right-hand side in assignment statement.");
 			return make_bad_stmt(f, token, f->curr_token);
 			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);
 	AstNodeArray list = make_ast_node_array(f);
 
 
 	do {
 	do {
-		gb_array_append(list, parse_identifier(f));
+		array_add(&list, parse_identifier(f));
 		if (f->curr_token.kind != Token_Comma ||
 		if (f->curr_token.kind != Token_Comma ||
 		    f->curr_token.kind == Token_EOF) {
 		    f->curr_token.kind == Token_EOF) {
 		    break;
 		    break;
@@ -1875,8 +1875,8 @@ Token parse_procedure_signature(AstFile *f,
                                 AstNodeArray *params, AstNodeArray *results);
                                 AstNodeArray *params, AstNodeArray *results);
 
 
 AstNode *parse_proc_type(AstFile *f) {
 AstNode *parse_proc_type(AstFile *f) {
-	AstNodeArray params = NULL;
-	AstNodeArray results = NULL;
+	AstNodeArray params = {};
+	AstNodeArray results = {};
 
 
 	Token proc_token = parse_procedure_signature(f, &params, &results);
 	Token proc_token = parse_procedure_signature(f, &params, &results);
 
 
@@ -1895,11 +1895,11 @@ AstNodeArray parse_parameter_list(AstFile *f) {
 		}
 		}
 
 
 		AstNodeArray names = parse_lhs_expr_list(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");
 			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");
 			syntax_error(f->curr_token, "Cannot apply `using` to more than one of the same type");
 			is_using = false;
 			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 `..`");
 				syntax_error(f->curr_token, "variadic parameter is missing a type after `..`");
 				type = make_bad_expr(f, ellipsis, f->curr_token);
 				type = make_bad_expr(f, ellipsis, f->curr_token);
 			} else {
 			} else {
-				if (gb_array_count(names) > 1) {
+				if (names.count > 1) {
 					syntax_error(f->curr_token, "mutliple variadic parameters, only  `..`");
 					syntax_error(f->curr_token, "mutliple variadic parameters, only  `..`");
 				} else {
 				} else {
 					type = make_ellipsis(f, ellipsis, type);
 					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");
 			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(&params, make_parameter(f, names, type, is_using));
 		if (f->curr_token.kind != Token_Comma) {
 		if (f->curr_token.kind != Token_Comma) {
 			break;
 			break;
 		}
 		}
@@ -1952,7 +1952,7 @@ AstNodeArray parse_struct_params(AstFile *f, isize *decl_count_, b32 using_allow
 			is_using = true;
 			is_using = true;
 		}
 		}
 		AstNodeArray names = parse_lhs_expr_list(f);
 		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");
 			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");
 			syntax_error(f->curr_token, "Cannot apply `using` to members of a union");
 			is_using = false;
 			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");
 			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);
 		expect_semicolon_after_stmt(f, decl);
 
 
 		if (decl != NULL && is_ast_node_decl(decl)) {
 		if (decl != NULL && is_ast_node_decl(decl)) {
-			gb_array_append(decls, decl);
+			array_add(&decls, decl);
 			if (decl->kind == AstNode_VarDecl) {
 			if (decl->kind == AstNode_VarDecl) {
 				decl->VarDecl.is_using = is_using && using_allowed;
 				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)");
 					syntax_error(f->curr_token, "Default variable assignments within a structure will be ignored (at the moment)");
 				}
 				}
 			} else {
 			} else {
@@ -2129,7 +2129,7 @@ AstNode *parse_identifier_or_type(AstFile *f, u32 flags) {
 				value = parse_value(f);
 				value = parse_value(f);
 			}
 			}
 			AstNode *field = make_field_value(f, name, value, eq);
 			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) {
 			if (f->curr_token.kind != Token_Comma) {
 				break;
 				break;
 			}
 			}
@@ -2185,7 +2185,7 @@ AstNodeArray parse_results(AstFile *f) {
 			expect_token(f, Token_OpenParen);
 			expect_token(f, Token_OpenParen);
 			while (f->curr_token.kind != Token_CloseParen &&
 			while (f->curr_token.kind != Token_CloseParen &&
 			       f->curr_token.kind != Token_EOF) {
 			       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) {
 				if (f->curr_token.kind != Token_Comma) {
 					break;
 					break;
 				}
 				}
@@ -2196,7 +2196,7 @@ AstNodeArray parse_results(AstFile *f) {
 			return results;
 			return results;
 		}
 		}
 
 
-		gb_array_append(results, parse_type(f));
+		array_add(&results, parse_type(f));
 		return results;
 		return results;
 	}
 	}
 	return results;
 	return results;
@@ -2214,7 +2214,7 @@ Token parse_procedure_signature(AstFile *f,
 }
 }
 
 
 AstNode *parse_body(AstFile *f) {
 AstNode *parse_body(AstFile *f) {
-	AstNodeArray stmts = NULL;
+	AstNodeArray stmts = {};
 	Token open, close;
 	Token open, close;
 	open = expect_token(f, Token_OpenBrace);
 	open = expect_token(f, Token_OpenBrace);
 	stmts = parse_stmt_list(f);
 	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) {
 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, &params, &results);
 	parse_procedure_signature(f, &params, &results);
 	AstNode *proc_type = make_proc_type(f, proc_token, params, 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) {
 AstNode *parse_decl(AstFile *f, AstNodeArray names) {
-	AstNodeArray values = NULL;
+	AstNodeArray values = {};
 	AstNode *type = NULL;
 	AstNode *type = NULL;
 
 
-	// gb_for_array(i, names) {
+	// for_array(i, names) {
 	// 	AstNode *name = names[i];
 	// 	AstNode *name = names[i];
 	// 	if (name->kind == AstNode_Ident) {
 	// 	if (name->kind == AstNode_Ident) {
 	// 		String n = name->Ident.string;
 	// 		String n = name->Ident.string;
@@ -2295,7 +2295,7 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) {
 			if (token.kind == Token_type) {
 			if (token.kind == Token_type) {
 				next_token(f);
 				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");
 				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);
 				return make_bad_decl(f, names[0]->Ident, token);
 			}
 			}
@@ -2311,7 +2311,7 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) {
 		    // NOTE(bill): Procedure declarations
 		    // NOTE(bill): Procedure declarations
 			Token proc_token = f->curr_token;
 			Token proc_token = f->curr_token;
 			AstNode *name = names[0];
 			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");
 				syntax_error(proc_token, "You can only declare one procedure at a time");
 				return make_bad_decl(f, name->Ident, proc_token);
 				return make_bad_decl(f, name->Ident, proc_token);
 			}
 			}
@@ -2320,29 +2320,29 @@ AstNode *parse_decl(AstFile *f, AstNodeArray names) {
 
 
 		} else {
 		} else {
 			values = parse_rhs_expr_list(f);
 			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");
 				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");
 				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");
 				syntax_error(f->curr_token, "Expected an expression for this declaration");
 			}
 			}
 		}
 		}
 	}
 	}
 
 
 	if (is_mutable) {
 	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");
 			syntax_error(f->curr_token, "Missing variable type or initialization");
 			return make_bad_decl(f, f->curr_token, f->curr_token);
 			return make_bad_decl(f, f->curr_token, f->curr_token);
 		}
 		}
 	} else {
 	} 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");
 			syntax_error(f->curr_token, "Missing constant value");
 			return make_bad_decl(f, f->curr_token, f->curr_token);
 			return make_bad_decl(f, f->curr_token, f->curr_token);
 		}
 		}
 	}
 	}
 
 
-	if (values == NULL) {
+	if (values.data == NULL) {
 		values = make_ast_node_array(f);
 		values = make_ast_node_array(f);
 	}
 	}
 
 
@@ -2421,7 +2421,7 @@ AstNode *parse_return_stmt(AstFile *f) {
 		results = parse_rhs_expr_list(f);
 		results = parse_rhs_expr_list(f);
 	}
 	}
 	if (f->curr_token.kind != Token_CloseBrace) {
 	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);
 	return make_return_stmt(f, token, results);
@@ -2491,7 +2491,7 @@ AstNode *parse_type_case_clause(AstFile *f) {
 	Token token = f->curr_token;
 	Token token = f->curr_token;
 	AstNodeArray clause = make_ast_node_array(f);
 	AstNodeArray clause = make_ast_node_array(f);
 	if (allow_token(f, Token_case)) {
 	if (allow_token(f, Token_case)) {
-		gb_array_append(clause, parse_expr(f, false));
+		array_add(&clause, parse_expr(f, false));
 	} else {
 	} else {
 		expect_token(f, Token_default);
 		expect_token(f, Token_default);
 	}
 	}
@@ -2532,7 +2532,7 @@ AstNode *parse_match_stmt(AstFile *f) {
 
 
 		while (f->curr_token.kind == Token_case ||
 		while (f->curr_token.kind == Token_case ||
 		       f->curr_token.kind == Token_default) {
 		       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);
 		close = expect_token(f, Token_CloseBrace);
@@ -2563,7 +2563,7 @@ AstNode *parse_match_stmt(AstFile *f) {
 
 
 		while (f->curr_token.kind == Token_case ||
 		while (f->curr_token.kind == Token_case ||
 		       f->curr_token.kind == Token_default) {
 		       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);
 		close = expect_token(f, Token_CloseBrace);
@@ -2833,7 +2833,7 @@ AstNodeArray parse_stmt_list(AstFile *f) {
 	       f->curr_token.kind != Token_EOF) {
 	       f->curr_token.kind != Token_EOF) {
 		AstNode *stmt = parse_stmt(f);
 		AstNode *stmt = parse_stmt(f);
 		if (stmt && stmt->kind != AstNode_EmptyStmt) {
 		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);
 	TokenizerInitError err = init_tokenizer(&f->tokenizer, fullpath);
 	if (err == TokenizerInit_None) {
 	if (err == TokenizerInit_None) {
-		gb_array_init(f->tokens, gb_heap_allocator());
+		array_init(&f->tokens, gb_heap_allocator());
 		for (;;) {
 		for (;;) {
 			Token token = tokenizer_get_token(&f->tokenizer);
 			Token token = tokenizer_get_token(&f->tokenizer);
 			if (token.kind == Token_Invalid) {
 			if (token.kind == Token_Invalid) {
 				return ParseFile_InvalidToken;
 				return ParseFile_InvalidToken;
 			}
 			}
-			gb_array_append(f->tokens, token);
+			array_add(&f->tokens, token);
 
 
 			if (token.kind == Token_EOF) {
 			if (token.kind == Token_EOF) {
 				break;
 				break;
@@ -2866,7 +2866,7 @@ ParseFileError init_ast_file(AstFile *f, String fullpath) {
 
 
 		// NOTE(bill): Is this big enough or too small?
 		// NOTE(bill): Is this big enough or too small?
 		isize arena_size = gb_size_of(AstNode);
 		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);
 		gb_arena_init_from_allocator(&f->arena, gb_heap_allocator(), arena_size);
 
 
 		f->curr_proc = NULL;
 		f->curr_proc = NULL;
@@ -2888,32 +2888,32 @@ ParseFileError init_ast_file(AstFile *f, String fullpath) {
 
 
 void destroy_ast_file(AstFile *f) {
 void destroy_ast_file(AstFile *f) {
 	gb_arena_free(&f->arena);
 	gb_arena_free(&f->arena);
-	gb_array_free(f->tokens);
+	array_free(&f->tokens);
 	gb_free(gb_heap_allocator(), f->tokenizer.fullpath.text);
 	gb_free(gb_heap_allocator(), f->tokenizer.fullpath.text);
 	destroy_tokenizer(&f->tokenizer);
 	destroy_tokenizer(&f->tokenizer);
 }
 }
 
 
 b32 init_parser(Parser *p) {
 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);
 	gb_mutex_init(&p->mutex);
 	return true;
 	return true;
 }
 }
 
 
 void destroy_parser(Parser *p) {
 void destroy_parser(Parser *p) {
 	// TODO(bill): Fix memory leak
 	// TODO(bill): Fix memory leak
-	gb_for_array(i, p->files) {
+	for_array(i, p->files) {
 		destroy_ast_file(&p->files[i]);
 		destroy_ast_file(&p->files[i]);
 	}
 	}
 #if 1
 #if 1
-	gb_for_array(i, p->imports) {
+	for_array(i, p->imports) {
 		// gb_free(gb_heap_allocator(), p->imports[i].text);
 		// gb_free(gb_heap_allocator(), p->imports[i].text);
 	}
 	}
 #endif
 #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);
 	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);
 	gb_mutex_lock(&p->mutex);
 	defer (gb_mutex_unlock(&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;
 		String import = p->imports[i].path;
 		if (import == path) {
 		if (import == path) {
 			return false;
 			return false;
@@ -2933,7 +2933,7 @@ b32 try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) {
 	item.path = path;
 	item.path = path;
 	item.rel_path = rel_path;
 	item.rel_path = rel_path;
 	item.pos = pos;
 	item.pos = pos;
-	gb_array_append(p->imports, item);
+	array_add(&p->imports, item);
 	return true;
 	return true;
 }
 }
 
 
@@ -2973,13 +2973,13 @@ b32 try_add_foreign_system_library_path(Parser *p, String import_file) {
 	gb_mutex_lock(&p->mutex);
 	gb_mutex_lock(&p->mutex);
 	defer (gb_mutex_unlock(&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];
 		String import = p->system_libraries[i];
 		if (import == import_file) {
 		if (import == import_file) {
 			return false;
 			return false;
 		}
 		}
 	}
 	}
-	gb_array_append(p->system_libraries, import_file);
+	array_add(&p->system_libraries, import_file);
 	return true;
 	return true;
 }
 }
 
 
@@ -3057,7 +3057,7 @@ void parse_file(Parser *p, AstFile *f) {
 
 
 	f->decls = parse_stmt_list(f);
 	f->decls = parse_stmt_list(f);
 
 
-	gb_for_array(i, f->decls) {
+	for_array(i, f->decls) {
 		AstNode *node = f->decls[i];
 		AstNode *node = f->decls[i];
 		if (!is_ast_node_decl(node) &&
 		if (!is_ast_node_decl(node) &&
 		    node->kind != AstNode_BadStmt &&
 		    node->kind != AstNode_BadStmt &&
@@ -3118,16 +3118,16 @@ ParseFileError parse_files(Parser *p, char *init_filename) {
 	String init_fullpath = make_string(fullpath_str);
 	String init_fullpath = make_string(fullpath_str);
 	TokenPos init_pos = {};
 	TokenPos init_pos = {};
 	ImportedFile init_imported_file = {init_fullpath, init_fullpath, 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;
 	p->init_fullpath = init_fullpath;
 
 
 	{
 	{
 		String s = get_fullpath_core(gb_heap_allocator(), make_string("_preload.odin"));
 		String s = get_fullpath_core(gb_heap_allocator(), make_string("_preload.odin"));
 		ImportedFile runtime_file = {s, s, init_pos};
 		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];
 		ImportedFile imported_file = p->imports[i];
 		String import_path = imported_file.path;
 		String import_path = imported_file.path;
 		String import_rel_path = imported_file.rel_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);
 			gb_mutex_lock(&p->mutex);
 			defer (gb_mutex_unlock(&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;
 	}
 	}
 
 
 
 

+ 16 - 16
src/printer.cpp

@@ -29,7 +29,7 @@ void print_ast(AstNode *node, isize indent) {
 		print_indent(indent);
 		print_indent(indent);
 		gb_printf("(compound lit)\n");
 		gb_printf("(compound lit)\n");
 		print_ast(node->CompoundLit.type, indent+1);
 		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);
 			print_ast(node->CompoundLit.elems[i], indent+1);
 		}
 		}
 		break;
 		break;
@@ -58,7 +58,7 @@ void print_ast(AstNode *node, isize indent) {
 		print_indent(indent);
 		print_indent(indent);
 		gb_printf("(call)\n");
 		gb_printf("(call)\n");
 		print_ast(node->CallExpr.proc, indent+1);
 		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);
 			print_ast(node->CallExpr.args[i], indent+1);
 		}
 		}
 		break;
 		break;
@@ -92,17 +92,17 @@ void print_ast(AstNode *node, isize indent) {
 	case AstNode_AssignStmt:
 	case AstNode_AssignStmt:
 		print_indent(indent);
 		print_indent(indent);
 		print_token(node->AssignStmt.op);
 		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);
 			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);
 			print_ast(node->AssignStmt.rhs[i], indent+1);
 		}
 		}
 		break;
 		break;
 	case AstNode_BlockStmt:
 	case AstNode_BlockStmt:
 		print_indent(indent);
 		print_indent(indent);
 		gb_printf("(block)\n");
 		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);
 			print_ast(node->BlockStmt.stmts[i], indent+1);
 		}
 		}
 		break;
 		break;
@@ -121,7 +121,7 @@ void print_ast(AstNode *node, isize indent) {
 	case AstNode_ReturnStmt:
 	case AstNode_ReturnStmt:
 		print_indent(indent);
 		print_indent(indent);
 		gb_printf("(return)\n");
 		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);
 			print_ast(node->ReturnStmt.results[i], indent+1);
 		}
 		}
 		break;
 		break;
@@ -143,22 +143,22 @@ void print_ast(AstNode *node, isize indent) {
 	case AstNode_VarDecl:
 	case AstNode_VarDecl:
 		print_indent(indent);
 		print_indent(indent);
 		gb_printf("(decl:var)\n");
 		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.names[i], indent+1);
 		}
 		}
 		print_ast(node->VarDecl.type, 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);
 			print_ast(node->VarDecl.values[i], indent+1);
 		}
 		}
 		break;
 		break;
 	case AstNode_ConstDecl:
 	case AstNode_ConstDecl:
 		print_indent(indent);
 		print_indent(indent);
 		gb_printf("(decl:const)\n");
 		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.names[i], indent+1);
 		}
 		}
 		print_ast(node->VarDecl.type, 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);
 			print_ast(node->VarDecl.values[i], indent+1);
 		}
 		}
 		break;
 		break;
@@ -178,20 +178,20 @@ void print_ast(AstNode *node, isize indent) {
 
 
 	case AstNode_ProcType:
 	case AstNode_ProcType:
 		print_indent(indent);
 		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);
 			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);
 			print_indent(indent+1);
 			gb_printf("->\n");
 			gb_printf("->\n");
-			gb_for_array(i, node->ProcType.results) {
+			for_array(i, node->ProcType.results) {
 				print_ast(node->ProcType.results[i], indent+1);
 				print_ast(node->ProcType.results[i], indent+1);
 			}
 			}
 		}
 		}
 		break;
 		break;
 	case AstNode_Parameter:
 	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.names[i], indent+1);
 		}
 		}
 		print_ast(node->Parameter.type, indent);
 		print_ast(node->Parameter.type, indent);
@@ -210,7 +210,7 @@ void print_ast(AstNode *node, isize indent) {
 	case AstNode_StructType:
 	case AstNode_StructType:
 		print_indent(indent);
 		print_indent(indent);
 		gb_printf("(struct)\n");
 		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);
 			print_ast(node->StructType.decls[i], indent+1);
 		}
 		}
 		break;
 		break;

+ 6 - 8
src/tokenizer.cpp

@@ -292,7 +292,7 @@ struct Tokenizer {
 	isize line_count;
 	isize line_count;
 
 
 	isize error_count;
 	isize error_count;
-	gbArray(String) allocated_strings;
+	Array<String> allocated_strings;
 };
 };
 
 
 
 
@@ -368,7 +368,7 @@ TokenizerInitError init_tokenizer(Tokenizer *t, String fullpath) {
 		if (t->curr_rune == GB_RUNE_BOM)
 		if (t->curr_rune == GB_RUNE_BOM)
 			advance_to_next_rune(t); // Ignore BOM at file beginning
 			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;
 		return TokenizerInit_None;
 	}
 	}
@@ -397,12 +397,10 @@ gb_inline void destroy_tokenizer(Tokenizer *t) {
 	if (t->start != NULL) {
 	if (t->start != NULL) {
 		gb_free(gb_heap_allocator(), t->start);
 		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) {
 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);
 			i32 success = unquote_string(gb_heap_allocator(), &token.string);
 			if (success > 0) {
 			if (success > 0) {
 				if (success == 2) {
 				if (success == 2) {
-					gb_array_append(t->allocated_strings, token.string);
+					array_add(&t->allocated_strings, token.string);
 				}
 				}
 				return token;
 				return token;
 			} else {
 			} else {