diff options
Diffstat (limited to 'src/badlib.h')
-rw-r--r-- | src/badlib.h | 90 |
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 | |||
637 | f64 | ||
638 | str_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 | } |