Allow pointers to append; Fix strconv stuff; new_slice allows for capacity

This commit is contained in:
Ginger Bill
2017-03-02 19:24:34 +00:00
parent 9bc37f4400
commit 9e8c9be1ea
12 changed files with 184 additions and 88 deletions
+2 -2
View File
@@ -44,8 +44,8 @@ del *.ilk > NUL 2> NUL
cl %compiler_settings% "src\main.c" ^ cl %compiler_settings% "src\main.c" ^
/link %linker_settings% -OUT:%exe_name% ^ /link %linker_settings% -OUT:%exe_name% ^
&& odin run code/demo.odin && odin build code/Jaze/src/main.odin
rem && odin run code/Jaze/src/main.odin rem && odin run code/demo.odin
rem && odin build_dll code/example.odin ^ rem && odin build_dll code/example.odin ^
rem odin run code/demo.odin rem odin run code/demo.odin
+2 -2
View File
@@ -6,6 +6,7 @@
#import "opengl.odin"; #import "opengl.odin";
#import "os.odin"; #import "os.odin";
#import "strconv.odin"; #import "strconv.odin";
#import "sync.odin";
main :: proc() { main :: proc() {
// buf: [64]byte; // buf: [64]byte;
@@ -15,8 +16,7 @@ main :: proc() {
// fmt.println(s); // fmt.println(s);
// fmt.printf("%3d\n", 102); // fmt.printf("%3d\n", 102);
a: [10]int; s := new_slice(int, 0, 10);
s := a[..0];
append(s, 1, 2, 6, 3, 6, 5, 5, 5, 5, 1, 2); append(s, 1, 2, 6, 3, 6, 5, 5, 5, 5, 1, 2);
fmt.println(s); fmt.println(s);
+4 -6
View File
@@ -8,10 +8,10 @@
_BUFFER_SIZE :: 1<<12; _BUFFER_SIZE :: 1<<12;
write_string :: proc(buf: ^[]byte, s: string) { write_string :: proc(buf: ^[]byte, s: string) {
append(buf^, ..cast([]byte)s); append(buf, ..cast([]byte)s);
} }
write_byte :: proc(buf: ^[]byte, b: byte) { write_byte :: proc(buf: ^[]byte, b: byte) {
append(buf^, b); append(buf, b);
} }
write_rune :: proc(buf: ^[]byte, r: rune) { write_rune :: proc(buf: ^[]byte, r: rune) {
if r < utf8.RUNE_SELF { if r < utf8.RUNE_SELF {
@@ -20,7 +20,7 @@ write_rune :: proc(buf: ^[]byte, r: rune) {
} }
b, n := utf8.encode_rune(r); b, n := utf8.encode_rune(r);
append(buf^, ..b[..n]); append(buf, ..b[..n]);
} }
Fmt_Info :: struct { Fmt_Info :: struct {
@@ -431,7 +431,7 @@ fmt_write_padding :: proc(fi: ^Fmt_Info, width: int) {
count := min(width, fi.buf.capacity-fi.buf.count); count := min(width, fi.buf.capacity-fi.buf.count);
for _ in 0..count { for _ in 0..count {
append(fi.buf^, pad_byte); append(fi.buf, pad_byte);
} }
} }
@@ -533,8 +533,6 @@ _pad :: proc(fi: ^Fmt_Info, s: string) {
} }
fmt_float :: proc(fi: ^Fmt_Info, v: f64, bit_size: int, verb: rune) { fmt_float :: proc(fi: ^Fmt_Info, v: f64, bit_size: int, verb: rune) {
match verb { match verb {
// case 'e', 'E', 'f', 'F', 'g', 'G', 'v': // case 'e', 'E', 'f', 'F', 'g', 'G', 'v':
// case 'f', 'F', 'v': // case 'f', 'F', 'v':
+10 -9
View File
@@ -109,12 +109,9 @@ generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, prec, bit_size: int) -> [
round_shortest(d, mant, exp, flt); round_shortest(d, mant, exp, flt);
digs = Decimal_Slice{digits = d.digits[..], count = d.count, decimal_point = d.decimal_point}; digs = Decimal_Slice{digits = d.digits[..], count = d.count, decimal_point = d.decimal_point};
match fmt { match fmt {
case 'e', 'E': case 'e', 'E': prec = digs.count-1;
prec = digs.count-1; case 'f', 'F': prec = max(digs.count-digs.decimal_point, 0);
case 'f', 'F': case 'g', 'G': prec = digs.count;
prec = max(digs.count-digs.decimal_point, 0);
case 'g', 'G':
prec = digs.count;
} }
} else { } else {
match fmt { match fmt {
@@ -139,9 +136,10 @@ format_digits :: proc(buf: []byte, shortest: bool, neg: bool, digs: Decimal_Slic
case 'f', 'F': case 'f', 'F':
add_bytes :: proc(dst: ^[]byte, w: ^int, bytes: ..byte) { add_bytes :: proc(dst: ^[]byte, w: ^int, bytes: ..byte) {
for b in bytes { for b in bytes {
if dst.count <= w^ { if dst.capacity <= w^ {
break; break;
} }
dst.count++;
dst[w^] = b; dst[w^] = b;
w^++; w^++;
} }
@@ -166,6 +164,7 @@ format_digits :: proc(buf: []byte, shortest: bool, neg: bool, digs: Decimal_Slic
add_bytes(^dst, ^w, '0'); add_bytes(^dst, ^w, '0');
} }
// fractional part // fractional part
if prec > 0 { if prec > 0 {
add_bytes(^dst, ^w, '.'); add_bytes(^dst, ^w, '.');
@@ -181,10 +180,12 @@ format_digits :: proc(buf: []byte, shortest: bool, neg: bool, digs: Decimal_Slic
return buf[..w]; return buf[..w];
case 'e', 'E': case 'e', 'E':
return nil; // TODO panic("strconv: e/E float printing is not yet supported");
return buf; // TODO
case 'g', 'G': case 'g', 'G':
return nil; // TODO panic("strconv: g/G float printing is not yet supported");
return buf; // TODO
} }
c: [2]byte; c: [2]byte;
+2 -2
View File
@@ -1,8 +1,8 @@
new_c_string :: proc(s: string) -> ^byte { new_c_string :: proc(s: string) -> ^byte {
c := new_c_string(byte, s.count+1); c := new_slice(byte, s.count+1);
copy(c, cast([]byte)s); copy(c, cast([]byte)s);
c[s.count] = 0; c[s.count] = 0;
return c; return c.data;
} }
to_odin_string :: proc(c: ^byte) -> string { to_odin_string :: proc(c: ^byte) -> string {
+31 -31
View File
@@ -2,14 +2,14 @@
#import "atomic.odin"; #import "atomic.odin";
Semaphore :: struct { Semaphore :: struct {
handle: win32.HANDLE, _handle: win32.HANDLE,
} }
Mutex :: struct { Mutex :: struct {
semaphore: Semaphore, _semaphore: Semaphore,
counter: i32, _counter: i32,
owner: i32, _owner: i32,
recursion: i32, _recursion: i32,
} }
current_thread_id :: proc() -> i32 { current_thread_id :: proc() -> i32 {
@@ -17,74 +17,74 @@ current_thread_id :: proc() -> i32 {
} }
semaphore_init :: proc(s: ^Semaphore) { semaphore_init :: proc(s: ^Semaphore) {
s.handle = win32.CreateSemaphoreA(nil, 0, 1<<31-1, nil); s._handle = win32.CreateSemaphoreA(nil, 0, 1<<31-1, nil);
} }
semaphore_destroy :: proc(s: ^Semaphore) { semaphore_destroy :: proc(s: ^Semaphore) {
win32.CloseHandle(s.handle); win32.CloseHandle(s._handle);
} }
semaphore_post :: proc(s: ^Semaphore, count: int) { semaphore_post :: proc(s: ^Semaphore, count: int) {
win32.ReleaseSemaphore(s.handle, cast(i32)count, nil); win32.ReleaseSemaphore(s._handle, cast(i32)count, nil);
} }
semaphore_release :: proc(s: ^Semaphore) #inline { semaphore_post(s, 1); } semaphore_release :: proc(s: ^Semaphore) #inline { semaphore_post(s, 1); }
semaphore_wait :: proc(s: ^Semaphore) { semaphore_wait :: proc(s: ^Semaphore) {
win32.WaitForSingleObject(s.handle, win32.INFINITE); win32.WaitForSingleObject(s._handle, win32.INFINITE);
} }
mutex_init :: proc(m: ^Mutex) { mutex_init :: proc(m: ^Mutex) {
atomic.store(^m.counter, 0); atomic.store(^m._counter, 0);
atomic.store(^m.owner, current_thread_id()); atomic.store(^m._owner, current_thread_id());
semaphore_init(^m.semaphore); semaphore_init(^m._semaphore);
m.recursion = 0; m._recursion = 0;
} }
mutex_destroy :: proc(m: ^Mutex) { mutex_destroy :: proc(m: ^Mutex) {
semaphore_destroy(^m.semaphore); semaphore_destroy(^m._semaphore);
} }
mutex_lock :: proc(m: ^Mutex) { mutex_lock :: proc(m: ^Mutex) {
thread_id := current_thread_id(); thread_id := current_thread_id();
if atomic.fetch_add(^m.counter, 1) > 0 { if atomic.fetch_add(^m._counter, 1) > 0 {
if thread_id != atomic.load(^m.owner) { if thread_id != atomic.load(^m._owner) {
semaphore_wait(^m.semaphore); semaphore_wait(^m._semaphore);
} }
} }
atomic.store(^m.owner, thread_id); atomic.store(^m._owner, thread_id);
m.recursion++; m._recursion++;
} }
mutex_try_lock :: proc(m: ^Mutex) -> bool { mutex_try_lock :: proc(m: ^Mutex) -> bool {
thread_id := current_thread_id(); thread_id := current_thread_id();
if atomic.load(^m.owner) == thread_id { if atomic.load(^m._owner) == thread_id {
atomic.fetch_add(^m.counter, 1); atomic.fetch_add(^m._counter, 1);
} else { } else {
expected: i32 = 0; expected: i32 = 0;
if atomic.load(^m.counter) != 0 { if atomic.load(^m._counter) != 0 {
return false; return false;
} }
if atomic.compare_exchange(^m.counter, expected, 1) == 0 { if atomic.compare_exchange(^m._counter, expected, 1) == 0 {
return false; return false;
} }
atomic.store(^m.owner, thread_id); atomic.store(^m._owner, thread_id);
} }
m.recursion++; m._recursion++;
return true; return true;
} }
mutex_unlock :: proc(m: ^Mutex) { mutex_unlock :: proc(m: ^Mutex) {
recursion: i32; recursion: i32;
thread_id := current_thread_id(); thread_id := current_thread_id();
assert(thread_id == atomic.load(^m.owner)); assert(thread_id == atomic.load(^m._owner));
m.recursion--; m._recursion--;
recursion = m.recursion; recursion = m._recursion;
if recursion == 0 { if recursion == 0 {
atomic.store(^m.owner, thread_id); atomic.store(^m._owner, thread_id);
} }
if atomic.fetch_add(^m.counter, -1) > 1 { if atomic.fetch_add(^m._counter, -1) > 1 {
if recursion == 0 { if recursion == 0 {
semaphore_release(^m.semaphore); semaphore_release(^m._semaphore);
} }
} }
} }
+75 -8
View File
@@ -40,14 +40,19 @@ WS_CAPTION :: 0x00C00000;
WS_VISIBLE :: 0x10000000; WS_VISIBLE :: 0x10000000;
WS_OVERLAPPEDWINDOW :: WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX; WS_OVERLAPPEDWINDOW :: WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX;
WM_DESTROY :: 0x0002; WM_DESTROY :: 0x0002;
WM_SIZE :: 0x0005; WM_SIZE :: 0x0005;
WM_CLOSE :: 0x0010; WM_CLOSE :: 0x0010;
WM_ACTIVATEAPP :: 0x001C; WM_ACTIVATEAPP :: 0x001C;
WM_QUIT :: 0x0012; WM_QUIT :: 0x0012;
WM_KEYDOWN :: 0x0100; WM_KEYDOWN :: 0x0100;
WM_KEYUP :: 0x0101; WM_KEYUP :: 0x0101;
WM_SIZING :: 0x0214; WM_SIZING :: 0x0214;
WM_MOUSEWHEEL :: 0x020A;
WM_SYSKEYDOWN :: 0x0104;
WM_WINDOWPOSCHANGED :: 0x0047;
WM_SETCURSOR :: 0x0020;
WM_CHAR :: 0x0102;
PM_REMOVE :: 1; PM_REMOVE :: 1;
@@ -300,6 +305,68 @@ ReadBarrier :: proc() #foreign kernel32;
HMONITOR :: HANDLE;
GWL_STYLE :: -16;
HWND_TOP :: cast(HWND)cast(uint)0;
MONITOR_DEFAULTTONULL :: 0x00000000;
MONITOR_DEFAULTTOPRIMARY :: 0x00000001;
MONITOR_DEFAULTTONEAREST :: 0x00000002;
SWP_FRAMECHANGED :: 0x0020;
SWP_NOOWNERZORDER :: 0x0200;
SWP_NOZORDER :: 0x0004;
SWP_NOSIZE :: 0x0001;
SWP_NOMOVE :: 0x0002;
MONITORINFO :: struct #ordered {
size: u32,
monitor: RECT,
work: RECT,
flags: u32,
}
WINDOWPLACEMENT :: struct #ordered {
length: u32,
flags: u32,
show_cmd: u32,
min_pos: POINT,
max_pos: POINT,
normal_pos: RECT,
}
GetMonitorInfoA :: proc(monitor: HMONITOR, mi: ^MONITORINFO) -> BOOL #foreign user32;
MonitorFromWindow :: proc(wnd: HWND, flags : u32) -> HMONITOR #foreign user32;
SetWindowPos :: proc(wnd: HWND, wndInsertAfter: HWND, x, y, width, height: i32, flags: u32) #foreign user32 "SetWindowPos";
GetWindowPlacement :: proc(wnd: HWND, wndpl: ^WINDOWPLACEMENT) -> BOOL #foreign user32;
SetWindowPlacement :: proc(wnd: HWND, wndpl: ^WINDOWPLACEMENT) -> BOOL #foreign user32;
GetWindowLongPtrA :: proc(wnd: HWND, index: i32) -> i64 #foreign user32;
SetWindowLongPtrA :: proc(wnd: HWND, index: i32, new: i64) -> i64 #foreign user32;
GetWindowText :: proc(wnd: HWND, str: ^byte, maxCount: i32) -> i32 #foreign user32;
HIWORD :: proc(wParam: WPARAM) -> u16 { return cast(u16)((cast(u32)wParam >> 16) & 0xffff); }
HIWORD :: proc(lParam: LPARAM) -> u16 { return cast(u16)((cast(u32)lParam >> 16) & 0xffff); }
LOWORD :: proc(wParam: WPARAM) -> u16 { return cast(u16)wParam; }
LOWORD :: proc(lParam: LPARAM) -> u16 { return cast(u16)lParam; }
BITMAPINFOHEADER :: struct #ordered { BITMAPINFOHEADER :: struct #ordered {
size: u32, size: u32,
width, height: i32, width, height: i32,
+35 -12
View File
@@ -2918,9 +2918,9 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
err = "Too many"; err = "Too many";
} }
if (err) { if (err != NULL) {
gbString expr = expr_to_string(ce->proc); gbString expr = expr_to_string(ce->proc);
error(ce->close, "`%s` arguments for `%s`, expected %td, got %td", error(ce->close, "%s arguments for `%s`, expected %td, got %td",
err, expr, err, expr,
bp->arg_count, ce->args.count); bp->arg_count, ce->args.count);
gb_string_free(expr); gb_string_free(expr);
@@ -2962,6 +2962,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
} break; } break;
case BuiltinProc_new_slice: { case BuiltinProc_new_slice: {
// new_slice :: proc(Type, len: int) -> []Type // new_slice :: proc(Type, len: int) -> []Type
// new_slice :: proc(Type, len, cap: int) -> []Type
Operand op = {0}; Operand op = {0};
check_expr_or_type(c, &op, ce->args.e[0]); check_expr_or_type(c, &op, ce->args.e[0]);
Type *type = op.type; Type *type = op.type;
@@ -2970,15 +2971,27 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
return false; return false;
} }
check_expr(c, &op, ce->args.e[1]); isize arg_count = ce->args.count;
if (op.mode == Addressing_Invalid) { if (arg_count < 2 || 3 < arg_count) {
return false; error_node(ce->args.e[0], "`new_slice` expects 2 or 3 arguments, found %td", arg_count);
} // NOTE(bill): Return the correct type to reduce errors
if (!is_type_integer(op.type)) { } else {
gbString type_str = type_to_string(op.type); // If any are constant
error_node(call, "Length for `new_slice` must be an integer, got `%s`", type_str); i64 sizes[2] = {0};
gb_string_free(type_str); isize size_count = 0;
return false; for (isize i = 1; i < arg_count; i++) {
i64 val = 0;
bool ok = check_index_value(c, ce->args.e[i], -1, &val);
if (ok && val >= 0) {
GB_ASSERT(size_count < gb_count_of(sizes));
sizes[size_count++] = val;
}
}
if (size_count == 2 && sizes[0] > sizes[1]) {
error_node(ce->args.e[1], "`new_slice` count and capacity are swapped");
// No need quit
}
} }
operand->mode = Addressing_Value; operand->mode = Addressing_Value;
@@ -3060,7 +3073,8 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
// append :: proc([dynamic]Type, item: ..Type) // append :: proc([dynamic]Type, item: ..Type)
// append :: proc([]Type, item: ..Type) // append :: proc([]Type, item: ..Type)
Type *type = operand->type; Type *type = operand->type;
type = base_type(type); bool is_pointer = is_type_pointer(type);
type = base_type(type_deref(type));
if (!is_type_dynamic_array(type) && !is_type_slice(type)) { if (!is_type_dynamic_array(type) && !is_type_slice(type)) {
gbString str = type_to_string(type); gbString str = type_to_string(type);
error_node(operand->expr, "Expected a slice or dynamic array, got `%s`", str); error_node(operand->expr, "Expected a slice or dynamic array, got `%s`", str);
@@ -3068,6 +3082,15 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
return false; return false;
} }
bool is_addressable = operand->mode == Addressing_Variable;
if (is_pointer) {
is_addressable = true;
}
if (!is_addressable) {
error_node(operand->expr, "`append` can only operate on addressable values");
return false;
}
Type *elem = NULL; Type *elem = NULL;
Type *slice_elem = NULL; Type *slice_elem = NULL;
if (is_type_dynamic_array(type)) { if (is_type_dynamic_array(type)) {
+1 -1
View File
@@ -68,7 +68,7 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
{STR_LIT(""), 0, false, Expr_Stmt}, {STR_LIT(""), 0, false, Expr_Stmt},
{STR_LIT("new"), 1, false, Expr_Expr}, {STR_LIT("new"), 1, false, Expr_Expr},
{STR_LIT("new_slice"), 2, false, Expr_Expr}, {STR_LIT("new_slice"), 2, true, Expr_Expr},
{STR_LIT("free"), 1, false, Expr_Stmt}, {STR_LIT("free"), 1, false, Expr_Stmt},
{STR_LIT("reserve"), 2, false, Expr_Stmt}, {STR_LIT("reserve"), 2, false, Expr_Stmt},
+16 -5
View File
@@ -3168,7 +3168,8 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
case BuiltinProc_new_slice: { case BuiltinProc_new_slice: {
ir_emit_comment(proc, str_lit("new_slice")); ir_emit_comment(proc, str_lit("new_slice"));
// new_slice :: proc(Type, len: int) -> ^Type // new_slice :: proc(Type, len: int) -> []Type
// new_slice :: proc(Type, len, cap: int) -> []Type
gbAllocator allocator = proc->module->allocator; gbAllocator allocator = proc->module->allocator;
Type *type = type_of_expr(proc->module->info, ce->args.e[0]); Type *type = type_of_expr(proc->module->info, ce->args.e[0]);
@@ -3182,10 +3183,15 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
irValue *elem_align = ir_make_const_int(allocator, a); irValue *elem_align = ir_make_const_int(allocator, a);
irValue *count = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[1]), t_int); irValue *count = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[1]), t_int);
irValue *capacity = count;
ir_emit_slice_bounds_check(proc, ast_node_token(ce->args.e[1]), v_zero, count, count, false); if (ce->args.count == 3) {
capacity = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[2]), t_int);
}
irValue *slice_size = ir_emit_arith(proc, Token_Mul, elem_size, count, t_int); ir_emit_slice_bounds_check(proc, ast_node_token(ce->args.e[1]), v_zero, count, capacity, false);
irValue *slice_size = ir_emit_arith(proc, Token_Mul, elem_size, capacity, t_int);
irValue **args = gb_alloc_array(allocator, irValue *, 2); irValue **args = gb_alloc_array(allocator, irValue *, 2);
args[0] = slice_size; args[0] = slice_size;
@@ -3195,7 +3201,7 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
irValue *ptr = ir_emit_conv(proc, call, ptr_type); irValue *ptr = ir_emit_conv(proc, call, ptr_type);
irValue *slice = ir_add_local_generated(proc, slice_type); irValue *slice = ir_add_local_generated(proc, slice_type);
ir_fill_slice(proc, slice, ptr, count, count); ir_fill_slice(proc, slice, ptr, count, capacity);
return ir_emit_load(proc, slice); return ir_emit_load(proc, slice);
} break; } break;
@@ -3330,7 +3336,12 @@ irValue *ir_build_single_expr(irProcedure *proc, AstNode *expr, TypeAndValue *tv
ir_emit_comment(proc, str_lit("append")); ir_emit_comment(proc, str_lit("append"));
gbAllocator a = proc->module->allocator; gbAllocator a = proc->module->allocator;
irValue *array_ptr = ir_build_addr(proc, ce->args.e[0]).addr; Type *value_type = type_of_expr(proc->module->info, ce->args.e[0]);
irAddr array_addr = ir_build_addr(proc, ce->args.e[0]);
irValue *array_ptr = array_addr.addr;
if (is_type_pointer(value_type)) {
array_ptr = ir_addr_load(proc, array_addr);
}
Type *type = ir_type(array_ptr); Type *type = ir_type(array_ptr);
GB_ASSERT(is_type_pointer(type)); GB_ASSERT(is_type_pointer(type));
type = base_type(type_deref(type)); type = base_type(type_deref(type));
+5 -6
View File
@@ -664,6 +664,11 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_fprintf(f, "\t"); ir_fprintf(f, "\t");
switch (instr->kind) { switch (instr->kind) {
default: {
GB_PANIC("<unknown instr> %d\n", instr->kind);
ir_fprintf(f, "; <unknown instr> %d\n", instr->kind);
} break;
case irInstr_StartupRuntime: { case irInstr_StartupRuntime: {
ir_fprintf(f, "call void "); ir_fprintf(f, "call void ");
ir_print_encoded_global(f, str_lit(IR_STARTUP_RUNTIME_PROC_NAME), false); ir_print_encoded_global(f, str_lit(IR_STARTUP_RUNTIME_PROC_NAME), false);
@@ -1281,12 +1286,6 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) {
ir_fprintf(f, "\n"); */ ir_fprintf(f, "\n"); */
} break; } break;
default: {
GB_PANIC("<unknown instr> %d\n", instr->kind);
ir_fprintf(f, "; <unknown instr> %d\n", instr->kind);
} break;
} }
} }
+1 -4
View File
@@ -1342,9 +1342,6 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
} }
} }
if (type->kind != Type_Record) {
return sel;
}
if (is_type) { if (is_type) {
if (type->kind == Type_Record) { if (type->kind == Type_Record) {
if (type->Record.names != NULL && if (type->Record.names != NULL &&
@@ -1395,7 +1392,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
} }
} }
} }
} else { } else if (type->kind == Type_Record) {
for (isize i = 0; i < type->Record.field_count; i++) { for (isize i = 0; i < type->Record.field_count; i++) {
Entity *f = type->Record.fields[i]; Entity *f = type->Record.fields[i];
if (f->kind != Entity_Variable || (f->flags & EntityFlag_Field) == 0) { if (f->kind != Entity_Variable || (f->flags & EntityFlag_Field) == 0) {