123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 |
- package runtime
- _INTEGER_DIGITS :: "0123456789abcdefghijklmnopqrstuvwxyz";
- encode_rune :: proc "contextless" (c: rune) -> ([4]u8, int) {
- r := c;
- buf: [4]u8;
- i := u32(r);
- mask :: u8(0x3f);
- if i <= 1<<7-1 {
- buf[0] = u8(r);
- return buf, 1;
- }
- if i <= 1<<11-1 {
- buf[0] = 0xc0 | u8(r>>6);
- buf[1] = 0x80 | u8(r) & mask;
- return buf, 2;
- }
- // Invalid or Surrogate range
- if i > 0x0010ffff ||
- (0xd800 <= i && i <= 0xdfff) {
- r = 0xfffd;
- }
- if i <= 1<<16-1 {
- buf[0] = 0xe0 | u8(r>>12);
- buf[1] = 0x80 | u8(r>>6) & mask;
- buf[2] = 0x80 | u8(r) & mask;
- return buf, 3;
- }
- buf[0] = 0xf0 | u8(r>>18);
- buf[1] = 0x80 | u8(r>>12) & mask;
- buf[2] = 0x80 | u8(r>>6) & mask;
- buf[3] = 0x80 | u8(r) & mask;
- return buf, 4;
- }
- print_string :: proc "contextless" (str: string) -> (int, _OS_Errno) {
- return os_write(transmute([]byte)str);
- }
- print_strings :: proc "contextless" (args: ..string) -> (n: int, err: _OS_Errno) {
- for str in args {
- m: int;
- m, err = os_write(transmute([]byte)str);
- n += m;
- if err != 0 {
- break;
- }
- }
- return;
- }
- print_byte :: proc "contextless" (b: byte) -> (int, _OS_Errno) {
- return os_write([]byte{b});
- }
- print_encoded_rune :: proc "contextless" (r: rune) {
- print_byte('\'');
- switch r {
- case '\a': print_string("\\a");
- case '\b': print_string("\\b");
- case '\e': print_string("\\e");
- case '\f': print_string("\\f");
- case '\n': print_string("\\n");
- case '\r': print_string("\\r");
- case '\t': print_string("\\t");
- case '\v': print_string("\\v");
- case:
- if r <= 0 {
- print_string("\\x00");
- } else if r < 32 {
- digits := _INTEGER_DIGITS;
- n0, n1 := u8(r) >> 4, u8(r) & 0xf;
- print_string("\\x");
- print_byte(digits[n0]);
- print_byte(digits[n1]);
- } else {
- print_rune(r);
- }
- }
- print_byte('\'');
- }
- print_rune :: proc "contextless" (r: rune) -> (int, _OS_Errno) #no_bounds_check {
- RUNE_SELF :: 0x80;
- if r < RUNE_SELF {
- return print_byte(byte(r));
- }
- b, n := encode_rune(r);
- return os_write(b[:n]);
- }
- print_u64 :: proc "contextless" (x: u64) #no_bounds_check {
- digits := _INTEGER_DIGITS;
- a: [129]byte;
- i := len(a);
- b := u64(10);
- u := x;
- for u >= b {
- i -= 1; a[i] = digits[u % b];
- u /= b;
- }
- i -= 1; a[i] = digits[u % b];
- os_write(a[i:]);
- }
- print_i64 :: proc "contextless" (x: i64) #no_bounds_check {
- digits := _INTEGER_DIGITS;
- b :: i64(10);
- u := x;
- neg := u < 0;
- u = abs(u);
- a: [129]byte;
- i := len(a);
- for u >= b {
- i -= 1; a[i] = digits[u % b];
- u /= b;
- }
- i -= 1; a[i] = digits[u % b];
- if neg {
- i -= 1; a[i] = '-';
- }
- os_write(a[i:]);
- }
- print_caller_location :: proc "contextless" (using loc: Source_Code_Location) {
- print_string(file_path);
- print_byte('(');
- print_u64(u64(line));
- print_byte(':');
- print_u64(u64(column));
- print_byte(')');
- }
- print_typeid :: proc "contextless" (id: typeid) {
- if id == nil {
- print_string("nil");
- } else {
- ti := type_info_of(id);
- print_type(ti);
- }
- }
- print_type :: proc "contextless" (ti: ^Type_Info) {
- if ti == nil {
- print_string("nil");
- return;
- }
- switch info in ti.variant {
- case Type_Info_Named:
- print_string(info.name);
- case Type_Info_Integer:
- switch ti.id {
- case int: print_string("int");
- case uint: print_string("uint");
- case uintptr: print_string("uintptr");
- case:
- print_byte('i' if info.signed else 'u');
- print_u64(u64(8*ti.size));
- }
- case Type_Info_Rune:
- print_string("rune");
- case Type_Info_Float:
- print_byte('f');
- print_u64(u64(8*ti.size));
- case Type_Info_Complex:
- print_string("complex");
- print_u64(u64(8*ti.size));
- case Type_Info_Quaternion:
- print_string("quaternion");
- print_u64(u64(8*ti.size));
- case Type_Info_String:
- print_string("string");
- case Type_Info_Boolean:
- switch ti.id {
- case bool: print_string("bool");
- case:
- print_byte('b');
- print_u64(u64(8*ti.size));
- }
- case Type_Info_Any:
- print_string("any");
- case Type_Info_Type_Id:
- print_string("typeid");
- case Type_Info_Pointer:
- if info.elem == nil {
- print_string("rawptr");
- } else {
- print_string("^");
- print_type(info.elem);
- }
- case Type_Info_Procedure:
- print_string("proc");
- if info.params == nil {
- print_string("()");
- } else {
- t := info.params.variant.(Type_Info_Tuple);
- print_byte('(');
- for t, i in t.types {
- if i > 0 { print_string(", "); }
- print_type(t);
- }
- print_string(")");
- }
- if info.results != nil {
- print_string(" -> ");
- print_type(info.results);
- }
- case Type_Info_Tuple:
- count := len(info.names);
- if count != 1 { print_byte('('); }
- for name, i in info.names {
- if i > 0 { print_string(", "); }
- t := info.types[i];
- if len(name) > 0 {
- print_string(name);
- print_string(": ");
- }
- print_type(t);
- }
- if count != 1 { print_string(")"); }
- case Type_Info_Array:
- print_byte('[');
- print_u64(u64(info.count));
- print_byte(']');
- print_type(info.elem);
- case Type_Info_Enumerated_Array:
- print_byte('[');
- print_type(info.index);
- print_byte(']');
- print_type(info.elem);
- case Type_Info_Dynamic_Array:
- print_string("[dynamic]");
- print_type(info.elem);
- case Type_Info_Slice:
- print_string("[]");
- print_type(info.elem);
- case Type_Info_Map:
- print_string("map[");
- print_type(info.key);
- print_byte(']');
- print_type(info.value);
- case Type_Info_Struct:
- switch info.soa_kind {
- case .None: // Ignore
- case .Fixed:
- print_string("#soa[");
- print_u64(u64(info.soa_len));
- print_byte(']');
- print_type(info.soa_base_type);
- return;
- case .Slice:
- print_string("#soa[]");
- print_type(info.soa_base_type);
- return;
- case .Dynamic:
- print_string("#soa[dynamic]");
- print_type(info.soa_base_type);
- return;
- }
- print_string("struct ");
- if info.is_packed { print_string("#packed "); }
- if info.is_raw_union { print_string("#raw_union "); }
- if info.custom_align {
- print_string("#align ");
- print_u64(u64(ti.align));
- print_byte(' ');
- }
- print_byte('{');
- for name, i in info.names {
- if i > 0 { print_string(", "); }
- print_string(name);
- print_string(": ");
- print_type(info.types[i]);
- }
- print_byte('}');
- case Type_Info_Union:
- print_string("union ");
- if info.custom_align {
- print_string("#align ");
- print_u64(u64(ti.align));
- }
- if info.no_nil {
- print_string("#no_nil ");
- }
- print_byte('{');
- for variant, i in info.variants {
- if i > 0 { print_string(", "); }
- print_type(variant);
- }
- print_string("}");
- case Type_Info_Enum:
- print_string("enum ");
- print_type(info.base);
- print_string(" {");
- for name, i in info.names {
- if i > 0 { print_string(", "); }
- print_string(name);
- }
- print_string("}");
- case Type_Info_Bit_Set:
- print_string("bit_set[");
- #partial switch elem in type_info_base(info.elem).variant {
- case Type_Info_Enum:
- print_type(info.elem);
- case Type_Info_Rune:
- print_encoded_rune(rune(info.lower));
- print_string("..");
- print_encoded_rune(rune(info.upper));
- case:
- print_i64(info.lower);
- print_string("..");
- print_i64(info.upper);
- }
- if info.underlying != nil {
- print_string("; ");
- print_type(info.underlying);
- }
- print_byte(']');
- case Type_Info_Simd_Vector:
- print_string("#simd[");
- print_u64(u64(info.count));
- print_byte(']');
- print_type(info.elem);
- case Type_Info_Relative_Pointer:
- print_string("#relative(");
- print_type(info.base_integer);
- print_string(") ");
- print_type(info.pointer);
- case Type_Info_Relative_Slice:
- print_string("#relative(");
- print_type(info.base_integer);
- print_string(") ");
- print_type(info.slice);
- }
- }
|