print.odin 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. package runtime
  2. _INTEGER_DIGITS :: "0123456789abcdefghijklmnopqrstuvwxyz";
  3. encode_rune :: proc "contextless" (c: rune) -> ([4]u8, int) {
  4. r := c;
  5. buf: [4]u8;
  6. i := u32(r);
  7. mask :: u8(0x3f);
  8. if i <= 1<<7-1 {
  9. buf[0] = u8(r);
  10. return buf, 1;
  11. }
  12. if i <= 1<<11-1 {
  13. buf[0] = 0xc0 | u8(r>>6);
  14. buf[1] = 0x80 | u8(r) & mask;
  15. return buf, 2;
  16. }
  17. // Invalid or Surrogate range
  18. if i > 0x0010ffff ||
  19. (0xd800 <= i && i <= 0xdfff) {
  20. r = 0xfffd;
  21. }
  22. if i <= 1<<16-1 {
  23. buf[0] = 0xe0 | u8(r>>12);
  24. buf[1] = 0x80 | u8(r>>6) & mask;
  25. buf[2] = 0x80 | u8(r) & mask;
  26. return buf, 3;
  27. }
  28. buf[0] = 0xf0 | u8(r>>18);
  29. buf[1] = 0x80 | u8(r>>12) & mask;
  30. buf[2] = 0x80 | u8(r>>6) & mask;
  31. buf[3] = 0x80 | u8(r) & mask;
  32. return buf, 4;
  33. }
  34. print_string :: proc "contextless" (str: string) -> (int, _OS_Errno) {
  35. return os_write(transmute([]byte)str);
  36. }
  37. print_strings :: proc "contextless" (args: ..string) -> (n: int, err: _OS_Errno) {
  38. for str in args {
  39. m: int;
  40. m, err = os_write(transmute([]byte)str);
  41. n += m;
  42. if err != 0 {
  43. break;
  44. }
  45. }
  46. return;
  47. }
  48. print_byte :: proc "contextless" (b: byte) -> (int, _OS_Errno) {
  49. return os_write([]byte{b});
  50. }
  51. print_encoded_rune :: proc "contextless" (r: rune) {
  52. print_byte('\'');
  53. switch r {
  54. case '\a': print_string("\\a");
  55. case '\b': print_string("\\b");
  56. case '\e': print_string("\\e");
  57. case '\f': print_string("\\f");
  58. case '\n': print_string("\\n");
  59. case '\r': print_string("\\r");
  60. case '\t': print_string("\\t");
  61. case '\v': print_string("\\v");
  62. case:
  63. if r <= 0 {
  64. print_string("\\x00");
  65. } else if r < 32 {
  66. digits := _INTEGER_DIGITS;
  67. n0, n1 := u8(r) >> 4, u8(r) & 0xf;
  68. print_string("\\x");
  69. print_byte(digits[n0]);
  70. print_byte(digits[n1]);
  71. } else {
  72. print_rune(r);
  73. }
  74. }
  75. print_byte('\'');
  76. }
  77. print_rune :: proc "contextless" (r: rune) -> (int, _OS_Errno) #no_bounds_check {
  78. RUNE_SELF :: 0x80;
  79. if r < RUNE_SELF {
  80. return print_byte(byte(r));
  81. }
  82. b, n := encode_rune(r);
  83. return os_write(b[:n]);
  84. }
  85. print_u64 :: proc "contextless" (x: u64) #no_bounds_check {
  86. digits := _INTEGER_DIGITS;
  87. a: [129]byte;
  88. i := len(a);
  89. b := u64(10);
  90. u := x;
  91. for u >= b {
  92. i -= 1; a[i] = digits[u % b];
  93. u /= b;
  94. }
  95. i -= 1; a[i] = digits[u % b];
  96. os_write(a[i:]);
  97. }
  98. print_i64 :: proc "contextless" (x: i64) #no_bounds_check {
  99. digits := _INTEGER_DIGITS;
  100. b :: i64(10);
  101. u := x;
  102. neg := u < 0;
  103. u = abs(u);
  104. a: [129]byte;
  105. i := len(a);
  106. for u >= b {
  107. i -= 1; a[i] = digits[u % b];
  108. u /= b;
  109. }
  110. i -= 1; a[i] = digits[u % b];
  111. if neg {
  112. i -= 1; a[i] = '-';
  113. }
  114. os_write(a[i:]);
  115. }
  116. print_caller_location :: proc "contextless" (using loc: Source_Code_Location) {
  117. print_string(file_path);
  118. print_byte('(');
  119. print_u64(u64(line));
  120. print_byte(':');
  121. print_u64(u64(column));
  122. print_byte(')');
  123. }
  124. print_typeid :: proc "contextless" (id: typeid) {
  125. if id == nil {
  126. print_string("nil");
  127. } else {
  128. ti := type_info_of(id);
  129. print_type(ti);
  130. }
  131. }
  132. print_type :: proc "contextless" (ti: ^Type_Info) {
  133. if ti == nil {
  134. print_string("nil");
  135. return;
  136. }
  137. switch info in ti.variant {
  138. case Type_Info_Named:
  139. print_string(info.name);
  140. case Type_Info_Integer:
  141. switch ti.id {
  142. case int: print_string("int");
  143. case uint: print_string("uint");
  144. case uintptr: print_string("uintptr");
  145. case:
  146. print_byte('i' if info.signed else 'u');
  147. print_u64(u64(8*ti.size));
  148. }
  149. case Type_Info_Rune:
  150. print_string("rune");
  151. case Type_Info_Float:
  152. print_byte('f');
  153. print_u64(u64(8*ti.size));
  154. case Type_Info_Complex:
  155. print_string("complex");
  156. print_u64(u64(8*ti.size));
  157. case Type_Info_Quaternion:
  158. print_string("quaternion");
  159. print_u64(u64(8*ti.size));
  160. case Type_Info_String:
  161. print_string("string");
  162. case Type_Info_Boolean:
  163. switch ti.id {
  164. case bool: print_string("bool");
  165. case:
  166. print_byte('b');
  167. print_u64(u64(8*ti.size));
  168. }
  169. case Type_Info_Any:
  170. print_string("any");
  171. case Type_Info_Type_Id:
  172. print_string("typeid");
  173. case Type_Info_Pointer:
  174. if info.elem == nil {
  175. print_string("rawptr");
  176. } else {
  177. print_string("^");
  178. print_type(info.elem);
  179. }
  180. case Type_Info_Procedure:
  181. print_string("proc");
  182. if info.params == nil {
  183. print_string("()");
  184. } else {
  185. t := info.params.variant.(Type_Info_Tuple);
  186. print_byte('(');
  187. for t, i in t.types {
  188. if i > 0 { print_string(", "); }
  189. print_type(t);
  190. }
  191. print_string(")");
  192. }
  193. if info.results != nil {
  194. print_string(" -> ");
  195. print_type(info.results);
  196. }
  197. case Type_Info_Tuple:
  198. count := len(info.names);
  199. if count != 1 { print_byte('('); }
  200. for name, i in info.names {
  201. if i > 0 { print_string(", "); }
  202. t := info.types[i];
  203. if len(name) > 0 {
  204. print_string(name);
  205. print_string(": ");
  206. }
  207. print_type(t);
  208. }
  209. if count != 1 { print_string(")"); }
  210. case Type_Info_Array:
  211. print_byte('[');
  212. print_u64(u64(info.count));
  213. print_byte(']');
  214. print_type(info.elem);
  215. case Type_Info_Enumerated_Array:
  216. print_byte('[');
  217. print_type(info.index);
  218. print_byte(']');
  219. print_type(info.elem);
  220. case Type_Info_Dynamic_Array:
  221. print_string("[dynamic]");
  222. print_type(info.elem);
  223. case Type_Info_Slice:
  224. print_string("[]");
  225. print_type(info.elem);
  226. case Type_Info_Map:
  227. print_string("map[");
  228. print_type(info.key);
  229. print_byte(']');
  230. print_type(info.value);
  231. case Type_Info_Struct:
  232. switch info.soa_kind {
  233. case .None: // Ignore
  234. case .Fixed:
  235. print_string("#soa[");
  236. print_u64(u64(info.soa_len));
  237. print_byte(']');
  238. print_type(info.soa_base_type);
  239. return;
  240. case .Slice:
  241. print_string("#soa[]");
  242. print_type(info.soa_base_type);
  243. return;
  244. case .Dynamic:
  245. print_string("#soa[dynamic]");
  246. print_type(info.soa_base_type);
  247. return;
  248. }
  249. print_string("struct ");
  250. if info.is_packed { print_string("#packed "); }
  251. if info.is_raw_union { print_string("#raw_union "); }
  252. if info.custom_align {
  253. print_string("#align ");
  254. print_u64(u64(ti.align));
  255. print_byte(' ');
  256. }
  257. print_byte('{');
  258. for name, i in info.names {
  259. if i > 0 { print_string(", "); }
  260. print_string(name);
  261. print_string(": ");
  262. print_type(info.types[i]);
  263. }
  264. print_byte('}');
  265. case Type_Info_Union:
  266. print_string("union ");
  267. if info.custom_align {
  268. print_string("#align ");
  269. print_u64(u64(ti.align));
  270. }
  271. if info.no_nil {
  272. print_string("#no_nil ");
  273. }
  274. print_byte('{');
  275. for variant, i in info.variants {
  276. if i > 0 { print_string(", "); }
  277. print_type(variant);
  278. }
  279. print_string("}");
  280. case Type_Info_Enum:
  281. print_string("enum ");
  282. print_type(info.base);
  283. print_string(" {");
  284. for name, i in info.names {
  285. if i > 0 { print_string(", "); }
  286. print_string(name);
  287. }
  288. print_string("}");
  289. case Type_Info_Bit_Set:
  290. print_string("bit_set[");
  291. #partial switch elem in type_info_base(info.elem).variant {
  292. case Type_Info_Enum:
  293. print_type(info.elem);
  294. case Type_Info_Rune:
  295. print_encoded_rune(rune(info.lower));
  296. print_string("..");
  297. print_encoded_rune(rune(info.upper));
  298. case:
  299. print_i64(info.lower);
  300. print_string("..");
  301. print_i64(info.upper);
  302. }
  303. if info.underlying != nil {
  304. print_string("; ");
  305. print_type(info.underlying);
  306. }
  307. print_byte(']');
  308. case Type_Info_Simd_Vector:
  309. print_string("#simd[");
  310. print_u64(u64(info.count));
  311. print_byte(']');
  312. print_type(info.elem);
  313. case Type_Info_Relative_Pointer:
  314. print_string("#relative(");
  315. print_type(info.base_integer);
  316. print_string(") ");
  317. print_type(info.pointer);
  318. case Type_Info_Relative_Slice:
  319. print_string("#relative(");
  320. print_type(info.base_integer);
  321. print_string(") ");
  322. print_type(info.slice);
  323. }
  324. }