authorgravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2015-12-15 14:54:16-07:00
committergravatar for thejoshwolfe@gmail.comJosh Wolfe <thejoshwolfe@gmail.com> 2015-12-15 14:54:16-07:00
log8a570c458bcf62bc3d882f8d253f75ec6d3fd719
tree2689c80e82a1a0a197af405a51fcd8f9c35296fb
parent43099932d55c7fa6279cba61eeba91c89a9cb1a0

base 10 decimals work now. closes #15


2 files changed, 44 insertions(+), 2 deletions(-)

src/parser.cpp+23-2
...@@ -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>
1515#include <errno.h>
1616
17static const char *bin_op_str(BinOpType bin_op) {17static 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 part624 // TODO: error for empty whole number part
625 num_lit->overflow = true;
625 return;626 return;
626 }627 }
627628
...@@ -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 // float647 // 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 // fraction667 // 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 part671 // 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 part720 // 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
711732
712 if (exponent_end <= exponent_start) {733 if (exponent_end <= exponent_start) {
713 // TODO: error for empty exponent part734 // TODO: error for empty exponent part
735 num_lit->overflow = true;
714 return;736 return;
715 }737 }
716738
...@@ -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 }
755777
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;
759780
760 num_lit->data.x_float = x;781 num_lit->data.x_float = x;
test/run_tests.cpp+21
...@@ -474,6 +474,20 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {...@@ -474,6 +474,20 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
474 0.000000000000000000000000000000000000000000000000000000000e0 as f64);474 0.000000000000000000000000000000000000000000000000000000000e0 as f64);
475 printf(c"0.0e000000000000000000000000000000000000000000000000000000000: %a\n",475 printf(c"0.0e000000000000000000000000000000000000000000000000000000000: %a\n",
476 0.0e000000000000000000000000000000000000000000000000000000000 as f64);476 0.0e000000000000000000000000000000000000000000000000000000000 as f64);
477 printf(c"1.0: %a\n",
478 1.0 as f64);
479 printf(c"10.0: %a\n",
480 10.0 as f64);
481 printf(c"10.5: %a\n",
482 10.5 as f64);
483 printf(c"10.5e5: %a\n",
484 10.5e5 as f64);
485 printf(c"10.5e+5: %a\n",
486 10.5e+5 as f64);
487 printf(c"50.0e-2: %a\n",
488 50.0e-2 as f64);
489 printf(c"50e-2: %a\n",
490 50e-2 as f64);
477491
478 printf(c"\n");492 printf(c"\n");
479493
...@@ -524,6 +538,13 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {...@@ -524,6 +538,13 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 {
524000000000000000000000000000000000000000000000000000000000.0e0: 0x0p+0538000000000000000000000000000000000000000000000000000000000.0e0: 0x0p+0
5250.000000000000000000000000000000000000000000000000000000000e0: 0x0p+05390.000000000000000000000000000000000000000000000000000000000e0: 0x0p+0
5260.0e000000000000000000000000000000000000000000000000000000000: 0x0p+05400.0e000000000000000000000000000000000000000000000000000000000: 0x0p+0
5411.0: 0x1p+0
54210.0: 0x1.4p+3
54310.5: 0x1.5p+3
54410.5e5: 0x1.0059p+20
54510.5e+5: 0x1.0059p+20
54650.0e-2: 0x1p-1
54750e-2: 0x1p-1
527548
5280x1.0: 0x1p+05490x1.0: 0x1p+0
5290x10.0: 0x1p+45500x10.0: 0x1p+4