diff options
| author | Josh Wolfe <thejoshwolfe@gmail.com> | 2015-12-15 14:54:16 -0700 |
|---|---|---|
| committer | Josh Wolfe <thejoshwolfe@gmail.com> | 2015-12-15 14:54:16 -0700 |
| commit | 8a570c458bcf62bc3d882f8d253f75ec6d3fd719 (patch) | |
| tree | 2689c80e82a1a0a197af405a51fcd8f9c35296fb | |
| parent | 43099932d55c7fa6279cba61eeba91c89a9cb1a0 (diff) | |
| download | zig-8a570c458bcf62bc3d882f8d253f75ec6d3fd719.tar.gz zig-8a570c458bcf62bc3d882f8d253f75ec6d3fd719.zip | |
base 10 decimals work now. closes #15
| -rw-r--r-- | src/parser.cpp | 25 | ||||
| -rw-r--r-- | test/run_tests.cpp | 21 |
2 files changed, 44 insertions, 2 deletions
diff --git a/src/parser.cpp b/src/parser.cpp index ab4c1d9a8a..8e87552588 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -12,7 +12,7 @@ #include <stdarg.h> #include <stdio.h> #include <limits.h> - +#include <errno.h> static const char *bin_op_str(BinOpType bin_op) { switch (bin_op) { @@ -622,6 +622,7 @@ static void parse_number_literal(ParseContext *pc, Token *token, AstNodeNumberLi int whole_number_end = token->decimal_point_pos; if (whole_number_end <= whole_number_start) { // TODO: error for empty whole number part + num_lit->overflow = true; return; } @@ -644,12 +645,31 @@ static void parse_number_literal(ParseContext *pc, Token *token, AstNodeNumberLi } } else { // float + + if (token->radix == 10) { + // use a third-party base-10 float parser + char *str_begin = buf_ptr(pc->buf) + whole_number_start; + char *str_end; + errno = 0; + double x = strtod(str_begin, &str_end); + if (errno) { + // TODO: forward error to user + num_lit->overflow = true; + return; + } + assert(str_end == buf_ptr(pc->buf) + token->end_pos); + num_lit->data.x_float = x; + num_lit->kind = NumLitF64; + return; + } + if (token->decimal_point_pos < token->exponent_marker_pos) { // fraction int fraction_start = token->decimal_point_pos + 1; int fraction_end = token->exponent_marker_pos; if (fraction_end <= fraction_start) { // TODO: error for empty fraction part + num_lit->overflow = true; return; } } @@ -698,6 +718,7 @@ static void parse_number_literal(ParseContext *pc, Token *token, AstNodeNumberLi int exponent_end = token->end_pos; if (exponent_end <= exponent_start) { // TODO: error for empty exponent part + num_lit->overflow = true; return; } bool is_exponent_negative = false; @@ -711,6 +732,7 @@ static void parse_number_literal(ParseContext *pc, Token *token, AstNodeNumberLi if (exponent_end <= exponent_start) { // TODO: error for empty exponent part + num_lit->overflow = true; return; } @@ -754,7 +776,6 @@ static void parse_number_literal(ParseContext *pc, Token *token, AstNodeNumberLi } uint64_t double_bits = (exponent_bits << 52) | significand_bits; - // TODO: check and swap endian double x = *(double *)&double_bits; num_lit->data.x_float = x; diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 0ca3d77aca..f6d4274bda 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -474,6 +474,20 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { 0.000000000000000000000000000000000000000000000000000000000e0 as f64); printf(c"0.0e000000000000000000000000000000000000000000000000000000000: %a\n", 0.0e000000000000000000000000000000000000000000000000000000000 as f64); + printf(c"1.0: %a\n", + 1.0 as f64); + printf(c"10.0: %a\n", + 10.0 as f64); + printf(c"10.5: %a\n", + 10.5 as f64); + printf(c"10.5e5: %a\n", + 10.5e5 as f64); + printf(c"10.5e+5: %a\n", + 10.5e+5 as f64); + printf(c"50.0e-2: %a\n", + 50.0e-2 as f64); + printf(c"50e-2: %a\n", + 50e-2 as f64); printf(c"\n"); @@ -524,6 +538,13 @@ export fn main(argc : isize, argv : &&u8, env : &&u8) -> i32 { 000000000000000000000000000000000000000000000000000000000.0e0: 0x0p+0 0.000000000000000000000000000000000000000000000000000000000e0: 0x0p+0 0.0e000000000000000000000000000000000000000000000000000000000: 0x0p+0 +1.0: 0x1p+0 +10.0: 0x1.4p+3 +10.5: 0x1.5p+3 +10.5e5: 0x1.0059p+20 +10.5e+5: 0x1.0059p+20 +50.0e-2: 0x1p-1 +50e-2: 0x1p-1 0x1.0: 0x1p+0 0x10.0: 0x1p+4 |
