From 3d1c4216ede8c628558c9fe700fb2be1aa08b473 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 2 Nov 2020 21:24:53 -0800 Subject: 7162 --- html/apps/arith.mu.html | 446 ++++++++++++++++++++++++------------------------ 1 file changed, 225 insertions(+), 221 deletions(-) (limited to 'html/apps/arith.mu.html') diff --git a/html/apps/arith.mu.html b/html/apps/arith.mu.html index 7350b6f2..6b94ab74 100644 --- a/html/apps/arith.mu.html +++ b/html/apps/arith.mu.html @@ -90,227 +90,231 @@ if ('onhashchange' in window) { 31 # 32 # Error handling is non-existent. This is just a prototype. 33 - 34 fn main -> exit-status/ebx: int { - 35 var look/esi: byte <- copy 0 # lookahead - 36 var n/eax: int <- copy 0 # result of each expression - 37 print-string 0, "press ctrl-c or ctrl-d to exit\n" - 38 # read-eval-print loop - 39 { - 40 # print prompt - 41 print-string 0, "> " - 42 # read and eval - 43 n, look <- simplify # we explicitly thread 'look' everywhere - 44 # if (look == 0) break - 45 compare look, 0 - 46 break-if-= - 47 # print - 48 print-int32-decimal 0, n - 49 print-string 0, "\n" - 50 # - 51 loop - 52 } - 53 exit-status <- copy 0 - 54 } - 55 - 56 fn simplify -> result/eax: int, look/esi: byte { - 57 # prime the pump - 58 look <- get-char - 59 # do it - 60 result, look <- expression look - 61 } - 62 - 63 fn expression _look: byte -> result/eax: int, look/esi: byte { - 64 look <- copy _look # should be a no-op - 65 # read arg - 66 result, look <- term look - 67 $expression:loop: { - 68 # while next non-space char in ['+', '-'] - 69 look <- skip-spaces look - 70 { - 71 var continue?/eax: boolean <- is-add-or-sub? look - 72 compare continue?, 0 # false - 73 break-if-= $expression:loop - 74 } - 75 # read operator - 76 var op/ecx: byte <- copy 0 - 77 op, look <- operator look - 78 # read next arg - 79 var second/edx: int <- copy 0 - 80 look <- skip-spaces look - 81 { - 82 var tmp/eax: int <- copy 0 - 83 tmp, look <- term look - 84 second <- copy tmp - 85 } - 86 # reduce - 87 $expression:perform-op: { - 88 { - 89 compare op, 0x2b # '+' - 90 break-if-!= - 91 result <- add second - 92 break $expression:perform-op - 93 } - 94 { - 95 compare op, 0x2d # '-' - 96 break-if-!= - 97 result <- subtract second - 98 break $expression:perform-op - 99 } -100 } -101 loop -102 } -103 look <- skip-spaces look -104 } -105 -106 fn term _look: byte -> result/eax: int, look/esi: byte { -107 look <- copy _look # should be a no-op -108 # read arg -109 look <- skip-spaces look -110 result, look <- factor look -111 $term:loop: { -112 # while next non-space char in ['*', '/'] -113 look <- skip-spaces look -114 { -115 var continue?/eax: boolean <- is-mul-or-div? look -116 compare continue?, 0 # false -117 break-if-= $term:loop -118 } -119 # read operator -120 var op/ecx: byte <- copy 0 -121 op, look <- operator look -122 # read next arg -123 var second/edx: int <- copy 0 -124 look <- skip-spaces look -125 { -126 var tmp/eax: int <- copy 0 -127 tmp, look <- factor look -128 second <- copy tmp -129 } -130 # reduce -131 $term:perform-op: { -132 { -133 compare op, 0x2a # '*' -134 break-if-!= -135 result <- multiply second -136 break $term:perform-op -137 } -138 #? { -139 #? compare op, 0x2f # '/' -140 #? break-if-!= -141 #? result <- divide second # not in Mu yet -142 #? break $term:perform-op -143 #? } -144 } -145 loop -146 } -147 } -148 -149 fn factor _look: byte -> result/eax: int, look/esi: byte { -150 $factor:body: { -151 look <- copy _look # should be a no-op -152 look <- skip-spaces look -153 # if next char is not '(', parse a number -154 compare look, 0x28 # '(' -155 { -156 break-if-= -157 result, look <- num look -158 break $factor:body -159 } -160 # otherwise recurse -161 look <- get-char # '(' -162 result, look <- expression look -163 look <- skip-spaces look -164 look <- get-char # ')' -165 } # $factor:body -166 } -167 -168 fn is-mul-or-div? c: byte -> result/eax: boolean { -169 $is-mul-or-div?:body: { -170 compare c, 0x2a # '*' -171 { -172 break-if-!= -173 result <- copy 1 # true -174 break $is-mul-or-div?:body -175 } -176 compare c, 0x2f # '/' -177 { -178 break-if-!= -179 result <- copy 1 # true -180 break $is-mul-or-div?:body -181 } -182 result <- copy 0 # false -183 } # $is-mul-or-div?:body -184 } -185 -186 fn is-add-or-sub? c: byte -> result/eax: boolean { -187 $is-add-or-sub?:body: { -188 compare c, 0x2b # '+' -189 { -190 break-if-!= -191 result <- copy 1 # true -192 break $is-add-or-sub?:body -193 } -194 compare c, 0x2d # '-' -195 { -196 break-if-!= -197 result <- copy 1 # true -198 break $is-add-or-sub?:body -199 } -200 result <- copy 0 # false -201 } # $is-add-or-sub?:body -202 } -203 -204 fn operator _look: byte -> op/ecx: byte, look/esi: byte { -205 op <- copy _look -206 look <- get-char -207 } -208 -209 fn num _look: byte -> result/eax: int, look/esi: byte { -210 look <- copy _look # should be a no-op -211 var out/edi: int <- copy 0 -212 { -213 var first-digit/eax: int <- to-decimal-digit look -214 out <- copy first-digit -215 } -216 { -217 look <- get-char -218 # done? -219 var digit?/eax: boolean <- is-decimal-digit? look -220 compare digit?, 0 # false -221 break-if-= -222 # out *= 10 -223 { -224 var ten/eax: int <- copy 0xa -225 out <- multiply ten -226 } -227 # out += digit(look) -228 var digit/eax: int <- to-decimal-digit look -229 out <- add digit -230 loop -231 } -232 result <- copy out -233 } -234 -235 fn skip-spaces _look: byte -> look/esi: byte { -236 look <- copy _look # should be a no-op -237 { -238 compare look, 0x20 -239 break-if-!= -240 look <- get-char -241 loop -242 } -243 } -244 -245 fn get-char -> look/esi: byte { -246 var tmp/eax: byte <- read-key-from-real-keyboard -247 look <- copy tmp -248 compare look, 0 -249 { -250 break-if-!= -251 print-string 0, "^D\n" -252 syscall_exit -253 } -254 } + 34 fn main -> _/ebx: int { + 35 enable-keyboard-immediate-mode + 36 var look/esi: grapheme <- copy 0 # lookahead + 37 var n/eax: int <- copy 0 # result of each expression + 38 print-string 0, "press ctrl-c or ctrl-d to exit\n" + 39 # read-eval-print loop + 40 { + 41 # print prompt + 42 print-string 0, "> " + 43 # read and eval + 44 n, look <- simplify # we explicitly thread 'look' everywhere + 45 # if (look == 0) break + 46 compare look, 0 + 47 break-if-= + 48 # print + 49 print-int32-decimal 0, n + 50 print-string 0, "\n" + 51 # + 52 loop + 53 } + 54 enable-keyboard-type-mode + 55 return 0 + 56 } + 57 + 58 fn simplify -> _/eax: int, _2/esi: grapheme { + 59 # prime the pump + 60 var look/esi: grapheme <- get-char + 61 # do it + 62 var result/eax: int <- copy 0 + 63 result, look <- expression look + 64 return result, look + 65 } + 66 + 67 fn expression _look: grapheme -> _/eax: int, _2/esi: grapheme { + 68 var look/esi: grapheme <- copy _look + 69 # read arg + 70 var result/eax: int <- copy 0 + 71 result, look <- term look + 72 $expression:loop: { + 73 # while next non-space char in ['+', '-'] + 74 look <- skip-spaces look + 75 { + 76 var continue?/eax: boolean <- is-add-or-sub? look + 77 compare continue?, 0 # false + 78 break-if-= $expression:loop + 79 } + 80 # read operator + 81 var op/ecx: byte <- copy 0 + 82 op, look <- operator look + 83 # read next arg + 84 var second/edx: int <- copy 0 + 85 look <- skip-spaces look + 86 { + 87 var tmp/eax: int <- copy 0 + 88 tmp, look <- term look + 89 second <- copy tmp + 90 } + 91 # reduce + 92 $expression:perform-op: { + 93 { + 94 compare op, 0x2b # '+' + 95 break-if-!= + 96 result <- add second + 97 break $expression:perform-op + 98 } + 99 { +100 compare op, 0x2d # '-' +101 break-if-!= +102 result <- subtract second +103 break $expression:perform-op +104 } +105 } +106 loop +107 } +108 look <- skip-spaces look +109 return result, look +110 } +111 +112 fn term _look: grapheme -> _/eax: int, _2/esi: grapheme { +113 var look/esi: grapheme <- copy _look +114 # read arg +115 look <- skip-spaces look +116 var result/eax: int <- copy 0 +117 result, look <- factor look +118 $term:loop: { +119 # while next non-space char in ['*', '/'] +120 look <- skip-spaces look +121 { +122 var continue?/eax: boolean <- is-mul-or-div? look +123 compare continue?, 0 # false +124 break-if-= $term:loop +125 } +126 # read operator +127 var op/ecx: byte <- copy 0 +128 op, look <- operator look +129 # read next arg +130 var second/edx: int <- copy 0 +131 look <- skip-spaces look +132 { +133 var tmp/eax: int <- copy 0 +134 tmp, look <- factor look +135 second <- copy tmp +136 } +137 # reduce +138 $term:perform-op: { +139 { +140 compare op, 0x2a # '*' +141 break-if-!= +142 result <- multiply second +143 break $term:perform-op +144 } +145 #? { +146 #? compare op, 0x2f # '/' +147 #? break-if-!= +148 #? result <- divide second # not in Mu yet +149 #? break $term:perform-op +150 #? } +151 } +152 loop +153 } +154 return result, look +155 } +156 +157 fn factor _look: grapheme -> _/eax: int, _2/esi: grapheme { +158 var look/esi: grapheme <- copy _look # should be a no-op +159 look <- skip-spaces look +160 # if next char is not '(', parse a number +161 compare look, 0x28 # '(' +162 { +163 break-if-= +164 var result/eax: int <- copy 0 +165 result, look <- num look +166 return result, look +167 } +168 # otherwise recurse +169 look <- get-char # '(' +170 var result/eax: int <- copy 0 +171 result, look <- expression look +172 look <- skip-spaces look +173 look <- get-char # ')' +174 return result, look +175 } +176 +177 fn is-mul-or-div? c: grapheme -> _/eax: boolean { +178 compare c, 0x2a # '*' +179 { +180 break-if-!= +181 return 1 # true +182 } +183 compare c, 0x2f # '/' +184 { +185 break-if-!= +186 return 1 # true +187 } +188 return 0 # false +189 } +190 +191 fn is-add-or-sub? c: grapheme -> _/eax: boolean { +192 compare c, 0x2b # '+' +193 { +194 break-if-!= +195 return 1 # true +196 } +197 compare c, 0x2d # '-' +198 { +199 break-if-!= +200 return 1 # true +201 } +202 return 0 # false +203 } +204 +205 fn operator _look: grapheme -> _/ecx: byte, _2/esi: grapheme { +206 var op/ecx: byte <- copy _look +207 var look/esi: grapheme <- get-char +208 return op, look +209 } +210 +211 fn num _look: grapheme -> _/eax: int, _2/esi: grapheme { +212 var look/esi: grapheme <- copy _look +213 var result/edi: int <- copy 0 +214 { +215 var first-digit/eax: int <- to-decimal-digit look +216 result <- copy first-digit +217 } +218 { +219 look <- get-char +220 # done? +221 var digit?/eax: boolean <- is-decimal-digit? look +222 compare digit?, 0 # false +223 break-if-= +224 # result *= 10 +225 { +226 var ten/eax: int <- copy 0xa +227 result <- multiply ten +228 } +229 # result += digit(look) +230 var digit/eax: int <- to-decimal-digit look +231 result <- add digit +232 loop +233 } +234 return result, look +235 } +236 +237 fn skip-spaces _look: grapheme -> _/esi: grapheme { +238 var look/esi: grapheme <- copy _look # should be a no-op +239 { +240 compare look, 0x20 +241 break-if-!= +242 look <- get-char +243 loop +244 } +245 return look +246 } +247 +248 fn get-char -> _/esi: grapheme { +249 var look/eax: grapheme <- read-key-from-real-keyboard +250 print-grapheme-to-real-screen look +251 compare look, 4 +252 { +253 break-if-!= +254 print-string 0, "^D\n" +255 syscall_exit +256 } +257 return look +258 } -- cgit 1.4.1-2-gfad0