summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-01-12 15:34:00 -0500
committerpommicket <pommicket@gmail.com>2022-01-12 15:34:00 -0500
commitee3c461e6e797e0442b8841aaa6780a76994238e (patch)
treeebf7a3f662ab3ce12bb6f3df9a6130be6f4a106d
parentf17720731d616c8b603ef4e853c69a2979f73604 (diff)
more complicated floats working so far
-rw-r--r--05/main.c2
-rw-r--r--05/tokenize.b51
2 files changed, 47 insertions, 6 deletions
diff --git a/05/main.c b/05/main.c
index 9509bd2..147bc0d 100644
--- a/05/main.c
+++ b/05/main.c
@@ -2,4 +2,4 @@
char * = "How are you"" d""o""i""ng today?\n";
hi
_TEST _ING _1
-1.00001
+50.1e100
diff --git a/05/tokenize.b b/05/tokenize.b
index ff70ca3..4868445 100644
--- a/05/tokenize.b
+++ b/05/tokenize.b
@@ -267,6 +267,7 @@ function tokenize
data = n
goto token_output
:tokenize_float
+ ; @NONSTANDARD: this doesn't allow for floats whose integral part is >=2^64, e.g. 1000000000000000000000000.0
significand = 0
exponent = 0
pow10 = 0
@@ -312,16 +313,19 @@ function tokenize
significand = right_shift(significand, n)
exponent = new_exponent
significand += right_shift(integer, exponent)
- if *1in != 'e goto float_no_exponent
+ :float_no_integer
+ if *1in == 'e goto float_exponent
+ if *1in == 'E goto float_exponent
- :float_no_exponent
+ :float_have_significand_and_exponent
if significand == 0 goto float_zero
normalize_float(&significand, &exponent)
putn(significand)
putc(32)
putn_signed(exponent)
putc(10)
- ; reduce to 53-bit significant (top bit is removed to get 52)
+ significand += 15 ; ensure number rounds to the nearest representable float (this is what gcc does)
+ ; reduce to 53-bit significand (top bit is removed to get 52)
significand >= 5
exponent += 5
exponent += 52 ; 1001010111... => 1.001010111...
@@ -333,15 +337,52 @@ function tokenize
data |= exponent < 52
+ :float_have_data
*1out = TOKEN_CONSTANT_FLOAT
out += 1
; suffix
*1out = read_number_suffix(file, line_number, &in)
out += 1
goto token_output
- :float_no_integer
- byte 0xcc
+ :float_exponent
+ in += 1
+ if *1in == '+ goto float_exponent_plus
+ if *1in == '- goto float_exponent_minus
+ ; e.g. 1e100
+ pow10 = strtoi(&in, 10)
+ :float_have_exponent
+ p = powers_of_10
+ p += pow10 < 4
+ full_multiply_signed(significand, *8p, &lower, &upper)
+ if upper == 0 goto fmultiply2_no_upper
+ n = leftmost_1bit(upper)
+ n += 1
+ significand = lower > n
+ exponent += n
+ n = 64 - n
+ significand |= upper < n
+ goto fmultiply2_cont
+ :fmultiply2_no_upper
+ significand = lower
+ goto fmultiply2_cont
+ :fmultiply2_cont
+ p += 8
+ exponent += *8p
+ goto float_have_significand_and_exponent
+ :float_exponent_plus
+ ; e.g. 1e+100
+ in += 1
+ pow10 = strtoi(&in, 10)
+ goto float_have_exponent
+ :float_exponent_minus
+ ; e.g. 1e-100
+ in += 1
+ pow10 = strtoi(&in, 10)
+ pow10 = 0 - pow10
+ goto float_have_exponent
:float_zero
+ data = 0
+ goto float_have_data
:tokenize_loop_end
return 0