opaque keyword and type

This commit is contained in:
gingerBill
2018-11-11 17:08:30 +00:00
parent 620d5d34f7
commit b55b1ffe14
13 changed files with 177 additions and 5 deletions
+51
View File
@@ -409,6 +409,11 @@ write_type :: proc(buf: ^String_Buffer, ti: ^runtime.Type_Info) {
write_type(buf, info.underlying);
}
write_byte(buf, ']');
case runtime.Type_Info_Opaque:
write_string(buf, "opaque ");
write_type(buf, info.elem);
}
}
@@ -927,6 +932,47 @@ fmt_bit_field :: proc(fi: ^Fmt_Info, v: any, name: string = "") {
}
}
fmt_opaque :: proc(fi: ^Fmt_Info, v: any) {
is_nil :: proc(data: rawptr, n: int) -> bool {
if data == nil do return true;
if n == 0 do return true;
a := (^byte)(data);
for i in 0..n-1 do if mem.ptr_offset(a, i)^ != 0 {
return false;
}
return true;
}
rt :: runtime;
type_info := type_info_of(v.id);
if is_nil(v.data, type_info.size) {
write_string(fi.buf, "nil");
return;
}
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);
write_byte(fi.buf, '{');
defer write_byte(fi.buf, '}');
switch in elem.variant {
case rt.Type_Info_Integer, rt.Type_Info_Pointer, rt.Type_Info_Float:
fmt_value(fi, any{v.data, elem.id}, 'v');
case:
// Okay
}
} else {
write_type(fi.buf, type_info);
write_byte(fi.buf, '{');
defer write_byte(fi.buf, '}');
}
}
fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
if v.data == nil || v.id == nil {
write_string(fi.buf, "<nil>");
@@ -986,6 +1032,8 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
fmt_bit_set(fi, v);
case runtime.Type_Info_Bit_Field:
fmt_bit_field(fi, v);
case runtime.Type_Info_Opaque:
fmt_opaque(fi, v);
case:
fmt_value(fi, any{v.data, info.base.id}, verb);
}
@@ -1158,6 +1206,9 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
case runtime.Type_Info_Bit_Set:
fmt_bit_set(fi, v);
case runtime.Type_Info_Opaque:
fmt_opaque(fi, v);
}
}
+6
View File
@@ -107,6 +107,10 @@ Type_Info_Bit_Set :: struct {
upper: i64,
};
Type_Info_Opaque :: struct {
elem: ^Type_Info,
}
Type_Info :: struct {
size: int,
align: int,
@@ -134,6 +138,7 @@ Type_Info :: struct {
Type_Info_Map,
Type_Info_Bit_Field,
Type_Info_Bit_Set,
Type_Info_Opaque,
},
}
@@ -160,6 +165,7 @@ Typeid_Kind :: enum u8 {
Map,
Bit_Field,
Bit_Set,
Opaque,
}
Typeid_Bit_Field :: bit_field #align align_of(uintptr) {
+10 -1
View File
@@ -154,12 +154,16 @@ are_types_identical :: proc(a, b: ^rt.Type_Info) -> bool {
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 {
@@ -258,3 +262,8 @@ is_enum :: proc(info: ^rt.Type_Info) -> bool {
_, 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;
}