diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-16 23:21:34 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-16 23:21:34 +0200 |
commit | 7fee0fc28809042a2ecbc03f2e1b5b569073982b (patch) | |
tree | 8058579d05f55fc3c36567b68d3ef0314cd72ed0 /src | |
parent | 357f02dc5f1f2ad99210faf13c2b1fd7dff6e669 (diff) | |
download | bdl-7fee0fc28809042a2ecbc03f2e1b5b569073982b.tar.gz bdl-7fee0fc28809042a2ecbc03f2e1b5b569073982b.zip |
Add support for parsing long long unsigned integers if using hex
Diffstat (limited to 'src')
-rw-r--r-- | src/badlib.h | 55 | ||||
-rw-r--r-- | src/main.c | 14 |
2 files changed, 65 insertions, 4 deletions
diff --git a/src/badlib.h b/src/badlib.h index d334fa7..6432562 100644 --- a/src/badlib.h +++ b/src/badlib.h | |||
@@ -470,13 +470,13 @@ str_from_int(sz num, Arena *a) { | |||
470 | } | 470 | } |
471 | 471 | ||
472 | Str | 472 | Str |
473 | str_from_hex(sz num, sz zeroes, Arena *a) { | 473 | str_from_hex(u64 num, sz zeroes, Arena *a) { |
474 | char char_map[] = "0123456789abcdef"; | 474 | char char_map[] = "0123456789abcdef"; |
475 | u8 tmp[64]; | 475 | u8 tmp[64]; |
476 | zeroes = MIN((sz)sizeof(ptrsize) * 2, zeroes); | 476 | zeroes = MIN((sz)sizeof(ptrsize) * 2, zeroes); |
477 | u8 *end = tmp + sizeof(tmp); | 477 | u8 *end = tmp + sizeof(tmp); |
478 | u8 *beg = end; | 478 | u8 *beg = end; |
479 | sz t = num > 0 ? num : -num; | 479 | u64 t = num; |
480 | do { | 480 | do { |
481 | *--beg = char_map[t % 16]; | 481 | *--beg = char_map[t % 16]; |
482 | } while (t /= 16); | 482 | } while (t /= 16); |
@@ -634,6 +634,57 @@ str_to_int(Str s) { | |||
634 | return num; | 634 | return num; |
635 | } | 635 | } |
636 | 636 | ||
637 | u64 | ||
638 | str_to_uint(Str s) { | ||
639 | u64 num = 0; | ||
640 | if (str_has_prefix(s, cstr("0b"))) { | ||
641 | // Binary number. | ||
642 | s = str_remove_prefix(s, cstr("0b")); | ||
643 | while (s.size) { | ||
644 | char c = str_next(&s); | ||
645 | if (c == '_') { | ||
646 | continue; | ||
647 | } | ||
648 | assert(c == '0' || c == '1'); | ||
649 | num = num * 2 + (c - '0'); | ||
650 | } | ||
651 | } else if (str_has_prefix(s, cstr("0x"))) { | ||
652 | // Hex number. | ||
653 | s = str_remove_prefix(s, cstr("0x")); | ||
654 | while (s.size) { | ||
655 | char c = str_next(&s); | ||
656 | if (c == '_') { | ||
657 | continue; | ||
658 | } | ||
659 | assert((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || | ||
660 | (c >= 'A' && c <= 'F')); | ||
661 | if (c >= '0' && c <= '9') { | ||
662 | num = num * 16 + (c - '0'); | ||
663 | } else if (c >= 'a' && c <= 'f') { | ||
664 | num = num * 16 + (c - 'a' + 10); | ||
665 | } else if (c >= 'A' && c <= 'F') { | ||
666 | num = num * 16 + (c - 'A' + 10); | ||
667 | } | ||
668 | } | ||
669 | } else { | ||
670 | // Decimal number. | ||
671 | char c = str_peek(s); | ||
672 | assert(c != '-'); | ||
673 | if (c == '+') { | ||
674 | str_next(&s); | ||
675 | } | ||
676 | while (s.size) { | ||
677 | char c = str_next(&s); | ||
678 | if (c == '_') { | ||
679 | continue; | ||
680 | } | ||
681 | assert(c >= '0' && c <= '9'); | ||
682 | num = num * 10 + (c - '0'); | ||
683 | } | ||
684 | } | ||
685 | return num; | ||
686 | } | ||
687 | |||
637 | f64 | 688 | f64 |
638 | str_to_float(Str s) { | 689 | str_to_float(Str s) { |
639 | char c = str_peek(s); | 690 | char c = str_peek(s); |
@@ -65,6 +65,7 @@ typedef enum NodeKind { | |||
65 | NODE_STRING, | 65 | NODE_STRING, |
66 | NODE_SYMBOL, | 66 | NODE_SYMBOL, |
67 | NODE_NUM_INT, | 67 | NODE_NUM_INT, |
68 | NODE_NUM_UINT, | ||
68 | NODE_NUM_FLOAT, | 69 | NODE_NUM_FLOAT, |
69 | NODE_TRUE, | 70 | NODE_TRUE, |
70 | NODE_FALSE, | 71 | NODE_FALSE, |
@@ -98,6 +99,7 @@ Str node_str[] = { | |||
98 | [NODE_STRING] = cstr("STRING"), | 99 | [NODE_STRING] = cstr("STRING"), |
99 | [NODE_SYMBOL] = cstr("SYMBOL"), | 100 | [NODE_SYMBOL] = cstr("SYMBOL"), |
100 | [NODE_NUM_INT] = cstr("INT"), | 101 | [NODE_NUM_INT] = cstr("INT"), |
102 | [NODE_NUM_UINT] = cstr("UINT"), | ||
101 | [NODE_NUM_FLOAT] = cstr("FLOAT"), | 103 | [NODE_NUM_FLOAT] = cstr("FLOAT"), |
102 | [NODE_TRUE] = cstr("TRUE"), | 104 | [NODE_TRUE] = cstr("TRUE"), |
103 | [NODE_FALSE] = cstr("FALSE"), | 105 | [NODE_FALSE] = cstr("FALSE"), |
@@ -113,6 +115,7 @@ typedef struct Node { | |||
113 | union { | 115 | union { |
114 | f64 d; | 116 | f64 d; |
115 | sz i; | 117 | sz i; |
118 | u64 u; | ||
116 | Str str; | 119 | Str str; |
117 | Str sym; | 120 | Str sym; |
118 | } value; | 121 | } value; |
@@ -374,8 +377,14 @@ parse_number(Parser *parser) { | |||
374 | Node *node = NULL; | 377 | Node *node = NULL; |
375 | switch (prev.kind) { | 378 | switch (prev.kind) { |
376 | case TOK_NUM_INT: { | 379 | case TOK_NUM_INT: { |
377 | node = node_alloc(NODE_NUM_INT, prev, parser->storage); | 380 | if (str_has_prefix(prev.val, cstr("0x")) || |
378 | node->value.i = str_to_int(prev.val); | 381 | str_has_prefix(prev.val, cstr("0b"))) { |
382 | node = node_alloc(NODE_NUM_UINT, prev, parser->storage); | ||
383 | node->value.u = str_to_uint(prev.val); | ||
384 | } else { | ||
385 | node = node_alloc(NODE_NUM_INT, prev, parser->storage); | ||
386 | node->value.i = str_to_int(prev.val); | ||
387 | } | ||
379 | } break; | 388 | } break; |
380 | case TOK_NUM_FLOAT: { | 389 | case TOK_NUM_FLOAT: { |
381 | node = node_alloc(NODE_NUM_FLOAT, prev, parser->storage); | 390 | node = node_alloc(NODE_NUM_FLOAT, prev, parser->storage); |
@@ -430,6 +439,7 @@ graph_node(Node *node) { | |||
430 | print("<top> %s ", node_str[node->kind]); | 439 | print("<top> %s ", node_str[node->kind]); |
431 | switch (node->kind) { | 440 | switch (node->kind) { |
432 | case NODE_NUM_INT: print("| Value: %d", node->value.i); break; | 441 | case NODE_NUM_INT: print("| Value: %d", node->value.i); break; |
442 | case NODE_NUM_UINT: print("| Value: %x", node->value.u); break; | ||
433 | case NODE_NUM_FLOAT: print("| Value: %f{2}", node->value.d); break; | 443 | case NODE_NUM_FLOAT: print("| Value: %f{2}", node->value.d); break; |
434 | case NODE_STRING: print("| Value: %s", node->value.str); break; | 444 | case NODE_STRING: print("| Value: %s", node->value.str); break; |
435 | case NODE_SYMBOL: print("| Value: %s", node->value.sym); break; | 445 | case NODE_SYMBOL: print("| Value: %s", node->value.sym); break; |