From 9b61adb97dd78e1cf04ad410e72166f684f97925 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Thu, 8 Jun 2017 12:03:40 +0100 Subject: Build as C++ --- src/entity.cpp | 282 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 src/entity.cpp (limited to 'src/entity.cpp') diff --git a/src/entity.cpp b/src/entity.cpp new file mode 100644 index 000000000..f029685c3 --- /dev/null +++ b/src/entity.cpp @@ -0,0 +1,282 @@ +typedef struct Scope Scope; +typedef struct Checker Checker; +typedef struct Type Type; +typedef struct DeclInfo DeclInfo; +// typedef enum BuiltinProcId BuiltinProcId; + + +#define ENTITY_KINDS \ + ENTITY_KIND(Invalid) \ + ENTITY_KIND(Constant) \ + ENTITY_KIND(Variable) \ + ENTITY_KIND(TypeName) \ + ENTITY_KIND(Procedure) \ + ENTITY_KIND(Builtin) \ + ENTITY_KIND(ImportName) \ + ENTITY_KIND(LibraryName) \ + ENTITY_KIND(TypeAlias) \ + ENTITY_KIND(ProcedureAlias) \ + ENTITY_KIND(Nil) \ + ENTITY_KIND(Label) + +typedef enum EntityKind { +#define ENTITY_KIND(k) GB_JOIN2(Entity_, k), + ENTITY_KINDS +#undef ENTITY_KIND + Entity_Count, +} EntityKind; + +String const entity_strings[] = { +#define ENTITY_KIND(k) {cast(u8 *)#k, gb_size_of(#k)-1}, + ENTITY_KINDS +#undef ENTITY_KIND +}; + +typedef enum EntityFlag { + EntityFlag_Visited = 1<<0, + EntityFlag_Used = 1<<1, + EntityFlag_Using = 1<<2, + EntityFlag_Field = 1<<3, + EntityFlag_Param = 1<<4, + EntityFlag_VectorElem = 1<<5, + EntityFlag_Ellipsis = 1<<6, + EntityFlag_NoAlias = 1<<7, + EntityFlag_TypeField = 1<<8, + EntityFlag_Value = 1<<9, + EntityFlag_Sret = 1<<10, + EntityFlag_BitFieldValue = 1<<11, +} EntityFlag; + +// Zero value means the overloading process is not yet done +typedef enum OverloadKind { + Overload_Unknown, + Overload_No, + Overload_Yes, +} OverloadKind; + +typedef enum EntityAliasKind { + EntityAlias_Invalid, + EntityAlias_Type, + EntityAlias_Entity, +} EntityAliasKind; + + +// An Entity is a named "thing" in the language +typedef struct Entity Entity; +struct Entity { + EntityKind kind; + u64 id; + u32 flags; + Token token; + Scope * scope; + Type * type; + AstNode * identifier; // Can be NULL + DeclInfo * parent_proc_decl; // NULL if in file/global scope + + // TODO(bill): Cleanup how `using` works for entities + Entity * using_parent; + AstNode * using_expr; + + union { + struct { + ExactValue value; + } Constant; + struct { + i32 field_index; + i32 field_src_index; + bool is_immutable; + bool is_thread_local; + } Variable; + struct { + bool is_type_alias; + } TypeName; + struct { + bool is_foreign; + String foreign_name; + Entity * foreign_library; + String link_name; + u64 tags; + OverloadKind overload_kind; + } Procedure; + struct { + i32 id; + } Builtin; + struct { + String path; + String name; + Scope *scope; + bool used; + } ImportName; + struct { + String path; + String name; + bool used; + } LibraryName; + i32 TypeAlias; + struct { + Entity *original; + } ProcedureAlias; + i32 Nil; + struct { + String name; + AstNode *node; + } Label; + }; +}; + +gb_global Entity *e_context = NULL; + +bool is_entity_kind_exported(EntityKind kind) { + switch (kind) { + case Entity_Builtin: + case Entity_ImportName: + case Entity_LibraryName: + case Entity_Nil: + return false; + } + return true; +} + +bool is_entity_exported(Entity *e) { + // TODO(bill): Determine the actual exportation rules for imports of entities + GB_ASSERT(e != NULL); + if (!is_entity_kind_exported(e->kind)) { + return false; + } + + String name = e->token.string; + if (name.len == 0) { + return false; + } + return name.text[0] != '_'; +} + +gb_global u64 global_entity_id = 0; + +Entity *alloc_entity(gbAllocator a, EntityKind kind, Scope *scope, Token token, Type *type) { + Entity *entity = gb_alloc_item(a, Entity); + entity->kind = kind; + entity->scope = scope; + entity->token = token; + entity->type = type; + entity->id = ++global_entity_id; + return entity; +} + +Entity *make_entity_variable(gbAllocator a, Scope *scope, Token token, Type *type, bool is_immutable) { + Entity *entity = alloc_entity(a, Entity_Variable, scope, token, type); + entity->Variable.is_immutable = is_immutable; + return entity; +} + +Entity *make_entity_using_variable(gbAllocator a, Entity *parent, Token token, Type *type) { + GB_ASSERT(parent != NULL); + token.pos = parent->token.pos; + Entity *entity = alloc_entity(a, Entity_Variable, parent->scope, token, type); + entity->using_parent = parent; + entity->parent_proc_decl = parent->parent_proc_decl; + entity->flags |= EntityFlag_Using; + return entity; +} + + +Entity *make_entity_constant(gbAllocator a, Scope *scope, Token token, Type *type, ExactValue value) { + Entity *entity = alloc_entity(a, Entity_Constant, scope, token, type); + entity->Constant.value = value; + return entity; +} + +Entity *make_entity_type_name(gbAllocator a, Scope *scope, Token token, Type *type) { + Entity *entity = alloc_entity(a, Entity_TypeName, scope, token, type); + return entity; +} + +Entity *make_entity_param(gbAllocator a, Scope *scope, Token token, Type *type, bool is_using, bool is_immutable) { + Entity *entity = make_entity_variable(a, scope, token, type, is_immutable); + entity->flags |= EntityFlag_Used; + if (is_using) entity->flags |= EntityFlag_Using; + entity->flags |= EntityFlag_Param; + return entity; +} + +Entity *make_entity_field(gbAllocator a, Scope *scope, Token token, Type *type, bool is_using, i32 field_src_index) { + Entity *entity = make_entity_variable(a, scope, token, type, false); + entity->Variable.field_src_index = field_src_index; + entity->Variable.field_index = field_src_index; + if (is_using) entity->flags |= EntityFlag_Using; + entity->flags |= EntityFlag_Field; + return entity; +} + +Entity *make_entity_vector_elem(gbAllocator a, Scope *scope, Token token, Type *type, i32 field_src_index) { + Entity *entity = make_entity_variable(a, scope, token, type, false); + entity->Variable.field_src_index = field_src_index; + entity->Variable.field_index = field_src_index; + entity->flags |= EntityFlag_Field; + entity->flags |= EntityFlag_VectorElem; + return entity; +} + +Entity *make_entity_procedure(gbAllocator a, Scope *scope, Token token, Type *signature_type, u64 tags) { + Entity *entity = alloc_entity(a, Entity_Procedure, scope, token, signature_type); + entity->Procedure.tags = tags; + return entity; +} + +Entity *make_entity_builtin(gbAllocator a, Scope *scope, Token token, Type *type, i32 id) { + Entity *entity = alloc_entity(a, Entity_Builtin, scope, token, type); + entity->Builtin.id = id; + return entity; +} + +Entity *make_entity_import_name(gbAllocator a, Scope *scope, Token token, Type *type, + String path, String name, Scope *import_scope) { + Entity *entity = alloc_entity(a, Entity_ImportName, scope, token, type); + entity->ImportName.path = path; + entity->ImportName.name = name; + entity->ImportName.scope = import_scope; + return entity; +} + +Entity *make_entity_library_name(gbAllocator a, Scope *scope, Token token, Type *type, + String path, String name) { + Entity *entity = alloc_entity(a, Entity_LibraryName, scope, token, type); + entity->LibraryName.path = path; + entity->LibraryName.name = name; + return entity; +} + +Entity *make_entity_type_alias(gbAllocator a, Scope *scope, Token token, Type *type) { + Entity *entity = alloc_entity(a, Entity_TypeAlias, scope, token, type); + return entity; +} +Entity *make_entity_procedure_alias(gbAllocator a, Scope *scope, Token token, Entity *original) { + GB_ASSERT(original != NULL); + Entity *entity = alloc_entity(a, Entity_ProcedureAlias, scope, token, original->type); + entity->ProcedureAlias.original = original; + return entity; +} + + + + +Entity *make_entity_nil(gbAllocator a, String name, Type *type) { + Token token = make_token_ident(name); + Entity *entity = alloc_entity(a, Entity_Nil, NULL, token, type); + return entity; +} + +Entity *make_entity_label(gbAllocator a, Scope *scope, Token token, Type *type, + AstNode *node) { + Entity *entity = alloc_entity(a, Entity_Label, scope, token, type); + entity->Label.node = node; + return entity; +} + + + +Entity *make_entity_dummy_variable(gbAllocator a, Scope *scope, Token token) { + token.string = str_lit("_"); + return make_entity_variable(a, scope, token, NULL, false); +} + -- cgit v1.2.3 From 13deb4706c37acbababc6f60a1b6ec58c630a3f5 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Thu, 8 Jun 2017 12:37:07 +0100 Subject: Update `String` to use overloading --- src/build_settings.cpp | 26 ++++++++-------- src/check_decl.cpp | 4 +-- src/check_expr.cpp | 58 ++++++++++++++++++------------------ src/check_stmt.cpp | 14 ++++----- src/checker.cpp | 24 +++++++-------- src/entity.cpp | 2 +- src/exact_value.cpp | 4 ++- src/integer128.cpp | 8 ++--- src/ir.cpp | 22 +++++++------- src/ir_print.cpp | 8 ++--- src/main.cpp | 18 ++++------- src/map.cpp | 2 +- src/parser.cpp | 80 ++++++++++++++++++++++++------------------------- src/ssa.cpp | 16 +++++----- src/string.cpp | 81 +++++++++++++++++++++++++++++++++++--------------- src/tokenizer.cpp | 2 +- src/types.cpp | 30 +++++++++---------- 17 files changed, 213 insertions(+), 186 deletions(-) (limited to 'src/entity.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index 0ba38e30f..1229c466c 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -65,7 +65,7 @@ String odin_root_dir(void) { GetModuleFileNameW(NULL, text, len); path = string16_to_string(heap_allocator(), make_string16(text, len)); for (i = path.len-1; i >= 0; i--) { - u8 c = path.text[i]; + u8 c = path[i]; if (c == '/' || c == '\\') { break; } @@ -118,7 +118,7 @@ String odin_root_dir(void) { path = make_string(text, len); for (i = path.len-1; i >= 0; i--) { - u8 c = path.text[i]; + u8 c = path[i]; if (c == '/' || c == '\\') { break; } @@ -175,7 +175,7 @@ String odin_root_dir(void) { path = make_string(text, len); for (i = path.len-1; i >= 0; i--) { - u8 c = path.text[i]; + u8 c = path[i]; if (c == '/' || c == '\\') { break; } @@ -200,10 +200,10 @@ String path_to_fullpath(gbAllocator a, String s) { String16 string16 = string_to_string16(string_buffer_allocator, s); String result = {0}; - DWORD len = GetFullPathNameW(string16.text, 0, NULL, NULL); + DWORD len = GetFullPathNameW(&string16[0], 0, NULL, NULL); if (len != 0) { wchar_t *text = gb_alloc_array(string_buffer_allocator, wchar_t, len+1); - GetFullPathNameW(string16.text, len, text, NULL); + GetFullPathNameW(&string16[0], len, text, NULL); text[len] = 0; result = string16_to_string(a, make_string16(text, len)); } @@ -212,7 +212,7 @@ String path_to_fullpath(gbAllocator a, String s) { } #elif defined(GB_SYSTEM_OSX) || defined(GB_SYSTEM_UNIX) String path_to_fullpath(gbAllocator a, String s) { - char *p = realpath(cast(char *)s.text, 0); + char *p = realpath(cast(char *)&s[0], 0); if(p == NULL) return make_string_c(""); return make_string_c(p); @@ -229,8 +229,8 @@ String get_fullpath_relative(gbAllocator a, String base_dir, String path) { u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1); isize i = 0; - gb_memmove(str+i, base_dir.text, base_dir.len); i += base_dir.len; - gb_memmove(str+i, path.text, path.len); + gb_memmove(str+i, &base_dir[0], base_dir.len); i += base_dir.len; + gb_memmove(str+i, &path[0], path.len); str[str_len] = '\0'; res = path_to_fullpath(a, make_string(str, str_len)); gb_free(heap_allocator(), str); @@ -247,9 +247,9 @@ String get_fullpath_core(gbAllocator a, String path) { isize str_len = module_dir.len + core_len + path.len; u8 *str = gb_alloc_array(heap_allocator(), u8, str_len+1); - gb_memmove(str, module_dir.text, module_dir.len); + gb_memmove(str, &module_dir[0], module_dir.len); gb_memmove(str+module_dir.len, core, core_len); - gb_memmove(str+module_dir.len+core_len, path.text, path.len); + gb_memmove(str+module_dir.len+core_len, &path[0], path.len); str[str_len] = '\0'; res = path_to_fullpath(a, make_string(str, str_len)); @@ -294,7 +294,7 @@ void init_build_context(void) { // NOTE(zangent): MacOS systems are x64 only, so ld doesn't have // an architecture option. All compilation done on MacOS must be x64. - GB_ASSERT(str_eq(bc->ODIN_ARCH, str_lit("amd64"))); + GB_ASSERT(bc->ODIN_ARCH == "amd64"); #define LINK_FLAG_X64 "" #define LINK_FLAG_X86 "" @@ -311,12 +311,12 @@ void init_build_context(void) { #define LINK_FLAG_X86 "-arch x86" #endif - if (str_eq(bc->ODIN_ARCH, str_lit("amd64"))) { + if (bc->ODIN_ARCH == "amd64") { bc->word_size = 8; bc->max_align = 16; bc->llc_flags = str_lit("-march=x86-64 "); bc->link_flags = str_lit(LINK_FLAG_X64 " "); - } else if (str_eq(bc->ODIN_ARCH, str_lit("x86"))) { + } else if (bc->ODIN_ARCH == "x86") { bc->word_size = 4; bc->max_align = 8; bc->llc_flags = str_lit("-march=x86 "); diff --git a/src/check_decl.cpp b/src/check_decl.cpp index f31434c01..f8c74c0be 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -274,7 +274,7 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) { bool is_require_results = (pd->tags & ProcTag_require_results) != 0; - if (d->scope->is_file && str_eq(e->token.string, str_lit("main"))) { + if (d->scope->is_file && e->token.string == "main") { if (proc_type != NULL) { TypeProc *pt = &proc_type->Proc; if (pt->param_count != 0 || @@ -334,7 +334,7 @@ void check_proc_lit(Checker *c, Entity *e, DeclInfo *d) { String name = foreign_library->Ident.string; Entity *found = scope_lookup_entity(c->context.scope, name); if (found == NULL) { - if (str_eq(name, str_lit("_"))) { + if (name == "_") { error_node(foreign_library, "`_` cannot be used as a value type"); } else { error_node(foreign_library, "Undeclared name: %.*s", LIT(name)); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 0c8bb0ab0..86d0541af 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -427,9 +427,9 @@ isize check_fields(Checker *c, AstNode *node, AstNodeArray decls, Entity *e = make_entity_field(c->allocator, c->context.scope, name_token, type, is_using, cast(i32)field_index); e->identifier = name; - if (str_eq(name_token.string, str_lit("_"))) { + if (name_token.string == "_") { fields[field_index++] = e; - } else if (str_eq(name_token.string, str_lit("__tag"))) { + } else if (name_token.string == "__tag") { error_node(name, "`__tag` is a reserved identifier for fields"); } else { HashKey key = hash_string(name_token.string); @@ -729,7 +729,7 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) { type->Named.type_name = e; add_entity(c, c->context.scope, f->name, e); - if (str_eq(name_token.string, str_lit("_"))) { + if (name_token.string == "_") { error(name_token, "`_` cannot be used a union subtype"); continue; } @@ -857,21 +857,21 @@ void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *nod // NOTE(bill): Skip blank identifiers - if (str_eq(name, str_lit("_"))) { + if (name == "_") { continue; - } else if (str_eq(name, str_lit("count"))) { + } else if (name == "count") { error_node(field, "`count` is a reserved identifier for enumerations"); continue; - } else if (str_eq(name, str_lit("min_value"))) { + } else if (name == "min_value") { error_node(field, "`min_value` is a reserved identifier for enumerations"); continue; - } else if (str_eq(name, str_lit("max_value"))) { + } else if (name == "max_value") { error_node(field, "`max_value` is a reserved identifier for enumerations"); continue; - } else if (str_eq(name, str_lit("names"))) { + } else if (name == "names") { error_node(field, "`names` is a reserved identifier for enumerations"); continue; - }/* else if (str_eq(name, str_lit("base_type"))) { + }/* else if (name == "base_type") { error_node(field, "`base_type` is a reserved identifier for enumerations"); continue; } */ @@ -966,7 +966,7 @@ void check_bit_field_type(Checker *c, Type *bit_field_type, Type *named_type, As e->flags |= EntityFlag_BitFieldValue; HashKey key = hash_string(name); - if (str_ne(name, str_lit("_")) && + if (name != "_" && map_entity_get(&entity_map, key) != NULL) { error_node(ident, "`%.*s` is already declared in this bit field", LIT(name)); } else { @@ -1164,15 +1164,15 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *_results) { for (isize i = 0; i < variable_index; i++) { String x = variables[i]->token.string; - if (x.len == 0 || str_eq(x, str_lit("_"))) { + if (x.len == 0 || x == "_") { continue; } for (isize j = i+1; j < variable_index; j++) { String y = variables[j]->token.string; - if (y.len == 0 || str_eq(y, str_lit("_"))) { + if (y.len == 0 || y == "_") { continue; } - if (str_eq(x, y)) { + if (x == y) { error(variables[j]->token, "Duplicate return value name `%.*s`", LIT(y)); } } @@ -1187,7 +1187,7 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *_results) { Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) { Type *new_type = original_type; - if (str_eq(build_context.ODIN_OS, str_lit("windows"))) { + if (build_context.ODIN_OS == "windows") { // NOTE(bill): Changing the passing parameter value type is to match C's ABI // IMPORTANT TODO(bill): This only matches the ABI on MSVC at the moment // SEE: https://msdn.microsoft.com/en-us/library/zthk2dkh.aspx @@ -1223,7 +1223,7 @@ Type *type_to_abi_compat_param_type(gbAllocator a, Type *original_type) { } } break; } - } else if (str_eq(build_context.ODIN_OS, str_lit("linux"))) { + } else if (build_context.ODIN_OS == "linux") { Type *bt = core_type(original_type); switch (bt->kind) { // Okay to pass by value @@ -1277,7 +1277,7 @@ Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type) { - if (str_eq(build_context.ODIN_OS, str_lit("windows"))) { + if (build_context.ODIN_OS == "windows") { Type *bt = core_type(reduce_tuple_to_single_type(original_type)); // NOTE(bill): This is just reversed engineered from LLVM IR output switch (bt->kind) { @@ -1301,7 +1301,7 @@ Type *type_to_abi_compat_result_type(gbAllocator a, Type *original_type) { } } break; } - } else if (str_eq(build_context.ODIN_OS, str_lit("linux"))) { + } else if (build_context.ODIN_OS == "linux") { } else { // IMPORTANT TODO(bill): figure out the ABI settings for Linux, OSX etc. for @@ -1330,7 +1330,7 @@ bool abi_compat_return_by_value(gbAllocator a, ProcCallingConvention cc, Type *a } - if (str_eq(build_context.ODIN_OS, str_lit("windows"))) { + if (build_context.ODIN_OS == "windows") { i64 size = 8*type_size_of(a, abi_return_type); switch (size) { case 0: @@ -1388,7 +1388,7 @@ Entity *check_ident(Checker *c, Operand *o, AstNode *n, Type *named_type, Type * Entity *e = scope_lookup_entity(c->context.scope, name); if (e == NULL) { - if (str_eq(name, str_lit("_"))) { + if (name == "_") { error(n->Ident, "`_` cannot be used as a value type"); } else { error(n->Ident, "Undeclared name: %.*s", LIT(name)); @@ -1959,7 +1959,7 @@ Type *check_type_extra(Checker *c, AstNode *e, Type *named_type) { } if (is_type_typed(type)) { - add_type_and_value(&c->info, e, Addressing_Type, type, ExactValue{}); + add_type_and_value(&c->info, e, Addressing_Type, type, empty_exact_value); } else { gbString name = type_to_string(type); error_node(e, "Invalid type definition of %s", name); @@ -3016,7 +3016,7 @@ void convert_untyped_error(Checker *c, Operand *operand, Type *target_type) { if (operand->mode == Addressing_Constant) { if (i128_eq(operand->value.value_integer, I128_ZERO)) { - if (str_ne(make_string_c(expr_str), str_lit("nil"))) { // HACK NOTE(bill): Just in case + if (make_string_c(expr_str) != "nil") { // HACK NOTE(bill): Just in case // NOTE(bill): Doesn't matter what the type is as it's still zero in the union extra_text = " - Did you want `nil`?"; } @@ -5213,7 +5213,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t case Token_Rune: t = t_untyped_rune; break; case Token_Imag: { String s = bl->string; - Rune r = s.text[s.len-1]; + Rune r = s[s.len-1]; switch (r) { case 'i': t = t_untyped_complex; break; } @@ -5226,13 +5226,13 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t case_end; case_ast_node(bd, BasicDirective, node); - if (str_eq(bd->name, str_lit("file"))) { + if (bd->name == "file") { o->type = t_untyped_string; o->value = exact_value_string(bd->token.pos.file); - } else if (str_eq(bd->name, str_lit("line"))) { + } else if (bd->name == "line") { o->type = t_untyped_integer; o->value = exact_value_i64(bd->token.pos.line); - } else if (str_eq(bd->name, str_lit("procedure"))) { + } else if (bd->name == "procedure") { if (c->proc_stack.count == 0) { error_node(node, "#procedure may only be used within procedures"); o->type = t_untyped_string; @@ -5448,7 +5448,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t bool all_fields_are_blank = true; for (isize i = 0; i < t->Record.field_count; i++) { Entity *field = t->Record.fields_in_src_order[i]; - if (str_ne(field->token.string, str_lit("_"))) { + if (field->token.string != "_") { all_fields_are_blank = false; break; } @@ -5466,7 +5466,7 @@ ExprKind check_expr_base_internal(Checker *c, Operand *o, AstNode *node, Type *t } Entity *field = t->Record.fields_in_src_order[index]; - if (!all_fields_are_blank && str_eq(field->token.string, str_lit("_"))) { + if (!all_fields_are_blank && field->token.string == "_") { // NOTE(bill): Ignore blank identifiers continue; } @@ -6153,7 +6153,7 @@ gbString write_record_fields_to_string(gbString str, AstNodeArray params) { gbString string_append_token(gbString str, Token token) { if (token.string.len > 0) { - return gb_string_append_length(str, token.string.text, token.string.len); + return gb_string_append_length(str, &token.string[0], token.string.len); } return str; } @@ -6186,7 +6186,7 @@ gbString write_expr_to_string(gbString str, AstNode *node) { case_ast_node(bd, BasicDirective, node); str = gb_string_appendc(str, "#"); - str = gb_string_append_length(str, bd->name.text, bd->name.len); + str = gb_string_append_length(str, &bd->name[0], bd->name.len); case_end; case_ast_node(pl, ProcLit, node); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 6031c9120..187dab3b7 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -187,7 +187,7 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) { // NOTE(bill): Ignore assignments to `_` if (node->kind == AstNode_Ident && - str_eq(node->Ident.string, str_lit("_"))) { + node->Ident.string == "_") { add_entity_definition(&c->info, node, NULL); check_assignment(c, rhs, NULL, str_lit("assignment to `_` identifier")); if (rhs->mode == Addressing_Invalid) { @@ -434,7 +434,7 @@ void check_label(Checker *c, AstNode *label) { return; } String name = l->name->Ident.string; - if (str_eq(name, str_lit("_"))) { + if (name == "_") { error_node(l->name, "A label's name cannot be a blank identifier"); return; } @@ -449,7 +449,7 @@ void check_label(Checker *c, AstNode *label) { bool ok = true; for_array(i, c->context.decl->labels) { BlockLabel bl = c->context.decl->labels.e[i]; - if (str_eq(bl.name, name)) { + if (bl.name == name) { error_node(label, "Duplicate label with the name `%.*s`", LIT(name)); ok = false; break; @@ -943,10 +943,10 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { } if (x.mode != Addressing_Constant) { - x.value = ExactValue{}; + x.value = empty_exact_value; } if (y.mode != Addressing_Constant) { - y.value = ExactValue{}; + y.value = empty_exact_value; } @@ -1032,7 +1032,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { String str = token.string; Entity *found = NULL; - if (str_ne(str, str_lit("_"))) { + if (str != "_") { found = current_scope_lookup_entity(c->context.scope, str); } if (found == NULL) { @@ -1564,7 +1564,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { String str = token.string; Entity *found = NULL; // NOTE(bill): Ignore assignments to `_` - if (str_ne(str, str_lit("_"))) { + if (str != "_") { found = current_scope_lookup_entity(c->context.scope, str); } if (found == NULL) { diff --git a/src/checker.cpp b/src/checker.cpp index 9477dccb2..4922dd548 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -867,7 +867,7 @@ void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity) { GB_ASSERT(identifier != NULL); if (identifier->kind == AstNode_Ident) { - if (str_eq(identifier->Ident.string, str_lit("_"))) { + if (identifier->Ident.string == "_") { return; } HashKey key = hash_pointer(identifier); @@ -879,7 +879,7 @@ void add_entity_definition(CheckerInfo *i, AstNode *identifier, Entity *entity) bool add_entity(Checker *c, Scope *scope, AstNode *identifier, Entity *entity) { String name = entity->token.string; - if (!str_eq(name, str_lit("_"))) { + if (name != "_") { Entity *ie = scope_insert_entity(scope, entity); if (ie) { TokenPos pos = ie->token.pos; @@ -929,7 +929,7 @@ void add_entity_use(Checker *c, AstNode *identifier, Entity *entity) { void add_entity_and_decl_info(Checker *c, AstNode *identifier, Entity *e, DeclInfo *d) { GB_ASSERT(identifier->kind == AstNode_Ident); GB_ASSERT(e != NULL && d != NULL); - GB_ASSERT(str_eq(identifier->Ident.string, e->token.string)); + GB_ASSERT(identifier->Ident.string == e->token.string); add_entity(c, e->scope, identifier, e); map_decl_info_set(&c->info.entities, hash_pointer(e), d); } @@ -1580,7 +1580,7 @@ void check_collect_entities(Checker *c, AstNodeArray nodes, bool is_file_scope) d->proc_lit = up_init; d->type_expr = vd->type; } else { - e = make_entity_constant(c->allocator, d->scope, name->Ident, NULL, ExactValue{}); + e = make_entity_constant(c->allocator, d->scope, name->Ident, NULL, empty_exact_value); d->type_expr = vd->type; d->init_expr = init; } @@ -1678,12 +1678,12 @@ void check_all_global_entities(Checker *c) { continue; } - if (e->kind != Entity_Procedure && str_eq(e->token.string, str_lit("main"))) { + if (e->kind != Entity_Procedure && e->token.string == "main") { if (e->scope->is_init) { error(e->token, "`main` is reserved as the entry point procedure in the initial scope"); continue; } - } else if (e->scope->is_global && str_eq(e->token.string, str_lit("main"))) { + } else if (e->scope->is_global && e->token.string == "main") { error(e->token, "`main` is reserved as the entry point procedure in the initial scope"); continue; } @@ -1745,7 +1745,7 @@ String path_to_entity_name(String name, String fullpath) { isize slash = 0; isize dot = 0; for (isize i = filename.len-1; i >= 0; i--) { - u8 c = filename.text[i]; + u8 c = filename[i]; if (c == '/' || c == '\\') { break; } @@ -1757,7 +1757,7 @@ String path_to_entity_name(String name, String fullpath) { dot = filename.len; while (dot --> 0) { - u8 c = filename.text[dot]; + u8 c = filename[dot]; if (c == '.') { break; } @@ -1932,7 +1932,7 @@ void check_import_entities(Checker *c, MapScope *file_scopes) { scope->has_been_imported = true; - if (str_eq(id->import_name.string, str_lit("."))) { + if (id->import_name.string == ".") { // NOTE(bill): Add imported entities to this file's scope for_array(elem_index, scope->elements.entries) { Entity *e = scope->elements.entries.e[elem_index].value; @@ -1958,7 +1958,7 @@ void check_import_entities(Checker *c, MapScope *file_scopes) { } } else { String import_name = path_to_entity_name(id->import_name.string, id->fullpath); - if (str_eq(import_name, str_lit("_"))) { + if (import_name == "_") { error(token, "File name, %.*s, cannot be as an import name as it is not a valid identifier", LIT(id->import_name.string)); } else { GB_ASSERT(id->import_name.pos.line != 0); @@ -2010,7 +2010,7 @@ void check_import_entities(Checker *c, MapScope *file_scopes) { String library_name = path_to_entity_name(fl->library_name.string, file_str); - if (str_eq(library_name, str_lit("_"))) { + if (library_name == "_") { error(fl->token, "File name, %.*s, cannot be as a library name as it is not a valid identifier", LIT(fl->library_name.string)); } else { GB_ASSERT(fl->library_name.pos.line != 0); @@ -2035,7 +2035,7 @@ void check_parsed_files(Checker *c) { scope->is_global = f->is_global_scope; scope->is_file = true; scope->file = f; - if (str_eq(f->tokenizer.fullpath, c->parser->init_fullpath)) { + if (f->tokenizer.fullpath == c->parser->init_fullpath) { scope->is_init = true; } diff --git a/src/entity.cpp b/src/entity.cpp index f029685c3..042f6f39f 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -148,7 +148,7 @@ bool is_entity_exported(Entity *e) { if (name.len == 0) { return false; } - return name.text[0] != '_'; + return name[0] != '_'; } gb_global u64 global_entity_id = 0; diff --git a/src/exact_value.cpp b/src/exact_value.cpp index d8d015d47..2bdf3fdf5 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -36,6 +36,8 @@ typedef struct ExactValue { }; } ExactValue; +gb_global ExactValue const empty_exact_value = {}; + HashKey hash_exact_value(ExactValue v) { return hashing_proc(&v, gb_size_of(ExactValue)); } @@ -191,7 +193,7 @@ ExactValue exact_value_from_basic_literal(Token token) { case Token_Float: return exact_value_float_from_string(token.string); case Token_Imag: { String str = token.string; - Rune last_rune = cast(Rune)str.text[str.len-1]; + Rune last_rune = cast(Rune)str[str.len-1]; str.len--; // Ignore the `i|j|k` f64 imag = float_from_string(str); diff --git a/src/integer128.cpp b/src/integer128.cpp index 7682ae56c..39d834ab3 100644 --- a/src/integer128.cpp +++ b/src/integer128.cpp @@ -109,8 +109,8 @@ u128 u128_from_string(String string) { // TODO(bill): Allow for numbers with underscores in them u64 base = 10; bool has_prefix = false; - if (string.len > 2 && string.text[0] == '0') { - switch (string.text[1]) { + if (string.len > 2 && string[0] == '0') { + switch (string[1]) { case 'b': base = 2; has_prefix = true; break; case 'o': base = 8; has_prefix = true; break; case 'd': base = 10; has_prefix = true; break; @@ -160,8 +160,8 @@ i128 i128_from_string(String string) { // TODO(bill): Allow for numbers with underscores in them u64 base = 10; bool has_prefix = false; - if (string.len > 2 && string.text[0] == '0') { - switch (string.text[1]) { + if (string.len > 2 && string[0] == '0') { + switch (string[1]) { case 'b': base = 2; has_prefix = true; break; case 'o': base = 8; has_prefix = true; break; case 'd': base = 10; has_prefix = true; break; diff --git a/src/ir.cpp b/src/ir.cpp index 5c665bfa8..bab4027ef 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -1399,8 +1399,8 @@ irDebugInfo *ir_add_debug_info_file(irProcedure *proc, AstFile *file) { String directory = filename; isize slash_index = 0; for (isize i = filename.len-1; i >= 0; i--) { - if (filename.text[i] == '\\' || - filename.text[i] == '/') { + if (filename[i] == '\\' || + filename[i] == '/') { break; } slash_index = i; @@ -1612,7 +1612,7 @@ void ir_emit_if(irProcedure *proc, irValue *cond, irBlock *true_block, irBlock * } void ir_emit_startup_runtime(irProcedure *proc) { - GB_ASSERT(proc->parent == NULL && str_eq(proc->name, str_lit("main"))); + GB_ASSERT(proc->parent == NULL && proc->name == "main"); ir_emit(proc, ir_alloc_instr(proc, irInstr_StartupRuntime)); } @@ -4813,7 +4813,7 @@ irAddr ir_build_addr(irProcedure *proc, AstNode *expr) { GB_ASSERT(e->kind == Entity_Variable); GB_ASSERT(e->flags & EntityFlag_TypeField); String name = e->token.string; - if (str_eq(name, str_lit("names"))) { + if (name == "names") { irValue *ti_ptr = ir_type_info(proc, type); irValue *names_ptr = NULL; @@ -6733,8 +6733,8 @@ void ir_begin_procedure_body(irProcedure *proc) { Entity *e = params->variables[i]; Type *abi_type = proc->type->Proc.abi_compat_params[i]; - if (!str_eq(e->token.string, str_lit("")) && - !str_eq(e->token.string, str_lit("_"))) { + if (e->token.string != "" && + e->token.string != "_") { irValue *param = ir_add_param(proc, e, name, abi_type); array_add(&proc->params, param); } @@ -6764,7 +6764,7 @@ void ir_end_procedure_body(irProcedure *proc) { void ir_insert_code_before_proc(irProcedure* proc, irProcedure *parent) { if (parent == NULL) { - if (str_eq(proc->name, str_lit("main"))) { + if (proc->name == "main") { ir_emit_startup_runtime(proc); } } @@ -7101,15 +7101,15 @@ void ir_gen_tree(irGen *s) { if (e->kind == Entity_Variable) { global_variable_max_count++; } else if (e->kind == Entity_Procedure && !e->scope->is_global) { - if (e->scope->is_init && str_eq(name, str_lit("main"))) { + if (e->scope->is_init && name == "main") { entry_point = e; } if ((e->Procedure.tags & ProcTag_export) != 0 || (e->Procedure.link_name.len > 0) || (e->scope->is_file && e->Procedure.link_name.len > 0)) { - if (!has_dll_main && str_eq(name, str_lit("DllMain"))) { + if (!has_dll_main && name == "DllMain") { has_dll_main = true; - } else if (!has_win_main && str_eq(name, str_lit("WinMain"))) { + } else if (!has_win_main && name == "WinMain") { has_win_main = true; } } @@ -7146,7 +7146,7 @@ void ir_gen_tree(irGen *s) { if (e->kind == Entity_Procedure && (e->Procedure.tags & ProcTag_export) != 0) { } else if (e->kind == Entity_Procedure && e->Procedure.link_name.len > 0) { // Handle later - } else if (scope->is_init && e->kind == Entity_Procedure && str_eq(name, str_lit("main"))) { + } else if (scope->is_init && e->kind == Entity_Procedure && name == "main") { } else { name = ir_mangle_name(s, e->token.pos.file, e); } diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 2a4e79996..5bbe83e05 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -81,7 +81,7 @@ bool ir_valid_char(u8 c) { void ir_print_escape_string(irFileBuffer *f, String name, bool print_quotes, bool prefix_with_dot) { isize extra = 0; for (isize i = 0; i < name.len; i++) { - u8 c = name.text[i]; + u8 c = name[i]; if (!ir_valid_char(c)) { extra += 2; } @@ -111,7 +111,7 @@ void ir_print_escape_string(irFileBuffer *f, String name, bool print_quotes, boo } for (isize i = 0; i < name.len; i++) { - u8 c = name.text[i]; + u8 c = name[i]; if (ir_valid_char(c)) { buf[j++] = c; } else { @@ -1500,8 +1500,8 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) { ir_fprintf(f, " noalias"); } if (proc->body != NULL) { - if (!str_eq(e->token.string, str_lit("")) && - !str_eq(e->token.string, str_lit("_"))) { + if (e->token.string != "" && + e->token.string != "_") { ir_fprintf(f, " "); ir_print_encoded_local(f, e->token.string); } else { diff --git a/src/main.cpp b/src/main.cpp index 0e2bf2650..296a9e921 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,3 @@ -#if defined(__cplusplus) -extern "C" { -#endif - #define USE_CUSTOM_BACKEND false #include "common.cpp" @@ -154,27 +150,27 @@ int main(int argc, char **argv) { char *init_filename = NULL; bool run_output = false; String arg1 = make_string_c(argv[1]); - if (str_eq(arg1, str_lit("run"))) { + if (arg1 == "run") { if (argc != 3) { usage(argv[0]); return 1; } init_filename = argv[2]; run_output = true; - } else if (str_eq(arg1, str_lit("build_dll"))) { + } else if (arg1 == "build_dll") { if (argc != 3) { usage(argv[0]); return 1; } init_filename = argv[2]; build_context.is_dll = true; - } else if (str_eq(arg1, str_lit("build"))) { + } else if (arg1 == "build") { if (argc != 3) { usage(argv[0]); return 1; } init_filename = argv[2]; - } else if (str_eq(arg1, str_lit("version"))) { + } else if (arg1 == "version") { gb_printf("%s version %.*s\n", argv[0], LIT(build_context.ODIN_VERSION)); return 0; } else { @@ -382,7 +378,7 @@ int main(int argc, char **argv) { // without having to implement any new syntax specifically for MacOS. #if defined(GB_SYSTEM_OSX) isize len; - if(lib.len > 2 && lib.text[0] == '-' && lib.text[1] == 'f') { + if(lib.len > 2 && lib[0] == '-' && lib[1] == 'f') { len = gb_snprintf(lib_str_buf, gb_size_of(lib_str_buf), " -framework %.*s ", (int)(lib.len) - 2, lib.text + 2); } else { @@ -460,7 +456,3 @@ int main(int argc, char **argv) { return 0; } - -#if defined(__cplusplus) -} -#endif diff --git a/src/map.cpp b/src/map.cpp index d616490e2..49ca604d0 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -65,7 +65,7 @@ bool hash_key_equal(HashKey a, HashKey b) { // NOTE(bill): If two string's hashes collide, compare the strings themselves if (a.kind == HashKey_String) { if (b.kind == HashKey_String) { - return str_eq(a.string, b.string); + return a.string == b.string; } return false; } diff --git a/src/parser.cpp b/src/parser.cpp index ed87b2cb2..01510343e 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1547,7 +1547,7 @@ bool allow_token(AstFile *f, TokenKind kind) { bool is_blank_ident(String str) { if (str.len == 1) { - return str.text[0] == '_'; + return str[0] == '_'; } return false; } @@ -1605,7 +1605,7 @@ void fix_advance_to_next_stmt(AstFile *f) { Token expect_closing(AstFile *f, TokenKind kind, String context) { if (f->curr_token.kind != kind && f->curr_token.kind == Token_Semicolon && - str_eq(f->curr_token.string, str_lit("\n"))) { + f->curr_token.string == "\n") { error(f->curr_token, "Missing `,` before newline in %.*s", LIT(context)); next_token(f); } @@ -1847,11 +1847,11 @@ void parse_proc_tags(AstFile *f, u64 *tags, AstNode **foreign_library_token, Str String tag_name = te->name.string; #define ELSE_IF_ADD_TAG(name) \ - else if (str_eq(tag_name, str_lit(#name))) { \ + else if (tag_name == #name) { \ check_proc_add_tag(f, tag_expr, tags, ProcTag_##name, tag_name); \ } - if (str_eq(tag_name, str_lit("foreign"))) { + if (tag_name == "foreign") { check_proc_add_tag(f, tag_expr, tags, ProcTag_foreign, tag_name); *foreign_library_token = parse_ident(f); if (f->curr_token.kind == Token_String) { @@ -1863,7 +1863,7 @@ void parse_proc_tags(AstFile *f, u64 *tags, AstNode **foreign_library_token, Str next_token(f); } - } else if (str_eq(tag_name, str_lit("link_name"))) { + } else if (tag_name == "link_name") { check_proc_add_tag(f, tag_expr, tags, ProcTag_link_name, tag_name); if (f->curr_token.kind == Token_String) { *link_name = f->curr_token.string; @@ -1885,25 +1885,25 @@ void parse_proc_tags(AstFile *f, u64 *tags, AstNode **foreign_library_token, Str ELSE_IF_ADD_TAG(no_inline) // ELSE_IF_ADD_TAG(dll_import) // ELSE_IF_ADD_TAG(dll_export) - else if (str_eq(tag_name, str_lit("cc_odin"))) { + else if (tag_name == "cc_odin") { if (cc == ProcCC_Invalid) { cc = ProcCC_Odin; } else { syntax_error_node(tag_expr, "Multiple calling conventions for procedure type"); } - } else if (str_eq(tag_name, str_lit("cc_c"))) { + } else if (tag_name == "cc_c") { if (cc == ProcCC_Invalid) { cc = ProcCC_C; } else { syntax_error_node(tag_expr, "Multiple calling conventions for procedure type"); } - } else if (str_eq(tag_name, str_lit("cc_std"))) { + } else if (tag_name == "cc_std") { if (cc == ProcCC_Invalid) { cc = ProcCC_Std; } else { syntax_error_node(tag_expr, "Multiple calling conventions for procedure type"); } - } else if (str_eq(tag_name, str_lit("cc_fast"))) { + } else if (tag_name == "cc_fast") { if (cc == ProcCC_Invalid) { cc = ProcCC_Fast; } else { @@ -2025,7 +2025,7 @@ AstNode *parse_operand(AstFile *f, bool lhs) { case Token_Hash: { Token token = expect_token(f, Token_Hash); Token name = expect_token(f, Token_Ident); - if (str_eq(name.string, str_lit("run"))) { + if (name.string == "run") { AstNode *expr = parse_expr(f, false); operand = ast_run_expr(f, token, name, expr); if (unparen_expr(expr)->kind != AstNode_CallExpr) { @@ -2033,11 +2033,11 @@ AstNode *parse_operand(AstFile *f, bool lhs) { operand = ast_bad_expr(f, token, f->curr_token); } warning(token, "#run is not yet implemented"); - } else if (str_eq(name.string, str_lit("file"))) { return ast_basic_directive(f, token, name.string); - } else if (str_eq(name.string, str_lit("line"))) { return ast_basic_directive(f, token, name.string); - } else if (str_eq(name.string, str_lit("procedure"))) { return ast_basic_directive(f, token, name.string); - } else if (str_eq(name.string, str_lit("type"))) { return ast_helper_type(f, token, parse_type(f)); - } else if (!lhs && str_eq(name.string, str_lit("alias"))) { return ast_alias(f, token, parse_expr(f, false)); + } else if (name.string == "file") { return ast_basic_directive(f, token, name.string); + } else if (name.string == "line") { return ast_basic_directive(f, token, name.string); + } else if (name.string == "procedure") { return ast_basic_directive(f, token, name.string); + } else if (name.string == "type") { return ast_helper_type(f, token, parse_type(f)); + } else if (!lhs && name.string == "alias") { return ast_alias(f, token, parse_expr(f, false)); } else { operand = ast_tag_expr(f, token, name, parse_expr(f, false)); } @@ -2721,7 +2721,7 @@ FieldPrefixKind is_token_field_prefix(AstFile *f) { next_token(f); switch (f->curr_token.kind) { case Token_Ident: - if (str_eq(f->curr_token.string, str_lit("no_alias"))) { + if (f->curr_token.string == "no_alias") { return FieldPrefix_NoAlias; } break; @@ -2941,7 +2941,7 @@ AstNode *parse_type_or_ident(AstFile *f) { Token hash_token = expect_token(f, Token_Hash); Token name = expect_token(f, Token_Ident); String tag = name.string; - if (str_eq(tag, str_lit("type"))) { + if (tag == "type") { AstNode *type = parse_type(f); return ast_helper_type(f, hash_token, type); } @@ -3023,17 +3023,17 @@ AstNode *parse_type_or_ident(AstFile *f) { while (allow_token(f, Token_Hash)) { Token tag = expect_token_after(f, Token_Ident, "#"); - if (str_eq(tag.string, str_lit("packed"))) { + if (tag.string == "packed") { if (is_packed) { syntax_error(tag, "Duplicate struct tag `#%.*s`", LIT(tag.string)); } is_packed = true; - } else if (str_eq(tag.string, str_lit("ordered"))) { + } else if (tag.string == "ordered") { if (is_ordered) { syntax_error(tag, "Duplicate struct tag `#%.*s`", LIT(tag.string)); } is_ordered = true; - } else if (str_eq(tag.string, str_lit("align"))) { + } else if (tag.string == "align") { if (align) { syntax_error(tag, "Duplicate struct tag `#%.*s`", LIT(tag.string)); } @@ -3157,7 +3157,7 @@ AstNode *parse_type_or_ident(AstFile *f) { while (allow_token(f, Token_Hash)) { Token tag = expect_token_after(f, Token_Ident, "#"); - if (str_eq(tag.string, str_lit("align"))) { + if (tag.string == "align") { if (align) { syntax_error(tag, "Duplicate bit_field tag `#%.*s`", LIT(tag.string)); } @@ -3687,7 +3687,7 @@ AstNode *parse_stmt(AstFile *f) { Token name = expect_token(f, Token_Ident); String tag = name.string; - if (str_eq(tag, str_lit("import"))) { + if (tag == "import") { AstNode *cond = NULL; Token import_name = {}; @@ -3706,7 +3706,7 @@ AstNode *parse_stmt(AstFile *f) { break; } - if (str_eq(import_name.string, str_lit("_"))) { + if (import_name.string == "_") { syntax_error(import_name, "Illegal #import name: `_`"); } @@ -3724,7 +3724,7 @@ AstNode *parse_stmt(AstFile *f) { } expect_semicolon(f, decl); return decl; - } else if (str_eq(tag, str_lit("load"))) { + } else if (tag == "load") { AstNode *cond = NULL; Token file_path = expect_token_after(f, Token_String, "#load"); Token import_name = file_path; @@ -3743,7 +3743,7 @@ AstNode *parse_stmt(AstFile *f) { } expect_semicolon(f, decl); return decl; - } else if (str_eq(tag, str_lit("shared_global_scope"))) { + } else if (tag == "shared_global_scope") { if (f->curr_proc == NULL) { f->is_global_scope = true; s = ast_empty_stmt(f, f->curr_token); @@ -3753,7 +3753,7 @@ AstNode *parse_stmt(AstFile *f) { } expect_semicolon(f, s); return s; - } else if (str_eq(tag, str_lit("foreign_system_library"))) { + } else if (tag == "foreign_system_library") { AstNode *cond = NULL; Token lib_name = {}; @@ -3767,7 +3767,7 @@ AstNode *parse_stmt(AstFile *f) { break; } - if (str_eq(lib_name.string, str_lit("_"))) { + if (lib_name.string == "_") { syntax_error(lib_name, "Illegal #foreign_library name: `_`"); } Token file_path = expect_token(f, Token_String); @@ -3784,7 +3784,7 @@ AstNode *parse_stmt(AstFile *f) { } expect_semicolon(f, s); return s; - } else if (str_eq(tag, str_lit("foreign_library"))) { + } else if (tag == "foreign_library") { AstNode *cond = NULL; Token lib_name = {}; @@ -3798,7 +3798,7 @@ AstNode *parse_stmt(AstFile *f) { break; } - if (str_eq(lib_name.string, str_lit("_"))) { + if (lib_name.string == "_") { syntax_error(lib_name, "Illegal #foreign_library name: `_`"); } Token file_path = expect_token(f, Token_String); @@ -3815,7 +3815,7 @@ AstNode *parse_stmt(AstFile *f) { } expect_semicolon(f, s); return s; - } else if (str_eq(tag, str_lit("thread_local"))) { + } else if (tag == "thread_local") { AstNode *s = parse_stmt(f); if (s->kind == AstNode_ValueDecl) { @@ -3831,14 +3831,14 @@ AstNode *parse_stmt(AstFile *f) { } syntax_error(token, "`thread_local` may only be applied to a variable declaration"); return ast_bad_stmt(f, token, f->curr_token); - } else if (str_eq(tag, str_lit("bounds_check"))) { + } else if (tag == "bounds_check") { s = parse_stmt(f); s->stmt_state_flags |= StmtStateFlag_bounds_check; if ((s->stmt_state_flags & StmtStateFlag_no_bounds_check) != 0) { syntax_error(token, "#bounds_check and #no_bounds_check cannot be applied together"); } return s; - } else if (str_eq(tag, str_lit("no_bounds_check"))) { + } else if (tag == "no_bounds_check") { s = parse_stmt(f); s->stmt_state_flags |= StmtStateFlag_no_bounds_check; if ((s->stmt_state_flags & StmtStateFlag_bounds_check) != 0) { @@ -3847,7 +3847,7 @@ AstNode *parse_stmt(AstFile *f) { return s; } - if (str_eq(tag, str_lit("include"))) { + if (tag == "include") { syntax_error(token, "#include is not a valid import declaration kind. Use #load instead"); s = ast_bad_stmt(f, token, f->curr_token); } else { @@ -3983,7 +3983,7 @@ bool try_add_import_path(Parser *p, String path, String rel_path, TokenPos pos) for_array(i, p->imports) { String import = p->imports.e[i].path; - if (str_eq(import, path)) { + if (import == path) { return false; } } @@ -4059,7 +4059,7 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, AstNodeArray #if 0 isize colon_pos = -1; for (isize j = 0; j < file_str.len; j++) { - if (file_str.text[j] == ':') { + if (file_str[j] == ':') { colon_pos = j; break; } @@ -4077,12 +4077,12 @@ void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, AstNodeArray } - if (str_eq(collection_name, str_lit("core"))) { + if (collection_name == "core") { String abs_path = get_fullpath_core(allocator, file_str); if (gb_file_exists(cast(char *)abs_path.text)) { // NOTE(bill): This should be null terminated import_file = abs_path; } - } else if (str_eq(collection_name, str_lit("local"))) { + } else if (collection_name == "local") { String rel_path = get_fullpath_relative(allocator, base_dir, file_str); if (gb_file_exists(cast(char *)rel_path.text)) { // NOTE(bill): This should be null terminated import_file = rel_path; @@ -4153,8 +4153,8 @@ void parse_file(Parser *p, AstFile *f) { String filepath = f->tokenizer.fullpath; String base_dir = filepath; for (isize i = filepath.len-1; i >= 0; i--) { - if (base_dir.text[i] == '\\' || - base_dir.text[i] == '/') { + if (base_dir[i] == '\\' || + base_dir[i] == '/') { break; } base_dir.len--; @@ -4202,7 +4202,7 @@ ParseFileError parse_files(Parser *p, char *init_filename) { if (err != ParseFile_None) { if (err == ParseFile_EmptyFile) { - if (str_eq(import_path, init_fullpath)) { + if (import_path == init_fullpath) { gb_printf_err("Initial file is empty - %.*s\n", LIT(init_fullpath)); gb_exit(1); } diff --git a/src/ssa.cpp b/src/ssa.cpp index d1f950858..b6bdb290a 100644 --- a/src/ssa.cpp +++ b/src/ssa.cpp @@ -378,9 +378,9 @@ ssaValue *ssa_const_i64 (ssaProc *p, Type *t, i64 c) { return ssa ssaValue *ssa_const_f32 (ssaProc *p, Type *t, f32 c) { return ssa_const_val(p, ssaOp_Const32F, t, exact_value_float(c)); } ssaValue *ssa_const_f64 (ssaProc *p, Type *t, f64 c) { return ssa_const_val(p, ssaOp_Const64F, t, exact_value_float(c)); } ssaValue *ssa_const_string (ssaProc *p, Type *t, String c) { return ssa_const_val(p, ssaOp_ConstString, t, exact_value_string(c)); } -ssaValue *ssa_const_empty_string(ssaProc *p, Type *t) { return ssa_const_val(p, ssaOp_ConstString, t, ExactValue{}); } +ssaValue *ssa_const_empty_string(ssaProc *p, Type *t) { return ssa_const_val(p, ssaOp_ConstString, t, empty_exact_value); } ssaValue *ssa_const_slice (ssaProc *p, Type *t, ExactValue v) { return ssa_const_val(p, ssaOp_ConstSlice, t, v); } -ssaValue *ssa_const_nil (ssaProc *p, Type *t) { return ssa_const_val(p, ssaOp_ConstNil, t, ExactValue{}); } +ssaValue *ssa_const_nil (ssaProc *p, Type *t) { return ssa_const_val(p, ssaOp_ConstNil, t, empty_exact_value); } ssaValue *ssa_const_int(ssaProc *p, Type *t, i64 c) { switch (8*type_size_of(p->allocator, t)) { @@ -413,7 +413,7 @@ void ssa_reset_value_args(ssaValue *v) { void ssa_reset(ssaValue *v, ssaOp op) { v->op = op; - v->exact_value = ExactValue{}; + v->exact_value = empty_exact_value; ssa_reset_value_args(v); } @@ -1071,7 +1071,7 @@ ssaAddr ssa_build_addr(ssaProc *p, AstNode *expr) { // GB_ASSERT(e->kind == Entity_Variable); // GB_ASSERT(e->flags & EntityFlag_TypeField); // String name = e->token.string; - // if (str_eq(name, str_lit("names"))) { + // if (name == "names") { // ssaValue *ti_ptr = ir_type_info(p, type); // ssaValue *names_ptr = NULL; @@ -2497,15 +2497,15 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) { if (e->kind == Entity_Variable) { global_variable_max_count++; } else if (e->kind == Entity_Procedure && !e->scope->is_global) { - if (e->scope->is_init && str_eq(name, str_lit("main"))) { + if (e->scope->is_init && name == "main") { entry_point = e; } if ((e->Procedure.tags & ProcTag_export) != 0 || (e->Procedure.link_name.len > 0) || (e->scope->is_file && e->Procedure.link_name.len > 0)) { - if (!has_dll_main && str_eq(name, str_lit("DllMain"))) { + if (!has_dll_main && name == "DllMain") { has_dll_main = true; - } else if (!has_win_main && str_eq(name, str_lit("WinMain"))) { + } else if (!has_win_main && name == "WinMain") { has_win_main = true; } } @@ -2536,7 +2536,7 @@ bool ssa_generate(Parser *parser, CheckerInfo *info) { if (e->kind == Entity_Procedure && (e->Procedure.tags & ProcTag_export) != 0) { } else if (e->kind == Entity_Procedure && e->Procedure.link_name.len > 0) { // Handle later - } else if (scope->is_init && e->kind == Entity_Procedure && str_eq(name, str_lit("main"))) { + } else if (scope->is_init && e->kind == Entity_Procedure && name == "main") { } else { name = ssa_mangle_name(&m, e->token.pos.file, e); } diff --git a/src/string.cpp b/src/string.cpp index 3db3c21f4..105e9961b 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -12,6 +12,15 @@ void init_string_buffer_memory(void) { typedef struct String { u8 * text; isize len; + + u8 &operator[](isize i) { + GB_ASSERT(0 <= i && i < len); + return text[i]; + } + u8 const &operator[](isize i) const { + GB_ASSERT(0 <= i && i < len); + return text[i]; + } } String; // NOTE(bill): used for printf style arguments #define LIT(x) ((int)(x).len), (x).text @@ -23,6 +32,14 @@ typedef struct String { typedef struct String16 { wchar_t *text; isize len; + wchar_t &operator[](isize i) { + GB_ASSERT(0 <= i && i < len); + return text[i]; + } + wchar_t const &operator[](isize i) const { + GB_ASSERT(0 <= i && i < len); + return text[i]; + } } String16; @@ -56,8 +73,8 @@ gb_inline bool str_eq_ignore_case(String a, String b) { if (a.len == b.len) { isize i; for (i = 0; i < a.len; i++) { - char x = cast(char)a.text[i]; - char y = cast(char)b.text[i]; + char x = cast(char)a[i]; + char y = cast(char)b[i]; if (gb_char_to_lower(x) != gb_char_to_lower(y)) return false; } @@ -88,16 +105,16 @@ int string_compare(String x, String y) { for (; curr_block < fast; curr_block++) { if (la[curr_block] ^ lb[curr_block]) { for (pos = curr_block*gb_size_of(isize); pos < n; pos++) { - if (x.text[pos] ^ y.text[pos]) { - return cast(int)x.text[pos] - cast(int)y.text[pos]; + if (x[pos] ^ y[pos]) { + return cast(int)x[pos] - cast(int)y[pos]; } } } } for (; offset < n; offset++) { - if (x.text[offset] ^ y.text[offset]) { - return cast(int)x.text[offset] - cast(int)y.text[offset]; + if (x[offset] ^ y[offset]) { + return cast(int)x[offset] - cast(int)y[offset]; } } } @@ -117,13 +134,29 @@ gb_inline bool str_gt(String a, String b) { return string_compare(a, b) > 0; gb_inline bool str_le(String a, String b) { return string_compare(a, b) <= 0; } gb_inline bool str_ge(String a, String b) { return string_compare(a, b) >= 0; } +bool operator == (String a, String b) { return str_eq(a, b); } +bool operator != (String a, String b) { return str_ne(a, b); } +bool operator < (String a, String b) { return str_lt(a, b); } +bool operator > (String a, String b) { return str_gt(a, b); } +bool operator <= (String a, String b) { return str_le(a, b); } +bool operator >= (String a, String b) { return str_ge(a, b); } + +template bool operator == (String a, char const (&b)[N]) { return str_eq(a, make_string(cast(u8 *)b, N-1)); } +template bool operator != (String a, char const (&b)[N]) { return str_ne(a, make_string(cast(u8 *)b, N-1)); } +template bool operator < (String a, char const (&b)[N]) { return str_lt(a, make_string(cast(u8 *)b, N-1)); } +template bool operator > (String a, char const (&b)[N]) { return str_gt(a, make_string(cast(u8 *)b, N-1)); } +template bool operator <= (String a, char const (&b)[N]) { return str_le(a, make_string(cast(u8 *)b, N-1)); } +template bool operator >= (String a, char const (&b)[N]) { return str_ge(a, make_string(cast(u8 *)b, N-1)); } + + + gb_inline bool str_has_prefix(String s, String prefix) { isize i; if (prefix.len < s.len) { return false; } for (i = 0; i < prefix.len; i++) { - if (s.text[i] != prefix.text[i]) { + if (s[i] != prefix[i]) { return false; } } @@ -135,9 +168,9 @@ gb_inline isize string_extension_position(String str) { isize i = str.len; bool seen_dot = false; while (i --> 0) { - if (str.text[i] == GB_PATH_SEPARATOR) + if (str[i] == GB_PATH_SEPARATOR) break; - if (str.text[i] == '.') { + if (str[i] == '.') { dot_pos = i; break; } @@ -147,11 +180,11 @@ gb_inline isize string_extension_position(String str) { } String string_trim_whitespace(String str) { - while (str.len > 0 && rune_is_whitespace(str.text[str.len-1])) { + while (str.len > 0 && rune_is_whitespace(str[str.len-1])) { str.len--; } - while (str.len > 0 && rune_is_whitespace(str.text[0])) { + while (str.len > 0 && rune_is_whitespace(str[0])) { str.text++; str.len--; } @@ -166,7 +199,7 @@ gb_inline bool string_has_extension(String str, String ext) { } isize len = str.len; for (isize i = len-1; i >= 0; i--) { - if (str.text[i] == '.') { + if (str[i] == '.') { break; } len--; @@ -182,7 +215,7 @@ gb_inline bool string_has_extension(String str, String ext) { bool string_contains_char(String s, u8 c) { isize i; for (i = 0; i < s.len; i++) { - if (s.text[i] == c) + if (s[i] == c) return true; } return false; @@ -194,8 +227,8 @@ String filename_from_path(String s) { isize j = 0; s.len = i; for (j = i-1; j >= 0; j--) { - if (s.text[j] == '/' || - s.text[j] == '\\') { + if (s[j] == '/' || + s[j] == '\\') { break; } } @@ -315,18 +348,18 @@ String string16_to_string(gbAllocator a, String16 s) { bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String *tail_string) { u8 c; - if (s.text[0] == quote && + if (s[0] == quote && (quote == '\'' || quote == '"')) { return false; - } else if (s.text[0] >= 0x80) { + } else if (s[0] >= 0x80) { Rune r = -1; isize size = gb_utf8_decode(s.text, s.len, &r); *rune = r; *multiple_bytes = true; *tail_string = make_string(s.text+size, s.len-size); return true; - } else if (s.text[0] != '\\') { - *rune = s.text[0]; + } else if (s[0] != '\\') { + *rune = s[0]; *tail_string = make_string(s.text+1, s.len-1); return true; } @@ -334,7 +367,7 @@ bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String * if (s.len <= 1) { return false; } - c = s.text[1]; + c = s[1]; s = make_string(s.text+2, s.len-2); switch (c) { @@ -372,7 +405,7 @@ bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String * return false; } for (i = 0; i < 2; i++) { - i32 d = gb_digit_to_int(s.text[i]); + i32 d = gb_digit_to_int(s[i]); if (d < 0 || d > 7) { return false; } @@ -400,7 +433,7 @@ bool unquote_char(String s, u8 quote, Rune *rune, bool *multiple_bytes, String * return false; } for (i = 0; i < count; i++) { - i32 d = gb_hex_digit_to_int(s.text[i]); + i32 d = gb_hex_digit_to_int(s[i]); if (d < 0) { return false; } @@ -433,8 +466,8 @@ i32 unquote_string(gbAllocator a, String *s_) { if (n < 2) { return 0; } - quote = s.text[0]; - if (quote != s.text[n-1]) { + quote = s[0]; + if (quote != s[n-1]) { return 0; } s.text += 1; diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 06a527780..5c9809bd1 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -760,7 +760,7 @@ Token tokenizer_get_token(Tokenizer *t) { // NOTE(bill): All keywords are > 1 if (token.string.len > 1) { for (i32 k = Token__KeywordBegin+1; k < Token__KeywordEnd; k++) { - if (str_eq(token.string, token_strings[k])) { + if (token.string == token_strings[k]) { token.kind = cast(TokenKind)k; break; } diff --git a/src/types.cpp b/src/types.cpp index a64e1e79e..41fc1f901 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1025,7 +1025,7 @@ bool are_types_identical(Type *x, Type *y) { if (!are_types_identical(xf->type, yf->type)) { return false; } - if (str_ne(xf->token.string, yf->token.string)) { + if (xf->token.string != yf->token.string) { return false; } bool xf_is_using = (xf->flags&EntityFlag_Using) != 0; @@ -1039,7 +1039,7 @@ bool are_types_identical(Type *x, Type *y) { if (!are_types_identical(x->Record.variants[i]->type, y->Record.variants[i]->type)) { return false; } - if (str_ne(x->Record.variants[i]->token.string, y->Record.variants[i]->token.string)) { + if (x->Record.variants[i]->token.string != y->Record.variants[i]->token.string) { return false; } } @@ -1337,7 +1337,7 @@ gb_global Entity *entity__any_type_info = NULL; Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_name, bool is_type, Selection sel) { GB_ASSERT(type_ != NULL); - if (str_eq(field_name, str_lit("_"))) { + if (field_name == "_") { return empty_selection; } @@ -1362,11 +1362,11 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n entity__any_type_info = make_entity_field(a, NULL, make_token_ident(type_info_str), t_type_info_ptr, false, 1); } - if (str_eq(field_name, data_str)) { + if (field_name == data_str) { selection_add_index(&sel, 0); sel.entity = entity__any_data;; return sel; - } else if (str_eq(field_name, type_info_str)) { + } else if (field_name == type_info_str) { selection_add_index(&sel, 1); sel.entity = entity__any_type_info; return sel; @@ -1382,7 +1382,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n switch (type->Vector.count) { #define _VECTOR_FIELD_CASE(_length, _name) \ case (_length): \ - if (str_eq(field_name, str_lit(_name))) { \ + if (field_name == _name) { \ selection_add_index(&sel, (_length)-1); \ sel.entity = make_entity_vector_elem(a, NULL, make_token_ident(str_lit(_name)), type->Vector.elem, (_length)-1); \ return sel; \ @@ -1403,7 +1403,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n if (is_type) { if (type->kind == Type_Record) { if (type->Record.names != NULL && - str_eq(field_name, str_lit("names"))) { + field_name == "names") { sel.entity = type->Record.names; return sel; } @@ -1415,7 +1415,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n GB_ASSERT(f->kind == Entity_TypeName); String str = f->token.string; - if (str_eq(str, field_name)) { + if (str == field_name) { sel.entity = f; // selection_add_index(&sel, i); return sel; @@ -1424,15 +1424,15 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n } else if (is_type_enum(type)) { // NOTE(bill): These may not have been added yet, so check in case if (type->Record.enum_count != NULL) { - if (str_eq(field_name, str_lit("count"))) { + if (field_name == "count") { sel.entity = type->Record.enum_count; return sel; } - if (str_eq(field_name, str_lit("min_value"))) { + if (field_name == "min_value") { sel.entity = type->Record.enum_min_value; return sel; } - if (str_eq(field_name, str_lit("max_value"))) { + if (field_name == "max_value") { sel.entity = type->Record.enum_max_value; return sel; } @@ -1443,7 +1443,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n GB_ASSERT(f->kind == Entity_Constant); String str = f->token.string; - if (str_eq(field_name, str)) { + if (field_name == str) { sel.entity = f; // selection_add_index(&sel, i); return sel; @@ -1457,7 +1457,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n continue; } String str = f->token.string; - if (str_eq(field_name, str)) { + if (field_name == str) { selection_add_index(&sel, i); // HACK(bill): Leaky memory sel.entity = f; return sel; @@ -1479,7 +1479,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n } } if (type->Record.kind == TypeRecord_Union) { - if (str_eq(field_name, str_lit("__tag"))) { + if (field_name == "__tag") { Entity *e = type->Record.union__tag; GB_ASSERT(e != NULL); selection_add_index(&sel, -1); // HACK(bill): Leaky memory @@ -1496,7 +1496,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n } String str = f->token.string; - if (str_eq(field_name, str)) { + if (field_name == str) { selection_add_index(&sel, i); // HACK(bill): Leaky memory sel.entity = f; return sel; -- cgit v1.2.3 From 2b96be0ae8b74e6081a00d740dfcbe205f76fb22 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Thu, 8 Jun 2017 13:08:39 +0100 Subject: Remove unnecessary `typedef` usage --- src/build_settings.cpp | 4 +- src/check_decl.cpp | 4 +- src/check_expr.cpp | 28 +++--- src/check_stmt.cpp | 14 +-- src/checker.cpp | 73 ++++++++------- src/common.cpp | 2 - src/entity.cpp | 25 +++--- src/exact_value.cpp | 14 +-- src/ir.cpp | 152 +++++++++++++++---------------- src/ir_opt.cpp | 12 +-- src/ir_print.cpp | 4 +- src/parser.cpp | 237 ++++++++++++++++++++++++------------------------- src/ssa.cpp | 58 ++++++------ src/ssa_op.cpp | 1 - src/string.cpp | 8 +- src/timings.cpp | 8 +- src/tokenizer.cpp | 28 +++--- src/types.cpp | 42 ++++----- 18 files changed, 349 insertions(+), 365 deletions(-) (limited to 'src/entity.cpp') diff --git a/src/build_settings.cpp b/src/build_settings.cpp index dac763010..eb8a50c6a 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -1,5 +1,5 @@ // This stores the information for the specify architecture of this build -typedef struct BuildContext { +struct BuildContext { // Constants String ODIN_OS; // target operating system String ODIN_ARCH; // target architecture @@ -15,7 +15,7 @@ typedef struct BuildContext { String llc_flags; String link_flags; bool is_dll; -} BuildContext; +}; gb_global BuildContext build_context = {0}; diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 1e7e23398..356cd488b 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -58,7 +58,7 @@ Type *check_init_variable(Checker *c, Entity *e, Operand *operand, String contex return e->type; } -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, Array inits, String context_name) { if ((lhs == NULL || lhs_count == 0) && inits.count == 0) { return; } @@ -431,7 +431,7 @@ void check_var_decl(Checker *c, Entity *e, Entity **entities, isize entity_count } } - AstNodeArray inits; + Array inits; array_init(&inits, c->allocator, 1); array_add(&inits, init_expr); check_init_variables(c, entities, entity_count, inits, str_lit("variable declaration")); diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 55670f7e5..2af676831 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -16,7 +16,7 @@ void update_expr_type (Checker *c, AstNode *e, Type *type, boo bool check_is_terminating (AstNode *node); bool check_has_break (AstNode *stmt, bool implicit); void check_stmt (Checker *c, AstNode *node, u32 flags); -void check_stmt_list (Checker *c, AstNodeArray stmts, u32 flags); +void check_stmt_list (Checker *c, Array stmts, u32 flags); void check_init_constant (Checker *c, Entity *e, Operand *operand); bool check_representable_as_constant(Checker *c, ExactValue in_value, Type *type, ExactValue *out_value); Type * check_call_arguments (Checker *c, Operand *operand, Type *proc_type, AstNode *call); @@ -46,7 +46,7 @@ void error_operand_no_value(Operand *o) { } -void check_scope_decls(Checker *c, AstNodeArray nodes, isize reserve_size) { +void check_scope_decls(Checker *c, Array nodes, isize reserve_size) { Scope *s = c->context.scope; GB_ASSERT(!s->is_file); @@ -385,7 +385,7 @@ void populate_using_entity_map(Checker *c, AstNode *node, Type *t, MapEntity *en // Returns filled field_count -isize check_fields(Checker *c, AstNode *node, AstNodeArray decls, +isize check_fields(Checker *c, AstNode *node, Array decls, Entity **fields, isize field_count, String context) { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena); @@ -692,7 +692,7 @@ void check_union_type(Checker *c, Type *union_type, AstNode *node) { ast_node(fl, FieldList, f->list); // NOTE(bill): Copy the contents for the common fields for now - AstNodeArray list = {}; + Array list = {}; array_init_count(&list, c->allocator, ut->fields.count+fl->list.count); gb_memmove_array(list.data, ut->fields.data, ut->fields.count); gb_memmove_array(list.data+ut->fields.count, fl->list.data, fl->list.count); @@ -1033,7 +1033,7 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari return NULL; } ast_node(field_list, FieldList, _params); - AstNodeArray params = field_list->list; + Array params = field_list->list; if (params.count == 0) { return NULL; @@ -1118,7 +1118,7 @@ Type *check_get_results(Checker *c, Scope *scope, AstNode *_results) { return NULL; } ast_node(field_list, FieldList, _results); - AstNodeArray results = field_list->list; + Array results = field_list->list; if (results.count == 0) { return NULL; @@ -4698,7 +4698,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id return true; } -typedef enum CallArgumentError { +enum CallArgumentError { CallArgumentError_None, CallArgumentError_WrongTypes, CallArgumentError_NonVariadicExpand, @@ -4707,12 +4707,12 @@ typedef enum CallArgumentError { CallArgumentError_ArgumentCount, CallArgumentError_TooFewArguments, CallArgumentError_TooManyArguments, -} CallArgumentError; +}; -typedef enum CallArgumentErrorMode { +enum CallArgumentErrorMode { CallArgumentMode_NoErrors, CallArgumentMode_ShowErrors, -} CallArgumentErrorMode; +}; CallArgumentError check_call_arguments_internal(Checker *c, AstNode *call, Type *proc_type, Operand *operands, isize operand_count, CallArgumentErrorMode show_error_mode, i64 *score_) { @@ -4823,10 +4823,10 @@ CallArgumentError check_call_arguments_internal(Checker *c, AstNode *call, Type return err; } -typedef struct ValidProcAndScore { +struct ValidProcAndScore { isize index; i64 score; -} ValidProcAndScore; +}; int valid_proc_and_score_cmp(void const *a, void const *b) { i64 si = (cast(ValidProcAndScore const *)a)->score; @@ -4834,7 +4834,7 @@ int valid_proc_and_score_cmp(void const *a, void const *b) { return sj < si ? -1 : sj > si; } -bool check_unpack_arguments(Checker *c, isize lhs_count, Array *operands, AstNodeArray rhs, bool allow_ok) { +bool check_unpack_arguments(Checker *c, isize lhs_count, Array *operands, Array rhs, bool allow_ok) { bool optional_ok = false; for_array(i, rhs) { Operand o = {}; @@ -6139,7 +6139,7 @@ void check_expr_or_type(Checker *c, Operand *o, AstNode *e) { gbString write_expr_to_string(gbString str, AstNode *node); -gbString write_record_fields_to_string(gbString str, AstNodeArray params) { +gbString write_record_fields_to_string(gbString str, Array params) { for_array(i, params) { if (i > 0) { str = gb_string_appendc(str, ", "); diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 9a0f6afa5..859aa593d 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1,4 +1,4 @@ -void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) { +void check_stmt_list(Checker *c, Array stmts, u32 flags) { if (stmts.count == 0) { return; } @@ -40,7 +40,7 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) { } -bool check_is_terminating_list(AstNodeArray stmts) { +bool check_is_terminating_list(Array stmts) { // Iterate backwards for (isize n = stmts.count-1; n >= 0; n--) { AstNode *stmt = stmts[n]; @@ -52,7 +52,7 @@ bool check_is_terminating_list(AstNodeArray stmts) { return false; } -bool check_has_break_list(AstNodeArray stmts, bool implicit) { +bool check_has_break_list(Array stmts, bool implicit) { for_array(i, stmts) { AstNode *stmt = stmts[i]; if (check_has_break(stmt, implicit)) { @@ -340,11 +340,11 @@ Type *check_assignment_variable(Checker *c, Operand *rhs, AstNode *lhs_node) { return rhs->type; } -typedef enum MatchTypeKind { +enum MatchTypeKind { MatchType_Invalid, MatchType_Union, MatchType_Any, -} MatchTypeKind; +}; MatchTypeKind check_valid_type_match_type(Type *type) { type = type_deref(type); @@ -384,10 +384,10 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { -typedef struct TypeAndToken { +struct TypeAndToken { Type *type; Token token; -} TypeAndToken; +}; #define MAP_TYPE TypeAndToken #define MAP_PROC map_type_and_token_ diff --git a/src/checker.cpp b/src/checker.cpp index 6a9011df1..389740694 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1,27 +1,27 @@ #include "exact_value.cpp" #include "entity.cpp" -typedef enum ExprKind { +enum ExprKind { Expr_Expr, Expr_Stmt, -} ExprKind; +}; // Statements and Declarations -typedef enum StmtFlag { +enum StmtFlag { Stmt_BreakAllowed = 1<<0, Stmt_ContinueAllowed = 1<<1, Stmt_FallthroughAllowed = 1<<2, Stmt_CheckScopeDecls = 1<<5, -} StmtFlag; +}; -typedef struct BuiltinProc { +struct BuiltinProc { String name; isize arg_count; bool variadic; ExprKind kind; -} BuiltinProc; -typedef enum BuiltinProcId { +}; +enum BuiltinProcId { BuiltinProc_Invalid, BuiltinProc_len, @@ -71,7 +71,7 @@ typedef enum BuiltinProcId { BuiltinProc_transmute, BuiltinProc_Count, -} BuiltinProcId; +}; gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = { {STR_LIT(""), 0, false, Expr_Stmt}, @@ -125,7 +125,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = { #include "types.cpp" -typedef enum AddressingMode { +enum AddressingMode { Addressing_Invalid, // invalid addressing mode Addressing_NoValue, // no value (void in C) Addressing_Value, // computed value (rvalue) @@ -139,14 +139,14 @@ typedef enum AddressingMode { // lhs: acts like a Variable // rhs: acts like OptionalOk Addressing_OptionalOk, // rhs: acts like a value with an optional boolean part (for existence check) -} AddressingMode; +}; // Operand is used as an intermediate value whilst checking // Operands store an addressing mode, the expression being evaluated, // its type and node, and other specific information for certain // addressing modes // Its zero-value is a valid "invalid operand" -typedef struct Operand { +struct Operand { AddressingMode mode; Type * type; ExactValue value; @@ -154,13 +154,13 @@ typedef struct Operand { BuiltinProcId builtin_id; isize overload_count; Entity ** overload_entities; -} Operand; +}; -typedef struct TypeAndValue { +struct TypeAndValue { AddressingMode mode; Type * type; ExactValue value; -} TypeAndValue; +}; bool is_operand_value(Operand o) { switch (o.mode) { @@ -178,13 +178,12 @@ bool is_operand_nil(Operand o) { } -typedef struct BlockLabel { +struct BlockLabel { String name; AstNode *label; // AstNode_Label; -} BlockLabel; +}; // DeclInfo is used to store information of certain declarations to allow for "any order" usage -typedef struct DeclInfo DeclInfo; struct DeclInfo { DeclInfo * parent; // NOTE(bill): only used for procedure literals at the moment Scope * scope; @@ -203,22 +202,22 @@ struct DeclInfo { // ProcedureInfo stores the information needed for checking a procedure -typedef struct ProcedureInfo { +struct ProcedureInfo { AstFile * file; Token token; DeclInfo * decl; Type * type; // Type_Procedure AstNode * body; // AstNode_BlockStmt u32 tags; -} ProcedureInfo; +}; // ExprInfo stores information used for "untyped" expressions -typedef struct ExprInfo { +struct ExprInfo { bool is_lhs; // Debug info AddressingMode mode; Type * type; // Type_Basic ExactValue value; -} ExprInfo; +}; ExprInfo make_expr_info(bool is_lhs, AddressingMode mode, Type *type, ExactValue value) { ExprInfo ei = {is_lhs, mode, type, value}; @@ -232,7 +231,7 @@ ExprInfo make_expr_info(bool is_lhs, AddressingMode mode, Type *type, ExactValue #define MAP_NAME MapEntity #include "map.cpp" -typedef struct Scope { +struct Scope { Scope * parent; Scope * prev, *next; Scope * first_child; @@ -248,7 +247,7 @@ typedef struct Scope { bool is_init; bool has_been_imported; // This is only applicable to file scopes AstFile * file; -} Scope; +}; gb_global Scope *universal_scope = NULL; @@ -280,19 +279,19 @@ gb_global Scope *universal_scope = NULL; #define MAP_NAME MapExprInfo #include "map.cpp" -typedef struct DelayedDecl { +struct DelayedDecl { Scope * parent; AstNode *decl; -} DelayedDecl; +}; -typedef struct CheckerFileNode { +struct CheckerFileNode { i32 id; Array wheres; Array whats; i32 score; // Higher the score, the better -} CheckerFileNode; +}; -typedef struct CheckerContext { +struct CheckerContext { Scope * file_scope; Scope * scope; DeclInfo * decl; @@ -301,10 +300,10 @@ typedef struct CheckerContext { String proc_name; Type * type_hint; DeclInfo * curr_proc_decl; -} CheckerContext; +}; // CheckerInfo stores all the symbol information for a type-checked program -typedef struct CheckerInfo { +struct CheckerInfo { MapTypeAndValue types; // Key: AstNode * | Expression -> Type (and value) MapEntity definitions; // Key: AstNode * | Identifier -> Entity MapEntity uses; // Key: AstNode * | Identifier -> Entity @@ -316,9 +315,9 @@ typedef struct CheckerInfo { MapAstFile files; // Key: String (full path) MapIsize type_info_map; // Key: Type * isize type_info_count; -} CheckerInfo; +}; -typedef struct Checker { +struct Checker { Parser * parser; CheckerInfo info; @@ -338,14 +337,14 @@ typedef struct Checker { Array proc_stack; bool done_preload; -} Checker; +}; -typedef struct DelayedEntity { +struct DelayedEntity { AstNode * ident; Entity * entity; DeclInfo * decl; -} DelayedEntity; +}; @@ -1281,7 +1280,7 @@ void init_preload(Checker *c) { bool check_arity_match(Checker *c, AstNodeValueDecl *d); -void check_collect_entities(Checker *c, AstNodeArray nodes, bool is_file_scope); +void check_collect_entities(Checker *c, Array nodes, bool is_file_scope); void check_collect_entities_from_when_stmt(Checker *c, AstNodeWhenStmt *ws, bool is_file_scope); bool check_is_entity_overloaded(Entity *e) { @@ -1455,7 +1454,7 @@ void check_collect_entities_from_when_stmt(Checker *c, AstNodeWhenStmt *ws, bool } // NOTE(bill): If file_scopes == NULL, this will act like a local scope -void check_collect_entities(Checker *c, AstNodeArray nodes, bool is_file_scope) { +void check_collect_entities(Checker *c, Array nodes, bool is_file_scope) { // NOTE(bill): File scope and local scope are different kinds of scopes if (is_file_scope) { GB_ASSERT(c->context.scope->is_file); diff --git a/src/common.cpp b/src/common.cpp index 0aa37a001..c61f22a62 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -43,8 +43,6 @@ gbAllocator scratch_allocator(void) { return gb_scratch_allocator(&scratch_memory); } -typedef struct DynamicArenaBlock DynamicArenaBlock; -typedef struct DynamicArena DynamicArena; struct DynamicArenaBlock { DynamicArenaBlock *prev; diff --git a/src/entity.cpp b/src/entity.cpp index 042f6f39f..d8159d449 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -1,7 +1,7 @@ -typedef struct Scope Scope; -typedef struct Checker Checker; -typedef struct Type Type; -typedef struct DeclInfo DeclInfo; +struct Scope; +struct Checker; +struct Type; +struct DeclInfo; // typedef enum BuiltinProcId BuiltinProcId; @@ -19,12 +19,12 @@ typedef struct DeclInfo DeclInfo; ENTITY_KIND(Nil) \ ENTITY_KIND(Label) -typedef enum EntityKind { +enum EntityKind { #define ENTITY_KIND(k) GB_JOIN2(Entity_, k), ENTITY_KINDS #undef ENTITY_KIND Entity_Count, -} EntityKind; +}; String const entity_strings[] = { #define ENTITY_KIND(k) {cast(u8 *)#k, gb_size_of(#k)-1}, @@ -32,7 +32,7 @@ String const entity_strings[] = { #undef ENTITY_KIND }; -typedef enum EntityFlag { +enum EntityFlag { EntityFlag_Visited = 1<<0, EntityFlag_Used = 1<<1, EntityFlag_Using = 1<<2, @@ -45,24 +45,23 @@ typedef enum EntityFlag { EntityFlag_Value = 1<<9, EntityFlag_Sret = 1<<10, EntityFlag_BitFieldValue = 1<<11, -} EntityFlag; +}; // Zero value means the overloading process is not yet done -typedef enum OverloadKind { +enum OverloadKind { Overload_Unknown, Overload_No, Overload_Yes, -} OverloadKind; +}; -typedef enum EntityAliasKind { +enum EntityAliasKind { EntityAlias_Invalid, EntityAlias_Type, EntityAlias_Entity, -} EntityAliasKind; +}; // An Entity is a named "thing" in the language -typedef struct Entity Entity; struct Entity { EntityKind kind; u64 id; diff --git a/src/exact_value.cpp b/src/exact_value.cpp index 2bdf3fdf5..62ab326ea 100644 --- a/src/exact_value.cpp +++ b/src/exact_value.cpp @@ -3,13 +3,13 @@ // TODO(bill): Big numbers // IMPORTANT TODO(bill): This needs to be completely fixed!!!!!!!! -typedef struct AstNode AstNode; +struct AstNode; -typedef struct Complex128 { +struct Complex128 { f64 real, imag; -} Complex128; +}; -typedef enum ExactValueKind { +enum ExactValueKind { ExactValue_Invalid, ExactValue_Bool, @@ -21,9 +21,9 @@ typedef enum ExactValueKind { ExactValue_Compound, // TODO(bill): Is this good enough? ExactValue_Count, -} ExactValueKind; +}; -typedef struct ExactValue { +struct ExactValue { ExactValueKind kind; union { bool value_bool; @@ -34,7 +34,7 @@ typedef struct ExactValue { Complex128 value_complex; AstNode * value_compound; }; -} ExactValue; +}; gb_global ExactValue const empty_exact_value = {}; diff --git a/src/ir.cpp b/src/ir.cpp index c9afb05ba..4cd1734aa 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -1,9 +1,7 @@ -typedef struct irProcedure irProcedure; -typedef struct irBlock irBlock; -typedef struct irValue irValue; -typedef struct irDebugInfo irDebugInfo; - -typedef Array irValueArray; +struct irProcedure; +struct irBlock; +struct irValue; +struct irDebugInfo; #define MAP_TYPE irValue * #define MAP_PROC map_ir_value_ @@ -16,7 +14,7 @@ typedef Array irValueArray; #include "map.cpp" -typedef struct irModule { +struct irModule { CheckerInfo * info; gbArena arena; gbArena tmp_arena; @@ -42,20 +40,20 @@ typedef struct irModule { Entity * entry_point_entity; Array procs; // NOTE(bill): All procedures with bodies - irValueArray procs_to_generate; // NOTE(bill): Procedures to generate + Array procs_to_generate; // NOTE(bill): Procedures to generate Array foreign_library_paths; // Only the ones that were used -} irModule; +}; // NOTE(bill): For more info, see https://en.wikipedia.org/wiki/Dominator_(graph_theory) -typedef struct irDomNode { +struct irDomNode { irBlock * idom; // Parent (Immediate Dominator) Array children; i32 pre, post; // Ordering in tree -} irDomNode; +}; -typedef struct irBlock { +struct irBlock { i32 index; String label; irProcedure *parent; @@ -65,14 +63,13 @@ typedef struct irBlock { irDomNode dom; i32 gaps; - irValueArray instrs; - irValueArray locals; + Array instrs; + Array locals; Array preds; Array succs; -} irBlock; +}; -typedef struct irTargetList irTargetList; struct irTargetList { irTargetList *prev; irBlock * break_; @@ -80,17 +77,17 @@ struct irTargetList { irBlock * fallthrough_; }; -typedef enum irDeferExitKind { +enum irDeferExitKind { irDeferExit_Default, irDeferExit_Return, irDeferExit_Branch, -} irDeferExitKind; -typedef enum irDeferKind { +}; +enum irDeferKind { irDefer_Node, irDefer_Instr, -} irDeferKind; +}; -typedef struct irDefer { +struct irDefer { irDeferKind kind; isize scope_index; irBlock * block; @@ -99,14 +96,14 @@ typedef struct irDefer { // NOTE(bill): `instr` will be copied every time to create a new one irValue *instr; }; -} irDefer; +}; -typedef struct irBranchBlocks { +struct irBranchBlocks { AstNode *label; irBlock *break_; irBlock *continue_; -} irBranchBlocks; +}; struct irProcedure { @@ -122,7 +119,7 @@ struct irProcedure { u64 tags; irValue * return_ptr; - irValueArray params; + Array params; Array defer_stmts; Array blocks; i32 scope_index; @@ -130,7 +127,7 @@ struct irProcedure { irBlock * entry_block; irBlock * curr_block; irTargetList * target_list; - irValueArray referrers; + Array referrers; Array branch_blocks; @@ -153,7 +150,7 @@ struct irProcedure { Entity * entity; \ Type * type; \ bool zero_initialized; \ - irValueArray referrers; \ + Array referrers; \ i64 alignment; \ }) \ IR_INSTR_KIND(ZeroInit, struct { irValue *address; }) \ @@ -205,7 +202,7 @@ struct irProcedure { irValue *true_value; \ irValue *false_value; \ }) \ - IR_INSTR_KIND(Phi, struct { irValueArray edges; Type *type; }) \ + IR_INSTR_KIND(Phi, struct { Array edges; Type *type; }) \ IR_INSTR_KIND(Unreachable, i32) \ IR_INSTR_KIND(UnaryOp, struct { \ Type * type; \ @@ -261,12 +258,12 @@ struct irProcedure { IR_CONV_KIND(inttoptr) \ IR_CONV_KIND(bitcast) -typedef enum irInstrKind { +enum irInstrKind { irInstr_Invalid, #define IR_INSTR_KIND(x, ...) GB_JOIN2(irInstr_, x), IR_INSTR_KINDS #undef IR_INSTR_KIND -} irInstrKind; +}; String const ir_instr_strings[] = { {cast(u8 *)"Invalid", gb_size_of("Invalid")-1}, @@ -275,12 +272,12 @@ String const ir_instr_strings[] = { #undef IR_INSTR_KIND }; -typedef enum irConvKind { +enum irConvKind { irConv_Invalid, #define IR_CONV_KIND(x) GB_JOIN2(irConv_, x), IR_CONV_KINDS #undef IR_CONV_KIND -} irConvKind; +}; String const ir_conv_strings[] = { {cast(u8 *)"Invalid", gb_size_of("Invalid")-1}, @@ -293,7 +290,6 @@ String const ir_conv_strings[] = { IR_INSTR_KINDS #undef IR_INSTR_KIND -typedef struct irInstr irInstr; struct irInstr { irInstrKind kind; @@ -308,7 +304,7 @@ struct irInstr { }; -typedef enum irValueKind { +enum irValueKind { irValue_Invalid, irValue_Constant, @@ -323,58 +319,58 @@ typedef enum irValueKind { irValue_Instr, irValue_Count, -} irValueKind; +}; -typedef struct irValueConstant { +struct irValueConstant { Type * type; ExactValue value; -} irValueConstant; +}; -typedef struct irValueConstantSlice { +struct irValueConstantSlice { Type * type; irValue *backing_array; i64 count; -} irValueConstantSlice; +}; -typedef struct irValueNil { +struct irValueNil { Type *type; -} irValueNil; +}; -typedef struct irValueTypeName { +struct irValueTypeName { Type * type; String name; -} irValueTypeName; +}; -typedef struct irValueGlobal { +struct irValueGlobal { String name; Entity * entity; Type * type; irValue * value; - irValueArray referrers; + Array referrers; bool is_constant; bool is_private; bool is_thread_local; bool is_foreign; bool is_unnamed_addr; -} irValueGlobal; +}; -typedef enum irParamPasskind { +enum irParamPasskind { irParamPass_Value, // Pass by value irParamPass_Pointer, // Pass as a pointer rather than by value irParamPass_Integer, // Pass as an integer of the same size -} irParamPasskind; +}; -typedef struct irValueParam { +struct irValueParam { irParamPasskind kind; irProcedure * parent; Entity * entity; Type * type; Type * original_type; - irValueArray referrers; -} irValueParam; + Array referrers; +}; -typedef struct irValue { +struct irValue { irValueKind kind; i32 index; bool index_set; @@ -389,7 +385,7 @@ typedef struct irValue { irBlock Block; irInstr Instr; }; -} irValue; +}; gb_global irValue *v_zero = NULL; gb_global irValue *v_one = NULL; @@ -400,14 +396,14 @@ gb_global irValue *v_false = NULL; gb_global irValue *v_true = NULL; gb_global irValue *v_raw_nil = NULL; -typedef enum irAddrKind { +enum irAddrKind { irAddr_Default, // irAddr_Vector, irAddr_Map, irAddr_BitField, -} irAddrKind; +}; -typedef struct irAddr { +struct irAddr { irAddrKind kind; irValue * addr; union { @@ -423,7 +419,7 @@ typedef struct irAddr { // union { // struct { irValue *index; } Vector; // }; -} irAddr; +}; irAddr ir_addr(irValue *addr) { irAddr v = {irAddr_Default, addr}; @@ -444,7 +440,7 @@ irAddr ir_addr_bit_field(irValue *addr, isize bit_field_value_index) { return v; } -typedef enum irDebugEncoding { +enum irDebugEncoding { irDebugBasicEncoding_Invalid = 0, irDebugBasicEncoding_address = 1, @@ -464,9 +460,9 @@ typedef enum irDebugEncoding { irDebugBasicEncoding_structure_type = 19, irDebugBasicEncoding_union_type = 23, -} irDebugEncoding; +}; -typedef enum irDebugInfoKind { +enum irDebugInfoKind { irDebugInfo_Invalid, irDebugInfo_CompileUnit, @@ -485,9 +481,8 @@ typedef enum irDebugInfoKind { irDebugInfo_Count, -} irDebugInfoKind; +}; -typedef struct irDebugInfo irDebugInfo; struct irDebugInfo { irDebugInfoKind kind; i32 id; @@ -569,14 +564,13 @@ struct irDebugInfo { }; - -typedef struct irGen { +struct irGen { irModule module; gbFile output_file; bool opt_called; String output_base; String output_name; -} irGen; +}; @@ -698,7 +692,7 @@ void ir_set_instr_parent(irValue *instr, irBlock *parent) { } } -irValueArray *ir_value_referrers(irValue *v) { +Array *ir_value_referrers(irValue *v) { switch (v->kind) { case irValue_Global: return &v->Global.referrers; @@ -969,7 +963,7 @@ irValue *ir_instr_if(irProcedure *p, irValue *cond, irBlock *true_block, irBlock } -irValue *ir_instr_phi(irProcedure *p, irValueArray edges, Type *type) { +irValue *ir_instr_phi(irProcedure *p, Array edges, Type *type) { irValue *v = ir_alloc_instr(p, irInstr_Phi); irInstr *i = &v->Instr; i->Phi.edges = edges; @@ -3387,7 +3381,7 @@ irValue *ir_emit_logical_binary_expr(irProcedure *proc, AstNode *expr) { return ir_build_expr(proc, be->right); } - irValueArray edges = {}; + Array edges = {}; array_init(&edges, proc->module->allocator, done->preds.count+1); for_array(i, done->preds) { array_add(&edges, short_circuit); @@ -3613,7 +3607,7 @@ irValue *ir_find_global_variable(irProcedure *proc, String name) { return *value; } -void ir_build_stmt_list(irProcedure *proc, AstNodeArray stmts); +void ir_build_stmt_list(irProcedure *proc, Array stmts); bool is_double_pointer(Type *t) { @@ -3712,7 +3706,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { case_ast_node(te, TernaryExpr, expr); ir_emit_comment(proc, str_lit("TernaryExpr")); - irValueArray edges = {}; + Array edges = {}; array_init(&edges, proc->module->allocator, 2); GB_ASSERT(te->y != NULL); @@ -3752,7 +3746,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { ir_build_stmt(proc, ie->init); } - irValueArray edges = {}; + Array edges = {}; array_init(&edges, proc->module->allocator, 2); GB_ASSERT(ie->else_expr != NULL); @@ -5450,7 +5444,7 @@ irValue *ir_build_cond(irProcedure *proc, AstNode *cond, irBlock *true_block, ir -void ir_build_stmt_list(irProcedure *proc, AstNodeArray stmts) { +void ir_build_stmt_list(irProcedure *proc, Array stmts) { for_array(i, stmts) { ir_build_stmt(proc, stmts[i]); } @@ -5787,7 +5781,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { } } else { // Tuple(s) Array lvals = {}; - irValueArray inits = {}; + Array inits = {}; array_init(&lvals, m->tmp_allocator, vd->names.count); array_init(&inits, m->tmp_allocator, vd->names.count); @@ -5943,7 +5937,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { irValue *init = ir_build_expr(proc, rhs); ir_addr_store(proc, lvals[0], init); } else { - irValueArray inits; + Array inits; array_init(&inits, m->tmp_allocator, lvals.count); for_array(i, as->rhs) { @@ -5956,7 +5950,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { } } } else { - irValueArray inits; + Array inits; array_init(&inits, m->tmp_allocator, lvals.count); for_array(i, as->rhs) { @@ -6029,7 +6023,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { } else { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena); - irValueArray results; + Array results; array_init(&results, proc->module->tmp_allocator, return_count); for_array(res_index, rs->results) { @@ -6338,7 +6332,7 @@ void ir_build_stmt_internal(irProcedure *proc, AstNode *node) { ast_node(body, BlockStmt, ms->body); - AstNodeArray default_stmts = {}; + Array default_stmts = {}; irBlock *default_fall = NULL; irBlock *default_block = NULL; @@ -7116,10 +7110,10 @@ void ir_gen_tree(irGen *s) { } } - typedef struct irGlobalVariable { + struct irGlobalVariable { irValue *var, *init; DeclInfo *decl; - } irGlobalVariable; + }; Array global_variables; array_init(&global_variables, m->tmp_allocator, global_variable_max_count); diff --git a/src/ir_opt.cpp b/src/ir_opt.cpp index 856d8aaf0..c2c952b87 100644 --- a/src/ir_opt.cpp +++ b/src/ir_opt.cpp @@ -1,6 +1,6 @@ // Optimizations for the IR code -void ir_opt_add_operands(irValueArray *ops, irInstr *i) { +void ir_opt_add_operands(Array *ops, irInstr *i) { switch (i->kind) { case irInstr_Comment: break; @@ -126,8 +126,8 @@ bool ir_opt_block_has_phi(irBlock *b) { -irValueArray ir_get_block_phi_nodes(irBlock *b) { - irValueArray phis = {0}; +Array ir_get_block_phi_nodes(irBlock *b) { + Array phis = {0}; for_array(i, b->instrs) { irInstr *instr = &b->instrs[i]->Instr; if (instr->kind != irInstr_Phi) { @@ -140,7 +140,7 @@ irValueArray ir_get_block_phi_nodes(irBlock *b) { } void ir_remove_pred(irBlock *b, irBlock *p) { - irValueArray phis = ir_get_block_phi_nodes(b); + Array phis = ir_get_block_phi_nodes(b); isize i = 0; for_array(j, b->preds) { irBlock *pred = b->preds[j]; @@ -273,7 +273,7 @@ void ir_opt_blocks(irProcedure *proc) { void ir_opt_build_referrers(irProcedure *proc) { gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&proc->module->tmp_arena); - irValueArray ops = {0}; // NOTE(bill): Act as a buffer + Array ops = {0}; // NOTE(bill): Act as a buffer array_init(&ops, proc->module->tmp_allocator, 64); // HACK(bill): This _could_ overflow the temp arena for_array(i, proc->blocks) { irBlock *b = proc->blocks[i]; @@ -286,7 +286,7 @@ void ir_opt_build_referrers(irProcedure *proc) { if (op == NULL) { continue; } - irValueArray *refs = ir_value_referrers(op); + Array *refs = ir_value_referrers(op); if (refs != NULL) { array_add(refs, instr); } diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 81809fa0a..823960352 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -1,8 +1,8 @@ -typedef struct irFileBuffer { +struct irFileBuffer { gbVirtualMemory vm; isize offset; gbFile * output; -} irFileBuffer; +}; void ir_file_buffer_init(irFileBuffer *f, gbFile *output) { isize size = 8*gb_virtual_memory_page_size(NULL); diff --git a/src/parser.cpp b/src/parser.cpp index 2fc9f124d..120bb63cc 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -1,8 +1,8 @@ -typedef struct AstNode AstNode; -typedef struct Scope Scope; -typedef struct DeclInfo DeclInfo; +struct AstNode; +struct Scope; +struct DeclInfo; -typedef enum ParseFileError { +enum ParseFileError { ParseFile_None, ParseFile_WrongExtension, @@ -13,11 +13,10 @@ typedef enum ParseFileError { ParseFile_InvalidToken, ParseFile_Count, -} ParseFileError; +}; -typedef Array AstNodeArray; -typedef struct AstFile { +struct AstFile { i32 id; gbArena arena; Tokenizer tokenizer; @@ -32,8 +31,8 @@ typedef struct AstFile { isize expr_level; bool allow_range; // NOTE(bill): Ranges are only allowed in certain cases - AstNodeArray decls; - bool is_global_scope; + Array decls; + bool is_global_scope; AstNode * curr_proc; isize scope_level; @@ -44,15 +43,15 @@ typedef struct AstFile { #define PARSER_MAX_FIX_COUNT 6 isize fix_count; TokenPos fix_prev_pos; -} AstFile; +}; -typedef struct ImportedFile { +struct ImportedFile { String path; String rel_path; TokenPos pos; // #import -} ImportedFile; +}; -typedef struct Parser { +struct Parser { String init_fullpath; Array files; Array imports; @@ -60,9 +59,9 @@ typedef struct Parser { isize total_token_count; isize total_line_count; gbMutex mutex; -} Parser; +}; -typedef enum ProcTag { +enum ProcTag { ProcTag_bounds_check = 1<<0, ProcTag_no_bounds_check = 1<<1, @@ -75,47 +74,47 @@ typedef enum ProcTag { ProcTag_no_inline = 1<<14, // ProcTag_dll_import = 1<<15, // ProcTag_dll_export = 1<<16, -} ProcTag; +}; -typedef enum ProcCallingConvention { +enum ProcCallingConvention { ProcCC_Odin = 0, ProcCC_C = 1, ProcCC_Std = 2, ProcCC_Fast = 3, ProcCC_Invalid, -} ProcCallingConvention; +}; -typedef enum VarDeclFlag { +enum VarDeclFlag { VarDeclFlag_using = 1<<0, VarDeclFlag_immutable = 1<<1, VarDeclFlag_thread_local = 1<<2, -} VarDeclFlag; +}; -typedef enum StmtStateFlag { +enum StmtStateFlag { StmtStateFlag_bounds_check = 1<<0, StmtStateFlag_no_bounds_check = 1<<1, -} StmtStateFlag; +}; -typedef enum FieldFlag { +enum FieldFlag { FieldFlag_ellipsis = 1<<0, FieldFlag_using = 1<<1, FieldFlag_no_alias = 1<<2, FieldFlag_immutable = 1<<3, FieldFlag_Signature = FieldFlag_ellipsis|FieldFlag_using|FieldFlag_no_alias|FieldFlag_immutable, -} FieldListTag; +}; -typedef enum StmtAllowFlag { +enum StmtAllowFlag { StmtAllowFlag_None = 0, StmtAllowFlag_In = 1<<0, StmtAllowFlag_Label = 1<<1, -} StmtAllowFlag; +}; -AstNodeArray make_ast_node_array(AstFile *f) { - AstNodeArray a; +Array make_ast_node_array(AstFile *f) { + Array a; // array_init(&a, gb_arena_allocator(&f->arena)); array_init(&a, heap_allocator()); return a; @@ -147,7 +146,7 @@ AstNodeArray make_ast_node_array(AstFile *f) { }) \ AST_NODE_KIND(CompoundLit, "compound literal", struct { \ AstNode *type; \ - AstNodeArray elems; \ + Array elems; \ Token open, close; \ }) \ AST_NODE_KIND(Alias, "alias", struct { \ @@ -174,7 +173,7 @@ AST_NODE_KIND(_ExprBegin, "", i32) \ }) \ AST_NODE_KIND(CallExpr, "call expression", struct { \ AstNode * proc; \ - AstNodeArray args; \ + Array args; \ Token open; \ Token close; \ Token ellipsis; \ @@ -182,7 +181,7 @@ AST_NODE_KIND(_ExprBegin, "", i32) \ AST_NODE_KIND(MacroCallExpr, "macro call expression", struct { \ AstNode * macro; \ Token bang; \ - AstNodeArray args; \ + Array args; \ Token open; \ Token close; \ }) \ @@ -201,7 +200,7 @@ AST_NODE_KIND(_StmtBegin, "", i32) \ }) \ AST_NODE_KIND(AssignStmt, "assign statement", struct { \ Token op; \ - AstNodeArray lhs, rhs; \ + Array lhs, rhs; \ }) \ AST_NODE_KIND(IncDecStmt, "increment decrement statement", struct { \ Token op; \ @@ -209,7 +208,7 @@ AST_NODE_KIND(_StmtBegin, "", i32) \ }) \ AST_NODE_KIND(_ComplexStmtBegin, "", i32) \ AST_NODE_KIND(BlockStmt, "block statement", struct { \ - AstNodeArray stmts; \ + Array stmts; \ Token open, close; \ }) \ AST_NODE_KIND(IfStmt, "if statement", struct { \ @@ -227,7 +226,7 @@ AST_NODE_KIND(_ComplexStmtBegin, "", i32) \ }) \ AST_NODE_KIND(ReturnStmt, "return statement", struct { \ Token token; \ - AstNodeArray results; \ + Array results; \ }) \ AST_NODE_KIND(ForStmt, "for statement", struct { \ Token token; \ @@ -248,8 +247,8 @@ AST_NODE_KIND(_ComplexStmtBegin, "", i32) \ }) \ AST_NODE_KIND(CaseClause, "case clause", struct { \ Token token; \ - AstNodeArray list; \ - AstNodeArray stmts; \ + Array list; \ + Array stmts; \ }) \ AST_NODE_KIND(MatchStmt, "match statement", struct { \ Token token; \ @@ -268,7 +267,7 @@ AST_NODE_KIND(_ComplexStmtBegin, "", i32) \ AST_NODE_KIND(BranchStmt, "branch statement", struct { Token token; AstNode *label; }) \ AST_NODE_KIND(UsingStmt, "using statement", struct { \ Token token; \ - AstNodeArray list; \ + Array list; \ }) \ AST_NODE_KIND(AsmOperand, "assembly operand", struct { \ Token string; \ @@ -300,9 +299,9 @@ AST_NODE_KIND(_DeclBegin, "", i32) \ AST_NODE_KIND(BadDecl, "bad declaration", struct { Token begin, end; }) \ AST_NODE_KIND(ValueDecl, "value declaration", struct { \ bool is_var; \ - AstNodeArray names; \ + Array names; \ AstNode * type; \ - AstNodeArray values; \ + Array values; \ u32 flags; \ }) \ AST_NODE_KIND(ImportDecl, "import declaration", struct { \ @@ -327,13 +326,13 @@ AST_NODE_KIND(_DeclBegin, "", i32) \ }) \ AST_NODE_KIND(_DeclEnd, "", i32) \ AST_NODE_KIND(Field, "field", struct { \ - AstNodeArray names; \ + Array names; \ AstNode * type; \ u32 flags; \ }) \ AST_NODE_KIND(FieldList, "field list", struct { \ Token token; \ - AstNodeArray list; \ + Array list; \ }) \ AST_NODE_KIND(UnionField, "union field", struct { \ AstNode *name; \ @@ -375,7 +374,7 @@ AST_NODE_KIND(_TypeBegin, "", i32) \ }) \ AST_NODE_KIND(StructType, "struct type", struct { \ Token token; \ - AstNodeArray fields; \ + Array fields; \ isize field_count; \ bool is_packed; \ bool is_ordered; \ @@ -383,23 +382,23 @@ AST_NODE_KIND(_TypeBegin, "", i32) \ }) \ AST_NODE_KIND(UnionType, "union type", struct { \ Token token; \ - AstNodeArray fields; \ + Array fields; \ isize field_count; \ - AstNodeArray variants; \ + Array variants; \ }) \ AST_NODE_KIND(RawUnionType, "raw union type", struct { \ Token token; \ - AstNodeArray fields; \ + Array fields; \ isize field_count; \ }) \ AST_NODE_KIND(EnumType, "enum type", struct { \ Token token; \ AstNode *base_type; \ - AstNodeArray fields; /* FieldValue */ \ + Array fields; /* FieldValue */ \ }) \ AST_NODE_KIND(BitFieldType, "bit field type", struct { \ Token token; \ - AstNodeArray fields; /* FieldValue with : */ \ + Array fields; /* FieldValue with : */ \ AstNode *align; \ }) \ AST_NODE_KIND(MapType, "map type", struct { \ @@ -410,13 +409,13 @@ AST_NODE_KIND(_TypeBegin, "", i32) \ }) \ AST_NODE_KIND(_TypeEnd, "", i32) -typedef enum AstNodeKind { +enum AstNodeKind { AstNode_Invalid, #define AST_NODE_KIND(_kind_name_, ...) GB_JOIN2(AstNode_, _kind_name_), AST_NODE_KINDS #undef AST_NODE_KIND AstNode_Count, -} AstNodeKind; +}; String const ast_node_strings[] = { {cast(u8 *)"invalid node", gb_size_of("invalid node")}, @@ -429,7 +428,7 @@ String const ast_node_strings[] = { AST_NODE_KINDS #undef AST_NODE_KIND -typedef struct AstNode { +struct AstNode { AstNodeKind kind; u32 stmt_state_flags; union { @@ -437,7 +436,7 @@ typedef struct AstNode { AST_NODE_KINDS #undef AST_NODE_KIND }; -} AstNode; +}; #define ast_node(n_, Kind_, node_) GB_JOIN2(AstNode, Kind_) *n_ = &(node_)->Kind_; GB_ASSERT((node_)->kind == GB_JOIN2(AstNode_, Kind_)) @@ -560,8 +559,8 @@ Token ast_node_token(AstNode *node) { } AstNode *clone_ast_node(gbAllocator a, AstNode *node); -AstNodeArray clone_ast_node_array(gbAllocator a, AstNodeArray array) { - AstNodeArray result = {}; +Array clone_ast_node_array(gbAllocator a, Array array) { + Array result = {}; if (array.count > 0) { array_init_count(&result, a, array.count); for_array(i, array) { @@ -933,7 +932,7 @@ AstNode *ast_paren_expr(AstFile *f, AstNode *expr, Token open, Token close) { return result; } -AstNode *ast_call_expr(AstFile *f, AstNode *proc, AstNodeArray args, Token open, Token close, Token ellipsis) { +AstNode *ast_call_expr(AstFile *f, AstNode *proc, Array args, Token open, Token close, Token ellipsis) { AstNode *result = make_ast_node(f, AstNode_CallExpr); result->CallExpr.proc = proc; result->CallExpr.args = args; @@ -943,7 +942,7 @@ AstNode *ast_call_expr(AstFile *f, AstNode *proc, AstNodeArray args, Token open, return result; } -AstNode *ast_macro_call_expr(AstFile *f, AstNode *macro, Token bang, AstNodeArray args, Token open, Token close) { +AstNode *ast_macro_call_expr(AstFile *f, AstNode *macro, Token bang, Array args, Token open, Token close) { AstNode *result = make_ast_node(f, AstNode_MacroCallExpr); result->MacroCallExpr.macro = macro; result->MacroCallExpr.bang = bang; @@ -1048,7 +1047,7 @@ AstNode *ast_field_value(AstFile *f, AstNode *field, AstNode *value, Token eq) { return result; } -AstNode *ast_compound_lit(AstFile *f, AstNode *type, AstNodeArray elems, Token open, Token close) { +AstNode *ast_compound_lit(AstFile *f, AstNode *type, Array elems, Token open, Token close) { AstNode *result = make_ast_node(f, AstNode_CompoundLit); result->CompoundLit.type = type; result->CompoundLit.elems = elems; @@ -1101,7 +1100,7 @@ AstNode *ast_expr_stmt(AstFile *f, AstNode *expr) { return result; } -AstNode *ast_assign_stmt(AstFile *f, Token op, AstNodeArray lhs, AstNodeArray rhs) { +AstNode *ast_assign_stmt(AstFile *f, Token op, Array lhs, Array rhs) { AstNode *result = make_ast_node(f, AstNode_AssignStmt); result->AssignStmt.op = op; result->AssignStmt.lhs = lhs; @@ -1119,7 +1118,7 @@ AstNode *ast_inc_dec_stmt(AstFile *f, Token op, AstNode *expr) { -AstNode *ast_block_stmt(AstFile *f, AstNodeArray stmts, Token open, Token close) { +AstNode *ast_block_stmt(AstFile *f, Array stmts, Token open, Token close) { AstNode *result = make_ast_node(f, AstNode_BlockStmt); result->BlockStmt.stmts = stmts; result->BlockStmt.open = open; @@ -1147,7 +1146,7 @@ AstNode *ast_when_stmt(AstFile *f, Token token, AstNode *cond, AstNode *body, As } -AstNode *ast_return_stmt(AstFile *f, Token token, AstNodeArray results) { +AstNode *ast_return_stmt(AstFile *f, Token token, Array results) { AstNode *result = make_ast_node(f, AstNode_ReturnStmt); result->ReturnStmt.token = token; result->ReturnStmt.results = results; @@ -1194,7 +1193,7 @@ AstNode *ast_type_match_stmt(AstFile *f, Token token, AstNode *tag, AstNode *bod return result; } -AstNode *ast_case_clause(AstFile *f, Token token, AstNodeArray list, AstNodeArray stmts) { +AstNode *ast_case_clause(AstFile *f, Token token, Array list, Array stmts) { AstNode *result = make_ast_node(f, AstNode_CaseClause); result->CaseClause.token = token; result->CaseClause.list = list; @@ -1217,7 +1216,7 @@ AstNode *ast_branch_stmt(AstFile *f, Token token, AstNode *label) { return result; } -AstNode *ast_using_stmt(AstFile *f, Token token, AstNodeArray list) { +AstNode *ast_using_stmt(AstFile *f, Token token, Array list) { AstNode *result = make_ast_node(f, AstNode_UsingStmt); result->UsingStmt.token = token; result->UsingStmt.list = list; @@ -1277,7 +1276,7 @@ AstNode *ast_bad_decl(AstFile *f, Token begin, Token end) { return result; } -AstNode *ast_field(AstFile *f, AstNodeArray names, AstNode *type, u32 flags) { +AstNode *ast_field(AstFile *f, Array names, AstNode *type, u32 flags) { AstNode *result = make_ast_node(f, AstNode_Field); result->Field.names = names; result->Field.type = type; @@ -1285,7 +1284,7 @@ AstNode *ast_field(AstFile *f, AstNodeArray names, AstNode *type, u32 flags) { return result; } -AstNode *ast_field_list(AstFile *f, Token token, AstNodeArray list) { +AstNode *ast_field_list(AstFile *f, Token token, Array list) { AstNode *result = make_ast_node(f, AstNode_FieldList); result->FieldList.token = token; result->FieldList.list = list; @@ -1354,7 +1353,7 @@ AstNode *ast_vector_type(AstFile *f, Token token, AstNode *count, AstNode *elem) return result; } -AstNode *ast_struct_type(AstFile *f, Token token, AstNodeArray fields, isize field_count, +AstNode *ast_struct_type(AstFile *f, Token token, Array fields, isize field_count, bool is_packed, bool is_ordered, AstNode *align) { AstNode *result = make_ast_node(f, AstNode_StructType); result->StructType.token = token; @@ -1367,7 +1366,7 @@ AstNode *ast_struct_type(AstFile *f, Token token, AstNodeArray fields, isize fie } -AstNode *ast_union_type(AstFile *f, Token token, AstNodeArray fields, isize field_count, AstNodeArray variants) { +AstNode *ast_union_type(AstFile *f, Token token, Array fields, isize field_count, Array variants) { AstNode *result = make_ast_node(f, AstNode_UnionType); result->UnionType.token = token; result->UnionType.fields = fields; @@ -1376,7 +1375,7 @@ AstNode *ast_union_type(AstFile *f, Token token, AstNodeArray fields, isize fiel return result; } -AstNode *ast_raw_union_type(AstFile *f, Token token, AstNodeArray fields, isize field_count) { +AstNode *ast_raw_union_type(AstFile *f, Token token, Array fields, isize field_count) { AstNode *result = make_ast_node(f, AstNode_RawUnionType); result->RawUnionType.token = token; result->RawUnionType.fields = fields; @@ -1385,7 +1384,7 @@ AstNode *ast_raw_union_type(AstFile *f, Token token, AstNodeArray fields, isize } -AstNode *ast_enum_type(AstFile *f, Token token, AstNode *base_type, AstNodeArray fields) { +AstNode *ast_enum_type(AstFile *f, Token token, AstNode *base_type, Array fields) { AstNode *result = make_ast_node(f, AstNode_EnumType); result->EnumType.token = token; result->EnumType.base_type = base_type; @@ -1393,7 +1392,7 @@ AstNode *ast_enum_type(AstFile *f, Token token, AstNode *base_type, AstNodeArray return result; } -AstNode *ast_bit_field_type(AstFile *f, Token token, AstNodeArray fields, AstNode *align) { +AstNode *ast_bit_field_type(AstFile *f, Token token, Array fields, AstNode *align) { AstNode *result = make_ast_node(f, AstNode_BitFieldType); result->BitFieldType.token = token; result->BitFieldType.fields = fields; @@ -1411,7 +1410,7 @@ AstNode *ast_map_type(AstFile *f, Token token, AstNode *count, AstNode *key, Ast } -AstNode *ast_value_decl(AstFile *f, bool is_var, AstNodeArray names, AstNode *type, AstNodeArray values) { +AstNode *ast_value_decl(AstFile *f, bool is_var, Array names, AstNode *type, Array values) { AstNode *result = make_ast_node(f, AstNode_ValueDecl); result->ValueDecl.is_var = is_var; result->ValueDecl.names = names; @@ -1693,7 +1692,7 @@ void expect_semicolon(AstFile *f, AstNode *s) { AstNode * parse_expr(AstFile *f, bool lhs); AstNode * parse_proc_type(AstFile *f, AstNode **foreign_library, String *foreign_name, String *link_name); -AstNodeArray parse_stmt_list(AstFile *f); +Array parse_stmt_list(AstFile *f); AstNode * parse_stmt(AstFile *f); AstNode * parse_body(AstFile *f); @@ -1731,8 +1730,8 @@ AstNode *unparen_expr(AstNode *node) { AstNode *parse_value(AstFile *f); -AstNodeArray parse_element_list(AstFile *f) { - AstNodeArray elems = make_ast_node_array(f); +Array parse_element_list(AstFile *f) { + Array elems = make_ast_node_array(f); while (f->curr_token.kind != Token_CloseBrace && f->curr_token.kind != Token_EOF) { @@ -1754,7 +1753,7 @@ AstNodeArray parse_element_list(AstFile *f) { } AstNode *parse_literal_value(AstFile *f, AstNode *type) { - AstNodeArray elems = {}; + Array elems = {}; Token open = expect_token(f, Token_OpenBrace); f->expr_level++; if (f->curr_token.kind != Token_CloseBrace) { @@ -1946,8 +1945,8 @@ void parse_proc_tags(AstFile *f, u64 *tags, AstNode **foreign_library_token, Str } -AstNodeArray parse_lhs_expr_list(AstFile *f); -AstNodeArray parse_rhs_expr_list(AstFile *f); +Array parse_lhs_expr_list(AstFile *f); +Array parse_rhs_expr_list(AstFile *f); AstNode * parse_simple_stmt (AstFile *f, StmtAllowFlag flags); AstNode * parse_type (AstFile *f); @@ -2109,7 +2108,7 @@ bool is_literal_type(AstNode *node) { } AstNode *parse_call_expr(AstFile *f, AstNode *operand) { - AstNodeArray args = make_ast_node_array(f); + Array args = make_ast_node_array(f); Token open_paren, close_paren; Token ellipsis = {}; @@ -2144,7 +2143,7 @@ AstNode *parse_call_expr(AstFile *f, AstNode *operand) { AstNode *parse_macro_call_expr(AstFile *f, AstNode *operand) { - AstNodeArray args = make_ast_node_array(f); + Array args = make_ast_node_array(f); Token bang, open_paren, close_paren; bang = expect_token(f, Token_Not); @@ -2411,8 +2410,8 @@ AstNode *parse_expr(AstFile *f, bool lhs) { } -AstNodeArray parse_expr_list(AstFile *f, bool lhs) { - AstNodeArray list = make_ast_node_array(f); +Array parse_expr_list(AstFile *f, bool lhs) { + Array list = make_ast_node_array(f); for (;;) { AstNode *e = parse_expr(f, lhs); array_add(&list, e); @@ -2426,16 +2425,16 @@ AstNodeArray parse_expr_list(AstFile *f, bool lhs) { return list; } -AstNodeArray parse_lhs_expr_list(AstFile *f) { +Array parse_lhs_expr_list(AstFile *f) { return parse_expr_list(f, true); } -AstNodeArray parse_rhs_expr_list(AstFile *f) { +Array parse_rhs_expr_list(AstFile *f) { return parse_expr_list(f, false); } -AstNodeArray parse_ident_list(AstFile *f) { - AstNodeArray list = make_ast_node_array(f); +Array parse_ident_list(AstFile *f) { + Array list = make_ast_node_array(f); do { array_add(&list, parse_ident(f)); @@ -2470,9 +2469,9 @@ AstNode *parse_type(AstFile *f) { } -AstNode *parse_value_decl(AstFile *f, AstNodeArray lhs) { +AstNode *parse_value_decl(AstFile *f, Array lhs) { AstNode *type = NULL; - AstNodeArray values = {}; + Array values = {}; bool is_mutable = true; if (allow_token(f, Token_Colon)) { @@ -2516,7 +2515,7 @@ AstNode *parse_value_decl(AstFile *f, AstNodeArray lhs) { values = make_ast_node_array(f); } - AstNodeArray specs = {}; + Array specs = {}; array_init(&specs, heap_allocator(), 1); return ast_value_decl(f, is_mutable, lhs, type, values); } @@ -2524,7 +2523,7 @@ AstNode *parse_value_decl(AstFile *f, AstNodeArray lhs) { AstNode *parse_simple_stmt(AstFile *f, StmtAllowFlag flags) { - AstNodeArray lhs = parse_lhs_expr_list(f); + Array lhs = parse_lhs_expr_list(f); Token token = f->curr_token; switch (token.kind) { case Token_Eq: @@ -2548,7 +2547,7 @@ AstNode *parse_simple_stmt(AstFile *f, StmtAllowFlag flags) { return ast_bad_stmt(f, f->curr_token, f->curr_token); } next_token(f); - AstNodeArray rhs = parse_rhs_expr_list(f); + Array rhs = parse_rhs_expr_list(f); if (rhs.count == 0) { syntax_error(token, "No right-hand side in assignment statement."); return ast_bad_stmt(f, token, f->curr_token); @@ -2564,7 +2563,7 @@ AstNode *parse_simple_stmt(AstFile *f, StmtAllowFlag flags) { AstNode *expr = parse_expr(f, false); f->allow_range = prev_allow_range; - AstNodeArray rhs = {}; + Array rhs = {}; array_init_count(&rhs, heap_allocator(), 1); rhs[0] = expr; @@ -2638,8 +2637,8 @@ AstNode *parse_results(AstFile *f) { if (f->curr_token.kind != Token_OpenParen) { Token begin_token = f->curr_token; - AstNodeArray empty_names = {}; - AstNodeArray list = make_ast_node_array(f); + Array empty_names = {}; + Array list = make_ast_node_array(f); AstNode *type = parse_type(f); array_add(&list, ast_field(f, empty_names, type, 0)); return ast_field_list(f, begin_token, list); @@ -2698,13 +2697,13 @@ AstNode *parse_var_type(AstFile *f, bool allow_ellipsis) { } -typedef enum FieldPrefixKind { +enum FieldPrefixKind { FieldPrefix_Invalid, FieldPrefix_Using, FieldPrefix_Immutable, FieldPrefix_NoAlias, -} FieldPrefixKind; +}; FieldPrefixKind is_token_field_prefix(AstFile *f) { switch (f->curr_token.kind) { @@ -2781,13 +2780,13 @@ u32 check_field_prefixes(AstFile *f, isize name_count, u32 allowed_flags, u32 se return set_flags; } -typedef struct AstNodeAndFlags { +struct AstNodeAndFlags { AstNode *node; u32 flags; -} AstNodeAndFlags; +}; -AstNodeArray convert_to_ident_list(AstFile *f, Array list, bool ignore_flags) { - AstNodeArray idents = {}; +Array convert_to_ident_list(AstFile *f, Array list, bool ignore_flags) { + Array idents = {}; array_init(&idents, heap_allocator(), list.count); // Convert to ident list for_array(i, list) { @@ -2831,7 +2830,7 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok TokenKind separator = Token_Comma; Token start_token = f->curr_token; - AstNodeArray params = make_ast_node_array(f); + Array params = make_ast_node_array(f); Array list = {}; array_init(&list, heap_allocator()); // LEAK(bill): isize total_name_count = 0; bool allow_ellipsis = allowed_flags&FieldFlag_ellipsis; @@ -2850,7 +2849,7 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok } if (f->curr_token.kind == Token_Colon) { - AstNodeArray names = convert_to_ident_list(f, list, true); // Copy for semantic reasons + Array names = convert_to_ident_list(f, list, true); // Copy for semantic reasons if (names.count == 0) { syntax_error(f->curr_token, "Empty field declaration"); } @@ -2871,7 +2870,7 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok while (f->curr_token.kind != follow && f->curr_token.kind != Token_EOF) { u32 set_flags = parse_field_prefixes(f); - AstNodeArray names = parse_ident_list(f); + Array names = parse_ident_list(f); if (names.count == 0) { syntax_error(f->curr_token, "Empty field declaration"); break; @@ -2894,7 +2893,7 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok } for_array(i, list) { - AstNodeArray names = {}; + Array names = {}; AstNode *type = list[i].node; Token token = blank_token; @@ -3052,7 +3051,7 @@ AstNode *parse_type_or_ident(AstFile *f) { AstNode *fields = parse_record_fields(f, &decl_count, FieldFlag_using, str_lit("struct")); Token close = expect_token(f, Token_CloseBrace); - AstNodeArray decls = {}; + Array decls = {}; if (fields != NULL) { GB_ASSERT(fields->kind == AstNode_FieldList); decls = fields->FieldList.list; @@ -3064,15 +3063,15 @@ AstNode *parse_type_or_ident(AstFile *f) { case Token_union: { Token token = expect_token(f, Token_union); Token open = expect_token_after(f, Token_OpenBrace, "union"); - AstNodeArray decls = make_ast_node_array(f); - AstNodeArray variants = make_ast_node_array(f); + Array decls = make_ast_node_array(f); + Array variants = make_ast_node_array(f); isize total_decl_name_count = 0; while (f->curr_token.kind != Token_CloseBrace && f->curr_token.kind != Token_EOF) { u32 decl_flags = parse_field_prefixes(f); if (decl_flags != 0) { - AstNodeArray names = parse_ident_list(f); + Array names = parse_ident_list(f); if (names.count == 0) { syntax_error(f->curr_token, "Empty field declaration"); } @@ -3082,7 +3081,7 @@ AstNode *parse_type_or_ident(AstFile *f) { AstNode *type = parse_var_type(f, false); array_add(&decls, ast_field(f, names, type, set_flags)); } else { - AstNodeArray names = parse_ident_list(f); + Array names = parse_ident_list(f); if (names.count == 0) { break; } @@ -3121,7 +3120,7 @@ AstNode *parse_type_or_ident(AstFile *f) { AstNode *fields = parse_record_fields(f, &decl_count, FieldFlag_using, str_lit("raw_union")); Token close = expect_token(f, Token_CloseBrace); - AstNodeArray decls = {}; + Array decls = {}; if (fields != NULL) { GB_ASSERT(fields->kind == AstNode_FieldList); decls = fields->FieldList.list; @@ -3138,7 +3137,7 @@ AstNode *parse_type_or_ident(AstFile *f) { } Token open = expect_token(f, Token_OpenBrace); - AstNodeArray values = parse_element_list(f); + Array values = parse_element_list(f); Token close = expect_token(f, Token_CloseBrace); return ast_enum_type(f, token, base_type, values); @@ -3146,7 +3145,7 @@ AstNode *parse_type_or_ident(AstFile *f) { case Token_bit_field: { Token token = expect_token(f, Token_bit_field); - AstNodeArray fields = make_ast_node_array(f); + Array fields = make_ast_node_array(f); AstNode *align = NULL; Token open, close; @@ -3212,7 +3211,7 @@ AstNode *parse_type_or_ident(AstFile *f) { AstNode *parse_body(AstFile *f) { - AstNodeArray stmts = {}; + Array stmts = {}; Token open, close; isize prev_expr_level = f->expr_level; @@ -3328,7 +3327,7 @@ AstNode *parse_return_stmt(AstFile *f) { } Token token = expect_token(f, Token_return); - AstNodeArray results; + Array results; if (f->curr_token.kind != Token_Semicolon && f->curr_token.kind != Token_CloseBrace) { results = parse_rhs_expr_list(f); } else { @@ -3355,7 +3354,7 @@ AstNode *parse_return_stmt(AstFile *f) { // } // Token token = expect_token(f, Token_give); -// AstNodeArray results; +// Array results; // if (f->curr_token.kind != Token_Semicolon && f->curr_token.kind != Token_CloseBrace) { // results = parse_rhs_expr_list(f); // } else { @@ -3440,7 +3439,7 @@ AstNode *parse_for_stmt(AstFile *f) { AstNode *parse_case_clause(AstFile *f, bool is_type) { Token token = f->curr_token; - AstNodeArray list = make_ast_node_array(f); + Array list = make_ast_node_array(f); expect_token(f, Token_case); bool prev_allow_range = f->allow_range; f->allow_range = !is_type; @@ -3449,7 +3448,7 @@ AstNode *parse_case_clause(AstFile *f, bool is_type) { } f->allow_range = prev_allow_range; expect_token(f, Token_Colon); // TODO(bill): Is this the best syntax? - AstNodeArray stmts = parse_stmt_list(f); + Array stmts = parse_stmt_list(f); return ast_case_clause(f, token, list, stmts); } @@ -3467,7 +3466,7 @@ AstNode *parse_match_stmt(AstFile *f) { AstNode *body = NULL; Token open, close; bool is_type_match = false; - AstNodeArray list = make_ast_node_array(f); + Array list = make_ast_node_array(f); if (f->curr_token.kind != Token_OpenBrace) { isize prev_level = f->expr_level; @@ -3607,7 +3606,7 @@ AstNode *parse_stmt(AstFile *f) { case Token_using: { // TODO(bill): Make using statements better Token token = expect_token(f, Token_using); - AstNodeArray list = parse_lhs_expr_list(f); + Array list = parse_lhs_expr_list(f); if (list.count == 0) { syntax_error(token, "Illegal use of `using` statement"); expect_semicolon(f, NULL); @@ -3878,8 +3877,8 @@ AstNode *parse_stmt(AstFile *f) { return ast_bad_stmt(f, token, f->curr_token); } -AstNodeArray parse_stmt_list(AstFile *f) { - AstNodeArray list = make_ast_node_array(f); +Array parse_stmt_list(AstFile *f) { + Array list = make_ast_node_array(f); while (f->curr_token.kind != Token_case && f->curr_token.kind != Token_CloseBrace && @@ -4042,7 +4041,7 @@ bool is_import_path_valid(String path) { return false; } -void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, AstNodeArray decls) { +void parse_setup_file_decls(Parser *p, AstFile *f, String base_dir, Array decls) { for_array(i, decls) { AstNode *node = decls[i]; if (!is_ast_node_decl(node) && diff --git a/src/ssa.cpp b/src/ssa.cpp index ebda96c31..010d11e6c 100644 --- a/src/ssa.cpp +++ b/src/ssa.cpp @@ -1,15 +1,15 @@ -typedef struct ssaModule ssaModule; -typedef struct ssaValue ssaValue; -typedef struct ssaValueArgs ssaValueArgs; -typedef struct ssaDefer ssaDefer; -typedef struct ssaBlock ssaBlock; -typedef struct ssaProc ssaProc; -typedef struct ssaEdge ssaEdge; -typedef struct ssaRegister ssaRegister; -typedef struct ssaTargetList ssaTargetList; -typedef enum ssaBlockKind ssaBlockKind; -typedef enum ssaBranchPrediction ssaBranchPrediction; -typedef enum ssaDeferExitKind ssaDeferExitKind; +struct ssaModule; +struct ssaValue; +struct ssaValueArgs; +struct ssaDefer; +struct ssaBlock; +struct ssaProc; +struct ssaEdge; +struct ssaRegister; +struct ssaTargetList; +enum ssaBlockKind; +enum ssaBranchPrediction; +enum ssaDeferExitKind; String ssa_mangle_name(ssaModule *m, String path, Entity *e); @@ -19,8 +19,6 @@ String ssa_mangle_name(ssaModule *m, String path, Entity *e); #define MAP_NAME MapSsaValue #include "map.cpp" -typedef Array ssaValueArray; - #include "ssa_op.cpp" #define SSA_DEFAULT_VALUE_ARG_CAPACITY 8 @@ -76,10 +74,10 @@ enum ssaBranchPrediction { ssaBranch_Unlikely = -1, }; -typedef enum ssaDeferKind { +enum ssaDeferKind { ssaDefer_Node, ssaDefer_Instr, -} ssaDeferKind; +}; struct ssaDefer { ssaDeferKind kind; @@ -106,8 +104,6 @@ struct ssaEdge { isize index; }; -typedef Array ssaEdgeArray; - struct ssaBlock { i32 id; // Unique identifier but the pointer could be used too ssaBlockKind kind; @@ -124,9 +120,9 @@ struct ssaBlock { // - BlockExit will be a memory control value ssaValue *control; - ssaValueArray values; - ssaEdgeArray preds; - ssaEdgeArray succs; + Array values; + Array preds; + Array succs; }; struct ssaTargetList { @@ -182,18 +178,18 @@ struct ssaModule { u32 stmt_state_flags; Array procs; - ssaValueArray procs_to_generate; + Array procs_to_generate; }; -typedef enum ssaAddrKind { +enum ssaAddrKind { ssaAddr_Default, ssaAddr_Map, -} ssaAddrKind; +}; -typedef struct ssaAddr { +struct ssaAddr { ssaValue * addr; ssaAddrKind kind; -} ssaAddr; +}; @@ -408,7 +404,7 @@ ssaValue *ssa_const_int(ssaProc *p, Type *t, i64 c) { ssaAddr ssa_build_addr (ssaProc *p, AstNode *expr); ssaValue *ssa_build_expr (ssaProc *p, AstNode *expr); void ssa_build_stmt (ssaProc *p, AstNode *node); -void ssa_build_stmt_list(ssaProc *p, AstNodeArray nodes); +void ssa_build_stmt_list(ssaProc *p, Array nodes); ssaValue *ssa_emit_deep_field_ptr_index(ssaProc *p, ssaValue *e, Selection sel); @@ -1870,7 +1866,7 @@ ssaValue *ssa_build_expr(ssaProc *p, AstNode *expr) { -void ssa_build_stmt_list(ssaProc *p, AstNodeArray nodes) { +void ssa_build_stmt_list(ssaProc *p, Array nodes) { for_array(i, nodes) { ssa_build_stmt(p, nodes[i]); } @@ -1989,7 +1985,7 @@ void ssa_build_stmt_internal(ssaProc *p, AstNode *node) { } } else { Array lvals = {0}; - ssaValueArray inits = {0}; + Array inits = {0}; array_init(&lvals, m->tmp_allocator, vd->names.count); array_init(&inits, m->tmp_allocator, vd->names.count); @@ -2057,7 +2053,7 @@ void ssa_build_stmt_internal(ssaProc *p, AstNode *node) { ssaValue *init = ssa_build_expr(p, rhs); ssa_addr_store(p, lvals[0], init); } else { - ssaValueArray inits; + Array inits; array_init(&inits, m->tmp_allocator, lvals.count); for_array(i, as->rhs) { @@ -2070,7 +2066,7 @@ void ssa_build_stmt_internal(ssaProc *p, AstNode *node) { } } } else { - ssaValueArray inits; + Array inits; array_init(&inits, m->tmp_allocator, lvals.count); for_array(i, as->rhs) { diff --git a/src/ssa_op.cpp b/src/ssa_op.cpp index 4c1921065..c62e7cf77 100644 --- a/src/ssa_op.cpp +++ b/src/ssa_op.cpp @@ -267,7 +267,6 @@ enum ssaOp { SSA_OPS #undef SSA_OP }; -typedef enum ssaOp ssaOp; String const ssa_op_strings[] = { #define SSA_OP(k) {cast(u8 *)#k, gb_size_of(#k)-1}, diff --git a/src/string.cpp b/src/string.cpp index 105e9961b..6b6302ede 100644 --- a/src/string.cpp +++ b/src/string.cpp @@ -9,7 +9,7 @@ void init_string_buffer_memory(void) { // NOTE(bill): Used for UTF-8 strings -typedef struct String { +struct String { u8 * text; isize len; @@ -21,7 +21,7 @@ typedef struct String { GB_ASSERT(0 <= i && i < len); return text[i]; } -} String; +}; // NOTE(bill): used for printf style arguments #define LIT(x) ((int)(x).len), (x).text #define STR_LIT(c_str) {cast(u8 *)c_str, gb_size_of(c_str)-1} @@ -29,7 +29,7 @@ typedef struct String { // NOTE(bill): String16 is only used for Windows due to its file directories -typedef struct String16 { +struct String16 { wchar_t *text; isize len; wchar_t &operator[](isize i) { @@ -40,7 +40,7 @@ typedef struct String16 { GB_ASSERT(0 <= i && i < len); return text[i]; } -} String16; +}; gb_inline String make_string(u8 *text, isize len) { diff --git a/src/timings.cpp b/src/timings.cpp index 04c1667f4..d00d5d0ba 100644 --- a/src/timings.cpp +++ b/src/timings.cpp @@ -1,14 +1,14 @@ -typedef struct TimeStamp { +struct TimeStamp { u64 start; u64 finish; String label; -} TimeStamp; +}; -typedef struct Timings { +struct Timings { TimeStamp total; Array sections; u64 freq; -} Timings; +}; #if defined(GB_SYSTEM_WINDOWS) diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index 9e4151c50..38026deeb 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -117,11 +117,11 @@ TOKEN_KIND(Token__KeywordBegin, "_KeywordBegin"), \ TOKEN_KIND(Token__KeywordEnd, "_KeywordEnd"), \ TOKEN_KIND(Token_Count, "") -typedef enum TokenKind { +enum TokenKind { #define TOKEN_KIND(e, s) e TOKEN_KINDS #undef TOKEN_KIND -} TokenKind; +}; String const token_strings[] = { #define TOKEN_KIND(e, s) {cast(u8 *)s, gb_size_of(s)-1} @@ -130,11 +130,11 @@ String const token_strings[] = { }; -typedef struct TokenPos { +struct TokenPos { String file; isize line; isize column; -} TokenPos; +}; i32 token_pos_cmp(TokenPos a, TokenPos b) { if (a.line == b.line) { @@ -152,11 +152,11 @@ bool token_pos_eq(TokenPos a, TokenPos b) { return token_pos_cmp(a, b) == 0; } -typedef struct Token { +struct Token { TokenKind kind; String string; TokenPos pos; -} Token; +}; Token empty_token = {Token_Invalid}; Token blank_token = {Token_Ident, {cast(u8 *)"_", 1}}; @@ -167,12 +167,12 @@ Token make_token_ident(String s) { } -typedef struct ErrorCollector { +struct ErrorCollector { TokenPos prev; i64 count; i64 warning_count; gbMutex mutex; -} ErrorCollector; +}; gb_global ErrorCollector global_error_collector; @@ -306,7 +306,7 @@ gb_inline bool token_is_shift(TokenKind t) { gb_inline void print_token(Token t) { gb_printf("%.*s\n", LIT(t.string)); } -typedef enum TokenizerInitError { +enum TokenizerInitError { TokenizerInit_None, TokenizerInit_Invalid, @@ -315,18 +315,18 @@ typedef enum TokenizerInitError { TokenizerInit_Empty, TokenizerInit_Count, -} TokenizerInitError; +}; -typedef struct TokenizerState { +struct TokenizerState { Rune curr_rune; // current character u8 * curr; // character pos u8 * read_curr; // pos from start u8 * line; // current line pos isize line_count; -} TokenizerState; +}; -typedef struct Tokenizer { +struct Tokenizer { String fullpath; u8 *start; u8 *end; @@ -339,7 +339,7 @@ typedef struct Tokenizer { isize error_count; Array allocated_strings; -} Tokenizer; +}; TokenizerState save_tokenizer_state(Tokenizer *t) { diff --git a/src/types.cpp b/src/types.cpp index 5ec5a40e9..4c02e2283 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1,6 +1,6 @@ -typedef struct Scope Scope; +struct Scope; -typedef enum BasicKind { +enum BasicKind { Basic_Invalid, Basic_bool, Basic_i8, @@ -41,9 +41,9 @@ typedef enum BasicKind { Basic_COUNT, Basic_byte = Basic_u8, -} BasicKind; +}; -typedef enum BasicFlag { +enum BasicFlag { BasicFlag_Boolean = GB_BIT(0), BasicFlag_Integer = GB_BIT(1), BasicFlag_Unsigned = GB_BIT(2), @@ -57,16 +57,16 @@ typedef enum BasicFlag { BasicFlag_Numeric = BasicFlag_Integer | BasicFlag_Float | BasicFlag_Complex, BasicFlag_Ordered = BasicFlag_Integer | BasicFlag_Float | BasicFlag_String | BasicFlag_Pointer | BasicFlag_Rune, BasicFlag_ConstantType = BasicFlag_Boolean | BasicFlag_Numeric | BasicFlag_String | BasicFlag_Pointer | BasicFlag_Rune, -} BasicFlag; +}; -typedef struct BasicType { +struct BasicType { BasicKind kind; u32 flags; i64 size; // -1 if arch. dep. String name; -} BasicType; +}; -typedef enum TypeRecordKind { +enum TypeRecordKind { TypeRecord_Invalid, TypeRecord_Struct, @@ -75,9 +75,9 @@ typedef enum TypeRecordKind { TypeRecord_Enum, TypeRecord_Count, -} TypeRecordKind; +}; -typedef struct TypeRecord { +struct TypeRecord { TypeRecordKind kind; // All record types @@ -109,7 +109,7 @@ typedef struct TypeRecord { Entity * enum_count; Entity * enum_min_value; Entity * enum_max_value; -} TypeRecord; +}; #define TYPE_KINDS \ TYPE_KIND(Basic, BasicType) \ @@ -164,13 +164,13 @@ typedef struct TypeRecord { -typedef enum TypeKind { +enum TypeKind { Type_Invalid, #define TYPE_KIND(k, ...) GB_JOIN2(Type_, k), TYPE_KINDS #undef TYPE_KIND Type_Count, -} TypeKind; +}; String const type_strings[] = { {cast(u8 *)"Invalid", gb_size_of("Invalid")}, @@ -183,7 +183,7 @@ String const type_strings[] = { TYPE_KINDS #undef TYPE_KIND -typedef struct Type { +struct Type { TypeKind kind; union { #define TYPE_KIND(k, ...) GB_JOIN2(Type, k) k; @@ -191,16 +191,16 @@ typedef struct Type { #undef TYPE_KIND }; bool failure; -} Type; +}; // TODO(bill): Should I add extra information here specifying the kind of selection? // e.g. field, constant, vector field, type field, etc. -typedef struct Selection { +struct Selection { Entity * entity; Array index; bool indirect; // Set if there was a pointer deref anywhere down the line -} Selection; +}; Selection empty_selection = {0}; Selection make_selection(Entity *entity, Array index, bool indirect) { @@ -1199,7 +1199,7 @@ bool is_type_cte_safe(Type *type) { return false; } -typedef enum ProcTypeOverloadKind { +enum ProcTypeOverloadKind { ProcOverload_Identical, // The types are identical ProcOverload_CallingConvention, @@ -1211,7 +1211,7 @@ typedef enum ProcTypeOverloadKind { ProcOverload_NotProcedure, -} ProcTypeOverloadKind; +}; ProcTypeOverloadKind are_proc_types_overload_safe(Type *x, Type *y) { if (x == NULL && y == NULL) return ProcOverload_NotProcedure; @@ -1508,10 +1508,10 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n } -typedef struct TypePath { +struct TypePath { Array path; // Entity_TypeName; bool failure; -} TypePath; +}; void type_path_init(TypePath *tp) { // TODO(bill): Use an allocator that uses a backing array if it can and then use alternative allocator when exhausted -- cgit v1.2.3 From 366b306df04e14a5841868a40016cd844e120d99 Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Sun, 11 Jun 2017 18:38:30 +0100 Subject: Default parameters for procedures --- src/check_expr.cpp | 118 +++++++++++++++++++++++++++++++++++++++++------------ src/entity.cpp | 9 ++-- src/ir.cpp | 39 ++++++++++++++---- src/parser.cpp | 60 +++++++++++++++++++++------ 4 files changed, 175 insertions(+), 51 deletions(-) (limited to 'src/entity.cpp') diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 07fe9cbc2..a8453f0cb 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -255,13 +255,18 @@ i64 check_distance_between_types(Checker *c, Operand *operand, Type *type) { } +i64 assign_score_function(i64 distance) { + // TODO(bill): A decent score function + return gb_max(1000000 - distance*distance, 0); +} + + bool check_is_assignable_to_with_score(Checker *c, Operand *operand, Type *type, i64 *score_) { i64 score = 0; i64 distance = check_distance_between_types(c, operand, type); bool ok = distance >= 0; if (ok) { - // TODO(bill): A decent score function - score = gb_max(1000000 - distance*distance, 0); + score = assign_score_function(distance); } if (score_) *score_ = score; return ok; @@ -1051,7 +1056,22 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari } ast_node(p, Field, params[i]); AstNode *type_expr = p->type; - if (type_expr) { + Type *type = NULL; + AstNode *default_value = p->default_value; + ExactValue value = {}; + + if (type_expr == NULL) { + Operand o = {}; + check_expr(c, &o, default_value); + + if (o.mode != Addressing_Constant) { + error_node(default_value, "Default parameter must be a constant"); + } else { + value = o.value; + } + + type = default_type(o.type); + } else { if (type_expr->kind == AstNode_Ellipsis) { type_expr = type_expr->Ellipsis.expr; if (i+1 == params.count) { @@ -1061,28 +1081,49 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari } } - Type *type = check_type(c, type_expr); - if (p->flags&FieldFlag_no_alias) { - if (!is_type_pointer(type)) { - error_node(params[i], "`no_alias` can only be applied to fields of pointer type"); - p->flags &= ~FieldFlag_no_alias; // Remove the flag + type = check_type(c, type_expr); + + if (default_value != NULL) { + Operand o = {}; + check_expr(c, &o, default_value); + + if (o.mode != Addressing_Constant) { + error_node(default_value, "Default parameter must be a constant"); + } else { + value = o.value; } + + check_is_assignable_to(c, &o, type); } - for_array(j, p->names) { - AstNode *name = p->names[j]; - if (ast_node_expect(name, AstNode_Ident)) { - Entity *param = make_entity_param(c->allocator, scope, name->Ident, type, - (p->flags&FieldFlag_using) != 0, (p->flags&FieldFlag_immutable) != 0); - if (p->flags&FieldFlag_no_alias) { - param->flags |= EntityFlag_NoAlias; - } - if (p->flags&FieldFlag_immutable) { - param->Variable.is_immutable = true; - } - add_entity(c, scope, name, param); - variables[variable_index++] = param; + } + if (type == NULL) { + error_node(params[i], "Invalid parameter type"); + type = t_invalid; + } + + if (p->flags&FieldFlag_no_alias) { + if (!is_type_pointer(type)) { + error_node(params[i], "`no_alias` can only be applied to fields of pointer type"); + p->flags &= ~FieldFlag_no_alias; // Remove the flag + } + } + + for_array(j, p->names) { + AstNode *name = p->names[j]; + if (ast_node_expect(name, AstNode_Ident)) { + Entity *param = make_entity_param(c->allocator, scope, name->Ident, type, + (p->flags&FieldFlag_using) != 0, (p->flags&FieldFlag_immutable) != 0); + if (p->flags&FieldFlag_no_alias) { + param->flags |= EntityFlag_NoAlias; + } + if (p->flags&FieldFlag_immutable) { + param->Variable.is_immutable = true; } + param->Variable.default_value = value; + + add_entity(c, scope, name, param); + variables[variable_index++] = param; } } } @@ -4775,18 +4816,35 @@ typedef CALL_ARGUMENT_CHECKER(CallArgumentCheckerType); CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { ast_node(ce, CallExpr, call); isize param_count = 0; + isize param_count_excluding_defaults = 0; bool variadic = proc_type->Proc.variadic; bool vari_expand = (ce->ellipsis.pos.line != 0); i64 score = 0; bool show_error = show_error_mode == CallArgumentMode_ShowErrors; + TypeTuple *param_tuple = NULL; + if (proc_type->Proc.params != NULL) { - param_count = proc_type->Proc.params->Tuple.variable_count; + param_tuple = &proc_type->Proc.params->Tuple; + + param_count = param_tuple->variable_count; if (variadic) { param_count--; } } + param_count_excluding_defaults = param_count; + if (param_tuple != NULL) { + for (isize i = param_count-1; i >= 0; i--) { + Entity *e = param_tuple->variables[i]; + GB_ASSERT(e->kind == Entity_Variable); + if (e->Variable.default_value.kind == ExactValue_Invalid) { + break; + } + param_count_excluding_defaults--; + } + } + if (vari_expand && !variadic) { if (show_error) { error(ce->ellipsis, @@ -4797,13 +4855,13 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { return CallArgumentError_NonVariadicExpand; } - if (operands.count == 0 && param_count == 0) { + if (operands.count == 0 && param_count_excluding_defaults == 0) { if (score_) *score_ = score; return CallArgumentError_None; } i32 error_code = 0; - if (operands.count < param_count) { + if (operands.count < param_count_excluding_defaults) { error_code = -1; } else if (!variadic && operands.count > param_count) { error_code = +1; @@ -4818,7 +4876,7 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { if (show_error) { gbString proc_str = expr_to_string(ce->proc); - error_node(call, err_fmt, proc_str, param_count); + error_node(call, err_fmt, proc_str, param_count_excluding_defaults); gb_string_free(proc_str); } if (score_) *score_ = score; @@ -4828,9 +4886,9 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) { CallArgumentError err = CallArgumentError_None; GB_ASSERT(proc_type->Proc.params != NULL); - Entity **sig_params = proc_type->Proc.params->Tuple.variables; + Entity **sig_params = param_tuple->variables; isize operand_index = 0; - for (; operand_index < param_count; operand_index++) { + for (; operand_index < param_count_excluding_defaults; operand_index++) { Type *t = sig_params[operand_index]->type; Operand o = operands[operand_index]; if (variadic) { @@ -4972,6 +5030,12 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) { if (e->token.string == "_") { continue; } + GB_ASSERT(e->kind == Entity_Variable); + if (e->Variable.default_value.kind != ExactValue_Invalid) { + score += assign_score_function(1); + continue; + } + if (show_error) { gbString str = type_to_string(e->type); error_node(call, "Parameter `%.*s` of type `%s` is missing in procedure call", diff --git a/src/entity.cpp b/src/entity.cpp index d8159d449..26e94dbf1 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -81,10 +81,11 @@ struct Entity { ExactValue value; } Constant; struct { - i32 field_index; - i32 field_src_index; - bool is_immutable; - bool is_thread_local; + i32 field_index; + i32 field_src_index; + bool is_immutable; + bool is_thread_local; + ExactValue default_value; } Variable; struct { bool is_type_alias; diff --git a/src/ir.cpp b/src/ir.cpp index a8cfb0649..95c277f59 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -4616,16 +4616,20 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { } TypeTuple *pt = &type->params->Tuple; for (isize i = 0; i < param_count; i++) { - Type *param_type = pt->variables[i]->type; + Entity *e = pt->variables[i]; + GB_ASSERT(e->kind == Entity_Variable); if (args[i] == NULL) { - args[i] = ir_value_nil(proc->module->allocator, param_type); + if (e->Variable.default_value.kind != ExactValue_Invalid) { + args[i] = ir_value_constant(proc->module->allocator, e->type, e->Variable.default_value); + } else { + args[i] = ir_value_nil(proc->module->allocator, e->type); + } } else { - args[i] = ir_emit_conv(proc, args[i], param_type); + args[i] = ir_emit_conv(proc, args[i], e->type); } } return ir_emit_call(proc, value, args, param_count); - // GB_PANIC("HERE!\n"); } isize arg_index = 0; @@ -4640,7 +4644,9 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { arg_count++; } } - irValue **args = gb_alloc_array(proc->module->allocator, irValue *, arg_count); + + + irValue **args = gb_alloc_array(proc->module->allocator, irValue *, gb_max(type->param_count, arg_count)); bool variadic = type->variadic; bool vari_expand = ce->ellipsis.pos.line != 0; @@ -4660,6 +4666,23 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { TypeTuple *pt = &type->params->Tuple; + if (arg_count < type->param_count) { + isize end = type->param_count; + if (variadic) { + end--; + } + while (arg_index < end) { + Entity *e = pt->variables[arg_index]; + GB_ASSERT(e->kind == Entity_Variable); + if (e->Variable.default_value.kind != ExactValue_Invalid) { + args[arg_index++] = ir_value_constant(proc->module->allocator, e->type, e->Variable.default_value); + } else { + args[arg_index++] = ir_value_nil(proc->module->allocator, e->type); + } + } + } + + if (variadic) { isize i = 0; for (; i < type->param_count-1; i++) { @@ -4674,7 +4697,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { } } } else { - for (isize i = 0; i < arg_count; i++) { + for (isize i = 0; i < type->param_count; i++) { args[i] = ir_emit_conv(proc, args[i], pt->variables[i]->type); } } @@ -4704,7 +4727,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) { args[arg_count-1] = ir_emit_load(proc, slice); } - return ir_emit_call(proc, value, args, arg_count); + return ir_emit_call(proc, value, args, type->param_count); case_end; case_ast_node(se, SliceExpr, expr); @@ -6680,7 +6703,7 @@ void ir_number_proc_registers(irProcedure *proc) { b->index = i; for_array(j, b->instrs) { irValue *value = b->instrs[j]; - GB_ASSERT(value->kind == irValue_Instr); + GB_ASSERT_MSG(value->kind == irValue_Instr, "%.*s", LIT(proc->name)); irInstr *instr = &value->Instr; if (ir_instr_type(instr) == NULL) { // NOTE(bill): Ignore non-returning instructions value->index = -1; diff --git a/src/parser.cpp b/src/parser.cpp index d741e569f..2feaa1fc2 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -326,9 +326,10 @@ AST_NODE_KIND(_DeclBegin, "", i32) \ }) \ AST_NODE_KIND(_DeclEnd, "", i32) \ AST_NODE_KIND(Field, "field", struct { \ - Array names; \ - AstNode * type; \ - u32 flags; \ + Array names; \ + AstNode * type; \ + AstNode * default_value; \ + u32 flags; \ }) \ AST_NODE_KIND(FieldList, "field list", struct { \ Token token; \ @@ -1276,10 +1277,11 @@ AstNode *ast_bad_decl(AstFile *f, Token begin, Token end) { return result; } -AstNode *ast_field(AstFile *f, Array names, AstNode *type, u32 flags) { +AstNode *ast_field(AstFile *f, Array names, AstNode *type, AstNode *default_value, u32 flags) { AstNode *result = make_ast_node(f, AstNode_Field); result->Field.names = names; result->Field.type = type; + result->Field.default_value = default_value; result->Field.flags = flags; return result; } @@ -2645,7 +2647,7 @@ AstNode *parse_results(AstFile *f) { Array empty_names = {}; Array list = make_ast_node_array(f); AstNode *type = parse_type(f); - array_add(&list, ast_field(f, empty_names, type, 0)); + array_add(&list, ast_field(f, empty_names, type, NULL, 0)); return ast_field_list(f, begin_token, list); } @@ -2839,6 +2841,7 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok Array list = {}; array_init(&list, heap_allocator()); // LEAK(bill): isize total_name_count = 0; bool allow_ellipsis = allowed_flags&FieldFlag_ellipsis; + bool is_procedure = (allowed_flags&FieldFlag_Signature) != 0; while (f->curr_token.kind != follow && f->curr_token.kind != Token_Colon && @@ -2866,8 +2869,25 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok total_name_count += names.count; expect_token_after(f, Token_Colon, "field list"); - AstNode *type = parse_var_type(f, allow_ellipsis); - AstNode *param = ast_field(f, names, type, set_flags); + AstNode *type = NULL; + AstNode *default_value = NULL; + + if (f->curr_token.kind != Token_Eq) { + type = parse_var_type(f, allow_ellipsis); + } + if (allow_token(f, Token_Eq)) { + // TODO(bill): Should this be true==lhs or false==rhs? + default_value = parse_expr(f, true); + if (!is_procedure) { + syntax_error(f->curr_token, "Default parameters are only allowed for procedures"); + } + } + + if (default_value != NULL && names.count > 1) { + syntax_error(f->curr_token, "Default parameters can only be applied to single values"); + } + + AstNode *param = ast_field(f, names, type, default_value, set_flags); array_add(¶ms, param); parse_expect_field_separator(f, type); @@ -2884,8 +2904,24 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok total_name_count += names.count; expect_token_after(f, Token_Colon, "field list"); - AstNode *type = parse_var_type(f, allow_ellipsis); - AstNode *param = ast_field(f, names, type, set_flags); + AstNode *type = NULL; + AstNode *default_value = NULL; + if (f->curr_token.kind != Token_Eq) { + type = parse_var_type(f, allow_ellipsis); + } + if (allow_token(f, Token_Eq)) { + // TODO(bill): Should this be true==lhs or false==rhs? + default_value = parse_expr(f, true); + if (!is_procedure) { + syntax_error(f->curr_token, "Default parameters are only allowed for procedures"); + } + } + + if (default_value != NULL && names.count > 1) { + syntax_error(f->curr_token, "Default parameters can only be applied to single values"); + } + + AstNode *param = ast_field(f, names, type, default_value, set_flags); array_add(¶ms, param); if (!parse_expect_field_separator(f, param)) { @@ -2907,7 +2943,7 @@ AstNode *parse_field_list(AstFile *f, isize *name_count_, u32 allowed_flags, Tok names[0] = ast_ident(f, token); u32 flags = check_field_prefixes(f, list.count, allowed_flags, list[i].flags); - AstNode *param = ast_field(f, names, list[i].node, flags); + AstNode *param = ast_field(f, names, list[i].node, NULL, flags); array_add(¶ms, param); } @@ -3084,7 +3120,7 @@ AstNode *parse_type_or_ident(AstFile *f) { total_decl_name_count += names.count; expect_token_after(f, Token_Colon, "field list"); AstNode *type = parse_var_type(f, false); - array_add(&decls, ast_field(f, names, type, set_flags)); + array_add(&decls, ast_field(f, names, type, NULL, set_flags)); } else { Array names = parse_ident_list(f); if (names.count == 0) { @@ -3095,7 +3131,7 @@ AstNode *parse_type_or_ident(AstFile *f) { total_decl_name_count += names.count; expect_token_after(f, Token_Colon, "field list"); AstNode *type = parse_var_type(f, false); - array_add(&decls, ast_field(f, names, type, set_flags)); + array_add(&decls, ast_field(f, names, type, NULL, set_flags)); } else { AstNode *name = names[0]; Token open = expect_token(f, Token_OpenBrace); -- cgit v1.2.3