aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2024-06-16 23:21:34 +0200
committerBad Diode <bd@badd10de.dev>2024-06-16 23:21:34 +0200
commit7fee0fc28809042a2ecbc03f2e1b5b569073982b (patch)
tree8058579d05f55fc3c36567b68d3ef0314cd72ed0 /src
parent357f02dc5f1f2ad99210faf13c2b1fd7dff6e669 (diff)
downloadbdl-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.h55
-rw-r--r--src/main.c14
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
472Str 472Str
473str_from_hex(sz num, sz zeroes, Arena *a) { 473str_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
637u64
638str_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
637f64 688f64
638str_to_float(Str s) { 689str_to_float(Str s) {
639 char c = str_peek(s); 690 char c = str_peek(s);
diff --git a/src/main.c b/src/main.c
index 75faaf6..8dc645e 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;