mirror of
https://github.com/Ed94/Odin.git
synced 2026-07-23 07:57:52 +00:00
This commit is contained in:
+25
-22
@@ -52,15 +52,12 @@ Type_Info :: union {
|
||||
Float: struct #ordered {
|
||||
size: int, // in bytes
|
||||
},
|
||||
Any: struct #ordered {},
|
||||
String: struct #ordered {},
|
||||
Boolean: struct #ordered {},
|
||||
Any: struct #ordered {},
|
||||
Pointer: struct #ordered {
|
||||
elem: ^Type_Info, // nil -> rawptr
|
||||
},
|
||||
Maybe: struct #ordered {
|
||||
elem: ^Type_Info,
|
||||
},
|
||||
Procedure: struct #ordered {
|
||||
params: ^Type_Info, // Type_Info.Tuple
|
||||
results: ^Type_Info, // Type_Info.Tuple
|
||||
@@ -112,7 +109,7 @@ type_info_base :: proc(info: ^Type_Info) -> ^Type_Info {
|
||||
return nil;
|
||||
}
|
||||
base := info;
|
||||
match type i in base {
|
||||
match i in base {
|
||||
case Type_Info.Named:
|
||||
base = i.base;
|
||||
}
|
||||
@@ -125,7 +122,7 @@ type_info_base_without_enum :: proc(info: ^Type_Info) -> ^Type_Info {
|
||||
return nil;
|
||||
}
|
||||
base := info;
|
||||
match type i in base {
|
||||
match i in base {
|
||||
case Type_Info.Named:
|
||||
base = i.base;
|
||||
case Type_Info.Enum:
|
||||
@@ -146,6 +143,8 @@ __cpuid :: proc(level: u32, sig: ^u32) -> i32 #foreign __llvm_core "__get_cpuid"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// IMPORTANT NOTE(bill): Must be in this order (as the compiler relies upon it)
|
||||
Allocator_Mode :: enum u8 {
|
||||
ALLOC,
|
||||
@@ -153,9 +152,9 @@ Allocator_Mode :: enum u8 {
|
||||
FREE_ALL,
|
||||
RESIZE,
|
||||
}
|
||||
Allocator_Proc :: type proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int, flags: u64) -> rawptr;
|
||||
Allocator_Proc :: #type proc(allocator_data: rawptr, mode: Allocator_Mode,
|
||||
size, alignment: int,
|
||||
old_memory: rawptr, old_size: int, flags: u64) -> rawptr;
|
||||
Allocator :: struct #ordered {
|
||||
procedure: Allocator_Proc,
|
||||
data: rawptr,
|
||||
@@ -199,23 +198,17 @@ free_ptr_with_allocator :: proc(a: Allocator, ptr: rawptr) #inline {
|
||||
if ptr == nil {
|
||||
return;
|
||||
}
|
||||
if a.procedure == nil {
|
||||
return;
|
||||
}
|
||||
a.procedure(a.data, Allocator_Mode.FREE, 0, 0, ptr, 0, 0);
|
||||
}
|
||||
|
||||
__free_raw_dynamic_array :: proc(a: ^Raw_Dynamic_Array) {
|
||||
if a.allocator.procedure == nil {
|
||||
return;
|
||||
}
|
||||
if a.data == nil {
|
||||
return;
|
||||
}
|
||||
free_ptr_with_allocator(a.allocator, a.data);
|
||||
}
|
||||
|
||||
free_ptr :: proc(ptr: rawptr) #inline {
|
||||
__check_context();
|
||||
free_ptr_with_allocator(context.allocator, ptr);
|
||||
}
|
||||
|
||||
free_all :: proc() #inline {
|
||||
__check_context();
|
||||
a := context.allocator;
|
||||
@@ -306,11 +299,11 @@ __string_eq :: proc(a, b: string) -> bool {
|
||||
if a.data == b.data {
|
||||
return true;
|
||||
}
|
||||
return mem.compare(cast(rawptr)a.data, cast(rawptr)b.data, a.count) == 0;
|
||||
return __string_cmp(a, b) == 0;
|
||||
}
|
||||
|
||||
__string_cmp :: proc(a, b: string) -> int {
|
||||
return mem.compare(cast(rawptr)a.data, cast(rawptr)b.data, min(a.count, b.count));
|
||||
return mem.compare(cast([]byte)a, cast([]byte)b);
|
||||
}
|
||||
|
||||
__string_ne :: proc(a, b: string) -> bool #inline { return !__string_eq(a, b); }
|
||||
@@ -504,7 +497,7 @@ __dynamic_map_rehash :: proc(using header: __Map_Header, new_count: int) {
|
||||
nm: Raw_Dynamic_Map;
|
||||
new_header.m = ^nm;
|
||||
|
||||
reserve(^nm.hashes, new_count);
|
||||
reserve(nm.hashes, new_count);
|
||||
nm.hashes.count = nm.hashes.capacity;
|
||||
__dynamic_array_reserve(^nm.entries, entry_size, entry_align, m.entries.count);
|
||||
for _, i in nm.hashes {
|
||||
@@ -660,3 +653,13 @@ __dynamic_map_erase :: proc(using h: __Map_Header, fr: __Map_Find_Result) {
|
||||
m.hashes[last.hash_index] = fr.entry_index;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
__print_ti_ptr :: proc(ti: ^Type_Info) {
|
||||
fmt.println(ti);
|
||||
match e in ti {
|
||||
case Type_Info.Enum:
|
||||
fmt.println(e.names);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+16
-26
@@ -107,7 +107,7 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
||||
}
|
||||
|
||||
using Type_Info;
|
||||
match type info in ti {
|
||||
match info in ti {
|
||||
case Named:
|
||||
buffer_write_string(buf, info.name);
|
||||
case Integer:
|
||||
@@ -134,9 +134,6 @@ buffer_write_type :: proc(buf: ^Buffer, ti: ^Type_Info) {
|
||||
buffer_write_string(buf, "^");
|
||||
buffer_write_type(buf, info.elem);
|
||||
}
|
||||
case Maybe:
|
||||
buffer_write_string(buf, "?");
|
||||
buffer_write_type(buf, info.elem);
|
||||
case Procedure:
|
||||
buffer_write_string(buf, "proc");
|
||||
if info.params == nil {
|
||||
@@ -358,7 +355,7 @@ int_from_arg :: proc(args: []any, arg_index: int) -> (int, int, bool) {
|
||||
if arg_index < args.count {
|
||||
arg := args[arg_index];
|
||||
arg.type_info = type_info_base(arg.type_info);
|
||||
match type i in arg {
|
||||
match i in arg {
|
||||
case int: num = i;
|
||||
case i8: num = cast(int)i;
|
||||
case i16: num = cast(int)i;
|
||||
@@ -420,8 +417,9 @@ fmt_write_padding :: proc(fi: ^Fmt_Info, width: int) {
|
||||
}
|
||||
|
||||
fmt_integer :: proc(fi: ^Fmt_Info, u: u64, base: int, signed: bool, digits: string) {
|
||||
negative := signed && cast(i64)u < 0;
|
||||
u = abs(u);
|
||||
s := cast(i64)u;
|
||||
negative := signed && s < 0;
|
||||
u = cast(u64)abs(s);
|
||||
buf: [256]byte;
|
||||
if fi.width_set || fi.prec_set {
|
||||
width := fi.width + fi.prec + 3;
|
||||
@@ -628,6 +626,7 @@ fmt_string :: proc(fi: ^Fmt_Info, s: string, verb: rune) {
|
||||
fmt_pointer :: proc(fi: ^Fmt_Info, p: rawptr, verb: rune) {
|
||||
match verb {
|
||||
case 'p', 'v':
|
||||
// Okay
|
||||
default:
|
||||
fmt_bad_verb(fi, verb);
|
||||
return;
|
||||
@@ -646,7 +645,7 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
}
|
||||
|
||||
using Type_Info;
|
||||
match type e in v.type_info {
|
||||
match e in v.type_info {
|
||||
default:
|
||||
fmt_bad_verb(fi, verb);
|
||||
return;
|
||||
@@ -659,7 +658,7 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
f: f64;
|
||||
ok := false;
|
||||
a := any{type_info_base(e.base), v.data};
|
||||
match type v in a {
|
||||
match v in a {
|
||||
case i8: i = cast(i64)v;
|
||||
case i16: i = cast(i64)v;
|
||||
case i32: i = cast(i64)v;
|
||||
@@ -710,9 +709,9 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
}
|
||||
|
||||
using Type_Info;
|
||||
match type info in v.type_info {
|
||||
match info in v.type_info {
|
||||
case Named:
|
||||
match type b in info.base {
|
||||
match b in info.base {
|
||||
case Struct:
|
||||
if verb != 'v' {
|
||||
fmt_bad_verb(fi, verb);
|
||||
@@ -747,16 +746,6 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
fmt_pointer(fi, (cast(^rawptr)v.data)^, verb);
|
||||
}
|
||||
|
||||
case Maybe:
|
||||
// TODO(bill): Correct verbs for Maybe types?
|
||||
size := mem.size_of_type_info(info.elem);
|
||||
data := slice_ptr(cast(^byte)v.data, size+1);
|
||||
if data[size] != 0 {
|
||||
fmt_arg(fi, any{info.elem, v.data}, verb);
|
||||
} else {
|
||||
buffer_write_string(fi.buf, "nil");
|
||||
}
|
||||
|
||||
case Array:
|
||||
if verb != 'v' {
|
||||
fmt_bad_verb(fi, verb);
|
||||
@@ -799,9 +788,10 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
|
||||
buffer_write_string(fi.buf, "map[");
|
||||
defer buffer_write_byte(fi.buf, ']');
|
||||
entries := ^(cast(^Raw_Dynamic_Map)v.data).entries;
|
||||
gs, _ := union_cast(^Struct)info.generated_struct;
|
||||
ed, _ := union_cast(^Dynamic_Array)gs.fields[1].type_info;
|
||||
entry_type, _ := union_cast(^Struct)ed.elem;
|
||||
gs, gs_ok := union_cast(^Struct)type_info_base(info.generated_struct); assert(gs_ok);
|
||||
ed, ed_ok := union_cast(^Dynamic_Array)type_info_base(gs.fields[1].type_info); assert(ed_ok);
|
||||
|
||||
entry_type, et_ok := union_cast(^Struct)ed.elem; assert(et_ok);
|
||||
entry_size := ed.elem_size;
|
||||
for i in 0..<entries.count {
|
||||
if i > 0 {
|
||||
@@ -892,7 +882,7 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
|
||||
|
||||
if verb == 'T' {
|
||||
ti := arg.type_info;
|
||||
match type a in arg {
|
||||
match a in arg {
|
||||
case ^Type_Info: ti = a;
|
||||
}
|
||||
buffer_write_type(fi.buf, ti);
|
||||
@@ -902,7 +892,7 @@ fmt_arg :: proc(fi: ^Fmt_Info, arg: any, verb: rune) {
|
||||
|
||||
base_arg := arg;
|
||||
base_arg.type_info = type_info_base(base_arg.type_info);
|
||||
match type a in base_arg {
|
||||
match a in base_arg {
|
||||
case bool: fmt_bool(fi, a, verb);
|
||||
case f32: fmt_float(fi, cast(f64)a, 32, verb);
|
||||
case f64: fmt_float(fi, a, 64, verb);
|
||||
|
||||
@@ -46,10 +46,6 @@ bit_reverse :: proc(b: u16) -> u16 #foreign __llvm_core "llvm.bitreverse.i16";
|
||||
bit_reverse :: proc(b: u32) -> u32 #foreign __llvm_core "llvm.bitreverse.i32";
|
||||
bit_reverse :: proc(b: u64) -> u64 #foreign __llvm_core "llvm.bitreverse.i64";
|
||||
|
||||
byte_swap :: proc(b: u16) -> u16 #foreign __llvm_core "llvm.bswap.i16";
|
||||
byte_swap :: proc(b: u32) -> u32 #foreign __llvm_core "llvm.bswap.i32";
|
||||
byte_swap :: proc(b: u64) -> u64 #foreign __llvm_core "llvm.bswap.i64";
|
||||
|
||||
fmuladd :: proc(a, b, c: f32) -> f32 #foreign __llvm_core "llvm.fmuladd.f32";
|
||||
fmuladd :: proc(a, b, c: f64) -> f64 #foreign __llvm_core "llvm.fmuladd.f64";
|
||||
|
||||
|
||||
+36
-37
@@ -1,6 +1,11 @@
|
||||
#import "fmt.odin";
|
||||
#import "os.odin";
|
||||
|
||||
swap :: proc(b: u16) -> u16 #foreign __llvm_core "llvm.bswap.i16";
|
||||
swap :: proc(b: u32) -> u32 #foreign __llvm_core "llvm.bswap.i32";
|
||||
swap :: proc(b: u64) -> u64 #foreign __llvm_core "llvm.bswap.i64";
|
||||
|
||||
|
||||
set :: proc(data: rawptr, value: i32, len: int) -> rawptr #link_name "__mem_set" {
|
||||
llvm_memset_64bit :: proc(dst: rawptr, val: byte, len: int, align: i32, is_volatile: bool) #foreign __llvm_core "llvm.memset.p0i8.i64";
|
||||
llvm_memset_64bit(data, cast(byte)value, len, 1, false);
|
||||
@@ -12,22 +17,21 @@ zero :: proc(data: rawptr, len: int) -> rawptr #link_name "__mem_zero" {
|
||||
}
|
||||
|
||||
copy :: proc(dst, src: rawptr, len: int) -> rawptr #link_name "__mem_copy" {
|
||||
// NOTE(bill): This _must_ implemented like C's memmove
|
||||
// NOTE(bill): This _must_ be implemented like C's memmove
|
||||
llvm_memmove_64bit :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #foreign __llvm_core "llvm.memmove.p0i8.p0i8.i64";
|
||||
llvm_memmove_64bit(dst, src, len, 1, false);
|
||||
return dst;
|
||||
}
|
||||
|
||||
copy_non_overlapping :: proc(dst, src: rawptr, len: int) -> rawptr #link_name "__mem_copy_non_overlapping" {
|
||||
// NOTE(bill): This _must_ implemented like C's memcpy
|
||||
// NOTE(bill): This _must_ be implemented like C's memcpy
|
||||
llvm_memcpy_64bit :: proc(dst, src: rawptr, len: int, align: i32, is_volatile: bool) #foreign __llvm_core "llvm.memcpy.p0i8.p0i8.i64";
|
||||
llvm_memcpy_64bit(dst, src, len, 1, false);
|
||||
return dst;
|
||||
}
|
||||
|
||||
compare :: proc(dst, src: rawptr, n: int) -> int #link_name "__mem_compare" {
|
||||
a := slice_ptr(cast(^byte)dst, n);
|
||||
b := slice_ptr(cast(^byte)src, n);
|
||||
compare :: proc(a, b: []byte) -> int #link_name "__mem_compare" {
|
||||
n := min(a.count, b.count);
|
||||
for i in 0..<n {
|
||||
match {
|
||||
case a[i] < b[i]:
|
||||
@@ -43,8 +47,8 @@ compare :: proc(dst, src: rawptr, n: int) -> int #link_name "__mem_compare" {
|
||||
|
||||
kilobytes :: proc(x: int) -> int #inline { return (x) * 1024; }
|
||||
megabytes :: proc(x: int) -> int #inline { return kilobytes(x) * 1024; }
|
||||
gigabytes :: proc(x: int) -> int #inline { return gigabytes(x) * 1024; }
|
||||
terabytes :: proc(x: int) -> int #inline { return terabytes(x) * 1024; }
|
||||
gigabytes :: proc(x: int) -> int #inline { return megabytes(x) * 1024; }
|
||||
terabytes :: proc(x: int) -> int #inline { return gigabytes(x) * 1024; }
|
||||
|
||||
is_power_of_two :: proc(x: int) -> bool {
|
||||
if x <= 0 {
|
||||
@@ -213,8 +217,7 @@ align_of_type_info :: proc(type_info: ^Type_Info) -> int {
|
||||
WORD_SIZE :: size_of(int);
|
||||
MAX_ALIGN :: size_of([vector 64]f64); // TODO(bill): Should these constants be builtin constants?
|
||||
using Type_Info;
|
||||
|
||||
match type info in type_info {
|
||||
match info in type_info {
|
||||
case Named:
|
||||
return align_of_type_info(info.base);
|
||||
case Integer:
|
||||
@@ -225,14 +228,16 @@ align_of_type_info :: proc(type_info: ^Type_Info) -> int {
|
||||
return WORD_SIZE;
|
||||
case Boolean:
|
||||
return 1;
|
||||
case Any:
|
||||
return WORD_SIZE;
|
||||
case Pointer:
|
||||
return WORD_SIZE;
|
||||
case Maybe:
|
||||
return max(align_of_type_info(info.elem), 1);
|
||||
case Procedure:
|
||||
return WORD_SIZE;
|
||||
case Array:
|
||||
return align_of_type_info(info.elem);
|
||||
case Dynamic_Array:
|
||||
return WORD_SIZE;
|
||||
case Slice:
|
||||
return WORD_SIZE;
|
||||
case Vector:
|
||||
@@ -240,12 +245,18 @@ align_of_type_info :: proc(type_info: ^Type_Info) -> int {
|
||||
count := cast(int)max(prev_pow2(cast(i64)info.count), 1);
|
||||
total := size * count;
|
||||
return clamp(total, 1, MAX_ALIGN);
|
||||
case Tuple:
|
||||
return info.align;
|
||||
case Struct:
|
||||
return info.align;
|
||||
case Union:
|
||||
return info.align;
|
||||
case Raw_Union:
|
||||
return info.align;
|
||||
case Enum:
|
||||
return align_of_type_info(info.base);
|
||||
case Map:
|
||||
return align_of_type_info(info.generated_struct);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -259,23 +270,21 @@ align_formula :: proc(size, align: int) -> int {
|
||||
size_of_type_info :: proc(type_info: ^Type_Info) -> int {
|
||||
WORD_SIZE :: size_of(int);
|
||||
using Type_Info;
|
||||
match type info in type_info {
|
||||
match info in type_info {
|
||||
case Named:
|
||||
return size_of_type_info(info.base);
|
||||
case Integer:
|
||||
return info.size;
|
||||
case Float:
|
||||
return info.size;
|
||||
case Any:
|
||||
return 2*WORD_SIZE;
|
||||
case String:
|
||||
return 2*WORD_SIZE;
|
||||
case Boolean:
|
||||
return 1;
|
||||
case Any:
|
||||
return 2*WORD_SIZE;
|
||||
case Pointer:
|
||||
return WORD_SIZE;
|
||||
case Maybe:
|
||||
return size_of_type_info(info.elem) + 1;
|
||||
case Procedure:
|
||||
return WORD_SIZE;
|
||||
case Array:
|
||||
@@ -287,39 +296,29 @@ size_of_type_info :: proc(type_info: ^Type_Info) -> int {
|
||||
align := align_of_type_info(info.elem);
|
||||
alignment := align_formula(size, align);
|
||||
return alignment*(count-1) + size;
|
||||
case Dynamic_Array:
|
||||
return size_of(rawptr) + 2*size_of(int) + size_of(Allocator);
|
||||
case Slice:
|
||||
return 3*WORD_SIZE;
|
||||
return 2*WORD_SIZE;
|
||||
case Vector:
|
||||
is_bool :: proc(type_info: ^Type_Info) -> bool {
|
||||
match type info in type_info {
|
||||
case Named:
|
||||
return is_bool(info.base);
|
||||
case Boolean:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
count := info.count;
|
||||
if count == 0 {
|
||||
return 0;
|
||||
}
|
||||
bit_size := 8*size_of_type_info(info.elem);
|
||||
if is_bool(info.elem) {
|
||||
// NOTE(bill): LLVM can store booleans as 1 bit because a boolean _is_ an `i1`
|
||||
// Silly LLVM spec
|
||||
bit_size = 1;
|
||||
}
|
||||
total_size_in_bits := bit_size * count;
|
||||
total_size := (total_size_in_bits+7)/8;
|
||||
return total_size;
|
||||
|
||||
size := size_of_type_info(info.elem);
|
||||
align := align_of_type_info(info.elem);
|
||||
alignment := align_formula(size, align);
|
||||
return alignment*(count-1) + size;
|
||||
case Struct:
|
||||
return info.size;
|
||||
case Union:
|
||||
return info.size;
|
||||
case Raw_Union:
|
||||
return info.size;
|
||||
case Enum:
|
||||
return size_of_type_info(info.base);
|
||||
case Map:
|
||||
return size_of_type_info(info.generated_struct);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
_ := compile_assert(ODIN_OS == "windows");
|
||||
#foreign_system_library "kernel32.lib";
|
||||
#foreign_system_library "user32.lib";
|
||||
#foreign_system_library "gdi32.lib";
|
||||
@@ -19,7 +20,7 @@ LPARAM :: int;
|
||||
LRESULT :: int;
|
||||
ATOM :: i16;
|
||||
BOOL :: i32;
|
||||
WNDPROC :: type proc(HWND, u32, WPARAM, LPARAM) -> LRESULT #cc_c;
|
||||
WNDPROC :: #type proc(HWND, u32, WPARAM, LPARAM) -> LRESULT #cc_c;
|
||||
|
||||
|
||||
INVALID_HANDLE_VALUE :: cast(HANDLE)(~cast(int)0);
|
||||
@@ -358,8 +359,8 @@ PFD_DOUBLEBUFFER_DONTCARE :: 0x40000000;
|
||||
PFD_STEREO_DONTCARE :: 0x80000000;
|
||||
|
||||
HGLRC :: HANDLE;
|
||||
PROC :: type proc() #cc_c;
|
||||
wglCreateContextAttribsARBType :: type proc(hdc: HDC, hshareContext: rawptr, attribList: ^i32) -> HGLRC;
|
||||
PROC :: #type proc() #cc_c;
|
||||
wglCreateContextAttribsARBType :: #type proc(hdc: HDC, hshareContext: rawptr, attribList: ^i32) -> HGLRC;
|
||||
|
||||
|
||||
PIXELFORMATDESCRIPTOR :: struct #ordered {
|
||||
|
||||
+24
-24
@@ -11,7 +11,7 @@ is_signed :: proc(info: ^Type_Info) -> bool {
|
||||
is_integer :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Integer: return true;
|
||||
}
|
||||
return false;
|
||||
@@ -19,7 +19,7 @@ is_integer :: proc(info: ^Type_Info) -> bool {
|
||||
is_float :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Float: return true;
|
||||
}
|
||||
return false;
|
||||
@@ -27,7 +27,7 @@ is_float :: proc(info: ^Type_Info) -> bool {
|
||||
is_any :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Any: return true;
|
||||
}
|
||||
return false;
|
||||
@@ -35,7 +35,7 @@ is_any :: proc(info: ^Type_Info) -> bool {
|
||||
is_string :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.String: return true;
|
||||
}
|
||||
return false;
|
||||
@@ -43,7 +43,7 @@ is_string :: proc(info: ^Type_Info) -> bool {
|
||||
is_boolean :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Boolean: return true;
|
||||
}
|
||||
return false;
|
||||
@@ -51,23 +51,15 @@ is_boolean :: proc(info: ^Type_Info) -> bool {
|
||||
is_pointer :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Pointer: return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
is_maybe :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
case Type_Info.Maybe: return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
is_procedure :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Procedure: return true;
|
||||
}
|
||||
return false;
|
||||
@@ -75,7 +67,7 @@ is_procedure :: proc(info: ^Type_Info) -> bool {
|
||||
is_array :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Array: return true;
|
||||
}
|
||||
return false;
|
||||
@@ -83,15 +75,23 @@ is_array :: proc(info: ^Type_Info) -> bool {
|
||||
is_dynamic_array :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Dynamic_Array: return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
is_dynamic_map :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Map: return i.count == 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
is_slice :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Slice: return true;
|
||||
}
|
||||
return false;
|
||||
@@ -99,7 +99,7 @@ is_slice :: proc(info: ^Type_Info) -> bool {
|
||||
is_vector :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Vector: return true;
|
||||
}
|
||||
return false;
|
||||
@@ -107,7 +107,7 @@ is_vector :: proc(info: ^Type_Info) -> bool {
|
||||
is_tuple :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Tuple: return true;
|
||||
}
|
||||
return false;
|
||||
@@ -115,7 +115,7 @@ is_tuple :: proc(info: ^Type_Info) -> bool {
|
||||
is_struct :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Struct: return true;
|
||||
}
|
||||
return false;
|
||||
@@ -123,7 +123,7 @@ is_struct :: proc(info: ^Type_Info) -> bool {
|
||||
is_union :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Union: return true;
|
||||
}
|
||||
return false;
|
||||
@@ -131,7 +131,7 @@ is_union :: proc(info: ^Type_Info) -> bool {
|
||||
is_raw_union :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Raw_Union: return true;
|
||||
}
|
||||
return false;
|
||||
@@ -139,7 +139,7 @@ is_raw_union :: proc(info: ^Type_Info) -> bool {
|
||||
is_enum :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil { return false; }
|
||||
|
||||
match type i in type_info_base(info) {
|
||||
match i in type_info_base(info) {
|
||||
case Type_Info.Enum: return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user