From 478d63424fb99c368a0cfae88704b2c903956a1d Mon Sep 17 00:00:00 2001 From: Ginger Bill Date: Mon, 19 Dec 2016 14:03:59 +0000 Subject: [PATCH] Remove `enum` for favour of Go-style enumerations --- code/demo.odin | 6 +- core/_preload.odin | 56 +++------ core/fmt.odin | 20 --- core/mem.odin | 13 +- core/os_windows.odin | 19 +-- core/sys/windows.odin | 281 +++++++++++++++++++++--------------------- src/checker/checker.c | 87 +------------ src/checker/decl.c | 22 ++-- src/checker/entity.c | 1 + src/checker/expr.c | 263 ++------------------------------------- src/checker/stmt.c | 93 +++++++------- src/checker/types.c | 101 ++------------- src/parser.c | 51 +------- src/ssa.c | 149 +--------------------- src/ssa_print.c | 3 - 15 files changed, 266 insertions(+), 899 deletions(-) diff --git a/code/demo.odin b/code/demo.odin index 61e1d5217..409fc3837 100644 --- a/code/demo.odin +++ b/code/demo.odin @@ -29,8 +29,8 @@ const ( EB; ); + proc main() { - fmt.println(X, Y, Z); - fmt.println(A, B, C); - fmt.println(KB, MB, GB, TB, PB, EB); + var x = 123; + fmt.println(x); } diff --git a/core/_preload.odin b/core/_preload.odin index d1791474e..acf96114f 100644 --- a/core/_preload.odin +++ b/core/_preload.odin @@ -70,11 +70,6 @@ type Type_Info union { Struct Type_Info_Record; Union Type_Info_Record; Raw_Union Type_Info_Record; - Enum struct #ordered { - base ^Type_Info; - values []i64; - names []string; - }; }; proc type_info_base(info ^Type_Info) -> ^Type_Info { @@ -113,12 +108,13 @@ proc fmuladd64(a, b, c f64) -> f64 #foreign "llvm.fmuladd.f64" -type Allocator_Mode enum { - ALLOC, - FREE, - FREE_ALL, - RESIZE, -} +type Allocator_Mode int; +const ( + ALLOCATOR_ALLOC Allocator_Mode = iota; + ALLOCATOR_FREE; + ALLOCATOR_FREE_ALL; + ALLOCATOR_RESIZE; +); type Allocator_Proc proc(allocator_data rawptr, mode Allocator_Mode, size, alignment int, old_memory rawptr, old_size int, flags u64) -> rawptr; @@ -162,20 +158,20 @@ proc alloc(size int) -> rawptr #inline { return alloc_align(size, DEFAULT_ALIGNM proc alloc_align(size, alignment int) -> rawptr #inline { __check_context(); var a = context.allocator; - return a.procedure(a.data, Allocator_Mode.ALLOC, size, alignment, nil, 0, 0); + return a.procedure(a.data, ALLOCATOR_ALLOC, size, alignment, nil, 0, 0); } proc free(ptr rawptr) #inline { __check_context(); var a = context.allocator; if ptr != nil { - a.procedure(a.data, Allocator_Mode.FREE, 0, 0, ptr, 0, 0); + a.procedure(a.data, ALLOCATOR_FREE, 0, 0, ptr, 0, 0); } } proc free_all() #inline { __check_context(); var a = context.allocator; - a.procedure(a.data, Allocator_Mode.FREE_ALL, 0, 0, nil, 0, 0); + a.procedure(a.data, ALLOCATOR_FREE_ALL, 0, 0, nil, 0, 0); } @@ -183,7 +179,7 @@ proc resize (ptr rawptr, old_size, new_size int) -> rawptr #inline { return proc resize_align(ptr rawptr, old_size, new_size, alignment int) -> rawptr #inline { __check_context(); var a = context.allocator; - return a.procedure(a.data, Allocator_Mode.RESIZE, new_size, alignment, ptr, old_size, 0); + return a.procedure(a.data, ALLOCATOR_RESIZE, new_size, alignment, ptr, old_size, 0); } @@ -216,10 +212,9 @@ proc default_resize_align(old_memory rawptr, old_size, new_size, alignment int) proc default_allocator_proc(allocator_data rawptr, mode Allocator_Mode, size, alignment int, old_memory rawptr, old_size int, flags u64) -> rawptr { - using Allocator_Mode; when false { match mode { - case ALLOC: + case ALLOCATOR_ALLOC: var total_size = size + alignment + size_of(mem.AllocationHeader); var ptr = os.heap_alloc(total_size); var header = ptr as ^mem.AllocationHeader; @@ -227,14 +222,14 @@ proc default_allocator_proc(allocator_data rawptr, mode Allocator_Mode, mem.allocation_header_fill(header, ptr, size); return mem.zero(ptr, size); - case FREE: + case ALLOCATOR_FREE: os.heap_free(mem.allocation_header(old_memory)); return nil; - case FREE_ALL: + case ALLOCATOR_FREE_ALL: // NOTE(bill): Does nothing - case RESIZE: + case ALLOCATOR_RESIZE: var total_size = size + alignment + size_of(mem.AllocationHeader); var ptr = os.heap_resize(mem.allocation_header(old_memory), total_size); var header = ptr as ^mem.AllocationHeader; @@ -244,17 +239,17 @@ proc default_allocator_proc(allocator_data rawptr, mode Allocator_Mode, } } else { match mode { - case ALLOC: + case ALLOCATOR_ALLOC: return os.heap_alloc(size); - case FREE: + case ALLOCATOR_FREE: os.heap_free(old_memory); return nil; - case FREE_ALL: + case ALLOCATOR_FREE_ALL: // NOTE(bill): Does nothing - case RESIZE: + case ALLOCATOR_RESIZE: return os.heap_resize(old_memory, size); } } @@ -332,17 +327,4 @@ proc __substring_expr_error(file string, line, column int, low, high int) { __debug_trap(); } -proc __enum_to_string(info ^Type_Info, value i64) -> string { - match type ti : type_info_base(info) { - case Type_Info.Enum: - // TODO(bill): Search faster than linearly - for var i = 0; i < ti.values.count; i++ { - if ti.values[i] == value { - return ti.names[i]; - } - } - } - return ""; -} - diff --git a/core/fmt.odin b/core/fmt.odin index 2da874bcc..f31a9810a 100644 --- a/core/fmt.odin +++ b/core/fmt.odin @@ -290,11 +290,6 @@ proc bprint_type(buf ^[]byte, ti ^Type_Info) { bprint_type(buf, info.fields[i].type_info); } bprint_string(buf, "}"); - - case Enum: - bprint_string(buf, "enum "); - bprint_type(buf, info.base); - bprint_string(buf, "{}"); } } @@ -392,21 +387,6 @@ proc bprint_any(buf ^[]byte, arg any) { bprint_string(buf, "nil"); } - case Enum: - var value i64 = 0; - - match type i : make_any(info.base, arg.data) { - case i8: value = i as i64; - case i16: value = i as i64; - case i32: value = i as i64; - case i64: value = i as i64; - case u8: value = i as i64; - case u16: value = i as i64; - case u32: value = i as i64; - case u64: value = i as i64; - } - bprint_string(buf, __enum_to_string(arg.type_info, value)); - case Array: bprintf(buf, "[%]%{", info.count, info.elem); defer bprint_string(buf, "}"); diff --git a/core/mem.odin b/core/mem.odin index 059ca2011..b0347f6b2 100644 --- a/core/mem.odin +++ b/core/mem.odin @@ -162,9 +162,8 @@ proc arena_allocator_proc(allocator_data rawptr, mode Allocator_Mode, old_memory rawptr, old_size int, flags u64) -> rawptr { var arena = allocator_data as ^Arena; - using Allocator_Mode; match mode { - case ALLOC: + case ALLOCATOR_ALLOC: var total_size = size + alignment; if arena.memory.count + total_size > arena.memory.capacity { @@ -178,14 +177,14 @@ proc arena_allocator_proc(allocator_data rawptr, mode Allocator_Mode, arena.memory.count += total_size; return zero(ptr, size); - case FREE: + case ALLOCATOR_FREE: // NOTE(bill): Free all at once // Use Arena_Temp_Memory if you want to free a block - case FREE_ALL: + case ALLOCATOR_FREE_ALL: arena.memory.count = 0; - case RESIZE: + case ALLOCATOR_RESIZE: return default_resize_align(old_memory, old_size, size, alignment); } @@ -263,8 +262,6 @@ proc align_of_type_info(type_info ^Type_Info) -> int { return info.align; case Raw_Union: return info.align; - case Enum: - return align_of_type_info(info.base); } return 0; @@ -339,8 +336,6 @@ proc size_of_type_info(type_info ^Type_Info) -> int { return info.size; case Raw_Union: return info.size; - case Enum: - return size_of_type_info(info.base); } return 0; diff --git a/core/os_windows.odin b/core/os_windows.odin index 06e4c6e4d..b4686ae3d 100644 --- a/core/os_windows.odin +++ b/core/os_windows.odin @@ -83,23 +83,24 @@ proc last_write_time_by_name(name string) -> File_Time { +const ( + FILE_STANDARD_INPUT = iota; + FILE_STANDARD_OUTPUT; + FILE_STANDARD_ERROR; -type File_Standard enum { - INPUT, - OUTPUT, - ERROR, -} + FILE_STANDARD_COUNT; +); // NOTE(bill): Uses startup to initialize it -var __std_files = [File_Standard.count]File{ +var __std_files = [FILE_STANDARD_COUNT]File{ {handle = win32.GetStdHandle(win32.STD_INPUT_HANDLE) transmute File_Handle }, {handle = win32.GetStdHandle(win32.STD_OUTPUT_HANDLE) transmute File_Handle }, {handle = win32.GetStdHandle(win32.STD_ERROR_HANDLE) transmute File_Handle }, }; -var stdin = ^__std_files[File_Standard.INPUT]; -var stdout = ^__std_files[File_Standard.OUTPUT]; -var stderr = ^__std_files[File_Standard.ERROR]; +var stdin = ^__std_files[FILE_STANDARD_INPUT]; +var stdout = ^__std_files[FILE_STANDARD_OUTPUT]; +var stderr = ^__std_files[FILE_STANDARD_ERROR]; diff --git a/core/sys/windows.odin b/core/sys/windows.odin index 5ddbb5cab..dca7bce15 100644 --- a/core/sys/windows.odin +++ b/core/sys/windows.odin @@ -369,157 +369,158 @@ proc is_key_down(key Key_Code) -> bool { return GetAsyncKeyState(key as i32) < 0; } -type Key_Code enum i32 { - LBUTTON = 0x01, - RBUTTON = 0x02, - CANCEL = 0x03, - MBUTTON = 0x04, +type Key_Code i32; +const ( + KEY_LBUTTON Key_Code = 0x01; + KEY_RBUTTON = 0x02; + KEY_CANCEL = 0x03; + KEY_MBUTTON = 0x04; - BACK = 0x08, - TAB = 0x09, + KEY_BACK = 0x08; + KEY_TAB = 0x09; - CLEAR = 0x0C, - RETURN = 0x0D, + KEY_CLEAR = 0x0C; + KEY_RETURN = 0x0D; - SHIFT = 0x10, - CONTROL = 0x11, - MENU = 0x12, - PAUSE = 0x13, - CAPITAL = 0x14, + KEY_SHIFT = 0x10; + KEY_CONTROL = 0x11; + KEY_MENU = 0x12; + KEY_PAUSE = 0x13; + KEY_CAPITAL = 0x14; - KANA = 0x15, - HANGEUL = 0x15, - HANGUL = 0x15, - JUNJA = 0x17, - FINAL = 0x18, - HANJA = 0x19, - KANJI = 0x19, + KEY_KANA = 0x15; + KEY_HANGEUL = 0x15; + KEY_HANGUL = 0x15; + KEY_JUNJA = 0x17; + KEY_FINAL = 0x18; + KEY_HANJA = 0x19; + KEY_KANJI = 0x19; - ESCAPE = 0x1B, + KEY_ESCAPE = 0x1B; - CONVERT = 0x1C, - NONCONVERT = 0x1D, - ACCEPT = 0x1E, - MODECHANGE = 0x1F, + KEY_CONVERT = 0x1C; + KEY_NONCONVERT = 0x1D; + KEY_ACCEPT = 0x1E; + KEY_MODECHANGE = 0x1F; - SPACE = 0x20, - PRIOR = 0x21, - NEXT = 0x22, - END = 0x23, - HOME = 0x24, - LEFT = 0x25, - UP = 0x26, - RIGHT = 0x27, - DOWN = 0x28, - SELECT = 0x29, - PRINT = 0x2A, - EXECUTE = 0x2B, - SNAPSHOT = 0x2C, - INSERT = 0x2D, - DELETE = 0x2E, - HELP = 0x2F, + KEY_SPACE = 0x20; + KEY_PRIOR = 0x21; + KEY_NEXT = 0x22; + KEY_END = 0x23; + KEY_HOME = 0x24; + KEY_LEFT = 0x25; + KEY_UP = 0x26; + KEY_RIGHT = 0x27; + KEY_DOWN = 0x28; + KEY_SELECT = 0x29; + KEY_PRINT = 0x2A; + KEY_EXECUTE = 0x2B; + KEY_SNAPSHOT = 0x2C; + KEY_INSERT = 0x2D; + KEY_DELETE = 0x2E; + KEY_HELP = 0x2F; - NUM0 = '0', - NUM1 = '1', - NUM2 = '2', - NUM3 = '3', - NUM4 = '4', - NUM5 = '5', - NUM6 = '6', - NUM7 = '7', - NUM8 = '8', - NUM9 = '9', + KEY_NUM0 = '0'; + KEY_NUM1 = '1'; + KEY_NUM2 = '2'; + KEY_NUM3 = '3'; + KEY_NUM4 = '4'; + KEY_NUM5 = '5'; + KEY_NUM6 = '6'; + KEY_NUM7 = '7'; + KEY_NUM8 = '8'; + KEY_NUM9 = '9'; - A = 'A', - B = 'B', - C = 'C', - D = 'D', - E = 'E', - F = 'F', - G = 'G', - H = 'H', - I = 'I', - J = 'J', - K = 'K', - L = 'L', - M = 'M', - N = 'N', - O = 'O', - P = 'P', - Q = 'Q', - R = 'R', - S = 'S', - T = 'T', - U = 'U', - V = 'V', - W = 'W', - X = 'X', - Y = 'Y', - Z = 'Z', + KEY_A = 'A'; + KEY_B = 'B'; + KEY_C = 'C'; + KEY_D = 'D'; + KEY_E = 'E'; + KEY_F = 'F'; + KEY_G = 'G'; + KEY_H = 'H'; + KEY_I = 'I'; + KEY_J = 'J'; + KEY_K = 'K'; + KEY_L = 'L'; + KEY_M = 'M'; + KEY_N = 'N'; + KEY_O = 'O'; + KEY_P = 'P'; + KEY_Q = 'Q'; + KEY_R = 'R'; + KEY_S = 'S'; + KEY_T = 'T'; + KEY_U = 'U'; + KEY_V = 'V'; + KEY_W = 'W'; + KEY_X = 'X'; + KEY_Y = 'Y'; + KEY_Z = 'Z'; - LWIN = 0x5B, - RWIN = 0x5C, - APPS = 0x5D, + KEY_LWIN = 0x5B; + KEY_RWIN = 0x5C; + KEY_APPS = 0x5D; - NUMPAD0 = 0x60, - NUMPAD1 = 0x61, - NUMPAD2 = 0x62, - NUMPAD3 = 0x63, - NUMPAD4 = 0x64, - NUMPAD5 = 0x65, - NUMPAD6 = 0x66, - NUMPAD7 = 0x67, - NUMPAD8 = 0x68, - NUMPAD9 = 0x69, - MULTIPLY = 0x6A, - ADD = 0x6B, - SEPARATOR = 0x6C, - SUBTRACT = 0x6D, - DECIMAL = 0x6E, - DIVIDE = 0x6F, - F1 = 0x70, - F2 = 0x71, - F3 = 0x72, - F4 = 0x73, - F5 = 0x74, - F6 = 0x75, - F7 = 0x76, - F8 = 0x77, - F9 = 0x78, - F10 = 0x79, - F11 = 0x7A, - F12 = 0x7B, - F13 = 0x7C, - F14 = 0x7D, - F15 = 0x7E, - F16 = 0x7F, - F17 = 0x80, - F18 = 0x81, - F19 = 0x82, - F20 = 0x83, - F21 = 0x84, - F22 = 0x85, - F23 = 0x86, - F24 = 0x87, + KEY_NUMPAD0 = 0x60; + KEY_NUMPAD1 = 0x61; + KEY_NUMPAD2 = 0x62; + KEY_NUMPAD3 = 0x63; + KEY_NUMPAD4 = 0x64; + KEY_NUMPAD5 = 0x65; + KEY_NUMPAD6 = 0x66; + KEY_NUMPAD7 = 0x67; + KEY_NUMPAD8 = 0x68; + KEY_NUMPAD9 = 0x69; + KEY_MULTIPLY = 0x6A; + KEY_ADD = 0x6B; + KEY_SEPARATOR = 0x6C; + KEY_SUBTRACT = 0x6D; + KEY_DECIMAL = 0x6E; + KEY_DIVIDE = 0x6F; + KEY_F1 = 0x70; + KEY_F2 = 0x71; + KEY_F3 = 0x72; + KEY_F4 = 0x73; + KEY_F5 = 0x74; + KEY_F6 = 0x75; + KEY_F7 = 0x76; + KEY_F8 = 0x77; + KEY_F9 = 0x78; + KEY_F10 = 0x79; + KEY_F11 = 0x7A; + KEY_F12 = 0x7B; + KEY_F13 = 0x7C; + KEY_F14 = 0x7D; + KEY_F15 = 0x7E; + KEY_F16 = 0x7F; + KEY_F17 = 0x80; + KEY_F18 = 0x81; + KEY_F19 = 0x82; + KEY_F20 = 0x83; + KEY_F21 = 0x84; + KEY_F22 = 0x85; + KEY_F23 = 0x86; + KEY_F24 = 0x87; - NUMLOCK = 0x90, - SCROLL = 0x91, + KEY_NUMLOCK = 0x90; + KEY_SCROLL = 0x91; - LSHIFT = 0xA0, - RSHIFT = 0xA1, - LCONTROL = 0xA2, - RCONTROL = 0xA3, - LMENU = 0xA4, - RMENU = 0xA5, - PROCESSKEY = 0xE5, - ATTN = 0xF6, - CRSEL = 0xF7, - EXSEL = 0xF8, - EREOF = 0xF9, - PLAY = 0xFA, - ZOOM = 0xFB, - NONAME = 0xFC, - PA1 = 0xFD, - OEM_CLEAR = 0xFE, -} + KEY_LSHIFT = 0xA0; + KEY_RSHIFT = 0xA1; + KEY_LCONTROL = 0xA2; + KEY_RCONTROL = 0xA3; + KEY_LMENU = 0xA4; + KEY_RMENU = 0xA5; + KEY_PROCESSKEY = 0xE5; + KEY_ATTN = 0xF6; + KEY_CRSEL = 0xF7; + KEY_EXSEL = 0xF8; + KEY_EREOF = 0xF9; + KEY_PLAY = 0xFA; + KEY_ZOOM = 0xFB; + KEY_NONAME = 0xFC; + KEY_PA1 = 0xFD; + KEY_OEM_CLEAR = 0xFE; +); diff --git a/src/checker/checker.c b/src/checker/checker.c index 14cb62bdb..705fc54d9 100644 --- a/src/checker/checker.c +++ b/src/checker/checker.c @@ -127,8 +127,6 @@ typedef enum BuiltinProcId { BuiltinProc_abs, BuiltinProc_clamp, - BuiltinProc_enum_to_string, - BuiltinProc_Count, } BuiltinProcId; typedef struct BuiltinProc { @@ -171,8 +169,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = { {STR_LIT("max"), 2, false, Expr_Expr}, {STR_LIT("abs"), 1, false, Expr_Expr}, {STR_LIT("clamp"), 3, false, Expr_Expr}, - - {STR_LIT("enum_to_string"), 1, false, Expr_Expr}, }; typedef enum ImplicitValueId { @@ -681,7 +677,9 @@ void add_untyped(CheckerInfo *i, AstNode *expression, bool lhs, AddressingMode m } void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode, Type *type, ExactValue value) { - GB_ASSERT(expression != NULL); + if (expression == NULL) { + return; + } if (mode == Addressing_Invalid) { return; } @@ -864,10 +862,6 @@ void add_type_info_type(Checker *c, Type *t) { case Type_Record: { switch (bt->Record.kind) { - case TypeRecord_Enum: - add_type_info_type(c, bt->Record.enum_base); - break; - case TypeRecord_Union: add_type_info_type(c, t_int); /* fallthrough */ @@ -1012,7 +1006,7 @@ void init_preload(Checker *c) { t_type_info_member = type_info_member_entity->type; t_type_info_member_ptr = make_type_pointer(c->allocator, t_type_info_member); - if (record->field_count != 18) { + if (record->field_count != 17) { compiler_error("Invalid `Type_Info` layout"); } t_type_info_named = record->fields[ 1]->type; @@ -1031,7 +1025,6 @@ void init_preload(Checker *c) { t_type_info_struct = record->fields[14]->type; t_type_info_union = record->fields[15]->type; t_type_info_raw_union = record->fields[16]->type; - t_type_info_enum = record->fields[17]->type; } if (t_allocator == NULL) { @@ -1253,78 +1246,6 @@ void check_global_collect_entities_from_file(Checker *c, Scope *parent_scope, As DelayedDecl di = {parent_scope, decl}; array_add(&c->delayed_foreign_libraries, di); case_end; - case_ast_node(vd, VarDecl, decl); - if (!parent_scope->is_file) { - // NOTE(bill): Within a procedure, variables must be in order - continue; - } - - // NOTE(bill): You need to store the entity information here unline a constant declaration - isize entity_count = vd->names.count; - isize entity_index = 0; - Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count); - DeclInfo *di = NULL; - if (vd->values.count > 0) { - di = make_declaration_info(heap_allocator(), parent_scope); - di->entities = entities; - di->entity_count = entity_count; - di->type_expr = vd->type; - di->init_expr = vd->values.e[0]; - } - - for_array(i, vd->names) { - AstNode *name = vd->names.e[i]; - AstNode *value = NULL; - if (i < vd->values.count) { - value = vd->values.e[i]; - } - if (name->kind != AstNode_Ident) { - error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind])); - continue; - } - Entity *e = make_entity_variable(c->allocator, parent_scope, name->Ident, NULL); - e->identifier = name; - entities[entity_index++] = e; - - DeclInfo *d = di; - if (d == NULL) { - AstNode *init_expr = value; - d = make_declaration_info(heap_allocator(), e->scope); - d->type_expr = vd->type; - d->init_expr = init_expr; - d->var_decl_tags = vd->tags; - } - - add_entity_and_decl_info(c, name, e, d); - } - case_end; - case_ast_node(cd, ConstDecl, decl); - for_array(i, cd->values) { - AstNode *name = cd->names.e[i]; - AstNode *value = unparen_expr(cd->values.e[i]); - if (name->kind != AstNode_Ident) { - error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind])); - continue; - } - - ExactValue v = {ExactValue_Invalid}; - Entity *e = make_entity_constant(c->allocator, parent_scope, name->Ident, NULL, v); - e->identifier = name; - DeclInfo *di = make_declaration_info(c->allocator, e->scope); - di->type_expr = cd->type; - di->init_expr = value; - add_entity_and_decl_info(c, name, e, di); - } - - isize lhs_count = cd->names.count; - isize rhs_count = cd->values.count; - - if (rhs_count == 0 && cd->type == NULL) { - error_node(decl, "Missing type or initial expression"); - } else if (lhs_count < rhs_count) { - error_node(decl, "Extra initial expression"); - } - case_end; case_ast_node(td, TypeDecl, decl); if (td->name->kind != AstNode_Ident) { error_node(td->name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[td->name->kind])); diff --git a/src/checker/decl.c b/src/checker/decl.c index 603d04c5d..5266a8bba 100644 --- a/src/checker/decl.c +++ b/src/checker/decl.c @@ -98,15 +98,14 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra gb_temp_arena_memory_end(tmp); } - -void check_var_decl_node(Checker *c, AstNode *node) { - ast_node(vd, VarDecl, node); - isize entity_count = vd->names.count; +void check_var_spec_node(Checker *c, AstNodeValueSpec *vs) { + GB_ASSERT(vs->keyword == Token_var); + isize entity_count = vs->names.count; isize entity_index = 0; Entity **entities = gb_alloc_array(c->allocator, Entity *, entity_count); - for_array(i, vd->names) { - AstNode *name = vd->names.e[i]; + for_array(i, vs->names) { + AstNode *name = vs->names.e[i]; Entity *entity = NULL; if (name->kind == AstNode_Ident) { Token token = name->Ident; @@ -137,8 +136,8 @@ void check_var_decl_node(Checker *c, AstNode *node) { } Type *init_type = NULL; - if (vd->type) { - init_type = check_type_extra(c, vd->type, NULL); + if (vs->type) { + init_type = check_type_extra(c, vs->type, NULL); if (init_type == NULL) { init_type = t_invalid; } @@ -157,11 +156,12 @@ void check_var_decl_node(Checker *c, AstNode *node) { e->type = init_type; } - check_init_variables(c, entities, entity_count, vd->values, str_lit("variable declaration")); - for_array(i, vd->names) { + check_init_variables(c, entities, entity_count, vs->values, str_lit("variable declaration")); + + for_array(i, vs->names) { if (entities[i] != NULL) { - add_entity(c, c->context.scope, vd->names.e[i], entities[i]); + add_entity(c, c->context.scope, vs->names.e[i], entities[i]); } } diff --git a/src/checker/entity.c b/src/checker/entity.c index d02268837..3eb62db08 100644 --- a/src/checker/entity.c +++ b/src/checker/entity.c @@ -55,6 +55,7 @@ struct Entity { ExactValue value; } Constant; struct { + b32 is_let; i32 field_index; i32 field_src_index; } Variable; diff --git a/src/checker/expr.c b/src/checker/expr.c index 9562473ca..5b50e75a0 100644 --- a/src/checker/expr.c +++ b/src/checker/expr.c @@ -131,76 +131,6 @@ void check_local_collect_entities(Checker *c, AstNodeArray nodes, DelayedEntitie } } case_end; - case_ast_node(cd, ConstDecl, node); - gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena); - - isize entity_count = cd->names.count; - isize entity_index = 0; - Entity **entities = gb_alloc_array(c->tmp_allocator, Entity *, entity_count); - - for_array(i, cd->values) { - AstNode *name = cd->names.e[i]; - AstNode *value = unparen_expr(cd->values.e[i]); - if (name->kind != AstNode_Ident) { - error_node(name, "A declaration's name must be an identifier, got %.*s", LIT(ast_node_strings[name->kind])); - entities[entity_index++] = NULL; - continue; - } - - ExactValue v = {ExactValue_Invalid}; - Entity *e = make_entity_constant(c->allocator, c->context.scope, name->Ident, NULL, v); - e->identifier = name; - entities[entity_index++] = e; - DeclInfo *d = make_declaration_info(c->allocator, e->scope); - d->type_expr = cd->type; - d->init_expr = value; - add_entity_and_decl_info(c, name, e, d); - - DelayedEntity delay = {name, e, d}; - array_add(delayed_entities, delay); - } - - isize lhs_count = cd->names.count; - isize rhs_count = cd->values.count; - - // TODO(bill): Better error messages or is this good enough? - if (rhs_count == 0 && cd->type == NULL) { - error_node(node, "Missing type or initial expression"); - } else if (lhs_count < rhs_count) { - error_node(node, "Extra initial expression"); - } - - if (dof != NULL) { - // NOTE(bill): Within a record - for_array(i, cd->names) { - Entity *e = entities[i]; - if (e == NULL) { - continue; - } - AstNode *name = cd->names.e[i]; - if (name->kind != AstNode_Ident) { - continue; - } - Token name_token = name->Ident; - if (str_eq(name_token.string, str_lit("_"))) { - dof->other_fields[dof->other_field_index++] = e; - } else { - HashKey key = hash_string(name_token.string); - if (map_entity_get(dof->entity_map, key) != NULL) { - // TODO(bill): Scope checking already checks the declaration - error(name_token, "`%.*s` is already declared in this record", LIT(name_token.string)); - } else { - map_entity_set(dof->entity_map, key, e); - dof->other_fields[dof->other_field_index++] = e; - } - add_entity(c, c->context.scope, name, e); - } - } - } - - gb_temp_arena_memory_end(tmp); - case_end; - #if 0 case_ast_node(pd, ProcDecl, node); if (!ast_node_expect(pd->name, AstNode_Ident)) { @@ -362,9 +292,6 @@ bool check_is_assignable_to(Checker *c, Operand *operand, Type *type) { } if (are_types_identical(dst, src) && (!is_type_named(dst) || !is_type_named(src))) { - if (is_type_enum(dst) && is_type_enum(src)) { - return are_types_identical(s, type); - } return true; } @@ -794,127 +721,6 @@ GB_COMPARE_PROC(cmp_enum_order) { return i < j ? -1 : i > j; } - - -void check_enum_type(Checker *c, Type *enum_type, Type *named_type, AstNode *node) { - GB_ASSERT(node->kind == AstNode_EnumType); - GB_ASSERT(is_type_enum(enum_type)); - ast_node(et, EnumType, node); - - Type *base_type = t_int; - if (et->base_type != NULL) { - base_type = check_type(c, et->base_type); - } - - if (base_type == NULL || !is_type_integer(base_type)) { - error(et->token, "Base type for enumeration must be an integer"); - return; - } else - if (base_type == NULL) { - base_type = t_int; - } - enum_type->Record.enum_base = base_type; - - Entity **fields = gb_alloc_array(c->allocator, Entity *, et->fields.count); - isize field_index = 0; - ExactValue iota = make_exact_value_integer(-1); - i64 min_value = 0; - i64 max_value = 0; - - Type *constant_type = enum_type; - if (named_type != NULL) { - constant_type = named_type; - } - - - gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena); - - MapEntity entity_map = {0}; - map_entity_init_with_reserve(&entity_map, c->tmp_allocator, 2*(et->fields.count)); - - Entity *blank_entity = make_entity_constant(c->allocator, c->context.scope, blank_token, constant_type, make_exact_value_integer(0));; - - for_array(i, et->fields) { - AstNode *field = et->fields.e[i]; - - if (!ast_node_expect(field, AstNode_FieldValue)) { - continue; - } - - ast_node(f, FieldValue, field); - Token name_token = f->field->Ident; - - if (str_eq(name_token.string, str_lit("count"))) { - error(name_token, "`count` is a reserved identifier for enumerations"); - fields[field_index++] = blank_entity; - continue; - } else if (str_eq(name_token.string, str_lit("min_value"))) { - error(name_token, "`min_value` is a reserved identifier for enumerations"); - fields[field_index++] = blank_entity; - continue; - } else if (str_eq(name_token.string, str_lit("max_value"))) { - error(name_token, "`max_value` is a reserved identifier for enumerations"); - fields[field_index++] = blank_entity; - continue; - } - - Operand o = {0}; - if (f->value != NULL) { - check_expr(c, &o, f->value); - if (o.mode != Addressing_Constant) { - error_node(f->value, "Enumeration value must be a constant integer %d"); - o.mode = Addressing_Invalid; - } - if (o.mode != Addressing_Invalid) { - check_assignment(c, &o, constant_type, str_lit("enumeration")); - } - if (o.mode != Addressing_Invalid) { - iota = o.value; - } else { - iota = exact_binary_operator_value(Token_Add, iota, make_exact_value_integer(1)); - } - } else { - iota = exact_binary_operator_value(Token_Add, iota, make_exact_value_integer(1)); - } - - - Entity *e = make_entity_constant(c->allocator, c->context.scope, name_token, constant_type, iota); - if (min_value > iota.value_integer) { - min_value = iota.value_integer; - } - if (max_value < iota.value_integer) { - max_value = iota.value_integer; - } - - HashKey key = hash_string(name_token.string); - if (map_entity_get(&entity_map, key)) { - // TODO(bill): Scope checking already checks the declaration - error(name_token, "`%.*s` is already declared in this enumeration", LIT(name_token.string)); - } else { - map_entity_set(&entity_map, key, e); - add_entity(c, c->context.scope, NULL, e); - fields[field_index++] = e; - } - add_entity_use(c, f->field, e); - } - - GB_ASSERT(field_index <= et->fields.count); - - gb_sort_array(fields, field_index, cmp_enum_order); - - enum_type->Record.enum_values = fields; - enum_type->Record.enum_value_count = field_index; - - enum_type->Record.enum_count = make_entity_constant(c->allocator, NULL, - make_token_ident(str_lit("count")), t_int, make_exact_value_integer(enum_type->Record.enum_value_count)); - enum_type->Record.min_value = make_entity_constant(c->allocator, NULL, - make_token_ident(str_lit("min_value")), constant_type, make_exact_value_integer(min_value)); - enum_type->Record.max_value = make_entity_constant(c->allocator, NULL, - make_token_ident(str_lit("max_value")), constant_type, make_exact_value_integer(max_value)); - - gb_temp_arena_memory_end(tmp); -} - Type *check_get_params(Checker *c, Scope *scope, AstNodeArray params, bool *is_variadic_) { if (params.count == 0) { return NULL; @@ -1165,6 +971,11 @@ Type *check_type_extra(Checker *c, AstNode *e, Type *named_type) { Type *type = NULL; gbString err_str = NULL; + if (e == NULL) { + type = t_invalid; + goto end; + } + switch (e->kind) { case_ast_node(i, Ident, e); Operand o = {0}; @@ -1291,16 +1102,6 @@ Type *check_type_extra(Checker *c, AstNode *e, Type *named_type) { goto end; case_end; - case_ast_node(et, EnumType, e); - type = make_type_enum(c->allocator); - set_base_type(named_type, type); - check_open_scope(c, e); - check_enum_type(c, type, named_type, e); - check_close_scope(c); - type->Record.node = e; - goto end; - case_end; - case_ast_node(pt, ProcType, e); type = alloc_type(c->allocator, Type_Proc); set_base_type(named_type, type); @@ -1357,7 +1158,7 @@ end: bool check_unary_op(Checker *c, Operand *o, Token op) { // TODO(bill): Handle errors correctly - Type *type = base_type(get_enum_base_type(base_vector_type(o->type))); + Type *type = base_type(base_vector_type(o->type)); gbString str = NULL; switch (op.kind) { case Token_Add: @@ -1393,7 +1194,7 @@ bool check_unary_op(Checker *c, Operand *o, Token op) { bool check_binary_op(Checker *c, Operand *o, Token op) { // TODO(bill): Handle errors correctly - Type *type = base_type(get_enum_base_type(base_vector_type(o->type))); + Type *type = base_type(base_vector_type(o->type)); switch (op.kind) { case Token_Sub: case Token_SubEq: @@ -1470,8 +1271,6 @@ bool check_value_is_expressible(Checker *c, ExactValue in_value, Type *type, Exa return true; } - type = get_enum_base_type(type); - if (is_type_boolean(type)) { return in_value.kind == ExactValue_Bool; } else if (is_type_string(type)) { @@ -1554,8 +1353,8 @@ void check_is_expressible(Checker *c, Operand *o, Type *type) { if (!check_value_is_expressible(c, o->value, type, &o->value)) { gbString a = expr_to_string(o->expr); gbString b = type_to_string(type); - if (is_type_numeric(get_enum_base_type(o->type)) && is_type_numeric(get_enum_base_type(type))) { - if (!is_type_integer(get_enum_base_type(o->type)) && is_type_integer(get_enum_base_type(type))) { + if (is_type_numeric(o->type) && is_type_numeric(type)) { + if (!is_type_integer(o->type) && is_type_integer(type)) { error_node(o->expr, "`%s` truncated to `%s`", a, b); } else { error_node(o->expr, "`%s = %lld` overflows `%s`", a, o->value.value_integer, b); @@ -1859,8 +1658,6 @@ bool check_is_castable_to(Checker *c, Operand *operand, Type *y) { if (are_types_identical(xb, yb)) { return true; } - xb = get_enum_base_type(x); - yb = get_enum_base_type(y); // Cast between booleans and integers @@ -2460,7 +2257,7 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level return; } - Type *t = get_enum_base_type(base_type(target_type)); + Type *t = base_type(target_type); switch (t->kind) { case Type_Basic: if (operand->mode == Addressing_Constant) { @@ -2531,7 +2328,7 @@ bool check_index_value(Checker *c, AstNode *index_value, i64 max_count, i64 *val return false; } - if (!is_type_integer(get_enum_base_type(operand.type))) { + if (!is_type_integer(operand.type)) { gbString expr_str = expr_to_string(operand.expr); error_node(operand.expr, "Index `%s` must be an integer", expr_str); gb_string_free(expr_str); @@ -3598,44 +3395,6 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id } } } break; - - case BuiltinProc_enum_to_string: { - Type *type = base_type(operand->type); - if (!is_type_enum(type)) { - gbString type_str = type_to_string(operand->type); - gb_string_free(type_str); - error_node(call, - "Expected an enum to `enum_to_string`, got `%s`", - type_str); - return false; - } - - if (operand->mode == Addressing_Constant) { - ExactValue value = make_exact_value_string(str_lit("")); - if (operand->value.kind == ExactValue_Integer) { - i64 index = operand->value.value_integer; - for (isize i = 0; i < type->Record.enum_value_count; i++) { - Entity *f = type->Record.enum_values[i]; - if (f->kind == Entity_Constant && f->Constant.value.kind == ExactValue_Integer) { - i64 fv = f->Constant.value.value_integer; - if (index == fv) { - value = make_exact_value_string(f->token.string); - break; - } - } - } - } - - operand->value = value; - operand->type = t_string; - return true; - } - - add_type_info_type(c, operand->type); - - operand->mode = Addressing_Value; - operand->type = t_string; - } break; } return true; diff --git a/src/checker/stmt.c b/src/checker/stmt.c index 7e1578987..f9ac8cedb 100644 --- a/src/checker/stmt.c +++ b/src/checker/stmt.c @@ -279,6 +279,8 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) { c->context.stmt_state_flags = prev_stmt_state_flags; } + + typedef struct TypeAndToken { Type *type; Token token; @@ -907,19 +909,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { switch (e->kind) { case Entity_TypeName: { Type *t = base_type(e->type); - if (is_type_enum(t)) { - for (isize i = 0; i < t->Record.enum_value_count; i++) { - Entity *f = t->Record.enum_values[i]; - Entity *found = scope_insert_entity(c->context.scope, f); - if (found != NULL) { - gbString expr_str = expr_to_string(expr); - error(us->token, "Namespace collision while `using` `%s` of: %.*s", expr_str, LIT(found->token.string)); - gb_string_free(expr_str); - return; - } - f->using_parent = e; - } - } else if (is_type_union(t)) { + if (is_type_union(t)) { for (isize i = 0; i < t->Record.field_count; i++) { Entity *f = t->Record.fields[i]; Entity *found = scope_insert_entity(c->context.scope, f); @@ -931,6 +921,8 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { } f->using_parent = e; } + } else { + error(us->token, "`using` can be only applied to `union` type entities"); } } break; @@ -1008,40 +1000,52 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { } case_end; - case_ast_node(vd, VarDecl, us->node); - if (vd->names.count > 1 && vd->type != NULL) { - error(us->token, "`using` can only be applied to one variable of the same type"); - } - check_var_decl_node(c, us->node); + case_ast_node(gd, GenericDecl, us->node); + for_array(spec_index, gd->specs) { + AstNode *spec = gd->specs.e[spec_index]; + switch (spec->kind) { + case_ast_node(vs, ValueSpec, spec); + if (vs->keyword != Token_var) { + error_node(spec, "`using` can only be applied to a variable declaration"); + return; + } - for_array(name_index, vd->names) { - AstNode *item = vd->names.e[name_index]; - ast_node(i, Ident, item); - String name = i->string; - Entity *e = scope_lookup_entity(c->context.scope, name); - Type *t = base_type(type_deref(e->type)); - if (is_type_struct(t) || is_type_raw_union(t)) { - Scope **found = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node)); - GB_ASSERT(found != NULL); - for_array(i, (*found)->elements.entries) { - Entity *f = (*found)->elements.entries.e[i].value; - if (f->kind == Entity_Variable) { - Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type); - Entity *prev = scope_insert_entity(c->context.scope, uvar); - if (prev != NULL) { - error(us->token, "Namespace collision while `using` `%.*s` of: %.*s", LIT(name), LIT(prev->token.string)); - return; + if (vs->names.count > 1 && vs->type != NULL) { + error(us->token, "`using` can only be applied to one variable of the same type"); + } + + check_var_spec_node(c, vs); + + for_array(name_index, vs->names) { + AstNode *item = vs->names.e[name_index]; + ast_node(i, Ident, item); + String name = i->string; + Entity *e = scope_lookup_entity(c->context.scope, name); + Type *t = base_type(type_deref(e->type)); + if (is_type_struct(t) || is_type_raw_union(t)) { + Scope **found = map_scope_get(&c->info.scopes, hash_pointer(t->Record.node)); + GB_ASSERT(found != NULL); + for_array(i, (*found)->elements.entries) { + Entity *f = (*found)->elements.entries.e[i].value; + if (f->kind == Entity_Variable) { + Entity *uvar = make_entity_using_variable(c->allocator, e, f->token, f->type); + Entity *prev = scope_insert_entity(c->context.scope, uvar); + if (prev != NULL) { + error(us->token, "Namespace collision while `using` `%.*s` of: %.*s", LIT(name), LIT(prev->token.string)); + return; + } + } } + } else { + error(us->token, "`using` can only be applied to variables of type struct or raw_union"); + return; } } - } else { - error(us->token, "`using` can only be applied to variables of type struct or raw_union"); - return; + case_end; } } case_end; - default: error(us->token, "Invalid AST: Using Statement"); break; @@ -1068,12 +1072,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { - - - case_ast_node(vd, VarDecl, node); - check_var_decl_node(c, node); - case_end; - case_ast_node(gd, GenericDecl, node); for_array(spec_index, gd->specs) { AstNode *spec = gd->specs.e[spec_index]; @@ -1136,6 +1134,7 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { if (e->type == NULL) e->type = init_type; } + check_arity_match(c, vs, NULL); check_init_variables(c, entities, entity_count, vs->values, str_lit("variable declaration")); @@ -1158,10 +1157,6 @@ void check_stmt_internal(Checker *c, AstNode *node, u32 flags) { } case_end; - case_ast_node(cd, ConstDecl, node); - // NOTE(bill): Handled elsewhere - case_end; - case_ast_node(td, TypeDecl, node); // NOTE(bill): Handled elsewhere case_end; diff --git a/src/checker/types.c b/src/checker/types.c index a09254061..c3f3d2383 100644 --- a/src/checker/types.c +++ b/src/checker/types.c @@ -62,7 +62,6 @@ typedef enum TypeRecordKind { TypeRecord_Invalid, TypeRecord_Struct, - TypeRecord_Enum, TypeRecord_RawUnion, TypeRecord_Union, // Tagged @@ -78,23 +77,11 @@ typedef struct TypeRecord { i32 field_count; // == offset_count is struct AstNode *node; - union { // NOTE(bill): Reduce size_of Type - struct { // enum only - Type * enum_base; // Default is `int` - Entity * enum_count; - Entity * min_value; - Entity * max_value; - Entity **enum_values; - i32 enum_value_count; - }; - struct { // struct only - i64 * struct_offsets; - bool struct_are_offsets_set; - bool struct_is_packed; - bool struct_is_ordered; - Entity **fields_in_src_order; // Entity_Variable - }; - }; + i64 * struct_offsets; + bool struct_are_offsets_set; + bool struct_is_packed; + bool struct_is_ordered; + Entity **fields_in_src_order; // Entity_Variable } TypeRecord; #define TYPE_KINDS \ @@ -282,7 +269,6 @@ gb_global Type *t_type_info_tuple = NULL; gb_global Type *t_type_info_struct = NULL; gb_global Type *t_type_info_union = NULL; gb_global Type *t_type_info_raw_union = NULL; -gb_global Type *t_type_info_enum = NULL; gb_global Type *t_allocator = NULL; gb_global Type *t_allocator_ptr = NULL; @@ -380,11 +366,6 @@ Type *make_type_raw_union(gbAllocator a) { return t; } -Type *make_type_enum(gbAllocator a) { - Type *t = alloc_type(a, Type_Record); - t->Record.kind = TypeRecord_Enum; - return t; -} @@ -437,15 +418,6 @@ Type *type_deref(Type *t) { return t; } -Type *get_enum_base_type(Type *t) { - Type *bt = base_type(t); - if (bt->kind == Type_Record && bt->Record.kind == TypeRecord_Enum) { - GB_ASSERT(bt->Record.enum_base != NULL); - return bt->Record.enum_base; - } - return t; -} - bool is_type_named(Type *t) { if (t->kind == Type_Basic) { return true; @@ -508,7 +480,7 @@ bool is_type_untyped(Type *t) { return false; } bool is_type_ordered(Type *t) { - t = base_type(get_enum_base_type(t)); + t = base_type(t); if (t->kind == Type_Basic) { return (t->Basic.flags & BasicFlag_Ordered) != 0; } @@ -522,9 +494,6 @@ bool is_type_constant_type(Type *t) { if (t->kind == Type_Basic) { return (t->Basic.flags & BasicFlag_ConstantType) != 0; } - if (t->kind == Type_Record) { - return t->Record.kind == TypeRecord_Enum; - } return false; } bool is_type_float(Type *t) { @@ -615,10 +584,6 @@ Type *base_vector_type(Type *t) { } -bool is_type_enum(Type *t) { - t = base_type(t); - return (t->kind == Type_Record && t->Record.kind == TypeRecord_Enum); -} bool is_type_struct(Type *t) { t = base_type(t); return (t->kind == Type_Record && t->Record.kind == TypeRecord_Struct); @@ -656,20 +621,13 @@ bool type_has_nil(Type *t) { case Type_Tuple: return false; - - case Type_Record: - switch (t->Record.kind) { - case TypeRecord_Enum: - return false; - } - break; } return true; } bool is_type_comparable(Type *t) { - t = base_type(get_enum_base_type(t)); + t = base_type(t); switch (t->kind) { case Type_Basic: return t->kind != Basic_UntypedNil; @@ -682,8 +640,6 @@ bool is_type_comparable(Type *t) { if (!is_type_comparable(t->Record.fields[i]->type)) return false; } - } else if (is_type_enum(t)) { - return is_type_comparable(t->Record.enum_base); } return false; } break; @@ -753,10 +709,6 @@ bool are_types_identical(Type *x, Type *y) { return true; } break; - - case TypeRecord_Enum: - // NOTE(bill): Each enum is unique - return x == y; } } } @@ -981,33 +933,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n } } } - - if (is_type_enum(type)) { - for (isize i = 0; i < type->Record.enum_value_count; i++) { - Entity *f = type->Record.enum_values[i]; - GB_ASSERT(f->kind != Entity_Variable); - String str = f->token.string; - - if (str_eq(field_name, str)) { - sel.entity = f; - selection_add_index(&sel, i); - return sel; - } - } - - if (str_eq(field_name, str_lit("count"))) { - sel.entity = type->Record.enum_count; - return sel; - } else if (str_eq(field_name, str_lit("min_value"))) { - sel.entity = type->Record.min_value; - return sel; - } else if (str_eq(field_name, str_lit("max_value"))) { - sel.entity = type->Record.max_value; - return sel; - } - } - - } else if (!is_type_enum(type) && !is_type_union(type)) { + } else if (!is_type_union(type)) { for (isize i = 0; i < type->Record.field_count; i++) { Entity *f = type->Record.fields[i]; GB_ASSERT(f->kind == Entity_Variable && f->flags & EntityFlag_Field); @@ -1247,8 +1173,6 @@ i64 type_align_of_internal(BaseTypeSizes s, gbAllocator allocator, Type *t, Type } return max; } break; - case TypeRecord_Enum: - return type_align_of_internal(s, allocator, t->Record.enum_base, path); } } break; } @@ -1437,10 +1361,6 @@ i64 type_size_of_internal(BaseTypeSizes s, gbAllocator allocator, Type *t, TypeP // TODO(bill): Is this how it should work? return align_formula(max, align); } break; - - case TypeRecord_Enum: { - return type_size_of_internal(s, allocator, t->Record.enum_base, path); - } break; } } break; } @@ -1591,11 +1511,6 @@ gbString write_type_to_string(gbString str, Type *type) { } str = gb_string_appendc(str, "}"); break; - - case TypeRecord_Enum: - str = gb_string_appendc(str, "enum "); - str = write_type_to_string(str, type->Record.enum_base); - break; } } break; diff --git a/src/parser.c b/src/parser.c index dd4f2a8c5..f502cc316 100644 --- a/src/parser.c +++ b/src/parser.c @@ -241,21 +241,6 @@ AST_NODE_KIND(_DeclBegin, "", i32) \ u64 tags; \ bool is_using; \ }) \ - AST_NODE_KIND(VarDecl, "variable declaration", struct { \ - u64 tags; \ - bool is_using; \ - AstNodeArray names; \ - AstNode * type; \ - AstNodeArray values; \ - AstNode * note; \ - }) \ - AST_NODE_KIND(ConstDecl, "constant declaration", struct { \ - u64 tags; \ - AstNodeArray names; \ - AstNode * type; \ - AstNodeArray values; \ - AstNode * note; \ - }) \ AST_NODE_KIND(TypeDecl, "type declaration", struct { \ Token token; \ AstNode *name; \ @@ -480,10 +465,6 @@ Token ast_node_token(AstNode *node) { return node->BadDecl.begin; case AstNode_GenericDecl: return node->GenericDecl.token; - case AstNode_VarDecl: - return ast_node_token(node->VarDecl.names.e[0]); - case AstNode_ConstDecl: - return ast_node_token(node->ConstDecl.names.e[0]); case AstNode_ProcDecl: return ast_node_token(node->ProcDecl.name); case AstNode_TypeDecl: @@ -917,22 +898,6 @@ AstNode *make_bad_decl(AstFile *f, Token begin, Token end) { return result; } -AstNode *make_var_decl(AstFile *f, AstNodeArray names, AstNode *type, AstNodeArray values) { - AstNode *result = make_node(f, AstNode_VarDecl); - result->VarDecl.names = names; - result->VarDecl.type = type; - result->VarDecl.values = values; - return result; -} - -AstNode *make_const_decl(AstFile *f, AstNodeArray names, AstNode *type, AstNodeArray values) { - AstNode *result = make_node(f, AstNode_ConstDecl); - result->ConstDecl.names = names; - result->ConstDecl.type = type; - result->ConstDecl.values = values; - return result; -} - AstNode *make_parameter(AstFile *f, AstNodeArray names, AstNode *type, bool is_using) { AstNode *result = make_node(f, AstNode_Parameter); result->Parameter.names = names; @@ -2814,8 +2779,8 @@ AstNode *parse_stmt(AstFile *f) { valid = true; } } break; - case AstNode_VarDecl: - valid = true; + case AstNode_GenericDecl: + valid = node->GenericDecl.token.kind == Token_var; break; } @@ -2952,9 +2917,8 @@ AstNode *parse_stmt(AstFile *f) { return s; } else if (str_eq(tag, str_lit("thread_local"))) { AstNode *decl = parse_simple_stmt(f); - if (decl->kind != AstNode_VarDecl && - (decl->kind == AstNode_GenericDecl && - decl->GenericDecl.token.kind != Token_var)) { + if (decl->kind == AstNode_GenericDecl && + decl->GenericDecl.token.kind != Token_var) { syntax_error(token, "#thread_local may only be applied to variable declarations"); return make_bad_decl(f, token, ast_node_token(decl)); } @@ -2962,11 +2926,8 @@ AstNode *parse_stmt(AstFile *f) { syntax_error(token, "#thread_local is only allowed at the file scope"); return make_bad_decl(f, token, ast_node_token(decl)); } - if (decl->kind == AstNode_VarDecl) { - decl->VarDecl.tags |= VarDeclTag_thread_local; - } else if (decl->kind == AstNode_GenericDecl) { - decl->GenericDecl.tags |= VarDeclTag_thread_local; - } + GB_ASSERT(decl->kind == AstNode_GenericDecl); + decl->GenericDecl.tags |= VarDeclTag_thread_local; return decl; } else if (str_eq(tag, str_lit("bounds_check"))) { s = parse_stmt(f); diff --git a/src/ssa.c b/src/ssa.c index bc5737676..cd09eaf11 100644 --- a/src/ssa.c +++ b/src/ssa.c @@ -1919,8 +1919,8 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) { return value; } - Type *src = base_type(get_enum_base_type(src_type)); - Type *dst = base_type(get_enum_base_type(t)); + Type *src = base_type(src_type); + Type *dst = base_type(t); if (value->kind == ssaValue_Constant) { if (is_type_any(dst)) { @@ -2172,7 +2172,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t) { } bool ssa_is_type_aggregate(Type *t) { - t = base_type(get_enum_base_type(t)); + t = base_type(t); switch (t->kind) { case Type_Basic: switch (t->Basic.kind) { @@ -3088,19 +3088,6 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue x = ssa_emit_select(proc, cond, max, x); return x; } break; - - case BuiltinProc_enum_to_string: { - ssa_emit_comment(proc, str_lit("enum_to_string")); - ssaValue *x = ssa_build_expr(proc, ce->args.e[0]); - Type *t = ssa_type(x); - ssaValue *ti = ssa_type_info(proc, t); - - - ssaValue **args = gb_alloc_array(proc->module->allocator, ssaValue *, 2); - args[0] = ti; - args[1] = ssa_emit_conv(proc, x, t_i64); - return ssa_emit_global_call(proc, "__enum_to_string", args, 2); - } break; } } } @@ -3849,8 +3836,7 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { case_ast_node(us, UsingStmt, node); AstNode *decl = unparen_expr(us->node); - if (decl->kind == AstNode_VarDecl && - decl->kind == AstNode_GenericDecl) { + if (decl->kind == AstNode_GenericDecl) { ssa_build_stmt(proc, decl); } case_end; @@ -3928,61 +3914,6 @@ void ssa_build_stmt_internal(ssaProcedure *proc, AstNode *node) { } case_end; - case_ast_node(vd, VarDecl, node); - ssaModule *m = proc->module; - gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena); - - if (vd->values.count == 0) { // declared and zero-initialized - for_array(i, vd->names) { - AstNode *name = vd->names.e[i]; - if (!ssa_is_blank_ident(name)) { - ssa_add_local_for_identifier(proc, name, true); - } - } - } else { // Tuple(s) - Array(ssaAddr) lvals; - ssaValueArray inits; - array_init_reserve(&lvals, m->tmp_allocator, vd->names.count); - array_init_reserve(&inits, m->tmp_allocator, vd->names.count); - - for_array(i, vd->names) { - AstNode *name = vd->names.e[i]; - ssaAddr lval = ssa_make_addr(NULL, NULL); - if (!ssa_is_blank_ident(name)) { - ssa_add_local_for_identifier(proc, name, false); - lval = ssa_build_addr(proc, name); - } - - array_add(&lvals, lval); - } - - for_array(i, vd->values) { - ssaValue *init = ssa_build_expr(proc, vd->values.e[i]); - Type *t = ssa_type(init); - if (t->kind == Type_Tuple) { - for (isize i = 0; i < t->Tuple.variable_count; i++) { - Entity *e = t->Tuple.variables[i]; - ssaValue *v = ssa_emit_struct_ev(proc, init, i); - array_add(&inits, v); - } - } else { - array_add(&inits, init); - } - } - - - for_array(i, inits) { - if (lvals.e[i].addr == NULL) { - continue; - } - ssaValue *v = ssa_emit_conv(proc, inits.e[i], ssa_addr_type(lvals.e[i])); - ssa_addr_store(proc, lvals.e[i], v); - } - } - - gb_temp_arena_memory_end(tmp); - case_end; - case_ast_node(pd, ProcDecl, node); if (pd->body != NULL) { CheckerInfo *info = proc->module->info; @@ -5472,78 +5403,6 @@ void ssa_gen_tree(ssaGen *s) { ssa_emit_store(proc, len, field_count); ssa_emit_store(proc, cap, field_count); } break; - case TypeRecord_Enum: { - tag = ssa_add_local_generated(proc, t_type_info_enum); - Type *enum_base = t->Record.enum_base; - if (enum_base == NULL) { - enum_base = t_int; - } - ssaValue *base = ssa_emit_struct_ep(proc, tag, 0); - ssa_emit_store(proc, base, ssa_get_type_info_ptr(proc, type_info_data, enum_base)); - - if (t->Record.enum_value_count > 0) { - Entity **fields = t->Record.enum_values; - isize count = t->Record.enum_value_count; - ssaValue *value_array = NULL; - ssaValue *name_array = NULL; - - { - Token token = {Token_Ident}; - i32 id = cast(i32)entry_index; - char name_base[] = "__$enum_values"; - isize name_len = gb_size_of(name_base) + 10; - token.string.text = gb_alloc_array(a, u8, name_len); - token.string.len = gb_snprintf(cast(char *)token.string.text, name_len, - "%s-%d", name_base, id)-1; - Entity *e = make_entity_variable(a, NULL, token, make_type_array(a, t_i64, count)); - value_array = ssa_make_value_global(a, e, NULL); - value_array->Global.is_private = true; - ssa_module_add_value(m, e, value_array); - map_ssa_value_set(&m->members, hash_string(token.string), value_array); - } - { - Token token = {Token_Ident}; - i32 id = cast(i32)entry_index; - char name_base[] = "__$enum_names"; - isize name_len = gb_size_of(name_base) + 10; - token.string.text = gb_alloc_array(a, u8, name_len); - token.string.len = gb_snprintf(cast(char *)token.string.text, name_len, - "%s-%d", name_base, id)-1; - Entity *e = make_entity_variable(a, NULL, token, make_type_array(a, t_string, count)); - name_array = ssa_make_value_global(a, e, NULL); - name_array->Global.is_private = true; - ssa_module_add_value(m, e, name_array); - map_ssa_value_set(&m->members, hash_string(token.string), name_array); - } - - for (isize i = 0; i < count; i++) { - ssaValue *value_gep = ssa_emit_array_epi(proc, value_array, i); - ssaValue *name_gep = ssa_emit_array_epi(proc, name_array, i); - - ssa_emit_store(proc, value_gep, ssa_make_const_i64(a, fields[i]->Constant.value.value_integer)); - ssa_emit_store(proc, name_gep, ssa_make_const_string(a, fields[i]->token.string)); - } - - ssaValue *v_count = ssa_make_const_int(a, count); - - - ssaValue *values = ssa_emit_struct_ep(proc, tag, 1); - ssaValue *names = ssa_emit_struct_ep(proc, tag, 2); - ssaValue *value_slice = ssa_add_local_generated(proc, type_deref(t_i64_slice_ptr)); - ssaValue *name_slice = ssa_add_local_generated(proc, type_deref(t_string_slice_ptr)); - - ssa_emit_store(proc, ssa_emit_struct_ep(proc, value_slice, 0), ssa_array_elem(proc, value_array)); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, value_slice, 1), v_count); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, value_slice, 2), v_count); - - ssa_emit_store(proc, ssa_emit_struct_ep(proc, name_slice, 0), ssa_array_elem(proc, name_array)); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, name_slice, 1), v_count); - ssa_emit_store(proc, ssa_emit_struct_ep(proc, name_slice, 2), v_count); - - ssa_emit_store(proc, values, ssa_emit_load(proc, value_slice)); - ssa_emit_store(proc, names, ssa_emit_load(proc, name_slice)); - } - } break; } } break; diff --git a/src/ssa_print.c b/src/ssa_print.c index 31463bd17..c6f55893a 100644 --- a/src/ssa_print.c +++ b/src/ssa_print.c @@ -225,9 +225,6 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) { i64 align_of_union = type_align_of(s, heap_allocator(), t); ssa_fprintf(f, "{[0 x <%lld x i8>], [%lld x i8]}", align_of_union, size_of_union); } break; - case TypeRecord_Enum: - ssa_print_type(f, m, t->Record.enum_base); - break; } } break;