diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2021-10-12 22:31:57 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2021-10-12 22:31:57 -0700 |
commit | d280bd8dac5555a6dd8fdc34b8e423f120f05887 (patch) | |
tree | fe8be37328a65e7ec3f503cce790b033baed6b51 | |
parent | 72d104d1693ee7671ef5a956d0ae93540a792da7 (diff) | |
download | mu-d280bd8dac5555a6dd8fdc34b8e423f120f05887.tar.gz |
parse float from text
-rw-r--r-- | 515parse-float.mu | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/515parse-float.mu b/515parse-float.mu new file mode 100644 index 00000000..40bbb194 --- /dev/null +++ b/515parse-float.mu @@ -0,0 +1,170 @@ +# no support for scientific notation yet +fn parse-float-decimal in: (addr stream byte) -> _/xmm1: float { + var zero: float + var result/xmm1: float <- copy zero + var first-iter?/ecx: int <- copy 1/true + rewind-stream in + var negative?/edx: int <- copy 0/false + # first loop: integer part + var ten/eax: int <- copy 0xa + var ten-f/xmm2: float <- convert ten + { + var done?/eax: boolean <- stream-empty? in + compare done?, 0/false + break-if-!= + var key/eax: byte <- read-byte in + compare key, 0x2e/decimal-point + break-if-= + $parse-float-decimal:body: { + compare key, 0x2d/- + { + break-if-!= + compare first-iter?, 0/false + { + break-if-!= + abort "parse-float-decimal: '-' only allowed in first position" + } + negative? <- copy 1/true + break $parse-float-decimal:body + } + compare key, 0x30/0 + { + break-if->= + abort "parse-float-decimal: invalid character < '0'" + } + compare key, 0x39/9 + { + break-if-<= + abort "parse-float-decimal: invalid character > '9'" + } + # key is now a digit + var digit-value/eax: int <- copy key + digit-value <- subtract 0x30 + var digit-value-f/xmm3: float <- convert digit-value + result <- multiply ten-f + result <- add digit-value-f + } + first-iter? <- copy 0/false + loop + } + # second loop: fraction + var current-position/xmm0: float <- rational 1, 0xa + { + var done?/eax: boolean <- stream-empty? in + compare done?, 0/false + break-if-!= + var key/eax: byte <- read-byte in + compare key, 0x30/0 + { + break-if->= + abort "parse-float-decimal: invalid fraction character < '0'" + } + compare key, 0x39/9 + { + break-if-<= + abort "parse-float-decimal: invalid fraction character > '9'" + } + # key is now a digit + var digit-value/eax: int <- copy key + digit-value <- subtract 0x30 + var digit-value-f/xmm3: float <- convert digit-value + digit-value-f <- multiply current-position + result <- add digit-value-f + current-position <- divide ten-f + # + first-iter? <- copy 0/false + loop + } + # finally, the sign + compare negative?, 0/false + { + break-if-= + var minus-one/eax: int <- copy -1 + var minus-one-f/xmm2: float <- convert minus-one + result <- multiply minus-one-f + } + return result +} + +fn test-parse-float-decimal-zero { + var s-storage: (stream byte 0x10) + var s/esi: (addr stream byte) <- address s-storage + write s, "00" + var x/xmm1: float <- parse-float-decimal s + var expected/eax: int <- copy 0 + var expected-f/xmm0: float <- convert expected + compare x, expected-f + { + break-if-= + draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-zero", 3/fg 0/bg + move-cursor-to-left-margin-of-next-line 0/screen + count-test-failure + } + draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg +} + +fn test-parse-float-decimal-integer { + var s-storage: (stream byte 0x10) + var s/esi: (addr stream byte) <- address s-storage + write s, "34" + var x/xmm1: float <- parse-float-decimal s + var expected/eax: int <- copy 0x22/34 + var expected-f/xmm0: float <- convert expected + compare x, expected-f + { + break-if-= + draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-integer", 3/fg 0/bg + move-cursor-to-left-margin-of-next-line 0/screen + count-test-failure + } + draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg +} + +fn test-parse-float-decimal-negative-integer { + var s-storage: (stream byte 0x10) + var s/esi: (addr stream byte) <- address s-storage + write s, "-34" + var x/xmm1: float <- parse-float-decimal s + var expected/eax: int <- copy -0x22/-34 + var expected-f/xmm0: float <- convert expected + compare x, expected-f + { + break-if-= + draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-negative-integer", 3/fg 0/bg + move-cursor-to-left-margin-of-next-line 0/screen + count-test-failure + } + draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg +} + +fn test-parse-float-decimal-fraction { + var s-storage: (stream byte 0x10) + var s/esi: (addr stream byte) <- address s-storage + write s, "3.4" + var x/xmm1: float <- parse-float-decimal s + var expected-f/xmm0: float <- rational 0x22/34, 0xa/10 + compare x, expected-f + { + break-if-= + draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-fraction", 3/fg 0/bg + move-cursor-to-left-margin-of-next-line 0/screen + count-test-failure + } + draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg +} + +fn test-parse-float-decimal-negative-fraction { + var s-storage: (stream byte 0x10) + var s/esi: (addr stream byte) <- address s-storage + write s, "-3.4" + var x/xmm1: float <- parse-float-decimal s + var expected-f/xmm0: float <- rational -0x22/-34, 0xa/10 + compare x, expected-f + { + break-if-= + draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, "F - test-parse-float-decimal-negative-fraction", 3/fg 0/bg + move-cursor-to-left-margin-of-next-line 0/screen + count-test-failure + } + draw-text-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, ".", 3/fg=cyan, 0/bg +} |