Commit 8a570c458b

Josh Wolfe <thejoshwolfe@gmail.com>
2015-12-15 22:54:16
base 10 decimals work now. closes #15
1 parent 4309993
Changed files (2)
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;
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