diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index cd9aae169..52d75524a 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -5,7 +5,7 @@ import "core:math/bits" import "core:runtime" import "core:strconv" import "core:strings" -import "core:types" +import "core:reflect" Marshal_Error :: enum { None, @@ -194,7 +194,7 @@ marshal_arg :: proc(b: ^strings.Builder, v: any) -> Marshal_Error { data := uintptr(entries.data) + uintptr(i*entry_size); header := cast(^Map_Entry_Header)data; - if types.is_string(info.key) { + if reflect.is_string(info.key) { marshal_arg(b, header.key.str); } else { marshal_arg(b, any{rawptr(&header.key.hash), info.key.id}); diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index 60b1fdcc1..5dbebf972 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -5,9 +5,9 @@ import "core:os" import "core:mem" import "core:math/bits" import "core:unicode/utf8" -import "core:types" import "core:strconv" import "core:strings" +import "core:reflect" @private @@ -143,7 +143,7 @@ panicf :: proc "contextless" (fmt: string, args: ..any, loc := #caller_location) fprint_type :: proc(fd: os.Handle, info: ^runtime.Type_Info) { data: [DEFAULT_BUFFER_SIZE]byte; buf := strings.builder_from_slice(data[:]); - write_type(&buf, info); + reflect.write_type(&buf, info); os.write_string(fd, strings.to_string(buf)); } @@ -156,7 +156,7 @@ sbprint :: proc(buf: ^strings.Builder, args: ..any) -> string { fi.buf = buf; for arg, i in args { - is_string := arg != nil && types.is_string(type_info_of(arg.id)); + is_string := arg != nil && reflect.is_string(type_info_of(arg.id)); if i > 0 && !is_string && !prev_string { strings.write_byte(buf, ' '); } @@ -399,7 +399,7 @@ fmt_bad_verb :: proc(using fi: ^Info, verb: rune) { strings.write_rune(buf, verb); strings.write_byte(buf, '('); if arg.id != nil { - write_typeid(buf, arg.id); + reflect.write_typeid(buf, arg.id); strings.write_byte(buf, '='); fmt_value(fi, arg, 'v'); } else { @@ -792,7 +792,7 @@ enum_value_to_string :: proc(val: any) -> (string, bool) { case: return "", false; case runtime.Type_Info_Enum: get_str :: proc(i: $T, e: runtime.Type_Info_Enum) -> (string, bool) { - if types.is_string(e.base) { + if reflect.is_string(e.base) { for val, idx in e.values { if v, ok := val.(T); ok && v == i { return e.names[idx], true; @@ -947,7 +947,7 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") { if name != "" { strings.write_string(fi.buf, name); } else { - write_type(fi.buf, type_info); + reflect.write_type(fi.buf, type_info); } strings.write_byte(fi.buf, '{'); defer strings.write_byte(fi.buf, '}'); @@ -1042,7 +1042,7 @@ fmt_opaque :: proc(fi: ^Info, v: any) { if ot, ok := rt.type_info_base(type_info).variant.(rt.Type_Info_Opaque); ok { elem := rt.type_info_base(ot.elem); if elem == nil do return; - write_type(fi.buf, type_info); + reflect.write_type(fi.buf, type_info); strings.write_byte(fi.buf, '{'); defer strings.write_byte(fi.buf, '}'); @@ -1053,7 +1053,7 @@ fmt_opaque :: proc(fi: ^Info, v: any) { // Okay } } else { - write_type(fi.buf, type_info); + reflect.write_type(fi.buf, type_info); strings.write_byte(fi.buf, '{'); strings.write_byte(fi.buf, '}'); } @@ -1101,7 +1101,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { strings.write_string(fi.buf, name); strings.write_string(fi.buf, " = "); - if t := b.types[i]; types.is_any(t) { + if t := b.types[i]; reflect.is_any(t) { strings.write_string(fi.buf, "any{}"); } else { data := rawptr(uintptr(v.data) + b.offsets[i]); @@ -1133,7 +1133,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { case runtime.Type_Info_Pointer: if v.id == typeid_of(^runtime.Type_Info) { - write_type(fi.buf, (^^runtime.Type_Info)(v.data)^); + reflect.write_type(fi.buf, (^^runtime.Type_Info)(v.data)^); } else { ptr := (^rawptr)(v.data)^; if verb != 'p' && info.elem != nil { @@ -1256,7 +1256,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { data := uintptr(entries.data) + uintptr(i*entry_size); header := cast(^runtime.Map_Entry_Header)data; - if types.is_string(info.key) { + if reflect.is_string(info.key) { strings.write_string(fi.buf, header.key.str); } else { fi := Info{buf = fi.buf}; @@ -1297,7 +1297,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { strings.write_string(fi.buf, info.names[i]); strings.write_string(fi.buf, " = "); - if t := info.types[i]; types.is_any(t) { + if t := info.types[i]; reflect.is_any(t) { strings.write_string(fi.buf, "any{}"); } else { data := uintptr(v.data) + info.offsets[i]; @@ -1349,14 +1349,14 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) { if ptr == nil { strings.write_string(fi.buf, "nil"); } else { - write_typeid(fi.buf, v.id); + reflect.write_typeid(fi.buf, v.id); strings.write_string(fi.buf, " @ "); fmt_pointer(fi, ptr, 'p'); } case runtime.Type_Info_Type_Id: id := (^typeid)(v.data)^; - write_typeid(fi.buf, id); + reflect.write_typeid(fi.buf, id); case runtime.Type_Info_Bit_Field: fmt_bit_field(fi, v); @@ -1398,7 +1398,7 @@ fmt_arg :: proc(fi: ^Info, arg: any, verb: rune) { switch a in arg { case ^runtime.Type_Info: ti = a; } - write_type(fi.buf, ti); + reflect.write_type(fi.buf, ti); return; } @@ -1449,7 +1449,7 @@ fmt_arg :: proc(fi: ^Info, arg: any, verb: rune) { case string: fmt_string(fi, a, verb); case cstring: fmt_cstring(fi, a, verb); - case typeid: write_typeid(fi.buf, a); + case typeid: reflect.write_typeid(fi.buf, a); case i16le: fmt_int(fi, u64(a), true, 16, verb); case u16le: fmt_int(fi, u64(a), false, 16, verb); @@ -1482,212 +1482,3 @@ fmt_arg :: proc(fi: ^Info, arg: any, verb: rune) { - -write_typeid :: proc(buf: ^strings.Builder, id: typeid) { - write_type(buf, type_info_of(id)); -} - -write_type :: proc(buf: ^strings.Builder, ti: ^runtime.Type_Info) { - using strings; - if ti == nil { - write_string(buf, "nil"); - return; - } - - switch info in ti.variant { - case runtime.Type_Info_Named: - write_string(buf, info.name); - case runtime.Type_Info_Integer: - switch ti.id { - case int: write_string(buf, "int"); - case uint: write_string(buf, "uint"); - case uintptr: write_string(buf, "uintptr"); - case: - write_byte(buf, info.signed ? 'i' : 'u'); - write_i64(buf, i64(8*ti.size), 10); - switch info.endianness { - case runtime.Type_Info_Endianness.Little: - write_string(buf, "le"); - case runtime.Type_Info_Endianness.Big: - write_string(buf, "be"); - } - } - case runtime.Type_Info_Rune: - write_string(buf, "rune"); - case runtime.Type_Info_Float: - write_byte(buf, 'f'); - write_i64(buf, i64(8*ti.size), 10); - case runtime.Type_Info_Complex: - write_string(buf, "complex"); - write_i64(buf, i64(8*ti.size), 10); - case runtime.Type_Info_String: - if info.is_cstring { - write_string(buf, "cstring"); - } else { - write_string(buf, "string"); - } - case runtime.Type_Info_Boolean: - switch ti.id { - case bool: write_string(buf, "bool"); - case: - write_byte(buf, 'b'); - write_i64(buf, i64(8*ti.size), 10); - } - case runtime.Type_Info_Any: - write_string(buf, "any"); - - case runtime.Type_Info_Type_Id: - write_string(buf, "typeid"); - - case runtime.Type_Info_Pointer: - if info.elem == nil { - write_string(buf, "rawptr"); - } else { - write_string(buf, "^"); - write_type(buf, info.elem); - } - case runtime.Type_Info_Procedure: - write_string(buf, "proc"); - if info.params == nil { - write_string(buf, "()"); - } else { - t := info.params.variant.(runtime.Type_Info_Tuple); - write_string(buf, "("); - for t, i in t.types { - if i > 0 do write_string(buf, ", "); - write_type(buf, t); - } - write_string(buf, ")"); - } - if info.results != nil { - write_string(buf, " -> "); - write_type(buf, info.results); - } - case runtime.Type_Info_Tuple: - count := len(info.names); - if count != 1 do write_string(buf, "("); - for name, i in info.names { - if i > 0 do write_string(buf, ", "); - - t := info.types[i]; - - if len(name) > 0 { - write_string(buf, name); - write_string(buf, ": "); - } - write_type(buf, t); - } - if count != 1 do write_string(buf, ")"); - - case runtime.Type_Info_Array: - write_string(buf, "["); - write_i64(buf, i64(info.count), 10); - write_string(buf, "]"); - write_type(buf, info.elem); - case runtime.Type_Info_Dynamic_Array: - write_string(buf, "[dynamic]"); - write_type(buf, info.elem); - case runtime.Type_Info_Slice: - write_string(buf, "[]"); - write_type(buf, info.elem); - - case runtime.Type_Info_Map: - write_string(buf, "map["); - write_type(buf, info.key); - write_byte(buf, ']'); - write_type(buf, info.value); - - case runtime.Type_Info_Struct: - write_string(buf, "struct "); - if info.is_packed do write_string(buf, "#packed "); - if info.is_raw_union do write_string(buf, "#raw_union "); - if info.custom_align { - write_string(buf, "#align "); - write_i64(buf, i64(ti.align), 10); - write_byte(buf, ' '); - } - write_byte(buf, '{'); - for name, i in info.names { - if i > 0 do write_string(buf, ", "); - write_string(buf, name); - write_string(buf, ": "); - write_type(buf, info.types[i]); - } - write_byte(buf, '}'); - - case runtime.Type_Info_Union: - write_string(buf, "union "); - if info.custom_align { - write_string(buf, "#align "); - write_i64(buf, i64(ti.align), 10); - write_byte(buf, ' '); - } - write_byte(buf, '{'); - for variant, i in info.variants { - if i > 0 do write_string(buf, ", "); - write_type(buf, variant); - } - write_byte(buf, '}'); - - case runtime.Type_Info_Enum: - write_string(buf, "enum "); - write_type(buf, info.base); - write_string(buf, " {"); - for name, i in info.names { - if i > 0 do write_string(buf, ", "); - write_string(buf, name); - } - write_byte(buf, '}'); - - case runtime.Type_Info_Bit_Field: - write_string(buf, "bit_field "); - if ti.align != 1 { - write_string(buf, "#align "); - write_i64(buf, i64(ti.align), 10); - write_byte(buf, ' '); - } - write_string(buf, " {"); - for name, i in info.names { - if i > 0 do write_string(buf, ", "); - write_string(buf, name); - write_string(buf, ": "); - write_i64(buf, i64(info.bits[i]), 10); - } - write_byte(buf, '}'); - - case runtime.Type_Info_Bit_Set: - write_string(buf, "bit_set["); - switch { - case types.is_enum(info.elem): - write_type(buf, info.elem); - case types.is_rune(info.elem): - write_encoded_rune(buf, rune(info.lower)); - write_string(buf, ".."); - write_encoded_rune(buf, rune(info.upper)); - case: - write_i64(buf, info.lower, 10); - write_string(buf, ".."); - write_i64(buf, info.upper, 10); - } - if info.underlying != nil { - write_string(buf, "; "); - write_type(buf, info.underlying); - } - write_byte(buf, ']'); - - case runtime.Type_Info_Opaque: - write_string(buf, "opaque "); - write_type(buf, info.elem); - - case runtime.Type_Info_Simd_Vector: - if info.is_x86_mmx { - write_string(buf, "intrinsics.x86_mmx"); - } else { - write_string(buf, "intrinsics.vector("); - write_i64(buf, i64(info.count)); - write_string(buf, ", "); - write_type(buf, info.elem); - write_byte(buf, ')'); - } - } -} diff --git a/core/reflect/reflect.odin b/core/reflect/reflect.odin index c49c62daf..2e917710b 100644 --- a/core/reflect/reflect.odin +++ b/core/reflect/reflect.odin @@ -2,6 +2,7 @@ package reflect import "core:runtime" import "core:mem" +import "core:strings" Type_Kind :: enum { @@ -283,3 +284,214 @@ struct_tag_lookup :: proc(tag: Struct_Tag, key: string) -> (value: string, ok: b } return; } + + +write_typeid :: proc(buf: ^strings.Builder, id: typeid) { + write_type(buf, type_info_of(id)); +} + +write_type :: proc(buf: ^strings.Builder, ti: ^runtime.Type_Info) { + using strings; + if ti == nil { + write_string(buf, "nil"); + return; + } + + switch info in ti.variant { + case runtime.Type_Info_Named: + write_string(buf, info.name); + case runtime.Type_Info_Integer: + switch ti.id { + case int: write_string(buf, "int"); + case uint: write_string(buf, "uint"); + case uintptr: write_string(buf, "uintptr"); + case: + write_byte(buf, info.signed ? 'i' : 'u'); + write_i64(buf, i64(8*ti.size), 10); + switch info.endianness { + case runtime.Type_Info_Endianness.Little: + write_string(buf, "le"); + case runtime.Type_Info_Endianness.Big: + write_string(buf, "be"); + } + } + case runtime.Type_Info_Rune: + write_string(buf, "rune"); + case runtime.Type_Info_Float: + write_byte(buf, 'f'); + write_i64(buf, i64(8*ti.size), 10); + case runtime.Type_Info_Complex: + write_string(buf, "complex"); + write_i64(buf, i64(8*ti.size), 10); + case runtime.Type_Info_String: + if info.is_cstring { + write_string(buf, "cstring"); + } else { + write_string(buf, "string"); + } + case runtime.Type_Info_Boolean: + switch ti.id { + case bool: write_string(buf, "bool"); + case: + write_byte(buf, 'b'); + write_i64(buf, i64(8*ti.size), 10); + } + case runtime.Type_Info_Any: + write_string(buf, "any"); + + case runtime.Type_Info_Type_Id: + write_string(buf, "typeid"); + + case runtime.Type_Info_Pointer: + if info.elem == nil { + write_string(buf, "rawptr"); + } else { + write_string(buf, "^"); + write_type(buf, info.elem); + } + case runtime.Type_Info_Procedure: + write_string(buf, "proc"); + if info.params == nil { + write_string(buf, "()"); + } else { + t := info.params.variant.(runtime.Type_Info_Tuple); + write_string(buf, "("); + for t, i in t.types { + if i > 0 do write_string(buf, ", "); + write_type(buf, t); + } + write_string(buf, ")"); + } + if info.results != nil { + write_string(buf, " -> "); + write_type(buf, info.results); + } + case runtime.Type_Info_Tuple: + count := len(info.names); + if count != 1 do write_string(buf, "("); + for name, i in info.names { + if i > 0 do write_string(buf, ", "); + + t := info.types[i]; + + if len(name) > 0 { + write_string(buf, name); + write_string(buf, ": "); + } + write_type(buf, t); + } + if count != 1 do write_string(buf, ")"); + + case runtime.Type_Info_Array: + write_string(buf, "["); + write_i64(buf, i64(info.count), 10); + write_string(buf, "]"); + write_type(buf, info.elem); + case runtime.Type_Info_Dynamic_Array: + write_string(buf, "[dynamic]"); + write_type(buf, info.elem); + case runtime.Type_Info_Slice: + write_string(buf, "[]"); + write_type(buf, info.elem); + + case runtime.Type_Info_Map: + write_string(buf, "map["); + write_type(buf, info.key); + write_byte(buf, ']'); + write_type(buf, info.value); + + case runtime.Type_Info_Struct: + write_string(buf, "struct "); + if info.is_packed do write_string(buf, "#packed "); + if info.is_raw_union do write_string(buf, "#raw_union "); + if info.custom_align { + write_string(buf, "#align "); + write_i64(buf, i64(ti.align), 10); + write_byte(buf, ' '); + } + write_byte(buf, '{'); + for name, i in info.names { + if i > 0 do write_string(buf, ", "); + write_string(buf, name); + write_string(buf, ": "); + write_type(buf, info.types[i]); + } + write_byte(buf, '}'); + + case runtime.Type_Info_Union: + write_string(buf, "union "); + if info.custom_align { + write_string(buf, "#align "); + write_i64(buf, i64(ti.align), 10); + write_byte(buf, ' '); + } + write_byte(buf, '{'); + for variant, i in info.variants { + if i > 0 do write_string(buf, ", "); + write_type(buf, variant); + } + write_byte(buf, '}'); + + case runtime.Type_Info_Enum: + write_string(buf, "enum "); + write_type(buf, info.base); + write_string(buf, " {"); + for name, i in info.names { + if i > 0 do write_string(buf, ", "); + write_string(buf, name); + } + write_byte(buf, '}'); + + case runtime.Type_Info_Bit_Field: + write_string(buf, "bit_field "); + if ti.align != 1 { + write_string(buf, "#align "); + write_i64(buf, i64(ti.align), 10); + write_byte(buf, ' '); + } + write_string(buf, " {"); + for name, i in info.names { + if i > 0 do write_string(buf, ", "); + write_string(buf, name); + write_string(buf, ": "); + write_i64(buf, i64(info.bits[i]), 10); + } + write_byte(buf, '}'); + + case runtime.Type_Info_Bit_Set: + write_string(buf, "bit_set["); + switch { + case is_enum(info.elem): + write_type(buf, info.elem); + case is_rune(info.elem): + write_encoded_rune(buf, rune(info.lower)); + write_string(buf, ".."); + write_encoded_rune(buf, rune(info.upper)); + case: + write_i64(buf, info.lower, 10); + write_string(buf, ".."); + write_i64(buf, info.upper, 10); + } + if info.underlying != nil { + write_string(buf, "; "); + write_type(buf, info.underlying); + } + write_byte(buf, ']'); + + case runtime.Type_Info_Opaque: + write_string(buf, "opaque "); + write_type(buf, info.elem); + + case runtime.Type_Info_Simd_Vector: + if info.is_x86_mmx { + write_string(buf, "intrinsics.x86_mmx"); + } else { + write_string(buf, "intrinsics.vector("); + write_i64(buf, i64(info.count)); + write_string(buf, ", "); + write_type(buf, info.elem); + write_byte(buf, ')'); + } + } +} + diff --git a/core/types/types.odin b/core/types/types.odin deleted file mode 100644 index dc4db549f..000000000 --- a/core/types/types.odin +++ /dev/null @@ -1,274 +0,0 @@ -package types - -import rt "core:runtime" - -are_types_identical :: proc(a, b: ^rt.Type_Info) -> bool { - if a == b do return true; - - if (a == nil && b != nil) || - (a != nil && b == nil) { - return false; - } - - - switch { - case a.size != b.size, a.align != b.align: - return false; - } - - switch x in a.variant { - case rt.Type_Info_Named: - y, ok := b.variant.(rt.Type_Info_Named); - if !ok do return false; - return x.base == y.base; - - case rt.Type_Info_Integer: - y, ok := b.variant.(rt.Type_Info_Integer); - if !ok do return false; - return x.signed == y.signed; - - case rt.Type_Info_Rune: - _, ok := b.variant.(rt.Type_Info_Rune); - return ok; - - case rt.Type_Info_Float: - _, ok := b.variant.(rt.Type_Info_Float); - return ok; - - case rt.Type_Info_Complex: - _, ok := b.variant.(rt.Type_Info_Complex); - return ok; - - case rt.Type_Info_String: - _, ok := b.variant.(rt.Type_Info_String); - return ok; - - case rt.Type_Info_Boolean: - _, ok := b.variant.(rt.Type_Info_Boolean); - return ok; - - case rt.Type_Info_Any: - _, ok := b.variant.(rt.Type_Info_Any); - return ok; - - case rt.Type_Info_Pointer: - y, ok := b.variant.(rt.Type_Info_Pointer); - if !ok do return false; - return are_types_identical(x.elem, y.elem); - - case rt.Type_Info_Procedure: - y, ok := b.variant.(rt.Type_Info_Procedure); - if !ok do return false; - switch { - case x.variadic != y.variadic, - x.convention != y.convention: - return false; - } - - return are_types_identical(x.params, y.params) && are_types_identical(x.results, y.results); - - case rt.Type_Info_Array: - y, ok := b.variant.(rt.Type_Info_Array); - if !ok do return false; - if x.count != y.count do return false; - return are_types_identical(x.elem, y.elem); - - case rt.Type_Info_Dynamic_Array: - y, ok := b.variant.(rt.Type_Info_Dynamic_Array); - if !ok do return false; - return are_types_identical(x.elem, y.elem); - - case rt.Type_Info_Slice: - y, ok := b.variant.(rt.Type_Info_Slice); - if !ok do return false; - return are_types_identical(x.elem, y.elem); - - case rt.Type_Info_Tuple: - y, ok := b.variant.(rt.Type_Info_Tuple); - if !ok do return false; - if len(x.types) != len(y.types) do return false; - for _, i in x.types { - xt, yt := x.types[i], y.types[i]; - if !are_types_identical(xt, yt) { - return false; - } - } - return true; - - case rt.Type_Info_Struct: - y, ok := b.variant.(rt.Type_Info_Struct); - if !ok do return false; - switch { - case len(x.types) != len(y.types), - x.is_packed != y.is_packed, - x.is_raw_union != y.is_raw_union, - x.custom_align != y.custom_align: - return false; - } - for _, i in x.types { - xn, yn := x.names[i], y.names[i]; - xt, yt := x.types[i], y.types[i]; - - if xn != yn do return false; - if !are_types_identical(xt, yt) do return false; - } - return true; - - case rt.Type_Info_Union: - y, ok := b.variant.(rt.Type_Info_Union); - if !ok do return false; - if len(x.variants) != len(y.variants) do return false; - - for _, i in x.variants { - xv, yv := x.variants[i], y.variants[i]; - if !are_types_identical(xv, yv) do return false; - } - return true; - - case rt.Type_Info_Enum: - // NOTE(bill): Should be handled above - return false; - - case rt.Type_Info_Map: - y, ok := b.variant.(rt.Type_Info_Map); - if !ok do return false; - return are_types_identical(x.key, y.key) && are_types_identical(x.value, y.value); - - case rt.Type_Info_Bit_Field: - y, ok := b.variant.(rt.Type_Info_Bit_Field); - if !ok do return false; - if len(x.names) != len(y.names) do return false; - - for _, i in x.names { - xb, yb := x.bits[i], y.bits[i]; - xo, yo := x.offsets[i], y.offsets[i]; - xn, yn := x.names[i], y.names[i]; - - if xb != yb do return false; - if xo != yo do return false; - if xn != yn do return false; - } - return true; - - case rt.Type_Info_Bit_Set: - y, ok := b.variant.(rt.Type_Info_Bit_Set); - if !ok do return false; - return x.elem == y.elem && x.lower == y.lower && x.upper == y.upper; - - case rt.Type_Info_Opaque: - y, ok := b.variant.(rt.Type_Info_Opaque); - if !ok do return false; - return x.elem == y.elem; - } - - return false; -} - -is_signed :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - switch i in rt.type_info_base(info).variant { - case rt.Type_Info_Integer: return i.signed; - case rt.Type_Info_Float: return true; - } - return false; -} -is_integer :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Integer); - return ok; -} -is_rune :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Rune); - return ok; -} -is_float :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Float); - return ok; -} -is_complex :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Complex); - return ok; -} -is_any :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Any); - return ok; -} -is_string :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_String); - return ok; -} -is_boolean :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Boolean); - return ok; -} -is_pointer :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Pointer); - return ok; -} -is_procedure :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Procedure); - return ok; -} -is_array :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Array); - return ok; -} -is_dynamic_array :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Dynamic_Array); - return ok; -} -is_dynamic_map :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Map); - return ok; -} -is_slice :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Slice); - return ok; -} -is_tuple :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Tuple); - return ok; -} -is_struct :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - s, ok := rt.type_info_base(info).variant.(rt.Type_Info_Struct); - return ok && !s.is_raw_union; -} -is_raw_union :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - s, ok := rt.type_info_base(info).variant.(rt.Type_Info_Struct); - return ok && s.is_raw_union; -} -is_union :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Union); - return ok; -} -is_enum :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Enum); - return ok; -} -is_opaque :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Opaque); - return ok; -} -is_simd_vector :: proc(info: ^rt.Type_Info) -> bool { - if info == nil do return false; - _, ok := rt.type_info_base(info).variant.(rt.Type_Info_Simd_Vector); - return ok; -}