| ... | ... | @@ -12,7 +12,7 @@ |
| 12 | 12 | #include <stdarg.h> |
| 13 | 13 | #include <stdio.h> |
| 14 | 14 | #include <limits.h> |
| 15 | | |
| 15 | #include <errno.h> |
| 16 | 16 | |
| 17 | 17 | static const char *bin_op_str(BinOpType bin_op) { |
| 18 | 18 | switch (bin_op) { |
| ... | ... | @@ -622,6 +622,7 @@ static void parse_number_literal(ParseContext *pc, Token *token, AstNodeNumberLi |
| 622 | 622 | int whole_number_end = token->decimal_point_pos; |
| 623 | 623 | if (whole_number_end <= whole_number_start) { |
| 624 | 624 | // TODO: error for empty whole number part |
| 625 | num_lit->overflow = true; |
| 625 | 626 | return; |
| 626 | 627 | } |
| 627 | 628 | |
| ... | ... | @@ -644,12 +645,31 @@ static void parse_number_literal(ParseContext *pc, Token *token, AstNodeNumberLi |
| 644 | 645 | } |
| 645 | 646 | } else { |
| 646 | 647 | // float |
| 648 | |
| 649 | if (token->radix == 10) { |
| 650 | // use a third-party base-10 float parser |
| 651 | char *str_begin = buf_ptr(pc->buf) + whole_number_start; |
| 652 | char *str_end; |
| 653 | errno = 0; |
| 654 | double x = strtod(str_begin, &str_end); |
| 655 | if (errno) { |
| 656 | // TODO: forward error to user |
| 657 | num_lit->overflow = true; |
| 658 | return; |
| 659 | } |
| 660 | assert(str_end == buf_ptr(pc->buf) + token->end_pos); |
| 661 | num_lit->data.x_float = x; |
| 662 | num_lit->kind = NumLitF64; |
| 663 | return; |
| 664 | } |
| 665 | |
| 647 | 666 | if (token->decimal_point_pos < token->exponent_marker_pos) { |
| 648 | 667 | // fraction |
| 649 | 668 | int fraction_start = token->decimal_point_pos + 1; |
| 650 | 669 | int fraction_end = token->exponent_marker_pos; |
| 651 | 670 | if (fraction_end <= fraction_start) { |
| 652 | 671 | // TODO: error for empty fraction part |
| 672 | num_lit->overflow = true; |
| 653 | 673 | return; |
| 654 | 674 | } |
| 655 | 675 | } |
| ... | ... | @@ -698,6 +718,7 @@ static void parse_number_literal(ParseContext *pc, Token *token, AstNodeNumberLi |
| 698 | 718 | int exponent_end = token->end_pos; |
| 699 | 719 | if (exponent_end <= exponent_start) { |
| 700 | 720 | // TODO: error for empty exponent part |
| 721 | num_lit->overflow = true; |
| 701 | 722 | return; |
| 702 | 723 | } |
| 703 | 724 | bool is_exponent_negative = false; |
| ... | ... | @@ -711,6 +732,7 @@ static void parse_number_literal(ParseContext *pc, Token *token, AstNodeNumberLi |
| 711 | 732 | |
| 712 | 733 | if (exponent_end <= exponent_start) { |
| 713 | 734 | // TODO: error for empty exponent part |
| 735 | num_lit->overflow = true; |
| 714 | 736 | return; |
| 715 | 737 | } |
| 716 | 738 | |
| ... | ... | @@ -754,7 +776,6 @@ static void parse_number_literal(ParseContext *pc, Token *token, AstNodeNumberLi |
| 754 | 776 | } |
| 755 | 777 | |
| 756 | 778 | uint64_t double_bits = (exponent_bits << 52) | significand_bits; |
| 757 | | // TODO: check and swap endian |
| 758 | 779 | double x = *(double *)&double_bits; |
| 759 | 780 | |
| 760 | 781 | num_lit->data.x_float = x; |