diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2021-10-20 11:51:24 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2021-10-20 12:01:55 -0700 |
commit | 619dc31dfc565a2f8d76b6ab701b64394506f5ae (patch) | |
tree | e6fa4595c885f1582cdf7b6e89e5439aecdd0f68 /tutorial/converter.mu | |
parent | 909a0e2530142ea5bf506d66111a6ff75bf645e9 (diff) | |
download | mu-619dc31dfc565a2f8d76b6ab701b64394506f5ae.tar.gz |
sketching out a slow tutorial
Diffstat (limited to 'tutorial/converter.mu')
-rw-r--r-- | tutorial/converter.mu | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/tutorial/converter.mu b/tutorial/converter.mu new file mode 100644 index 00000000..a8aa26e3 --- /dev/null +++ b/tutorial/converter.mu @@ -0,0 +1,138 @@ +# Temperature Converter app +# https://eugenkiss.github.io/7guis/tasks/#temp +# +# To build: +# $ ./translate converter.mu +# To run: +# $ qemu-system-i386 code.img + +# todo: +# less duplication +# error checking for input without hard-aborting + +fn main screen: (addr screen), keyboard: (addr keyboard), data-disk: (addr disk) { + # celsius numeric representation + var zero: float + var celsius/xmm1: float <- fahrenheit-to-celsius zero + # celsius string representation + var s-storage: (stream byte 0x10) + var s/ecx: (addr stream byte) <- address s-storage + write-float-decimal-approximate s, celsius, 2/decimal-places + # celsius input/display + var celsius-input-storage: gap-buffer + var celsius-input/esi: (addr gap-buffer) <- address celsius-input-storage + initialize-gap-buffer celsius-input, 8/capacity + load-gap-buffer-from-stream celsius-input, s + var cursor-in-celsius?/edx: boolean <- copy 0xffffffff/true + # fahrenheit numeric representation + var fahrenheit/xmm2: float <- celsius-to-fahrenheit celsius + # fahrenheit string representation + clear-stream s + write-float-decimal-approximate s, fahrenheit, 2/decimal-places + # fahrenheit input/display + var fahrenheit-input-storage: gap-buffer + var fahrenheit-input/edi: (addr gap-buffer) <- address fahrenheit-input-storage + initialize-gap-buffer fahrenheit-input, 8/capacity + load-gap-buffer-from-stream fahrenheit-input, s + var cursor-in-fahrenheit?/ebx: boolean <- copy 0/false # exactly one cursor boolean must be true at any time + # widget title + set-cursor-position screen, 0x1f/x 0xe/y + draw-text-rightward-from-cursor-over-full-screen screen, " Converter ", 0xf/fg 0x16/bg + # event loop + { + # draw current state to screen + clear-rect screen, 0x1f/xmin 0xf/ymin, 0x45/xmax 0x14/ymax, 0xc5/color + var x/eax: int <- render-gap-buffer screen, celsius-input, 0x20/x 0x10/y, cursor-in-celsius?, 7/fg 0/bg + x <- draw-text-rightward screen, " celsius = ", x, 0x45/xmax, 0x10/y, 7/fg 0xc5/bg + x <- render-gap-buffer screen, fahrenheit-input, x 0x10/y, cursor-in-fahrenheit?, 7/fg 0/bg + x <- draw-text-rightward screen, " fahrenheit", x, 0x45/xmax, 0x10/y, 7/fg 0xc5/bg + # render a menu bar + set-cursor-position screen, 0x21/x 0x12/y + draw-text-rightward-from-cursor-over-full-screen screen, " tab ", 0/fg 0x5c/bg=highlight + draw-text-rightward-from-cursor-over-full-screen screen, " switch sides ", 7/fg 0xc5/bg + draw-text-rightward-from-cursor-over-full-screen screen, " enter ", 0/fg 0x5c/bg=highlight + draw-text-rightward-from-cursor-over-full-screen screen, " convert ", 7/fg 0xc5/bg + # process a single keystroke + $main:input: { + var key/eax: byte <- read-key keyboard + var key/eax: grapheme <- copy key + compare key, 0 + loop-if-= + # tab = switch cursor between input areas + compare key, 9/tab + { + break-if-!= + cursor-in-celsius? <- not + cursor-in-fahrenheit? <- not + break $main:input + } + # enter = convert in appropriate direction + compare key, 0xa/newline + { + break-if-!= + { + compare cursor-in-celsius?, 0/false + break-if-= + clear-stream s + emit-gap-buffer celsius-input, s + celsius <- parse-float-decimal s + fahrenheit <- celsius-to-fahrenheit celsius + clear-stream s + write-float-decimal-approximate s, fahrenheit, 2/decimal-places + clear-gap-buffer fahrenheit-input + load-gap-buffer-from-stream fahrenheit-input, s + } + { + compare cursor-in-fahrenheit?, 0/false + break-if-= + clear-stream s + emit-gap-buffer fahrenheit-input, s + { + var tmp/xmm1: float <- parse-float-decimal s + fahrenheit <- copy tmp + } + celsius <- fahrenheit-to-celsius fahrenheit + clear-stream s + write-float-decimal-approximate s, celsius, 2/decimal-places + clear-gap-buffer celsius-input + load-gap-buffer-from-stream celsius-input, s + } + break $main:input + } + # otherwise pass key to appropriate input area + compare cursor-in-celsius?, 0/false + { + break-if-= + edit-gap-buffer celsius-input, key + break $main:input + } + compare cursor-in-fahrenheit?, 0/false + { + break-if-= + edit-gap-buffer fahrenheit-input, key + break $main:input + } + } + loop + } +} + +fn fahrenheit-to-celsius f: float -> _/xmm1: float { + var result/xmm1: float <- copy f + var thirty-two/eax: int <- copy 0x20 + var thirty-two-f/xmm0: float <- convert thirty-two + result <- subtract thirty-two-f + var factor/xmm0: float <- rational 5, 9 + result <- multiply factor + return result +} + +fn celsius-to-fahrenheit c: float -> _/xmm2: float { + var result/xmm1: float <- copy c + var factor/xmm0: float <- rational 9, 5 + result <- multiply factor + var thirty-two/eax: int <- copy 0x20 + var thirty-two-f/xmm0: float <- convert thirty-two + result <- add thirty-two-f + return result +} |