aboutsummaryrefslogtreecommitdiffstats
path: root/src/badlib.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/badlib.h')
-rw-r--r--src/badlib.h90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/badlib.h b/src/badlib.h
index 9802278..d334fa7 100644
--- a/src/badlib.h
+++ b/src/badlib.h
@@ -586,6 +586,9 @@ str_to_int(Str s) {
586 s = str_remove_prefix(s, cstr("0b")); 586 s = str_remove_prefix(s, cstr("0b"));
587 while (s.size) { 587 while (s.size) {
588 char c = str_next(&s); 588 char c = str_next(&s);
589 if (c == '_') {
590 continue;
591 }
589 assert(c == '0' || c == '1'); 592 assert(c == '0' || c == '1');
590 num = num * 2 + (c - '0'); 593 num = num * 2 + (c - '0');
591 } 594 }
@@ -594,6 +597,9 @@ str_to_int(Str s) {
594 s = str_remove_prefix(s, cstr("0x")); 597 s = str_remove_prefix(s, cstr("0x"));
595 while (s.size) { 598 while (s.size) {
596 char c = str_next(&s); 599 char c = str_next(&s);
600 if (c == '_') {
601 continue;
602 }
597 assert((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || 603 assert((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') ||
598 (c >= 'A' && c <= 'F')); 604 (c >= 'A' && c <= 'F'));
599 if (c >= '0' && c <= '9') { 605 if (c >= '0' && c <= '9') {
@@ -606,11 +612,95 @@ str_to_int(Str s) {
606 } 612 }
607 } else { 613 } else {
608 // Decimal number. 614 // Decimal number.
615 char c = str_peek(s);
616 sz neg = 1;
617 if (c == '-') {
618 neg = -1;
619 str_next(&s);
620 } else if (c == '+') {
621 str_next(&s);
622 }
623 // TODO: check if it fits within the s64 range.
609 while (s.size) { 624 while (s.size) {
610 char c = str_next(&s); 625 char c = str_next(&s);
626 if (c == '_') {
627 continue;
628 }
611 assert(c >= '0' && c <= '9'); 629 assert(c >= '0' && c <= '9');
612 num = num * 10 + (c - '0'); 630 num = num * 10 + (c - '0');
613 } 631 }
632 num *= neg;
633 }
634 return num;
635}
636
637f64
638str_to_float(Str s) {
639 char c = str_peek(s);
640 f64 neg = 1.0;
641 if (c == '-') {
642 neg = -1.0;
643 str_next(&s);
644 } else if (c == '+') {
645 str_next(&s);
646 }
647 f64 num = 0.0;
648 // Integral part.
649 while (s.size) {
650 char c = str_next(&s);
651 if (c == '_') {
652 continue;
653 }
654 if (c == '.') {
655 break;
656 }
657 assert(c >= '0' && c <= '9');
658 num = num * 10 + (c - '0');
659 }
660 // Fractional part.
661 f64 frac = 0;
662 sz frac_digits = 1;
663 bool has_exponent = false;
664 while (s.size) {
665 char c = str_next(&s);
666 if (c == '_') {
667 continue;
668 }
669 if (c == 'e' || c == 'E') {
670 has_exponent = true;
671 break;
672 }
673 assert(c >= '0' && c <= '9');
674 frac = frac * 10 + (c - '0');
675 frac_digits *= 10;
676 }
677 num *= neg;
678 num += frac / frac_digits;
679 if (has_exponent) {
680 bool exp_neg = false;
681 char c = str_peek(s);
682 if (c == '-') {
683 exp_neg = true;
684 str_next(&s);
685 } else if (c == '+') {
686 str_next(&s);
687 }
688 sz exponent = 0;
689 while (s.size) {
690 c = str_next(&s);
691 if (c == '_') {
692 continue;
693 }
694 assert(c >= '0' && c <= '9');
695 exponent = exponent * 10 + (c - '0');
696 }
697 for (sz i = 0; i < exponent; i++) {
698 if (!exp_neg) {
699 num *= 10;
700 } else {
701 num /= 10;
702 }
703 }
614 } 704 }
615 return num; 705 return num;
616} 706}