Add bit_set type

This commit is contained in:
gingerBill
2018-08-14 17:07:56 +01:00
parent 89f4e7a8db
commit acc010cba5
14 changed files with 509 additions and 45 deletions
+87 -1
View File
@@ -70,7 +70,7 @@ write_rune :: proc(buf: ^String_Buffer, r: rune) {
write_i64 :: proc(buf: ^String_Buffer, i: i64, base: int) {
b: [129]byte;
s := strconv.append_bits(b[:], u64(i), base, true, 64, strconv.digits, 0);
s := strconv.append_bits(b[:], u64(i), base, true, 64, strconv.digits, nil);
write_string(buf, s);
}
@@ -312,6 +312,11 @@ write_type :: proc(buf: ^String_Buffer, ti: ^runtime.Type_Info) {
write_i64(buf, i64(info.bits[i]), 10);
}
write_string(buf, "}");
case runtime.Type_Info_Bit_Set:
write_string(buf, "bit_set[");
write_type(buf, info.base);
write_string(buf, "]");
}
}
@@ -714,6 +719,82 @@ fmt_enum :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
}
enum_value_to_u64 :: proc(ev: runtime.Type_Info_Enum_Value) -> u64 {
switch i in ev {
case rune: return u64(i);
case i8: return u64(i);
case i16: return u64(i);
case i32: return u64(i);
case i64: return u64(i);
case int: return u64(i);
case u8: return u64(i);
case u16: return u64(i);
case u32: return u64(i);
case u64: return u64(i);
case uint: return u64(i);
case uintptr: return u64(i);
case f32: return u64(i);
case f64: return u64(i);
}
return 0;
}
fmt_bit_set :: proc(fi: ^Fmt_Info, v: any, name: string = "") {
type_info := type_info_of(v.typeid);
switch info in type_info.variant {
case runtime.Type_Info_Named:
val := v;
val.typeid = info.base.id;
fmt_bit_set(fi, val, info.name);
case runtime.Type_Info_Bit_Set:
bits: u64;
bit_size := u64(8*type_info.size);
verb := 'b';
switch bit_size {
case 0: bits = 0;
case 8: bits = u64( (^u8)(v.data)^);
case 16: bits = u64((^u16)(v.data)^);
case 32: bits = u64((^u32)(v.data)^);
case 64: bits = u64((^u64)(v.data)^);
case: panic("unknown bit_size size");
}
et := runtime.type_info_base(info.base);
e := et.variant.(runtime.Type_Info_Enum);
if name != "" {
write_string(fi.buf, name);
} else {
write_type(fi.buf, type_info);
}
write_byte(fi.buf, '{');
defer write_byte(fi.buf, '}');
commas := 0;
loop: for i in 0 .. bit_size-1 {
if bits & (1<<i) == 0 {
continue loop;
}
if commas > 0 do write_string(fi.buf, ", ");
defer commas += 1;
for ev, evi in e.values {
v := enum_value_to_u64(ev);
if v == i {
write_string(fi.buf, e.names[evi]);
continue loop;
}
}
write_i64(fi.buf, i64(i), 10);
}
}
}
fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
if v.data == nil || v.typeid == nil {
write_string(fi.buf, "<nil>");
@@ -765,6 +846,8 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
if hash do for in 0..indent-1 do write_byte(fi.buf, '\t');
write_byte(fi.buf, '}');
case runtime.Type_Info_Bit_Set:
fmt_bit_set(fi, v);
case:
fmt_value(fi, any{v.data, typeid_of(info.base)}, verb);
}
@@ -929,6 +1012,9 @@ fmt_value :: proc(fi: ^Fmt_Info, v: any, verb: rune) {
case runtime.Type_Info_Type_Id:
id := (^typeid)(v.data)^;
write_typeid(fi.buf, id);
case runtime.Type_Info_Bit_Set:
fmt_bit_set(fi, v);
}
}
+4 -1
View File
@@ -99,7 +99,9 @@ Type_Info_Bit_Field :: struct {
bits: []i32,
offsets: []i32,
};
Type_Info_Bit_Set :: struct {
base: ^Type_Info,
};
Type_Info :: struct {
size: int,
@@ -127,6 +129,7 @@ Type_Info :: struct {
Type_Info_Enum,
Type_Info_Map,
Type_Info_Bit_Field,
Type_Info_Bit_Set,
},
}
+50
View File
@@ -0,0 +1,50 @@
package runtime
foreign import kernel32 "system:Kernel32.lib"
@(link_name="memcpy")
memcpy :: proc "c" (dst, src: rawptr, len: int) -> rawptr {
foreign kernel32 {
RtlCopyMemory :: proc "c" (dst, src: rawptr, len: int) ---
}
RtlCopyMemory(dst, src, len);
return dst;
}
@(link_name="memmove")
memmove :: proc "c" (dst, src: rawptr, len: int) -> rawptr {
foreign kernel32 {
RtlMoveMemory :: proc "c" (dst, src: rawptr, len: int) ---
}
RtlMoveMemory(dst, src, len);
return dst;
}
@(link_name="memset")
memset :: proc "c" (ptr: rawptr, val: i32, len: int) -> rawptr {
foreign kernel32 {
RtlFillMemory :: proc "c" (dst: rawptr, len: int, fill: byte) ---
}
RtlFillMemory(ptr, len, byte(val));
return ptr;
}
// @(link_name="memcmp")
// memcmp :: proc "c" (dst, src: rawptr, len: int) -> i32 {
// if dst == nil || src == nil {
// return 0;
// }
// if dst == src {
// return 0;
// }
// d, s := uintptr(dst), uintptr(src);
// n := uintptr(len);
// for i := uintptr(0); i < n; i += 1 {
// x, y := (^byte)(d+i)^, (^byte)(s+i)^;
// if x != y {
// return x < y ? -1 : +1;
// }
// }
// return 0;
// }
+5 -5
View File
@@ -198,10 +198,10 @@ append_bool :: proc(buf: []byte, b: bool) -> string {
}
append_uint :: proc(buf: []byte, u: u64, base: int) -> string {
return append_bits(buf, u64(u), base, false, 8*size_of(uint), digits, 0);
return append_bits(buf, u64(u), base, false, 8*size_of(uint), digits, nil);
}
append_int :: proc(buf: []byte, i: i64, base: int) -> string {
return append_bits(buf, u64(i), base, true, 8*size_of(int), digits, 0);
return append_bits(buf, u64(i), base, true, 8*size_of(int), digits, nil);
}
itoa :: proc(buf: []byte, i: int) -> string do return append_int(buf, i64(i), 10);
@@ -474,7 +474,7 @@ append_bits :: proc(buf: []byte, u: u64, base: int, is_signed: bool, bit_size: i
}
i-=1; a[i] = digits[u % b];
if flags&Int_Flag.Prefix != 0 {
if flags&Int_Flag.Prefix != nil {
ok := true;
switch base {
case 2: i-=1; a[i] = 'b';
@@ -492,9 +492,9 @@ append_bits :: proc(buf: []byte, u: u64, base: int, is_signed: bool, bit_size: i
switch {
case neg:
i-=1; a[i] = '-';
case flags&Int_Flag.Plus != 0:
case flags&Int_Flag.Plus != nil:
i-=1; a[i] = '+';
case flags&Int_Flag.Space != 0:
case flags&Int_Flag.Space != nil:
i-=1; a[i] = ' ';
}