len, cap, make; remove .count, .capacity, new_slice

This commit is contained in:
Ginger Bill
2017-04-02 18:16:45 +01:00
parent 2c8b99337b
commit 8ce58573df
16 changed files with 538 additions and 185 deletions
+13 -5
View File
@@ -1,10 +1,18 @@
#import "atomic.odin";
#import "decimal.odin";
#import "fmt.odin"; #import "fmt.odin";
#import "os.odin"; #import "hash.odin";
#import "math.odin"; #import "math.odin";
#import "mem.odin";
#import "opengl.odin";
#import "os.odin";
#import "strconv.odin";
#import "strings.odin";
#import "sync.odin";
#import "types.odin";
#import "utf8.odin";
#import "utf16.odin";
main :: proc() { main :: proc() {
x := 1+2i+3j+4k;
y := conj(x);
z := x/y;
fmt.println(z, abs(z));
} }
+66 -51
View File
@@ -277,17 +277,17 @@ default_allocator :: proc() -> Allocator {
__string_eq :: proc(a, b: string) -> bool { __string_eq :: proc(a, b: string) -> bool {
if a.count != b.count { if len(a) != len(b) {
return false; return false;
} }
if a.data == b.data { if ^a[0] == ^b[0] {
return true; return true;
} }
return __string_cmp(a, b) == 0; return __string_cmp(a, b) == 0;
} }
__string_cmp :: proc(a, b: string) -> int { __string_cmp :: proc(a, b: string) -> int {
return __mem_compare(a.data, b.data, min(a.count, b.count)); return __mem_compare(^a[0], ^b[0], min(len(a), len(b)));
} }
__string_ne :: proc(a, b: string) -> bool #inline { return !__string_eq(a, b); } __string_ne :: proc(a, b: string) -> bool #inline { return !__string_eq(a, b); }
@@ -426,19 +426,19 @@ Raw_Any :: struct #ordered {
Raw_String :: struct #ordered { Raw_String :: struct #ordered {
data: ^byte, data: ^byte,
count: int, len: int,
}; };
Raw_Slice :: struct #ordered { Raw_Slice :: struct #ordered {
data: rawptr, data: rawptr,
count: int, len: int,
capacity: int, cap: int,
}; };
Raw_Dynamic_Array :: struct #ordered { Raw_Dynamic_Array :: struct #ordered {
data: rawptr, data: rawptr,
count: int, len: int,
capacity: int, cap: int,
allocator: Allocator, allocator: Allocator,
}; };
@@ -448,11 +448,22 @@ Raw_Dynamic_Map :: struct #ordered {
}; };
__dynamic_array_make :: proc(array_: rawptr, elem_size, elem_align: int, len, cap: int) {
array := cast(^Raw_Dynamic_Array)array_;
__check_context();
array.allocator = context.allocator;
assert(array.allocator.procedure != nil);
__dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, capacity: int) -> bool { if cap > 0 {
__dynamic_array_reserve(array_, elem_size, elem_align, cap);
array.len = len;
}
}
__dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, cap: int) -> bool {
array := cast(^Raw_Dynamic_Array)array_; array := cast(^Raw_Dynamic_Array)array_;
if capacity <= array.capacity { if cap <= array.cap {
return true; return true;
} }
@@ -462,8 +473,8 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, capa
} }
assert(array.allocator.procedure != nil); assert(array.allocator.procedure != nil);
old_size := array.capacity * elem_size; old_size := array.cap * elem_size;
new_size := capacity * elem_size; new_size := cap * elem_size;
allocator := array.allocator; allocator := array.allocator;
new_data := allocator.procedure(allocator.data, Allocator_Mode.RESIZE, new_size, elem_align, array.data, old_size, 0); new_data := allocator.procedure(allocator.data, Allocator_Mode.RESIZE, new_size, elem_align, array.data, old_size, 0);
@@ -472,7 +483,7 @@ __dynamic_array_reserve :: proc(array_: rawptr, elem_size, elem_align: int, capa
} }
array.data = new_data; array.data = new_data;
array.capacity = capacity; array.cap = cap;
return true; return true;
} }
@@ -482,43 +493,43 @@ __dynamic_array_append :: proc(array_: rawptr, elem_size, elem_align: int,
array := cast(^Raw_Dynamic_Array)array_; array := cast(^Raw_Dynamic_Array)array_;
if item_count <= 0 || items == nil { if item_count <= 0 || items == nil {
return array.count; return array.len;
} }
ok := true; ok := true;
if array.capacity <= array.count+item_count { if array.cap <= array.len+item_count {
capacity := 2 * array.capacity + max(8, item_count); cap := 2 * array.cap + max(8, item_count);
ok = __dynamic_array_reserve(array, elem_size, elem_align, capacity); ok = __dynamic_array_reserve(array, elem_size, elem_align, cap);
} }
if !ok { if !ok {
// TODO(bill): Better error handling for failed reservation // TODO(bill): Better error handling for failed reservation
return array.count; return array.len;
} }
data := cast(^byte)array.data; data := cast(^byte)array.data;
assert(data != nil); assert(data != nil);
__mem_copy(data + (elem_size*array.count), items, elem_size * item_count); __mem_copy(data + (elem_size*array.len), items, elem_size * item_count);
array.count += item_count; array.len += item_count;
return array.count; return array.len;
} }
__dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: int) -> int { __dynamic_array_append_nothing :: proc(array_: rawptr, elem_size, elem_align: int) -> int {
array := cast(^Raw_Dynamic_Array)array_; array := cast(^Raw_Dynamic_Array)array_;
ok := true; ok := true;
if array.capacity <= array.count+1 { if array.cap <= array.len+1 {
capacity := 2 * array.capacity + max(8, 1); cap := 2 * array.cap + max(8, 1);
ok = __dynamic_array_reserve(array, elem_size, elem_align, capacity); ok = __dynamic_array_reserve(array, elem_size, elem_align, cap);
} }
if !ok { if !ok {
// TODO(bill): Better error handling for failed reservation // TODO(bill): Better error handling for failed reservation
return array.count; return array.len;
} }
data := cast(^byte)array.data; data := cast(^byte)array.data;
assert(data != nil); assert(data != nil);
__mem_zero(data + (elem_size*array.count), elem_size); __mem_zero(data + (elem_size*array.len), elem_size);
array.count++; array.len++;
return array.count; return array.len;
} }
__slice_append :: proc(slice_: rawptr, elem_size, elem_align: int, __slice_append :: proc(slice_: rawptr, elem_size, elem_align: int,
@@ -526,17 +537,17 @@ __slice_append :: proc(slice_: rawptr, elem_size, elem_align: int,
slice := cast(^Raw_Slice)slice_; slice := cast(^Raw_Slice)slice_;
if item_count <= 0 || items == nil { if item_count <= 0 || items == nil {
return slice.count; return slice.len;
} }
item_count = min(slice.capacity-slice.count, item_count); item_count = min(slice.cap-slice.len, item_count);
if item_count > 0 { if item_count > 0 {
data := cast(^byte)slice.data; data := cast(^byte)slice.data;
assert(data != nil); assert(data != nil);
__mem_copy(data + (elem_size*slice.count), items, elem_size * item_count); __mem_copy(data + (elem_size*slice.len), items, elem_size * item_count);
slice.count += item_count; slice.len += item_count;
} }
return slice.count; return slice.len;
} }
@@ -583,9 +594,9 @@ __Map_Header :: struct #ordered {
value_offset: int, value_offset: int,
} }
__dynamic_map_reserve :: proc(using header: __Map_Header, capacity: int) -> bool { __dynamic_map_reserve :: proc(using header: __Map_Header, cap: int) -> bool {
h := __dynamic_array_reserve(^m.hashes, size_of(int), align_of(int), capacity); h := __dynamic_array_reserve(^m.hashes, size_of(int), align_of(int), cap);
e := __dynamic_array_reserve(^m.entries, entry_size, entry_align, capacity); e := __dynamic_array_reserve(^m.entries, entry_size, entry_align, cap);
return h && e; return h && e;
} }
@@ -594,18 +605,22 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int) {
nm: Raw_Dynamic_Map; nm: Raw_Dynamic_Map;
new_header.m = ^nm; new_header.m = ^nm;
header_hashes := cast(^Raw_Dynamic_Array)^header.m.hashes;
nm_hashes := cast(^Raw_Dynamic_Array)^nm.hashes;
reserve(nm.hashes, new_count); reserve(nm.hashes, new_count);
nm.hashes.count = nm.hashes.capacity; nm_hashes.len = nm_hashes.cap;
__dynamic_array_reserve(^nm.entries, entry_size, entry_align, m.entries.count); __dynamic_array_reserve(^nm.entries, entry_size, entry_align, m.entries.len);
for _, i in nm.hashes { for _, i in nm.hashes {
nm.hashes[i] = -1; nm.hashes[i] = -1;
} }
for i := 0; i < nm.entries.count; i++ { for i := 0; i < nm.entries.len; i++ {
entry_header := __dynamic_map_get_entry(new_header, i); entry_header := __dynamic_map_get_entry(new_header, i);
data := cast(^byte)entry_header; data := cast(^byte)entry_header;
if nm.hashes.count == 0 { if len(nm.hashes) == 0 {
__dynamic_map_grow(new_header); __dynamic_map_grow(new_header);
} }
@@ -626,7 +641,7 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int) {
__dynamic_map_grow(new_header); __dynamic_map_grow(new_header);
} }
} }
free_ptr_with_allocator(header.m.hashes.allocator, header.m.hashes.data); free_ptr_with_allocator(header_hashes.allocator, header_hashes.data);
free_ptr_with_allocator(header.m.entries.allocator, header.m.entries.data); free_ptr_with_allocator(header.m.entries.allocator, header.m.entries.data);
header.m^ = nm; header.m^ = nm;
} }
@@ -644,7 +659,7 @@ __dynamic_map_get :: proc(h: __Map_Header, key: __Map_Key) -> rawptr {
__dynamic_map_set :: proc(using h: __Map_Header, key: __Map_Key, value: rawptr) { __dynamic_map_set :: proc(using h: __Map_Header, key: __Map_Key, value: rawptr) {
index: int; index: int;
if m.hashes.count == 0 { if len(m.hashes) == 0 {
__dynamic_map_grow(h); __dynamic_map_grow(h);
} }
fr := __dynamic_map_find(h, key); fr := __dynamic_map_find(h, key);
@@ -672,12 +687,12 @@ __dynamic_map_set :: proc(using h: __Map_Header, key: __Map_Key, value: rawptr)
__dynamic_map_grow :: proc(using h: __Map_Header) { __dynamic_map_grow :: proc(using h: __Map_Header) {
new_count := 2*m.entries.count + 8; new_count := 2*m.entries.len + 8;
__dynamic_map_rehash(h, new_count); __dynamic_map_rehash(h, new_count);
} }
__dynamic_map_full :: proc(using h: __Map_Header) -> bool { __dynamic_map_full :: proc(using h: __Map_Header) -> bool {
return cast(int)(0.75 * cast(f64)m.hashes.count) <= m.entries.count; return cast(int)(0.75 * cast(f64)len(m.hashes)) <= m.entries.len;
} }
@@ -693,8 +708,8 @@ __dynamic_map_hash_equal :: proc(h: __Map_Header, a, b: __Map_Key) -> bool {
__dynamic_map_find :: proc(using h: __Map_Header, key: __Map_Key) -> __Map_Find_Result { __dynamic_map_find :: proc(using h: __Map_Header, key: __Map_Key) -> __Map_Find_Result {
fr := __Map_Find_Result{-1, -1, -1}; fr := __Map_Find_Result{-1, -1, -1};
if m.hashes.count > 0 { if len(m.hashes) > 0 {
fr.hash_index = cast(int)(key.hash % cast(u64)m.hashes.count); fr.hash_index = cast(int)(key.hash % cast(u64)len(m.hashes));
fr.entry_index = m.hashes[fr.hash_index]; fr.entry_index = m.hashes[fr.hash_index];
for fr.entry_index >= 0 { for fr.entry_index >= 0 {
entry := __dynamic_map_get_entry(h, fr.entry_index); entry := __dynamic_map_get_entry(h, fr.entry_index);
@@ -709,7 +724,7 @@ __dynamic_map_find :: proc(using h: __Map_Header, key: __Map_Key) -> __Map_Find_
} }
__dynamic_map_add_entry :: proc(using h: __Map_Header, key: __Map_Key) -> int { __dynamic_map_add_entry :: proc(using h: __Map_Header, key: __Map_Key) -> int {
prev := m.entries.count; prev := m.entries.len;
c := __dynamic_array_append_nothing(^m.entries, entry_size, entry_align); c := __dynamic_array_append_nothing(^m.entries, entry_size, entry_align);
if c != prev { if c != prev {
end := __dynamic_map_get_entry(h, c-1); end := __dynamic_map_get_entry(h, c-1);
@@ -739,10 +754,10 @@ __dynamic_map_erase :: proc(using h: __Map_Header, fr: __Map_Find_Result) {
__dynamic_map_get_entry(h, fr.entry_prev).next = __dynamic_map_get_entry(h, fr.entry_index).next; __dynamic_map_get_entry(h, fr.entry_prev).next = __dynamic_map_get_entry(h, fr.entry_index).next;
} }
if fr.entry_index == m.entries.count-1 { if fr.entry_index == m.entries.len-1 {
m.entries.count--; m.entries.len--;
} }
__mem_copy(__dynamic_map_get_entry(h, fr.entry_index), __dynamic_map_get_entry(h, m.entries.count-1), entry_size); __mem_copy(__dynamic_map_get_entry(h, fr.entry_index), __dynamic_map_get_entry(h, m.entries.len-1), entry_size);
last := __dynamic_map_find(h, __dynamic_map_get_entry(h, fr.entry_index).key); last := __dynamic_map_find(h, __dynamic_map_get_entry(h, fr.entry_index).key);
if last.entry_prev >= 0 { if last.entry_prev >= 0 {
__dynamic_map_get_entry(h, last.entry_prev).next = fr.entry_index; __dynamic_map_get_entry(h, last.entry_prev).next = fr.entry_index;
+6 -6
View File
@@ -14,14 +14,14 @@ decimal_to_string :: proc(buf: []byte, a: ^Decimal) -> string {
for _, i in buf { for _, i in buf {
buf[i] = '0'; buf[i] = '0';
} }
return buf.count; return len(buf);
} }
n := 10 + a.count + abs(a.decimal_point); n := 10 + a.count + abs(a.decimal_point);
// TODO(bill): make this work with a buffer that's not big enough // TODO(bill): make this work with a buffer that's not big enough
assert(buf.count >= n); assert(len(buf) >= n);
buf = buf[..n]; buf = buf[..n];
if a.count == 0 { if a.count == 0 {
@@ -118,7 +118,7 @@ shift_right :: proc(a: ^Decimal, k: uint) {
for n > 0 { for n > 0 {
dig := n>>k; dig := n>>k;
n &= mask; n &= mask;
if w < a.digits.count { if w < len(a.digits) {
a.digits[w] = cast(byte)('0' + dig); a.digits[w] = cast(byte)('0' + dig);
w++; w++;
} else if dig > 0 { } else if dig > 0 {
@@ -144,7 +144,7 @@ shift_left :: proc(a: ^Decimal, k: uint) {
quo := n/10; quo := n/10;
rem := n - 10*quo; rem := n - 10*quo;
w--; w--;
if w < a.digits.count { if w < len(a.digits) {
a.digits[w] = cast(byte)('0' + rem); a.digits[w] = cast(byte)('0' + rem);
} else if rem != 0 { } else if rem != 0 {
a.trunc = true; a.trunc = true;
@@ -156,7 +156,7 @@ shift_left :: proc(a: ^Decimal, k: uint) {
quo := n/10; quo := n/10;
rem := n - 10*quo; rem := n - 10*quo;
w--; w--;
if w < a.digits.count { if w < len(a.digits) {
a.digits[w] = cast(byte)('0' + rem); a.digits[w] = cast(byte)('0' + rem);
} else if rem != 0 { } else if rem != 0 {
a.trunc = true; a.trunc = true;
@@ -165,7 +165,7 @@ shift_left :: proc(a: ^Decimal, k: uint) {
} }
a.count += delta; a.count += delta;
a.count = min(a.count, a.digits.count); a.count = min(a.count, len(a.digits));
a.decimal_point += delta; a.decimal_point += delta;
trim(a); trim(a);
} }
+37 -37
View File
@@ -48,23 +48,23 @@ fprint :: proc(fd: os.Handle, args: ..any) -> int {
data: [_BUFFER_SIZE]byte; data: [_BUFFER_SIZE]byte;
buf := data[..0]; buf := data[..0];
bprint(^buf, ..args); bprint(^buf, ..args);
os.write(fd, buf[..buf.count]); os.write(fd, buf[..len(buf)]);
return buf.count; return len(buf);
} }
fprintln :: proc(fd: os.Handle, args: ..any) -> int { fprintln :: proc(fd: os.Handle, args: ..any) -> int {
data: [_BUFFER_SIZE]byte; data: [_BUFFER_SIZE]byte;
buf := data[..0]; buf := data[..0];
bprintln(^buf, ..args); bprintln(^buf, ..args);
os.write(fd, buf[..buf.count]); os.write(fd, buf[..len(buf)]);
return buf.count; return len(buf);
} }
fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int { fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int {
data: [_BUFFER_SIZE]byte; data: [_BUFFER_SIZE]byte;
buf := data[..0]; buf := data[..0];
bprintf(^buf, fmt, ..args); bprintf(^buf, fmt, ..args);
os.write(fd, buf[..buf.count]); os.write(fd, buf[..len(buf)]);
return buf.count; return len(buf);
} }
@@ -83,7 +83,7 @@ fprint_type :: proc(fd: os.Handle, info: ^Type_Info) {
data: [_BUFFER_SIZE]byte; data: [_BUFFER_SIZE]byte;
buf := data[..0]; buf := data[..0];
write_type(^buf, info); write_type(^buf, info);
os.write(fd, buf[..buf.count]); os.write(fd, buf[..len(buf)]);
} }
write_type :: proc(buf: ^[]byte, ti: ^Type_Info) { write_type :: proc(buf: ^[]byte, ti: ^Type_Info) {
@@ -147,14 +147,14 @@ write_type :: proc(buf: ^[]byte, ti: ^Type_Info) {
write_type(buf, info.results); write_type(buf, info.results);
} }
case Tuple: case Tuple:
count := info.names.count; count := len(info.names);
if count != 1 { write_string(buf, "("); } if count != 1 { write_string(buf, "("); }
for name, i in info.names { for name, i in info.names {
if i > 0 { write_string(buf, ", "); } if i > 0 { write_string(buf, ", "); }
type := info.types[i]; type := info.types[i];
if name.count > 0 { if len(name) > 0 {
write_string(buf, name); write_string(buf, name);
write_string(buf, ": "); write_string(buf, ": ");
} }
@@ -233,12 +233,12 @@ write_type :: proc(buf: ^[]byte, ti: ^Type_Info) {
variant_type := type_info_base(info.variant_types[i]); variant_type := type_info_base(info.variant_types[i]);
variant := union_cast(^Struct)variant_type; variant := union_cast(^Struct)variant_type;
vc := variant.names.count-cf.names.count; vc := len(variant.names)-len(cf.names);
for j in 0..vc { for j in 0..vc {
if j > 0 { if j > 0 {
write_string(buf, ", "); write_string(buf, ", ");
} }
index := j + cf.names.count; index := j + len(cf.names);
write_string(buf, variant.names[index]); write_string(buf, variant.names[index]);
write_string(buf, ": "); write_string(buf, ": ");
write_type(buf, variant.types[index]); write_type(buf, variant.types[index]);
@@ -279,14 +279,14 @@ bprint :: proc(buf: ^[]byte, args: ..any) -> int {
prev_string := false; prev_string := false;
for arg, i in args { for arg, i in args {
is_string := arg.data != nil && types.is_string(arg.type_info); is_string := arg != nil && types.is_string(arg.type_info);
if i > 0 && !is_string && !prev_string { if i > 0 && !is_string && !prev_string {
write_byte(buf, ' '); write_byte(buf, ' ');
} }
fmt_value(^fi, args[i], 'v'); fmt_value(^fi, args[i], 'v');
prev_string = is_string; prev_string = is_string;
} }
return buf.count; return len(buf);
} }
bprintln :: proc(buf: ^[]byte, args: ..any) -> int { bprintln :: proc(buf: ^[]byte, args: ..any) -> int {
@@ -300,7 +300,7 @@ bprintln :: proc(buf: ^[]byte, args: ..any) -> int {
fmt_value(^fi, args[i], 'v'); fmt_value(^fi, args[i], 'v');
} }
write_byte(buf, '\n'); write_byte(buf, '\n');
return buf.count; return len(buf);
} }
sprint :: proc(buf: []byte, args: ..any) -> string { sprint :: proc(buf: []byte, args: ..any) -> string {
@@ -328,7 +328,7 @@ parse_int :: proc(s: string, offset: int) -> (result: int, offset: int, ok: bool
ok := true; ok := true;
i := 0; i := 0;
for o in offset..s.count { for o in offset..len(s) {
c := cast(rune)s[offset+i]; c := cast(rune)s[offset+i];
if !is_digit(c) { if !is_digit(c) {
break; break;
@@ -349,11 +349,11 @@ _arg_number :: proc(fi: ^Fmt_Info,
arg_count: int, arg_count: int,
) -> (index: int, offset: int, ok: bool) { ) -> (index: int, offset: int, ok: bool) {
parse_arg_number :: proc(format: string) -> (int, int, bool) { parse_arg_number :: proc(format: string) -> (int, int, bool) {
if format.count < 3 { if len(format) < 3 {
return 0, 1, false; return 0, 1, false;
} }
for i in 1..format.count { for i in 1..len(format) {
if format[i] == ']' { if format[i] == ']' {
width, new_index, ok := parse_int(format, 1); width, new_index, ok := parse_int(format, 1);
if !ok || new_index != i { if !ok || new_index != i {
@@ -367,7 +367,7 @@ _arg_number :: proc(fi: ^Fmt_Info,
} }
if format.count <= offset || format[offset] != '[' { if len(format) <= offset || format[offset] != '[' {
return arg_index, offset, false; return arg_index, offset, false;
} }
fi.reordered = true; fi.reordered = true;
@@ -383,7 +383,7 @@ int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) {
num := 0; num := 0;
new_arg_index := arg_index; new_arg_index := arg_index;
ok := true; ok := true;
if arg_index < args.count { if arg_index < len(args) {
arg := args[arg_index]; arg := args[arg_index];
arg.type_info = type_info_base(arg.type_info); arg.type_info = type_info_base(arg.type_info);
match i in arg { match i in arg {
@@ -439,7 +439,7 @@ fmt_write_padding :: proc(fi: ^Fmt_Info, width: int) {
pad_byte = '0'; pad_byte = '0';
} }
count := min(width, fi.buf.capacity-fi.buf.count); count := min(width, cap(fi.buf)-len(fi.buf));
for _ in 0..count { for _ in 0..count {
append(fi.buf, pad_byte); append(fi.buf, pad_byte);
} }
@@ -585,7 +585,7 @@ fmt_float :: proc(fi: ^Fmt_Info, v: f64, bit_size: int, verb: rune) {
} }
buf: [128]byte; buf: [128]byte;
str := strconv.append_float(buf[1..1], v, 'f', prec, bit_size); str := strconv.append_float(buf[1..1], v, 'f', prec, bit_size);
str = cast(string)buf[..str.count+1]; str = cast(string)buf[..len(str)+1];
if str[1] == '+' || str[1] == '-' { if str[1] == '+' || str[1] == '-' {
str = str[1..]; str = str[1..];
} else { } else {
@@ -602,9 +602,9 @@ fmt_float :: proc(fi: ^Fmt_Info, v: f64, bit_size: int, verb: rune) {
} }
if fi.plus || str[0] != '+' { if fi.plus || str[0] != '+' {
if fi.zero && fi.width_set && fi.width > str.count { if fi.zero && fi.width_set && fi.width > len(str) {
write_byte(fi.buf, str[0]); write_byte(fi.buf, str[0]);
fmt_write_padding(fi, fi.width - str.count); fmt_write_padding(fi, fi.width - len(str));
write_string(fi.buf, str[1..]); write_string(fi.buf, str[1..]);
} else { } else {
_pad(fi, str); _pad(fi, str);
@@ -685,7 +685,7 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
break; break;
} }
} }
} else if e.values.count == 0 { } else if len(e.values) == 0 {
write_string(fi.buf, ""); write_string(fi.buf, "");
ok = true; ok = true;
} else { } else {
@@ -780,7 +780,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
write_byte(fi.buf, '['); write_byte(fi.buf, '[');
defer write_byte(fi.buf, ']'); defer write_byte(fi.buf, ']');
array := cast(^Raw_Dynamic_Array)v.data; array := cast(^Raw_Dynamic_Array)v.data;
for i in 0..array.count { for i in 0..array.len {
if i > 0 { if i > 0 {
write_string(fi.buf, ", "); write_string(fi.buf, ", ");
} }
@@ -802,7 +802,7 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
entry_type := union_cast(^Struct)ed.elem; entry_type := union_cast(^Struct)ed.elem;
entry_size := ed.elem_size; entry_size := ed.elem_size;
for i in 0..entries.count { for i in 0..entries.len {
if i > 0 { if i > 0 {
write_string(fi.buf, ", "); write_string(fi.buf, ", ");
} }
@@ -831,11 +831,11 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
write_byte(fi.buf, '['); write_byte(fi.buf, '[');
defer write_byte(fi.buf, ']'); defer write_byte(fi.buf, ']');
slice := cast(^[]byte)v.data; slice := cast(^[]byte)v.data;
for i in 0..slice.count { for i in 0..len(slice) {
if i > 0 { if i > 0 {
write_string(fi.buf, ", "); write_string(fi.buf, ", ");
} }
data := slice.data + i*info.elem_size; data := ^slice[0] + i*info.elem_size;
fmt_arg(fi, any{info.elem, cast(rawptr)data}, 'v'); fmt_arg(fi, any{info.elem, cast(rawptr)data}, 'v');
} }
@@ -941,7 +941,7 @@ fmt_quaternion :: proc(fi: ^Fmt_Info, c: quaternion256, bits: int, verb: rune) {
} }
fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) { fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
if arg.data == nil || arg.type_info == nil { if arg == nil {
write_string(fi.buf, "<nil>"); write_string(fi.buf, "<nil>");
return; return;
} }
@@ -987,7 +987,7 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
bprintf :: proc(b: ^[]byte, fmt: string, args: ..any) -> int { bprintf :: proc(b: ^[]byte, fmt: string, args: ..any) -> int {
fi := Fmt_Info{}; fi := Fmt_Info{};
end := fmt.count; end := len(fmt);
arg_index := 0; arg_index := 0;
was_prev_index := false; was_prev_index := false;
for i := 0; i < end; { for i := 0; i < end; {
@@ -1026,7 +1026,7 @@ bprintf :: proc(b: ^[]byte, fmt: string, args: ..any) -> int {
} }
} }
arg_index, i, was_prev_index = _arg_number(^fi, arg_index, fmt, i, args.count); arg_index, i, was_prev_index = _arg_number(^fi, arg_index, fmt, i, len(args));
// Width // Width
if i < end && fmt[i] == '*' { if i < end && fmt[i] == '*' {
@@ -1056,7 +1056,7 @@ bprintf :: proc(b: ^[]byte, fmt: string, args: ..any) -> int {
fi.good_arg_index = false; fi.good_arg_index = false;
} }
if i < end && fmt[i] == '*' { if i < end && fmt[i] == '*' {
arg_index, i, was_prev_index = _arg_number(^fi, arg_index, fmt, i, args.count); arg_index, i, was_prev_index = _arg_number(^fi, arg_index, fmt, i, len(args));
i++; i++;
fi.prec, arg_index, fi.prec_set = int_from_arg(args, arg_index); fi.prec, arg_index, fi.prec_set = int_from_arg(args, arg_index);
if fi.prec < 0 { if fi.prec < 0 {
@@ -1077,7 +1077,7 @@ bprintf :: proc(b: ^[]byte, fmt: string, args: ..any) -> int {
} }
if !was_prev_index { if !was_prev_index {
arg_index, i, was_prev_index = _arg_number(^fi, arg_index, fmt, i, args.count); arg_index, i, was_prev_index = _arg_number(^fi, arg_index, fmt, i, len(args));
} }
if i >= end { if i >= end {
@@ -1092,7 +1092,7 @@ bprintf :: proc(b: ^[]byte, fmt: string, args: ..any) -> int {
write_byte(b, '%'); write_byte(b, '%');
} else if !fi.good_arg_index { } else if !fi.good_arg_index {
write_string(b, "%!(BAD ARGUMENT NUMBER)"); write_string(b, "%!(BAD ARGUMENT NUMBER)");
} else if arg_index >= args.count { } else if arg_index >= len(args) {
write_string(b, "%!(MISSING ARGUMENT)"); write_string(b, "%!(MISSING ARGUMENT)");
} else { } else {
fmt_arg(^fi, args[arg_index], verb); fmt_arg(^fi, args[arg_index], verb);
@@ -1100,13 +1100,13 @@ bprintf :: proc(b: ^[]byte, fmt: string, args: ..any) -> int {
} }
} }
if !fi.reordered && arg_index < args.count { if !fi.reordered && arg_index < len(args) {
write_string(b, "%!(EXTRA "); write_string(b, "%!(EXTRA ");
for arg, index in args[arg_index..] { for arg, index in args[arg_index..] {
if index > 0 { if index > 0 {
write_string(b, ", "); write_string(b, ", ");
} }
if arg.data == nil || arg.type_info == nil { if arg == nil {
write_string(b, "<nil>"); write_string(b, "<nil>");
} else { } else {
fmt_arg(^fi, args[index], 'v'); fmt_arg(^fi, args[index], 'v');
@@ -1115,5 +1115,5 @@ bprintf :: proc(b: ^[]byte, fmt: string, args: ..any) -> int {
write_string(b, ")"); write_string(b, ")");
} }
return b.count; return len(b);
} }
+7 -7
View File
@@ -50,8 +50,8 @@ murmur32 :: proc(data: []byte) -> u32 {
c2_32: u32 : 0x1b873593; c2_32: u32 : 0x1b873593;
h1: u32 = 0; h1: u32 = 0;
nblocks := data.count/4; nblocks := len(data)/4;
p := data.data; p := ^data[0];
p1 := p + 4*nblocks; p1 := p + 4*nblocks;
for ; p < p1; p += 4 { for ; p < p1; p += 4 {
@@ -69,7 +69,7 @@ murmur32 :: proc(data: []byte) -> u32 {
tail := data[nblocks*4 ..]; tail := data[nblocks*4 ..];
k1: u32; k1: u32;
match tail.count&3 { match len(tail)&3 {
case 3: case 3:
k1 ~= cast(u32)tail[2] << 16; k1 ~= cast(u32)tail[2] << 16;
fallthrough; fallthrough;
@@ -84,7 +84,7 @@ murmur32 :: proc(data: []byte) -> u32 {
h1 ~= k1; h1 ~= k1;
} }
h1 ~= cast(u32)data.count; h1 ~= cast(u32)len(data);
h1 ~= h1 >> 16; h1 ~= h1 >> 16;
h1 *= 0x85ebca6b; h1 *= 0x85ebca6b;
@@ -137,11 +137,11 @@ murmur64 :: proc(data: []byte) -> u64 {
m :: 0x5bd1e995; m :: 0x5bd1e995;
r :: 24; r :: 24;
h1: u32 = cast(u32)SEED ~ cast(u32)data.count; h1: u32 = cast(u32)SEED ~ cast(u32)len(data);
h2: u32 = SEED >> 32; h2: u32 = SEED >> 32;
data32 := slice_ptr(cast(^u32)^data[0], data.count/size_of(u32)); data32 := slice_ptr(cast(^u32)^data[0], len(data)/size_of(u32));
len := data.count; len := len(data);
i := 0; i := 0;
for len >= 8 { for len >= 8 {
+6 -6
View File
@@ -19,7 +19,7 @@ copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr {
return __mem_copy_non_overlapping(dst, src, len); return __mem_copy_non_overlapping(dst, src, len);
} }
compare :: proc(a, b: []byte) -> int { compare :: proc(a, b: []byte) -> int {
return __mem_compare(a.data, b.data, min(a.count, b.count)); return __mem_compare(^a[0], ^b[0], min(len(a), len(b)));
} }
@@ -102,7 +102,7 @@ init_arena_from_memory :: proc(using a: ^Arena, data: []byte) {
init_arena_from_context :: proc(using a: ^Arena, size: int) { init_arena_from_context :: proc(using a: ^Arena, size: int) {
backing = context.allocator; backing = context.allocator;
memory = new_slice(byte, size); memory = make([]byte, size);
temp_count = 0; temp_count = 0;
} }
@@ -133,7 +133,7 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
case ALLOC: case ALLOC:
total_size := size + alignment; total_size := size + alignment;
if arena.offset + total_size > arena.memory.count { if arena.offset + total_size > len(arena.memory) {
fmt.fprintln(os.stderr, "Arena out of memory"); fmt.fprintln(os.stderr, "Arena out of memory");
return nil; return nil;
} }
@@ -161,15 +161,15 @@ arena_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
begin_arena_temp_memory :: proc(a: ^Arena) -> Arena_Temp_Memory { begin_arena_temp_memory :: proc(a: ^Arena) -> Arena_Temp_Memory {
tmp: Arena_Temp_Memory; tmp: Arena_Temp_Memory;
tmp.arena = a; tmp.arena = a;
tmp.original_count = a.memory.count; tmp.original_count = len(a.memory);
a.temp_count++; a.temp_count++;
return tmp; return tmp;
} }
end_arena_temp_memory :: proc(using tmp: Arena_Temp_Memory) { end_arena_temp_memory :: proc(using tmp: Arena_Temp_Memory) {
assert(arena.memory.count >= original_count); assert(len(arena.memory) >= original_count);
assert(arena.temp_count > 0); assert(arena.temp_count > 0);
arena.memory.count = original_count; arena.memory = arena.memory[..original_count];
arena.temp_count--; arena.temp_count--;
} }
+3 -3
View File
@@ -35,10 +35,10 @@ string_data :: proc(s: string) -> ^u8 #inline { return ^s[0]; }
_libgl := win32.LoadLibraryA(string_data("opengl32.dll\x00")); _libgl := win32.LoadLibraryA(string_data("opengl32.dll\x00"));
GetProcAddress :: proc(name: string) -> proc() #cc_c { GetProcAddress :: proc(name: string) -> proc() #cc_c {
assert(name[name.count-1] == 0); assert(name[len(name)-1] == 0);
res := wgl.GetProcAddress(name.data); res := wgl.GetProcAddress(^name[0]);
if res == nil { if res == nil {
res = win32.GetProcAddress(_libgl, name.data); res = win32.GetProcAddress(_libgl, ^name[0]);
} }
return res; return res;
} }
+8 -9
View File
@@ -53,7 +53,7 @@ args := _alloc_command_line_arguments();
open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) { open :: proc(path: string, mode: int, perm: u32) -> (Handle, Errno) {
if path.count == 0 { if len(path) == 0 {
return INVALID_HANDLE, ERROR_FILE_NOT_FOUND; return INVALID_HANDLE, ERROR_FILE_NOT_FOUND;
} }
@@ -110,7 +110,7 @@ close :: proc(fd: Handle) {
write :: proc(fd: Handle, data: []byte) -> (int, Errno) { write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
bytes_written: i32; bytes_written: i32;
e := win32.WriteFile(cast(win32.Handle)fd, data.data, cast(i32)data.count, ^bytes_written, nil); e := win32.WriteFile(cast(win32.Handle)fd, ^data[0], cast(i32)len(data), ^bytes_written, nil);
if e == win32.FALSE { if e == win32.FALSE {
err := win32.GetLastError(); err := win32.GetLastError();
return 0, cast(Errno)err; return 0, cast(Errno)err;
@@ -120,7 +120,7 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) {
read :: proc(fd: Handle, data: []byte) -> (int, Errno) { read :: proc(fd: Handle, data: []byte) -> (int, Errno) {
bytes_read: i32; bytes_read: i32;
e := win32.ReadFile(cast(win32.Handle)fd, data.data, cast(u32)data.count, ^bytes_read, nil); e := win32.ReadFile(cast(win32.Handle)fd, ^data[0], cast(u32)len(data), ^bytes_read, nil);
if e == win32.FALSE { if e == win32.FALSE {
err := win32.GetLastError(); err := win32.GetLastError();
return 0, cast(Errno)err; return 0, cast(Errno)err;
@@ -180,7 +180,7 @@ last_write_time_by_name :: proc(name: string) -> File_Time {
data: win32.File_Attribute_Data; data: win32.File_Attribute_Data;
buf: [1024]byte; buf: [1024]byte;
assert(buf.count > name.count); assert(len(buf) > len(name));
copy(buf[..], cast([]byte)name); copy(buf[..], cast([]byte)name);
@@ -213,8 +213,8 @@ read_entire_file :: proc(name: string) -> ([]byte, bool) {
return nil, false; return nil, false;
} }
data := new_slice(u8, length); data := make([]byte, length);
if data.data == nil { if ^data[0] == nil {
return nil, false; return nil, false;
} }
@@ -286,10 +286,9 @@ _alloc_command_line_arguments :: proc() -> []string {
wstr_len++; wstr_len++;
} }
len := 2*wstr_len-1; len := 2*wstr_len-1;
buf := new_slice(byte, len+1); buf := make([]byte, len+1);
str := slice_ptr(wstr, wstr_len+1); str := slice_ptr(wstr, wstr_len+1);
i, j := 0, 0; i, j := 0, 0;
for str[j] != 0 { for str[j] != 0 {
match { match {
@@ -334,7 +333,7 @@ _alloc_command_line_arguments :: proc() -> []string {
arg_count: i32; arg_count: i32;
arg_list_ptr := win32.CommandLineToArgvW(win32.GetCommandLineW(), ^arg_count); arg_list_ptr := win32.CommandLineToArgvW(win32.GetCommandLineW(), ^arg_count);
arg_list := new_slice(string, arg_count); arg_list := make([]string, arg_count);
for _, i in arg_list { for _, i in arg_list {
arg_list[i] = alloc_ucs2_to_utf8((arg_list_ptr+i)^); arg_list[i] = alloc_ucs2_to_utf8((arg_list_ptr+i)^);
} }
+8 -25
View File
@@ -131,50 +131,33 @@ generic_ftoa :: proc(buf: []byte, val: f64, fmt: byte, prec, bit_size: int) -> [
format_digits :: proc(buf: []byte, shortest: bool, neg: bool, digs: Decimal_Slice, prec: int, fmt: byte) -> []byte { format_digits :: proc(buf: []byte, shortest: bool, neg: bool, digs: Decimal_Slice, prec: int, fmt: byte) -> []byte {
match fmt { match fmt {
case 'f', 'F': case 'f', 'F':
add_bytes :: proc(dst: ^[]byte, w: ^int, bytes: ..byte) { append(buf, neg ? '-' : '+');
for b in bytes {
if dst.capacity <= w^ {
break;
}
dst.count++;
dst[w^] = b;
w^++;
}
}
dst := buf[..];
w := 0;
if neg {
add_bytes(^dst, ^w, '-');
} else {
add_bytes(^dst, ^w, '+');
}
// integer, padded with zeros when needed // integer, padded with zeros when needed
if digs.decimal_point > 0 { if digs.decimal_point > 0 {
m := min(digs.count, digs.decimal_point); m := min(digs.count, digs.decimal_point);
add_bytes(^dst, ^w, ..digs.digits[..m]); append(buf, ..digs.digits[..m]);
for ; m < digs.decimal_point; m++ { for ; m < digs.decimal_point; m++ {
add_bytes(^dst, ^w, '0'); append(buf, '0');
} }
} else { } else {
add_bytes(^dst, ^w, '0'); append(buf, '0');
} }
// fractional part // fractional part
if prec > 0 { if prec > 0 {
add_bytes(^dst, ^w, '.'); append(buf, '.');
for i in 0..prec { for i in 0..prec {
c: byte = '0'; c: byte = '0';
if j := digs.decimal_point + i; 0 <= j && j < digs.count { if j := digs.decimal_point + i; 0 <= j && j < digs.count {
c = digs.digits[j]; c = digs.digits[j];
} }
add_bytes(^dst, ^w, c); append(buf, c);
} }
} }
return buf[..w]; return buf;
case 'e', 'E': case 'e', 'E':
panic("strconv: e/E float printing is not yet supported"); panic("strconv: e/E float printing is not yet supported");
@@ -308,7 +291,7 @@ append_bits :: proc(buf: []byte, u: u64, base: int, is_signed: bool, bit_size: i
} }
a: [65]byte; a: [65]byte;
i := a.count; i := len(a);
neg: bool; neg: bool;
u, neg = is_integer_negative(u, is_signed, bit_size); u, neg = is_integer_negative(u, is_signed, bit_size);
+7 -8
View File
@@ -1,15 +1,14 @@
new_c_string :: proc(s: string) -> ^byte { new_c_string :: proc(s: string) -> ^byte {
c := new_slice(byte, s.count+1); c := make([]byte, len(s)+1);
copy(c, cast([]byte)s); copy(c, cast([]byte)s);
c[s.count] = 0; c[len(s)] = 0;
return c.data; return ^c[0];
} }
to_odin_string :: proc(c: ^byte) -> string { to_odin_string :: proc(c: ^byte) -> string {
s: string; len := 0;
s.data = c; for (c+len)^ != 0 {
for (c+s.count)^ != 0 { len++;
s.count++;
} }
return s; return cast(string)slice_ptr(c, len);
} }
+4 -4
View File
@@ -94,7 +94,7 @@ encode_rune :: proc(r: rune) -> ([4]byte, int) {
decode_rune :: proc(s: string) -> (rune, int) #inline { return decode_rune(cast([]byte)s); } decode_rune :: proc(s: string) -> (rune, int) #inline { return decode_rune(cast([]byte)s); }
decode_rune :: proc(s: []byte) -> (rune, int) { decode_rune :: proc(s: []byte) -> (rune, int) {
n := s.count; n := len(s);
if n < 1 { if n < 1 {
return RUNE_ERROR, 0; return RUNE_ERROR, 0;
} }
@@ -138,7 +138,7 @@ decode_last_rune :: proc(s: []byte) -> (rune, int) {
size: int; size: int;
start, end, limit: int; start, end, limit: int;
end = s.count; end = len(s);
if end == 0 { if end == 0 {
return RUNE_ERROR, 0; return RUNE_ERROR, 0;
} }
@@ -183,7 +183,7 @@ valid_rune :: proc(r: rune) -> bool {
} }
valid_string :: proc(s: string) -> bool { valid_string :: proc(s: string) -> bool {
n := s.count; n := len(s);
for i := 0; i < n; { for i := 0; i < n; {
si := s[i]; si := s[i];
if si < RUNE_SELF { // ascii if si < RUNE_SELF { // ascii
@@ -220,7 +220,7 @@ rune_start :: proc(b: byte) -> bool #inline { return b&0xc0 != 0x80; }
rune_count :: proc(s: string) -> int #inline { return rune_count(cast([]byte)s); } rune_count :: proc(s: string) -> int #inline { return rune_count(cast([]byte)s); }
rune_count :: proc(s: []byte) -> int { rune_count :: proc(s: []byte) -> int {
count := 0; count := 0;
n := s.count; n := len(s);
for i := 0; i < n; { for i := 0; i < n; {
defer count++; defer count++;
+127 -6
View File
@@ -249,8 +249,12 @@ void check_assignment(Checker *c, Operand *operand, Type *type, String context_n
operand->mode = Addressing_Invalid; operand->mode = Addressing_Invalid;
return; return;
} }
target_type = default_type(operand->type); if (is_type_any(type)) {
GB_ASSERT(is_type_typed(target_type)); target_type = t_any;
} else {
target_type = default_type(operand->type);
}
GB_ASSERT_MSG(is_type_typed(target_type), "%s", type_to_string(type));
add_type_info_type(c, type); add_type_info_type(c, type);
add_type_info_type(c, target_type); add_type_info_type(c, target_type);
} }
@@ -1963,7 +1967,9 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
switch (op) { switch (op) {
case Token_CmpEq: case Token_CmpEq:
case Token_NotEq: case Token_NotEq:
defined = is_type_comparable(x->type); defined = is_type_comparable(x->type) ||
(is_operand_nil(*x) && type_has_nil(y->type)) ||
(is_operand_nil(*y) && type_has_nil(x->type));
break; break;
case Token_Lt: case Token_Lt:
case Token_Gt: case Token_Gt:
@@ -1973,6 +1979,7 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
} break; } break;
} }
#if 0
// CLEANUP(bill) NOTE(bill): there is an auto assignment to `any` which needs to be checked // CLEANUP(bill) NOTE(bill): there is an auto assignment to `any` which needs to be checked
if (is_type_any(x->type) && !is_type_any(y->type)) { if (is_type_any(x->type) && !is_type_any(y->type)) {
err_type = x->type; err_type = x->type;
@@ -1981,8 +1988,14 @@ void check_comparison(Checker *c, Operand *x, Operand *y, TokenKind op) {
err_type = y->type; err_type = y->type;
defined = false; defined = false;
} }
#endif
if (!defined) { if (!defined) {
if (x->type == err_type && is_operand_nil(*x)) {
err_type = y->type;
}
gb_printf_err("%d %d\n", is_operand_nil(*x), type_has_nil(y->type));
gb_printf_err("%d %d\n", is_operand_nil(*y), type_has_nil(x->type));
gbString type_string = type_to_string(err_type); gbString type_string = type_to_string(err_type);
err_str = gb_string_make(c->tmp_allocator, err_str = gb_string_make(c->tmp_allocator,
gb_bprintf("operator `%.*s` not defined for type `%s`", LIT(token_strings[op]), type_string)); gb_bprintf("operator `%.*s` not defined for type `%s`", LIT(token_strings[op]), type_string));
@@ -2659,7 +2672,9 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level
break; break;
case Basic_UntypedNil: case Basic_UntypedNil:
if (!type_has_nil(target_type)) { if (is_type_any(target_type)) {
target_type = t_untyped_nil;
} else if (!type_has_nil(target_type)) {
operand->mode = Addressing_Invalid; operand->mode = Addressing_Invalid;
convert_untyped_error(c, operand, target_type); convert_untyped_error(c, operand, target_type);
return; return;
@@ -3070,11 +3085,11 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
} }
} }
Operand prev_operand = *operand;
switch (id) { switch (id) {
case BuiltinProc_new: case BuiltinProc_new:
case BuiltinProc_new_slice: // case BuiltinProc_new_slice:
case BuiltinProc_make:
case BuiltinProc_size_of: case BuiltinProc_size_of:
case BuiltinProc_align_of: case BuiltinProc_align_of:
case BuiltinProc_offset_of: case BuiltinProc_offset_of:
@@ -3090,6 +3105,53 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
GB_PANIC("Implement builtin procedure: %.*s", LIT(builtin_procs[id].name)); GB_PANIC("Implement builtin procedure: %.*s", LIT(builtin_procs[id].name));
break; break;
case BuiltinProc_len:
case BuiltinProc_cap: {
// len :: proc(Type) -> int
// cap :: proc(Type) -> int
Type *op_type = type_deref(operand->type);
Type *type = t_int;
AddressingMode mode = Addressing_Invalid;
ExactValue value = {0};
if (is_type_string(op_type) && id == BuiltinProc_len) {
if (operand->mode == Addressing_Constant) {
mode = Addressing_Constant;
String str = operand->value.value_string;
value = exact_value_integer(str.len);
type = t_untyped_integer;
} else {
mode = Addressing_Value;
}
} else if (is_type_array(op_type)) {
Type *at = core_type(op_type);
mode = Addressing_Constant;
value = exact_value_integer(at->Array.count);
type = t_untyped_integer;
} else if (is_type_vector(op_type) && id == BuiltinProc_len) {
Type *at = core_type(op_type);
mode = Addressing_Constant;
value = exact_value_integer(at->Vector.count);
type = t_untyped_integer;
} else if (is_type_slice(op_type)) {
mode = Addressing_Value;
} else if (is_type_dynamic_array(op_type)) {
mode = Addressing_Value;
} else if (is_type_map(op_type)) {
mode = Addressing_Value;
}
if (mode == Addressing_Invalid) {
String name = builtin_procs[id].name;
gbString t = type_to_string(operand->type);
error_node(call, "`%.*s` is not supported for `%s`", LIT(name), t);
return false;
}
operand->mode = mode;
operand->value = value;
operand->type = type;
} break;
case BuiltinProc_new: { case BuiltinProc_new: {
// new :: proc(Type) -> ^Type // new :: proc(Type) -> ^Type
Operand op = {0}; Operand op = {0};
@@ -3102,6 +3164,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->mode = Addressing_Value; operand->mode = Addressing_Value;
operand->type = make_type_pointer(c->allocator, type); operand->type = make_type_pointer(c->allocator, type);
} break; } break;
#if 0
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 // new_slice :: proc(Type, len, cap: int) -> []Type
@@ -3139,6 +3202,62 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
operand->mode = Addressing_Value; operand->mode = Addressing_Value;
operand->type = make_type_slice(c->allocator, type); operand->type = make_type_slice(c->allocator, type);
} break; } break;
#endif
case BuiltinProc_make: {
// make :: proc(Type, len: int) -> []Type
// make :: proc(Type, len, cap: int) -> []Type
Operand op = {0};
check_expr_or_type(c, &op, ce->args.e[0]);
Type *type = op.type;
if ((op.mode != Addressing_Type && type == NULL) || type == t_invalid) {
error_node(ce->args.e[0], "Expected a type for `make`");
return false;
}
isize min_args = 0;
isize max_args = 1;
if (is_type_slice(type)) {
min_args = 2;
max_args = 3;
} else if (is_type_dynamic_map(type)) {
min_args = 1;
max_args = 2;
} else if (is_type_dynamic_array(type)) {
min_args = 1;
max_args = 3;
} else {
gbString str = type_to_string(type);
error_node(call, "Cannot `make` %s; type must be a slice, map, or dynamic array", str);
gb_string_free(str);
return false;
}
isize arg_count = ce->args.count;
if (arg_count < min_args || max_args < arg_count) {
error_node(ce->args.e[0], "`make` expects %td or %d argument, found %td", min_args, max_args, arg_count);
return false;
}
// If any are constant
i64 sizes[4] = {0};
isize size_count = 0;
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], "`make` count and capacity are swapped");
// No need quit
}
operand->mode = Addressing_Value;
operand->type = type;
} break;
case BuiltinProc_free: { case BuiltinProc_free: {
// free :: proc(^Type) // free :: proc(^Type)
@@ -3216,6 +3335,8 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
case BuiltinProc_append: { case BuiltinProc_append: {
// append :: proc([dynamic]Type, item: ..Type) // append :: proc([dynamic]Type, item: ..Type)
// append :: proc([]Type, item: ..Type) // append :: proc([]Type, item: ..Type)
Operand prev_operand = *operand;
Type *type = operand->type; Type *type = operand->type;
bool is_pointer = is_type_pointer(type); bool is_pointer = is_type_pointer(type);
type = base_type(type_deref(type)); type = base_type(type_deref(type));
+10 -2
View File
@@ -23,9 +23,13 @@ typedef struct BuiltinProc {
typedef enum BuiltinProcId { typedef enum BuiltinProcId {
BuiltinProc_Invalid, BuiltinProc_Invalid,
BuiltinProc_len,
BuiltinProc_cap,
BuiltinProc_new, BuiltinProc_new,
BuiltinProc_new_slice,
BuiltinProc_free, BuiltinProc_free,
// BuiltinProc_new_slice,
BuiltinProc_make,
BuiltinProc_reserve, BuiltinProc_reserve,
BuiltinProc_clear, BuiltinProc_clear,
@@ -75,9 +79,13 @@ typedef enum BuiltinProcId {
gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = { gb_global BuiltinProc builtin_procs[BuiltinProc_Count] = {
{STR_LIT(""), 0, false, Expr_Stmt}, {STR_LIT(""), 0, false, Expr_Stmt},
{STR_LIT("len"), 1, false, Expr_Expr},
{STR_LIT("cap"), 1, false, Expr_Expr},
{STR_LIT("new"), 1, false, Expr_Expr}, {STR_LIT("new"), 1, 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("new_slice"), 2, true, Expr_Expr},
{STR_LIT("make"), 1, true, Expr_Expr},
{STR_LIT("reserve"), 2, false, Expr_Stmt}, {STR_LIT("reserve"), 2, false, Expr_Stmt},
{STR_LIT("clear"), 1, false, Expr_Stmt}, {STR_LIT("clear"), 1, false, Expr_Stmt},
+212 -9
View File
@@ -1470,6 +1470,7 @@ irValue *ir_gen_map_header(irProcedure *proc, irValue *map_val, Type *map_type)
GB_ASSERT_MSG(is_type_pointer(ir_type(map_val)), "%s", type_to_string(ir_type(map_val))); GB_ASSERT_MSG(is_type_pointer(ir_type(map_val)), "%s", type_to_string(ir_type(map_val)));
gbAllocator a = proc->module->allocator; gbAllocator a = proc->module->allocator;
irValue *h = ir_add_local_generated(proc, t_map_header); irValue *h = ir_add_local_generated(proc, t_map_header);
map_type = base_type(map_type);
Type *key_type = map_type->Map.key; Type *key_type = map_type->Map.key;
Type *val_type = map_type->Map.value; Type *val_type = map_type->Map.value;
@@ -1962,12 +1963,74 @@ irValue *ir_emit_arith(irProcedure *proc, TokenKind op, irValue *left, irValue *
return ir_emit(proc, ir_instr_binary_op(proc, op, left, right, type)); return ir_emit(proc, ir_instr_binary_op(proc, op, left, right, type));
} }
irValue *ir_emit_comp_against_nil(irProcedure *proc, TokenKind op_kind, irValue *x) {
Type *t = ir_type(x);
if (is_type_any(t)) {
irValue *ti = ir_emit_struct_ev(proc, x, 0);
irValue *data = ir_emit_struct_ev(proc, x, 1);
if (op_kind == Token_CmpEq) {
irValue *a = ir_emit_comp(proc, Token_CmpEq, ti, v_raw_nil);
irValue *b = ir_emit_comp(proc, Token_CmpEq, data, v_raw_nil);
return ir_emit_arith(proc, Token_Or, a, b, t_bool);
} else if (op_kind == Token_NotEq) {
irValue *a = ir_emit_comp(proc, Token_NotEq, ti, v_raw_nil);
irValue *b = ir_emit_comp(proc, Token_NotEq, data, v_raw_nil);
return ir_emit_arith(proc, Token_And, a, b, t_bool);
}
} else if (is_type_slice(t)) {
irValue *data = ir_emit_struct_ev(proc, x, 0);
irValue *cap = ir_emit_struct_ev(proc, x, 2);
if (op_kind == Token_CmpEq) {
irValue *a = ir_emit_comp(proc, Token_CmpEq, data, v_raw_nil);
irValue *b = ir_emit_comp(proc, Token_CmpEq, cap, v_zero);
return ir_emit_arith(proc, Token_Or, a, b, t_bool);
} else if (op_kind == Token_NotEq) {
irValue *a = ir_emit_comp(proc, Token_NotEq, data, v_raw_nil);
irValue *b = ir_emit_comp(proc, Token_NotEq, cap, v_zero);
return ir_emit_arith(proc, Token_And, a, b, t_bool);
}
} else if (is_type_dynamic_array(t)) {
irValue *data = ir_emit_struct_ev(proc, x, 0);
irValue *cap = ir_emit_struct_ev(proc, x, 2);
if (op_kind == Token_CmpEq) {
irValue *a = ir_emit_comp(proc, Token_CmpEq, data, v_raw_nil);
irValue *b = ir_emit_comp(proc, Token_CmpEq, cap, v_zero);
return ir_emit_arith(proc, Token_Or, a, b, t_bool);
} else if (op_kind == Token_NotEq) {
irValue *a = ir_emit_comp(proc, Token_NotEq, data, v_raw_nil);
irValue *b = ir_emit_comp(proc, Token_NotEq, cap, v_zero);
return ir_emit_arith(proc, Token_And, a, b, t_bool);
}
} else if (is_type_map(t)) {
irValue *hashes = ir_emit_struct_ev(proc, x, 0);
irValue *entries = ir_emit_struct_ev(proc, x, 1);
irValue *a = ir_emit_comp_against_nil(proc, op_kind, hashes);
irValue *b = ir_emit_comp_against_nil(proc, op_kind, entries);
if (op_kind == Token_CmpEq) {
return ir_emit_arith(proc, Token_Or, a, b, t_bool);
} else if (op_kind == Token_NotEq) {
return ir_emit_arith(proc, Token_And, a, b, t_bool);
}
}
return NULL;
}
irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irValue *right) { irValue *ir_emit_comp(irProcedure *proc, TokenKind op_kind, irValue *left, irValue *right) {
Type *a = base_type(ir_type(left)); Type *a = base_type(ir_type(left));
Type *b = base_type(ir_type(right)); Type *b = base_type(ir_type(right));
GB_ASSERT(gb_is_between(op_kind, Token__ComparisonBegin+1, Token__ComparisonEnd-1)); GB_ASSERT(gb_is_between(op_kind, Token__ComparisonBegin+1, Token__ComparisonEnd-1));
irValue *nil_check = NULL;
if (left->kind == irValue_Nil) {
nil_check = ir_emit_comp_against_nil(proc, op_kind, right);
} else if (right->kind == irValue_Nil) {
nil_check = ir_emit_comp_against_nil(proc, op_kind, left);
}
if (nil_check != NULL) {
return nil_check;
}
if (are_types_identical(a, b)) { if (are_types_identical(a, b)) {
// NOTE(bill): No need for a conversion // NOTE(bill): No need for a conversion
} else if (left->kind == irValue_Constant || left->kind == irValue_Nil) { } else if (left->kind == irValue_Constant || left->kind == irValue_Nil) {
@@ -3222,6 +3285,20 @@ void ir_build_defer_stmt(irProcedure *proc, irDefer d) {
} }
irValue *ir_emit_clamp(irProcedure *proc, Type *t, irValue *x, irValue *min, irValue *max) {
irValue *cond = NULL;
ir_emit_comment(proc, str_lit("clamp"));
x = ir_emit_conv(proc, x, t);
min = ir_emit_conv(proc, min, t);
max = ir_emit_conv(proc, max, t);
cond = ir_emit_comp(proc, Token_Gt, min, x);
x = ir_emit_select(proc, cond, min, x);
cond = ir_emit_comp(proc, Token_Lt, max, x);
x = ir_emit_select(proc, cond, max, x);
return x;
}
irValue *ir_find_global_variable(irProcedure *proc, String name) { irValue *ir_find_global_variable(irProcedure *proc, String name) {
irValue **value = map_ir_value_get(&proc->module->members, hash_string(name)); irValue **value = map_ir_value_get(&proc->module->members, hash_string(name));
@@ -3505,6 +3582,59 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
return ir_type_info(proc, t); return ir_type_info(proc, t);
} break; } break;
case BuiltinProc_len: {
irValue *v = ir_build_expr(proc, ce->args.e[0]);
Type *t = base_type(ir_type(v));
if (is_type_pointer(t)) {
// IMPORTANT TODO(bill): Should there be a nil pointer check?
v = ir_emit_load(proc, v);
t = type_deref(t);
}
if (is_type_string(t)) {
return ir_string_len(proc, v);
} else if (is_type_array(t)) {
GB_PANIC("Array lengths are constant");
} else if (is_type_vector(t)) {
GB_PANIC("Vector lengths are constant");
} else if (is_type_slice(t)) {
return ir_slice_count(proc, v);
} else if (is_type_dynamic_array(t)) {
return ir_dynamic_array_count(proc, v);
} else if (is_type_map(t)) {
irValue *entries = ir_emit_struct_ev(proc, v, 1);
return ir_dynamic_array_count(proc, entries);
}
GB_PANIC("Unreachable");
} break;
case BuiltinProc_cap: {
irValue *v = ir_build_expr(proc, ce->args.e[0]);
Type *t = base_type(ir_type(v));
if (is_type_pointer(t)) {
// IMPORTANT TODO(bill): Should there be a nil pointer check?
v = ir_emit_load(proc, v);
t = type_deref(t);
}
if (is_type_string(t)) {
GB_PANIC("Unreachable");
} else if (is_type_array(t)) {
GB_PANIC("Array lengths are constant");
} else if (is_type_vector(t)) {
GB_PANIC("Unreachable");
} else if (is_type_slice(t)) {
return ir_slice_capacity(proc, v);
} else if (is_type_dynamic_array(t)) {
return ir_dynamic_array_capacity(proc, v);
} else if (is_type_map(t)) {
irValue *entries = ir_emit_struct_ev(proc, v, 1);
return ir_dynamic_array_capacity(proc, entries);
}
GB_PANIC("Unreachable");
} break;
case BuiltinProc_new: { case BuiltinProc_new: {
ir_emit_comment(proc, str_lit("new")); ir_emit_comment(proc, str_lit("new"));
// new :: proc(Type) -> ^Type // new :: proc(Type) -> ^Type
@@ -3524,6 +3654,7 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
return v; return v;
} break; } break;
#if 0
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
@@ -3562,6 +3693,83 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
ir_fill_slice(proc, slice, ptr, count, capacity); ir_fill_slice(proc, slice, ptr, count, capacity);
return ir_emit_load(proc, slice); return ir_emit_load(proc, slice);
} break; } break;
#endif
case BuiltinProc_make: {
ir_emit_comment(proc, str_lit("make"));
gbAllocator a = proc->module->allocator;
Type *type = type_of_expr(proc->module->info, ce->args.e[0]);
if (is_type_slice(type)) {
Type *elem_type = core_type(type)->Slice.elem;
Type *elem_ptr_type = make_type_pointer(a, elem_type);
irValue *elem_size = ir_const_int(a, type_size_of(a, elem_type));
irValue *elem_align = ir_const_int(a, type_align_of(a, elem_type));
irValue *count = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[1]), t_int);
irValue *capacity = count;
if (ce->args.count == 3) {
capacity = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[2]), 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(a, irValue *, 2);
args[0] = slice_size;
args[1] = elem_align;
irValue *call = ir_emit_global_call(proc, "alloc_align", args, 2);
irValue *ptr = ir_emit_conv(proc, call, elem_ptr_type);
irValue *slice = ir_add_local_generated(proc, type);
ir_fill_slice(proc, slice, ptr, count, capacity);
return ir_emit_load(proc, slice);
} else if (is_type_dynamic_map(type)) {
irValue *int_16 = ir_const_int(a, 16);
irValue *cap = v_zero;
if (ce->args.count == 2) {
cap = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[1]), t_int);
}
irValue *cond = ir_emit_comp(proc, Token_Gt, cap, v_zero);
cap = ir_emit_select(proc, cond, cap, int_16);
irValue *map = ir_add_local_generated(proc, type);
irValue *header = ir_gen_map_header(proc, map, base_type(type));
irValue **args = gb_alloc_array(a, irValue *, 2);
args[0] = header;
args[1] = cap;
ir_emit_global_call(proc, "__dynamic_map_reserve", args, 2);
return ir_emit_load(proc, map);
} else if (is_type_dynamic_array(type)) {
Type *elem_type = base_type(type)->DynamicArray.elem;
irValue *len = v_zero;
irValue *cap = ir_const_int(a, 8);
if (ce->args.count > 1) {
len = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[1]), t_int);
}
if (ce->args.count > 2) {
cap = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[2]), t_int);
}
ir_emit_slice_bounds_check(proc, ast_node_token(ce->args.e[0]), v_zero, len, cap, false);
irValue *array = ir_add_local_generated(proc, type);
irValue **args = gb_alloc_array(a, irValue *, 5);
args[0] = array;
args[1] = ir_const_int(a, type_size_of(a, elem_type));
args[2] = ir_const_int(a, type_align_of(a, elem_type));;
args[3] = len;
args[4] = cap;
ir_emit_global_call(proc, "__dynamic_array_make", args, 5);
return ir_emit_load(proc, array);
}
} break;
case BuiltinProc_free: { case BuiltinProc_free: {
ir_emit_comment(proc, str_lit("free")); ir_emit_comment(proc, str_lit("free"));
@@ -4112,15 +4320,10 @@ irValue *ir_build_expr(irProcedure *proc, AstNode *expr) {
case BuiltinProc_clamp: { case BuiltinProc_clamp: {
ir_emit_comment(proc, str_lit("clamp")); ir_emit_comment(proc, str_lit("clamp"));
Type *t = type_of_expr(proc->module->info, expr); Type *t = type_of_expr(proc->module->info, expr);
irValue *x = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[0]), t); return ir_emit_clamp(proc, t,
irValue *min = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[1]), t); ir_build_expr(proc, ce->args.e[0]),
irValue *max = ir_emit_conv(proc, ir_build_expr(proc, ce->args.e[2]), t); ir_build_expr(proc, ce->args.e[1]),
irValue *cond; ir_build_expr(proc, ce->args.e[2]));
cond = ir_emit_comp(proc, Token_Gt, min, x);
x = ir_emit_select(proc, cond, min, x);
cond = ir_emit_comp(proc, Token_Lt, max, x);
x = ir_emit_select(proc, cond, max, x);
return x;
} break; } break;
} }
} }
+6 -4
View File
@@ -619,20 +619,22 @@ bool scan_escape(Tokenizer *t, Rune quote) {
advance_to_next_rune(t); advance_to_next_rune(t);
len = 8; base = 16; max = GB_RUNE_MAX; len = 8; base = 16; max = GB_RUNE_MAX;
} else { } else {
if (t->curr_rune < 0) if (t->curr_rune < 0) {
tokenizer_err(t, "Escape sequence was not terminated"); tokenizer_err(t, "Escape sequence was not terminated");
else } else {
tokenizer_err(t, "Unknown escape sequence"); tokenizer_err(t, "Unknown escape sequence");
}
return false; return false;
} }
while (len --> 0) { while (len --> 0) {
u32 d = cast(u32)digit_value(t->curr_rune); u32 d = cast(u32)digit_value(t->curr_rune);
if (d >= base) { if (d >= base) {
if (t->curr_rune < 0) if (t->curr_rune < 0) {
tokenizer_err(t, "Escape sequence was not terminated"); tokenizer_err(t, "Escape sequence was not terminated");
else } else {
tokenizer_err(t, "Illegal character %d in escape sequence", t->curr_rune); tokenizer_err(t, "Illegal character %d in escape sequence", t->curr_rune);
}
return false; return false;
} }
+18 -3
View File
@@ -834,9 +834,10 @@ bool type_has_nil(Type *t) {
return false; return false;
} break; } break;
case Type_Slice: case Type_Slice:
case Type_DynamicArray:
case Type_Proc: case Type_Proc:
case Type_Pointer: case Type_Pointer:
case Type_DynamicArray:
case Type_Map:
return true; return true;
} }
return false; return false;
@@ -1232,6 +1233,9 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
if (type->kind == Type_Basic) { if (type->kind == Type_Basic) {
switch (type->Basic.kind) { switch (type->Basic.kind) {
case Basic_any: { case Basic_any: {
#if 1
// IMPORTANT TODO(bill): Should these members be available to should I only allow them with
// `Raw_Any` type?
String type_info_str = str_lit("type_info"); String type_info_str = str_lit("type_info");
String data_str = str_lit("data"); String data_str = str_lit("data");
if (entity__any_type_info == NULL) { if (entity__any_type_info == NULL) {
@@ -1250,8 +1254,10 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = entity__any_data; sel.entity = entity__any_data;
return sel; return sel;
} }
#endif
} break; } break;
case Basic_string: { case Basic_string: {
#if 0
String data_str = str_lit("data"); String data_str = str_lit("data");
String count_str = str_lit("count"); String count_str = str_lit("count");
if (entity__string_data == NULL) { if (entity__string_data == NULL) {
@@ -1271,11 +1277,13 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = entity__string_count; sel.entity = entity__string_count;
return sel; return sel;
} }
#endif
} break; } break;
} }
return sel; return sel;
} else if (type->kind == Type_Array) { } else if (type->kind == Type_Array) {
#if 0
String count_str = str_lit("count"); String count_str = str_lit("count");
// NOTE(bill): Underlying memory address cannot be changed // NOTE(bill): Underlying memory address cannot be changed
if (str_eq(field_name, count_str)) { if (str_eq(field_name, count_str)) {
@@ -1283,7 +1291,9 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = make_entity_constant(a, NULL, make_token_ident(count_str), t_int, exact_value_integer(type->Array.count)); sel.entity = make_entity_constant(a, NULL, make_token_ident(count_str), t_int, exact_value_integer(type->Array.count));
return sel; return sel;
} }
#endif
} else if (type->kind == Type_Vector) { } else if (type->kind == Type_Vector) {
#if 0
String count_str = str_lit("count"); String count_str = str_lit("count");
// NOTE(bill): Vectors are not addressable // NOTE(bill): Vectors are not addressable
if (str_eq(field_name, count_str)) { if (str_eq(field_name, count_str)) {
@@ -1291,7 +1301,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = make_entity_constant(a, NULL, make_token_ident(count_str), t_int, exact_value_integer(type->Vector.count)); sel.entity = make_entity_constant(a, NULL, make_token_ident(count_str), t_int, exact_value_integer(type->Vector.count));
return sel; return sel;
} }
#endif
if (type->Vector.count <= 4 && !is_type_boolean(type->Vector.elem)) { if (type->Vector.count <= 4 && !is_type_boolean(type->Vector.elem)) {
// HACK(bill): Memory leak // HACK(bill): Memory leak
switch (type->Vector.count) { switch (type->Vector.count) {
@@ -1315,6 +1325,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
} }
} else if (type->kind == Type_Slice) { } else if (type->kind == Type_Slice) {
#if 0
String data_str = str_lit("data"); String data_str = str_lit("data");
String count_str = str_lit("count"); String count_str = str_lit("count");
String capacity_str = str_lit("capacity"); String capacity_str = str_lit("capacity");
@@ -1341,8 +1352,9 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = entity__slice_capacity; sel.entity = entity__slice_capacity;
return sel; return sel;
} }
#endif
} else if (type->kind == Type_DynamicArray) { } else if (type->kind == Type_DynamicArray) {
#if 0
String data_str = str_lit("data"); String data_str = str_lit("data");
String count_str = str_lit("count"); String count_str = str_lit("count");
String capacity_str = str_lit("capacity"); String capacity_str = str_lit("capacity");
@@ -1375,7 +1387,9 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = entity__dynamic_array_allocator; sel.entity = entity__dynamic_array_allocator;
return sel; return sel;
} }
#endif
} else if (type->kind == Type_Map) { } else if (type->kind == Type_Map) {
#if 0
String count_str = str_lit("count"); String count_str = str_lit("count");
String capacity_str = str_lit("capacity"); String capacity_str = str_lit("capacity");
String allocator_str = str_lit("allocator"); String allocator_str = str_lit("allocator");
@@ -1405,6 +1419,7 @@ Selection lookup_field_with_selection(gbAllocator a, Type *type_, String field_n
sel.entity = entity__dynamic_map_allocator; sel.entity = entity__dynamic_map_allocator;
return sel; return sel;
} }
#endif
} }
if (is_type) { if (is_type) {