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