mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-02 12:48:14 +00:00
Replace many built-in procedures with user-level procedures
This commit is contained in:
+185
-45
@@ -5,6 +5,7 @@ import (
|
|||||||
"fmt.odin";
|
"fmt.odin";
|
||||||
"utf8.odin";
|
"utf8.odin";
|
||||||
"raw.odin";
|
"raw.odin";
|
||||||
|
"types.odin";
|
||||||
)
|
)
|
||||||
// Naming Conventions:
|
// Naming Conventions:
|
||||||
// In general, PascalCase for types and snake_case for values
|
// In general, PascalCase for types and snake_case for values
|
||||||
@@ -117,6 +118,38 @@ __argv__: ^^u8;
|
|||||||
__argc__: i32;
|
__argc__: i32;
|
||||||
|
|
||||||
|
|
||||||
|
__INITIAL_MAP_CAP :: 16;
|
||||||
|
|
||||||
|
__MapKey :: struct #ordered {
|
||||||
|
hash: u128,
|
||||||
|
str: string,
|
||||||
|
}
|
||||||
|
|
||||||
|
__MapFindResult :: struct #ordered {
|
||||||
|
hash_index: int,
|
||||||
|
entry_prev: int,
|
||||||
|
entry_index: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
__MapEntryHeader :: struct #ordered {
|
||||||
|
key: __MapKey,
|
||||||
|
next: int,
|
||||||
|
/*
|
||||||
|
value: Value_Type,
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
__MapHeader :: struct #ordered {
|
||||||
|
m: ^raw.DynamicMap,
|
||||||
|
is_key_string: bool,
|
||||||
|
entry_size: int,
|
||||||
|
entry_align: int,
|
||||||
|
value_offset: int,
|
||||||
|
value_size: int,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
type_info_base :: proc(info: ^TypeInfo) -> ^TypeInfo {
|
type_info_base :: proc(info: ^TypeInfo) -> ^TypeInfo {
|
||||||
if info == nil do return nil;
|
if info == nil do return nil;
|
||||||
|
|
||||||
@@ -256,6 +289,14 @@ resize :: proc(ptr: rawptr, old_size, new_size: int, alignment: int = DEFAULT_AL
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
copy :: proc(dst, src: []$T) -> int #cc_contextless {
|
||||||
|
n := max(0, min(len(dst), len(src)));
|
||||||
|
if n > 0 do __mem_copy(&dst[0], &src[0], n*size_of(T));
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
append :: proc(array: ^[]$T, args: ..T) -> int {
|
append :: proc(array: ^[]$T, args: ..T) -> int {
|
||||||
if array == nil {
|
if array == nil {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -277,36 +318,148 @@ append :: proc(array: ^[]$T, args: ..T) -> int {
|
|||||||
return slice.len;
|
return slice.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
append :: proc(array_: ^[dynamic]$T, args: ..T) -> int {
|
append :: proc(array: ^[dynamic]$T, args: ..T) -> int {
|
||||||
array := ^raw.DynamicArray(array_);
|
if array == nil {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
a := ^raw.DynamicArray(array);
|
||||||
|
|
||||||
arg_len := len(args);
|
arg_len := len(args);
|
||||||
if arg_len <= 0 {
|
if arg_len <= 0 {
|
||||||
return array.len;
|
return a.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ok := true;
|
ok := true;
|
||||||
if array.cap <= array.len+arg_len {
|
if a.cap <= a.len+arg_len {
|
||||||
cap := 2 * array.cap + max(8, arg_len);
|
cap := 2 * a.cap + max(8, arg_len);
|
||||||
ok = __dynamic_array_reserve(array, size_of(T), align_of(T), cap);
|
ok = __dynamic_array_reserve(a, size_of(T), align_of(T), cap);
|
||||||
}
|
}
|
||||||
// TODO(bill): Better error handling for failed reservation
|
// TODO(bill): Better error handling for failed reservation
|
||||||
if !ok do return array.len;
|
if !ok do return a.len;
|
||||||
|
|
||||||
data := ^T(array.data);
|
data := ^T(a.data);
|
||||||
assert(data != nil);
|
assert(data != nil);
|
||||||
__mem_copy(data + array.len, &args[0], size_of(T) * arg_len);
|
__mem_copy(data + a.len, &args[0], size_of(T) * arg_len);
|
||||||
array.len += arg_len;
|
a.len += arg_len;
|
||||||
return array.len;
|
return a.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
copy :: proc(dst, src: []$T) -> int #cc_contextless {
|
pop :: proc(array: ^[]$T) -> T {
|
||||||
n := max(0, min(len(dst), len(src)));
|
res: T;
|
||||||
if n > 0 do __mem_copy(&dst[0], &src[0], n*size_of(T));
|
if array do return res;
|
||||||
return n;
|
assert(len(array) > 0);
|
||||||
|
res = array[len(array)-1];
|
||||||
|
^raw.Slice(array).len -= 1;
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pop :: proc(array: ^[dynamic]$T) -> T {
|
||||||
|
res: T;
|
||||||
|
if array do return res;
|
||||||
|
assert(len(array) > 0);
|
||||||
|
res = array[len(array)-1];
|
||||||
|
^raw.DynamicArray(array).len -= 1;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
clear :: proc(slice: ^[]$T) #cc_contextless #inline {
|
||||||
|
if slice != nil do ^raw.Slice(slice).len = 0;
|
||||||
|
}
|
||||||
|
clear :: proc(array: ^[dynamic]$T) #cc_contextless #inline {
|
||||||
|
if array != nil do ^raw.DynamicArray(array).len = 0;
|
||||||
|
}
|
||||||
|
clear :: proc(m: ^map[$K]$V) #cc_contextless #inline {
|
||||||
|
if m == nil do return;
|
||||||
|
raw_map := ^raw.DynamicMap(array);
|
||||||
|
hashes := ^raw.DynamicArray(&raw_map.hashes);
|
||||||
|
entries := ^raw.DynamicArray(&raw_map.entries);
|
||||||
|
hashes.len = 0;
|
||||||
|
entries.len = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
reserve :: proc(array: ^[dynamic]$T, capacity: int) -> bool {
|
||||||
|
if array == nil do return false;
|
||||||
|
a := ^raw.DynamicArray(array);
|
||||||
|
|
||||||
|
if capacity <= a.cap do return true;
|
||||||
|
|
||||||
|
// __check_context();
|
||||||
|
if a.allocator.procedure == nil {
|
||||||
|
a.allocator = context.allocator;
|
||||||
|
}
|
||||||
|
assert(a.allocator.procedure != nil);
|
||||||
|
|
||||||
|
old_size := a.cap * size_of(T);
|
||||||
|
new_size := capacity * size_of(T);
|
||||||
|
allocator := a.allocator;
|
||||||
|
|
||||||
|
new_data := allocator.procedure(allocator.data, AllocatorMode.Resize, new_size, align_of(T), a.data, old_size, 0);
|
||||||
|
if new_data == nil do return false;
|
||||||
|
|
||||||
|
a.data = new_data;
|
||||||
|
a.cap = capacity;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__get_map_header :: proc(m: ^map[$K]$V) -> __MapHeader {
|
||||||
|
header := __MapHeader{m = ^raw.DynamicMap(m)};
|
||||||
|
Entry :: struct {
|
||||||
|
key: __MapKey,
|
||||||
|
next: int,
|
||||||
|
value: V,
|
||||||
|
}
|
||||||
|
|
||||||
|
header.is_key_string = types.is_string(type_info(K));
|
||||||
|
header.entry_size = size_of(Entry);
|
||||||
|
header.entry_align = align_of(Entry);
|
||||||
|
header.value_offset = offset_of(Entry, value);
|
||||||
|
header.value_size = size_of(V);
|
||||||
|
return header;
|
||||||
|
}
|
||||||
|
|
||||||
|
__get_map_key :: proc(key: $K) -> __MapKey {
|
||||||
|
map_key: __MapKey;
|
||||||
|
ti := type_info(K);
|
||||||
|
match {
|
||||||
|
case types.is_integer(ti):
|
||||||
|
match 8*size_of(key) {
|
||||||
|
case 8: map_key.hash = u128( ^u8(&key)^);
|
||||||
|
case 16: map_key.hash = u128( ^u16(&key)^);
|
||||||
|
case 32: map_key.hash = u128( ^u32(&key)^);
|
||||||
|
case 64: map_key.hash = u128( ^u64(&key)^);
|
||||||
|
case 128: map_key.hash = u128(^u128(&key)^);
|
||||||
|
}
|
||||||
|
case types.is_rune(ti):
|
||||||
|
map_key.hash = u128(^rune(&key)^);
|
||||||
|
case types.is_pointer(ti):
|
||||||
|
map_key.hash = u128(uint(^rawptr(&key)^));
|
||||||
|
case types.is_float(ti):
|
||||||
|
match 8*size_of(key) {
|
||||||
|
case 32: map_key.hash = u128(^u32(&key)^);
|
||||||
|
case 64: map_key.hash = u128(^u64(&key)^);
|
||||||
|
case: panic("Unhandled float size");
|
||||||
|
}
|
||||||
|
case types.is_string(ti):
|
||||||
|
str := ^string(&key)^;
|
||||||
|
map_key.hash = __default_hash_string(str);
|
||||||
|
map_key.str = str;
|
||||||
|
case:
|
||||||
|
panic("Unhandled map key type");
|
||||||
|
}
|
||||||
|
return map_key;
|
||||||
|
}
|
||||||
|
|
||||||
|
reserve :: proc(m: ^map[$K]$V, capacity: int) {
|
||||||
|
if m != nil do __dynamic_map_reserve(__get_map_header(m), capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
delete :: proc(m: ^map[$K]$V, key: K) {
|
||||||
|
if m != nil do __dynamic_map_delete(__get_map_header(m), __get_map_key(key));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
new :: proc(T: type) -> ^T #inline do return ^T(alloc(size_of(T), align_of(T)));
|
new :: proc(T: type) -> ^T #inline do return ^T(alloc(size_of(T), align_of(T)));
|
||||||
|
|
||||||
@@ -315,6 +468,23 @@ free :: proc(slice: []$T) do free_ptr(^raw.Slice(&slice).data);
|
|||||||
free :: proc(str: string) do free_ptr(^raw.String(&str).data);
|
free :: proc(str: string) do free_ptr(^raw.String(&str).data);
|
||||||
free :: proc(ptr: rawptr) do free_ptr(ptr);
|
free :: proc(ptr: rawptr) do free_ptr(ptr);
|
||||||
|
|
||||||
|
slice_to_bytes :: proc(slice: []$T) -> []u8 {
|
||||||
|
s := ^raw.Slice(&slice);
|
||||||
|
s.len *= size_of(T);
|
||||||
|
s.cap *= size_of(T);
|
||||||
|
return ^[]u8(s)^;
|
||||||
|
}
|
||||||
|
|
||||||
|
slice_ptr :: proc(ptr: ^$T, len: int) -> []T {
|
||||||
|
assert(0 <= len);
|
||||||
|
s := raw.Slice{ptr, len, len};
|
||||||
|
return ^[]T(&s)^;
|
||||||
|
}
|
||||||
|
slice_ptr :: proc(ptr: ^$T, len, cap: int) -> []T {
|
||||||
|
assert(0 <= len && len <= cap);
|
||||||
|
s := raw.Slice{ptr, len, cap};
|
||||||
|
return ^[]T(&s)^;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -648,36 +818,6 @@ __default_hash :: proc(data: []u8) -> u128 {
|
|||||||
}
|
}
|
||||||
__default_hash_string :: proc(s: string) -> u128 do return __default_hash([]u8(s));
|
__default_hash_string :: proc(s: string) -> u128 do return __default_hash([]u8(s));
|
||||||
|
|
||||||
__INITIAL_MAP_CAP :: 16;
|
|
||||||
|
|
||||||
__MapKey :: struct #ordered {
|
|
||||||
hash: u128,
|
|
||||||
str: string,
|
|
||||||
}
|
|
||||||
|
|
||||||
__MapFindResult :: struct #ordered {
|
|
||||||
hash_index: int,
|
|
||||||
entry_prev: int,
|
|
||||||
entry_index: int,
|
|
||||||
}
|
|
||||||
|
|
||||||
__MapEntryHeader :: struct #ordered {
|
|
||||||
key: __MapKey,
|
|
||||||
next: int,
|
|
||||||
/*
|
|
||||||
value: Value_Type,
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
__MapHeader :: struct #ordered {
|
|
||||||
m: ^raw.DynamicMap,
|
|
||||||
is_key_string: bool,
|
|
||||||
entry_size: int,
|
|
||||||
entry_align: int,
|
|
||||||
value_offset: int,
|
|
||||||
value_size: int,
|
|
||||||
}
|
|
||||||
|
|
||||||
__dynamic_map_reserve :: proc(using header: __MapHeader, cap: int) {
|
__dynamic_map_reserve :: proc(using header: __MapHeader, cap: int) {
|
||||||
__dynamic_array_reserve(&m.hashes, size_of(int), align_of(int), cap);
|
__dynamic_array_reserve(&m.hashes, size_of(int), align_of(int), cap);
|
||||||
__dynamic_array_reserve(&m.entries, entry_size, entry_align, cap);
|
__dynamic_array_reserve(&m.entries, entry_size, entry_align, cap);
|
||||||
|
|||||||
+27
-36
@@ -44,18 +44,18 @@ foreign __llvm_core {
|
|||||||
fmuladd :: proc(a, b, c: f64) -> f64 #link_name "llvm.fmuladd.f64" ---;
|
fmuladd :: proc(a, b, c: f64) -> f64 #link_name "llvm.fmuladd.f64" ---;
|
||||||
}
|
}
|
||||||
|
|
||||||
tan :: proc(θ: f32) -> f32 #inline { return sin(θ)/cos(θ); }
|
tan :: proc(θ: f32) -> f32 #inline do return sin(θ)/cos(θ);
|
||||||
tan :: proc(θ: f64) -> f64 #inline { return sin(θ)/cos(θ); }
|
tan :: proc(θ: f64) -> f64 #inline do return sin(θ)/cos(θ);
|
||||||
|
|
||||||
|
|
||||||
lerp :: proc(a, b, t: f32) -> (x: f32) { return a*(1-t) + b*t; }
|
lerp :: proc(a, b, t: f32) -> (x: f32) do return a*(1-t) + b*t;
|
||||||
lerp :: proc(a, b, t: f64) -> (x: f64) { return a*(1-t) + b*t; }
|
lerp :: proc(a, b, t: f64) -> (x: f64) do return a*(1-t) + b*t;
|
||||||
unlerp :: proc(a, b, x: f32) -> (t: f32) { return (x-a)/(b-a); }
|
unlerp :: proc(a, b, x: f32) -> (t: f32) do return (x-a)/(b-a);
|
||||||
unlerp :: proc(a, b, x: f64) -> (t: f64) { return (x-a)/(b-a); }
|
unlerp :: proc(a, b, x: f64) -> (t: f64) do return (x-a)/(b-a);
|
||||||
|
|
||||||
|
|
||||||
sign :: proc(x: f32) -> f32 { return x >= 0 ? +1 : -1; }
|
sign :: proc(x: f32) -> f32 do return x >= 0 ? +1 : -1;
|
||||||
sign :: proc(x: f64) -> f64 { return x >= 0 ? +1 : -1; }
|
sign :: proc(x: f64) -> f64 do return x >= 0 ? +1 : -1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -75,17 +75,17 @@ copy_sign :: proc(x, y: f64) -> f64 {
|
|||||||
return transmute(f64, ix);
|
return transmute(f64, ix);
|
||||||
}
|
}
|
||||||
|
|
||||||
round :: proc(x: f32) -> f32 { return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5); }
|
round :: proc(x: f32) -> f32 do return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5);
|
||||||
round :: proc(x: f64) -> f64 { return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5); }
|
round :: proc(x: f64) -> f64 do return x >= 0 ? floor(x + 0.5) : ceil(x - 0.5);
|
||||||
|
|
||||||
floor :: proc(x: f32) -> f32 { return x >= 0 ? f32(i64(x)) : f32(i64(x-0.5)); } // TODO: Get accurate versions
|
floor :: proc(x: f32) -> f32 do return x >= 0 ? f32(i64(x)) : f32(i64(x-0.5)); // TODO: Get accurate versions
|
||||||
floor :: proc(x: f64) -> f64 { return x >= 0 ? f64(i64(x)) : f64(i64(x-0.5)); } // TODO: Get accurate versions
|
floor :: proc(x: f64) -> f64 do return x >= 0 ? f64(i64(x)) : f64(i64(x-0.5)); // TODO: Get accurate versions
|
||||||
|
|
||||||
ceil :: proc(x: f32) -> f32 { return x < 0 ? f32(i64(x)) : f32(i64(x+1)); } // TODO: Get accurate versions
|
ceil :: proc(x: f32) -> f32 do return x < 0 ? f32(i64(x)) : f32(i64(x+1)); // TODO: Get accurate versions
|
||||||
ceil :: proc(x: f64) -> f64 { return x < 0 ? f64(i64(x)) : f64(i64(x+1)); } // TODO: Get accurate versions
|
ceil :: proc(x: f64) -> f64 do return x < 0 ? f64(i64(x)) : f64(i64(x+1)); // TODO: Get accurate versions
|
||||||
|
|
||||||
remainder :: proc(x, y: f32) -> f32 { return x - round(x/y) * y; }
|
remainder :: proc(x, y: f32) -> f32 do return x - round(x/y) * y;
|
||||||
remainder :: proc(x, y: f64) -> f64 { return x - round(x/y) * y; }
|
remainder :: proc(x, y: f64) -> f64 do return x - round(x/y) * y;
|
||||||
|
|
||||||
mod :: proc(x, y: f32) -> f32 {
|
mod :: proc(x, y: f32) -> f32 {
|
||||||
result: f32;
|
result: f32;
|
||||||
@@ -107,8 +107,8 @@ mod :: proc(x, y: f64) -> f64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
to_radians :: proc(degrees: f32) -> f32 { return degrees * TAU / 360; }
|
to_radians :: proc(degrees: f32) -> f32 do return degrees * TAU / 360;
|
||||||
to_degrees :: proc(radians: f32) -> f32 { return radians * 360 / TAU; }
|
to_degrees :: proc(radians: f32) -> f32 do return radians * 360 / TAU;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -123,36 +123,27 @@ cross :: proc(x, y: Vec3) -> Vec3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mag :: proc(v: Vec2) -> f32 { return sqrt(dot(v, v)); }
|
mag :: proc(v: Vec2) -> f32 do return sqrt(dot(v, v));
|
||||||
mag :: proc(v: Vec3) -> f32 { return sqrt(dot(v, v)); }
|
mag :: proc(v: Vec3) -> f32 do return sqrt(dot(v, v));
|
||||||
mag :: proc(v: Vec4) -> f32 { return sqrt(dot(v, v)); }
|
mag :: proc(v: Vec4) -> f32 do return sqrt(dot(v, v));
|
||||||
|
|
||||||
norm :: proc(v: Vec2) -> Vec2 { return v / mag(v); }
|
norm :: proc(v: Vec2) -> Vec2 do return v / mag(v);
|
||||||
norm :: proc(v: Vec3) -> Vec3 { return v / mag(v); }
|
norm :: proc(v: Vec3) -> Vec3 do return v / mag(v);
|
||||||
norm :: proc(v: Vec4) -> Vec4 { return v / mag(v); }
|
norm :: proc(v: Vec4) -> Vec4 do return v / mag(v);
|
||||||
|
|
||||||
norm0 :: proc(v: Vec2) -> Vec2 {
|
norm0 :: proc(v: Vec2) -> Vec2 {
|
||||||
m := mag(v);
|
m := mag(v);
|
||||||
if m == 0 {
|
return m == 0 ? 0 : v/m;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return v / m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
norm0 :: proc(v: Vec3) -> Vec3 {
|
norm0 :: proc(v: Vec3) -> Vec3 {
|
||||||
m := mag(v);
|
m := mag(v);
|
||||||
if m == 0 {
|
return m == 0 ? 0 : v/m;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return v / m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
norm0 :: proc(v: Vec4) -> Vec4 {
|
norm0 :: proc(v: Vec4) -> Vec4 {
|
||||||
m := mag(v);
|
m := mag(v);
|
||||||
if m == 0 {
|
return m == 0 ? 0 : v/m;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return v / m;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ is_integer :: proc(info: ^TypeInfo) -> bool {
|
|||||||
_, ok := type_info_base(info).(^TypeInfo.Integer);
|
_, ok := type_info_base(info).(^TypeInfo.Integer);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
is_rune :: proc(info: ^TypeInfo) -> bool {
|
||||||
|
if info == nil do return false;
|
||||||
|
_, ok := type_info_base(info).(^TypeInfo.Rune);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
is_float :: proc(info: ^TypeInfo) -> bool {
|
is_float :: proc(info: ^TypeInfo) -> bool {
|
||||||
if info == nil do return false;
|
if info == nil do return false;
|
||||||
_, ok := type_info_base(info).(^TypeInfo.Float);
|
_, ok := type_info_base(info).(^TypeInfo.Float);
|
||||||
|
|||||||
+8
-6
@@ -4217,7 +4217,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
operand->type = type;
|
operand->type = type;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
case BuiltinProc_free: {
|
case BuiltinProc_free: {
|
||||||
// proc free(^Type)
|
// proc free(^Type)
|
||||||
// proc free([]Type)
|
// proc free([]Type)
|
||||||
@@ -4250,6 +4250,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
case BuiltinProc_reserve: {
|
case BuiltinProc_reserve: {
|
||||||
// proc reserve([dynamic]Type, count: int) {
|
// proc reserve([dynamic]Type, count: int) {
|
||||||
// proc reserve(map[Key]Type, count: int) {
|
// proc reserve(map[Key]Type, count: int) {
|
||||||
@@ -4276,7 +4277,8 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
operand->type = NULL;
|
operand->type = NULL;
|
||||||
operand->mode = Addressing_NoValue;
|
operand->mode = Addressing_NoValue;
|
||||||
} break;
|
} break;
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
case BuiltinProc_clear: {
|
case BuiltinProc_clear: {
|
||||||
Type *type = operand->type;
|
Type *type = operand->type;
|
||||||
bool is_pointer = is_type_pointer(type);
|
bool is_pointer = is_type_pointer(type);
|
||||||
@@ -4291,7 +4293,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
operand->type = NULL;
|
operand->type = NULL;
|
||||||
operand->mode = Addressing_NoValue;
|
operand->mode = Addressing_NoValue;
|
||||||
} break;
|
} break;
|
||||||
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
case BuiltinProc_append: {
|
case BuiltinProc_append: {
|
||||||
// proc append([dynamic]Type, item: ..Type)
|
// proc append([dynamic]Type, item: ..Type)
|
||||||
@@ -4341,7 +4343,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
operand->type = t_int;
|
operand->type = t_int;
|
||||||
} break;
|
} break;
|
||||||
#endif
|
#endif
|
||||||
|
#if 0
|
||||||
case BuiltinProc_delete: {
|
case BuiltinProc_delete: {
|
||||||
// proc delete(map[Key]Value, key: Key)
|
// proc delete(map[Key]Value, key: Key)
|
||||||
Type *type = operand->type;
|
Type *type = operand->type;
|
||||||
@@ -4372,6 +4374,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
|
|
||||||
operand->mode = Addressing_NoValue;
|
operand->mode = Addressing_NoValue;
|
||||||
} break;
|
} break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
case BuiltinProc_size_of: {
|
case BuiltinProc_size_of: {
|
||||||
@@ -4701,7 +4704,7 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
case BuiltinProc_slice_ptr: {
|
case BuiltinProc_slice_ptr: {
|
||||||
// proc slice_ptr(a: ^T, len: int) -> []T
|
// proc slice_ptr(a: ^T, len: int) -> []T
|
||||||
// proc slice_ptr(a: ^T, len, cap: int) -> []T
|
// proc slice_ptr(a: ^T, len, cap: int) -> []T
|
||||||
@@ -4759,7 +4762,6 @@ bool check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id
|
|||||||
operand->mode = Addressing_Value;
|
operand->mode = Addressing_Value;
|
||||||
} break;
|
} break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case BuiltinProc_expand_to_tuple: {
|
case BuiltinProc_expand_to_tuple: {
|
||||||
Type *type = base_type(operand->type);
|
Type *type = base_type(operand->type);
|
||||||
if (!is_type_struct(type) &
|
if (!is_type_struct(type) &
|
||||||
|
|||||||
+12
-26
@@ -29,12 +29,12 @@ enum BuiltinProcId {
|
|||||||
|
|
||||||
// BuiltinProc_new,
|
// BuiltinProc_new,
|
||||||
BuiltinProc_make,
|
BuiltinProc_make,
|
||||||
BuiltinProc_free,
|
// BuiltinProc_free,
|
||||||
|
|
||||||
BuiltinProc_reserve,
|
// BuiltinProc_reserve,
|
||||||
BuiltinProc_clear,
|
// BuiltinProc_clear,
|
||||||
// BuiltinProc_append,
|
// BuiltinProc_append,
|
||||||
BuiltinProc_delete,
|
// BuiltinProc_delete,
|
||||||
|
|
||||||
BuiltinProc_size_of,
|
BuiltinProc_size_of,
|
||||||
BuiltinProc_align_of,
|
BuiltinProc_align_of,
|
||||||
@@ -51,8 +51,8 @@ enum BuiltinProcId {
|
|||||||
BuiltinProc_imag,
|
BuiltinProc_imag,
|
||||||
BuiltinProc_conj,
|
BuiltinProc_conj,
|
||||||
|
|
||||||
BuiltinProc_slice_ptr,
|
// BuiltinProc_slice_ptr,
|
||||||
BuiltinProc_slice_to_bytes,
|
// BuiltinProc_slice_to_bytes,
|
||||||
|
|
||||||
BuiltinProc_expand_to_tuple,
|
BuiltinProc_expand_to_tuple,
|
||||||
|
|
||||||
@@ -61,12 +61,6 @@ enum BuiltinProcId {
|
|||||||
BuiltinProc_abs,
|
BuiltinProc_abs,
|
||||||
BuiltinProc_clamp,
|
BuiltinProc_clamp,
|
||||||
|
|
||||||
/* BuiltinProc_sqrt,
|
|
||||||
BuiltinProc_sin,
|
|
||||||
BuiltinProc_cos,
|
|
||||||
BuiltinProc_tan,
|
|
||||||
BuiltinProc_pow, */
|
|
||||||
|
|
||||||
BuiltinProc_transmute,
|
BuiltinProc_transmute,
|
||||||
|
|
||||||
BuiltinProc_DIRECTIVE, // NOTE(bill): This is used for specialized hash-prefixed procedures
|
BuiltinProc_DIRECTIVE, // NOTE(bill): This is used for specialized hash-prefixed procedures
|
||||||
@@ -81,12 +75,12 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
|||||||
|
|
||||||
// {STR_LIT("new"), 1, false, Expr_Expr},
|
// {STR_LIT("new"), 1, false, Expr_Expr},
|
||||||
{STR_LIT("make"), 1, true, Expr_Expr},
|
{STR_LIT("make"), 1, 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},
|
||||||
{STR_LIT("clear"), 1, false, Expr_Stmt},
|
// {STR_LIT("clear"), 1, false, Expr_Stmt},
|
||||||
// {STR_LIT("append"), 1, true, Expr_Expr},
|
// {STR_LIT("append"), 1, true, Expr_Expr},
|
||||||
{STR_LIT("delete"), 2, false, Expr_Stmt},
|
// {STR_LIT("delete"), 2, false, Expr_Stmt},
|
||||||
|
|
||||||
{STR_LIT("size_of"), 1, false, Expr_Expr},
|
{STR_LIT("size_of"), 1, false, Expr_Expr},
|
||||||
{STR_LIT("align_of"), 1, false, Expr_Expr},
|
{STR_LIT("align_of"), 1, false, Expr_Expr},
|
||||||
@@ -103,8 +97,8 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
|||||||
{STR_LIT("imag"), 1, false, Expr_Expr},
|
{STR_LIT("imag"), 1, false, Expr_Expr},
|
||||||
{STR_LIT("conj"), 1, false, Expr_Expr},
|
{STR_LIT("conj"), 1, false, Expr_Expr},
|
||||||
|
|
||||||
{STR_LIT("slice_ptr"), 2, true, Expr_Expr},
|
// {STR_LIT("slice_ptr"), 2, true, Expr_Expr},
|
||||||
{STR_LIT("slice_to_bytes"), 1, false, Expr_Stmt},
|
// {STR_LIT("slice_to_bytes"), 1, false, Expr_Expr},
|
||||||
|
|
||||||
{STR_LIT("expand_to_tuple"), 1, false, Expr_Expr},
|
{STR_LIT("expand_to_tuple"), 1, false, Expr_Expr},
|
||||||
|
|
||||||
@@ -113,14 +107,6 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
|
|||||||
{STR_LIT("abs"), 1, false, Expr_Expr},
|
{STR_LIT("abs"), 1, false, Expr_Expr},
|
||||||
{STR_LIT("clamp"), 3, false, Expr_Expr},
|
{STR_LIT("clamp"), 3, false, Expr_Expr},
|
||||||
|
|
||||||
/*
|
|
||||||
{STR_LIT("__sqrt"), 1, false, Expr_Expr},
|
|
||||||
{STR_LIT("__sin"), 1, false, Expr_Expr},
|
|
||||||
{STR_LIT("__cos"), 1, false, Expr_Expr},
|
|
||||||
{STR_LIT("__tan"), 1, false, Expr_Expr},
|
|
||||||
{STR_LIT("__pow"), 2, false, Expr_Expr},
|
|
||||||
*/
|
|
||||||
|
|
||||||
{STR_LIT("transmute"), 2, false, Expr_Expr},
|
{STR_LIT("transmute"), 2, false, Expr_Expr},
|
||||||
|
|
||||||
{STR_LIT(""), 0, true, Expr_Expr}, // DIRECTIVE
|
{STR_LIT(""), 0, true, Expr_Expr}, // DIRECTIVE
|
||||||
|
|||||||
+8
-7
@@ -3922,7 +3922,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
case BuiltinProc_free: {
|
case BuiltinProc_free: {
|
||||||
ir_emit_comment(proc, str_lit("free"));
|
ir_emit_comment(proc, str_lit("free"));
|
||||||
|
|
||||||
@@ -3997,7 +3997,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
|||||||
return ir_emit_global_call(proc, "free_ptr", args, 1);
|
return ir_emit_global_call(proc, "free_ptr", args, 1);
|
||||||
} break;
|
} break;
|
||||||
#endif
|
#endif
|
||||||
|
#if 0
|
||||||
case BuiltinProc_reserve: {
|
case BuiltinProc_reserve: {
|
||||||
ir_emit_comment(proc, str_lit("reserve"));
|
ir_emit_comment(proc, str_lit("reserve"));
|
||||||
gbAllocator a = proc->module->allocator;
|
gbAllocator a = proc->module->allocator;
|
||||||
@@ -4032,7 +4032,8 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
|||||||
GB_PANIC("Unknown type for `reserve`");
|
GB_PANIC("Unknown type for `reserve`");
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
case BuiltinProc_clear: {
|
case BuiltinProc_clear: {
|
||||||
ir_emit_comment(proc, str_lit("clear"));
|
ir_emit_comment(proc, str_lit("clear"));
|
||||||
Type *original_type = type_of_expr(proc->module->info, ce->args[0]);
|
Type *original_type = type_of_expr(proc->module->info, ce->args[0]);
|
||||||
@@ -4058,7 +4059,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
} break;
|
} break;
|
||||||
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
case BuiltinProc_append: {
|
case BuiltinProc_append: {
|
||||||
ir_emit_comment(proc, str_lit("append"));
|
ir_emit_comment(proc, str_lit("append"));
|
||||||
@@ -4169,7 +4170,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
|||||||
return ir_emit_global_call(proc, "__dynamic_array_append", daa_args, 5);
|
return ir_emit_global_call(proc, "__dynamic_array_append", daa_args, 5);
|
||||||
} break;
|
} break;
|
||||||
#endif
|
#endif
|
||||||
|
#if 0
|
||||||
case BuiltinProc_delete: {
|
case BuiltinProc_delete: {
|
||||||
ir_emit_comment(proc, str_lit("delete"));
|
ir_emit_comment(proc, str_lit("delete"));
|
||||||
irValue *map = ir_build_expr(proc, ce->args[0]);
|
irValue *map = ir_build_expr(proc, ce->args[0]);
|
||||||
@@ -4186,7 +4187,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
|||||||
args[1] = ir_gen_map_key(proc, key, key_type);
|
args[1] = ir_gen_map_key(proc, key, key_type);
|
||||||
return ir_emit_global_call(proc, "__dynamic_map_delete", args, 2);
|
return ir_emit_global_call(proc, "__dynamic_map_delete", args, 2);
|
||||||
} break;
|
} break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case BuiltinProc_swizzle: {
|
case BuiltinProc_swizzle: {
|
||||||
ir_emit_comment(proc, str_lit("swizzle.begin"));
|
ir_emit_comment(proc, str_lit("swizzle.begin"));
|
||||||
@@ -4260,7 +4261,7 @@ irValue *ir_build_builtin_proc(irProcedure *proc, AstNode *expr, TypeAndValue tv
|
|||||||
return ir_emit_load(proc, res);
|
return ir_emit_load(proc, res);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
#if 1
|
#if 0
|
||||||
case BuiltinProc_slice_ptr: {
|
case BuiltinProc_slice_ptr: {
|
||||||
ir_emit_comment(proc, str_lit("slice_ptr"));
|
ir_emit_comment(proc, str_lit("slice_ptr"));
|
||||||
irValue *ptr = ir_build_expr(proc, ce->args[0]);
|
irValue *ptr = ir_build_expr(proc, ce->args[0]);
|
||||||
|
|||||||
@@ -919,6 +919,9 @@ bool is_type_untyped_undef(Type *t) {
|
|||||||
|
|
||||||
bool is_type_valid_for_keys(Type *t) {
|
bool is_type_valid_for_keys(Type *t) {
|
||||||
t = core_type(t);
|
t = core_type(t);
|
||||||
|
if (t->kind == Type_Generic) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (is_type_untyped(t)) {
|
if (is_type_untyped(t)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user