From d3a9db3aff54ea485f409eaaef3d8f56ad77f0dc Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Mon, 5 Oct 2020 11:00:05 -0700 Subject: 6958 --- html/apps/arith.mu.html | 513 ++++++++++++++++++++++++------------------------ 1 file changed, 256 insertions(+), 257 deletions(-) (limited to 'html/apps/arith.mu.html') diff --git a/html/apps/arith.mu.html b/html/apps/arith.mu.html index 80cd7ae6..7350b6f2 100644 --- a/html/apps/arith.mu.html +++ b/html/apps/arith.mu.html @@ -15,11 +15,11 @@ body { font-size:12pt; font-family: monospace; color: #000000; background-color: a { color:inherit; } * { font-size:12pt; font-size: 1em; } .CommentedCode { color: #8a8a8a; } +.muComment { color: #005faf; } .LineNr { } -.muFunction { color: #af5f00; text-decoration: underline; } .SpecialChar { color: #d70000; } -.Comment { color: #005faf; } .Constant { color: #008787; } +.muFunction { color: #af5f00; text-decoration: underline; } .Delimiter { color: #c000c0; } .PreProc { color: #c000c0; } --> @@ -57,261 +57,260 @@ if ('onhashchange' in window) { https://github.com/akkartik/mu/blob/master/apps/arith.mu
-  1 # Integer arithmetic using conventional precedence.
-  2 #
-  3 # Follows part 2 of Jack Crenshaw's "Let's build a compiler!"
-  4 #   https://compilers.iecc.com/crenshaw
-  5 #
-  6 # Limitations:
-  7 #   Reads numbers in decimal, but prints numbers in hex :(
-  8 #   No division yet.
-  9 #
- 10 # To build:
- 11 #   $ ./translate_mu apps/arith.mu
- 12 #
- 13 # Example session:
- 14 #   $ ./a.elf
- 15 #   press ctrl-c or ctrl-d to exit
- 16 #   > 1
- 17 #   0x00000001
- 18 #   > 1+1
- 19 #   0x00000002
- 20 #   > 1 + 1
- 21 #   0x00000002
- 22 #   > 1+2 +3
- 23 #   0x00000006
- 24 #   > 1+2 *3
- 25 #   0x00000007
- 26 #   > (1+2) *3
- 27 #   0x00000009
- 28 #   > 1 + 3*4
- 29 #   0x0000000d
- 30 #   > ^D
- 31 #   $
- 32 #
- 33 # Error handling is non-existent. This is just a prototype.
- 34 
- 35 fn main -> exit-status/ebx: int {
- 36   var look/esi: byte <- 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-hex 0, n
- 50     print-string 0, "\n"
- 51     #
- 52     loop
- 53   }
- 54   exit-status <- copy 0
- 55 }
- 56 
- 57 fn simplify -> result/eax: int, look/esi: byte {
- 58   # prime the pump
- 59   look <- get-char
- 60   # do it
- 61   result, look <- expression look
- 62 }
- 63 
- 64 fn expression _look: byte -> result/eax: int, look/esi: byte {
- 65   look <- copy _look  # should be a no-op
- 66   # read arg
- 67   result, look <- term look
- 68   $expression:loop: {
- 69     # while next non-space char in ['+', '-']
- 70     look <- skip-spaces look
- 71     {
- 72       var continue?/eax: boolean <- is-add-or-sub? look
- 73       compare continue?, 0  # false
- 74       break-if-= $expression:loop
- 75     }
- 76     # read operator
- 77     var op/ecx: byte <- copy 0
- 78     op, look <- operator look
- 79     # read next arg
- 80     var second/edx: int <- copy 0
- 81     look <- skip-spaces look
- 82     {
- 83       var tmp/eax: int <- copy 0
- 84       tmp, look <- term look
- 85       second <- copy tmp
- 86     }
- 87     # reduce
- 88     $expression:perform-op: {
- 89       {
- 90         compare op, 0x2b  # '+'
- 91         break-if-!=
- 92         result <- add second
- 93         break $expression:perform-op
- 94       }
- 95       {
- 96         compare op, 0x2d  # '-'
- 97         break-if-!=
- 98         result <- subtract second
- 99         break $expression:perform-op
-100       }
-101     }
-102     loop
-103   }
-104   look <- skip-spaces look
-105 }
-106 
-107 fn term _look: byte -> result/eax: int, look/esi: byte {
-108   look <- copy _look  # should be a no-op
-109   # read arg
-110   look <- skip-spaces look
-111   result, look <- factor look
-112   $term:loop: {
-113     # while next non-space char in ['*', '/']
-114     look <- skip-spaces look
-115     {
-116       var continue?/eax: boolean <- is-mul-or-div? look
-117       compare continue?, 0  # false
-118       break-if-= $term:loop
-119     }
-120     # read operator
-121     var op/ecx: byte <- copy 0
-122     op, look <- operator look
-123     # read next arg
-124     var second/edx: int <- copy 0
-125     look <- skip-spaces look
-126     {
-127       var tmp/eax: int <- copy 0
-128       tmp, look <- factor look
-129       second <- copy tmp
-130     }
-131     # reduce
-132     $term:perform-op: {
-133       {
-134         compare op, 0x2a  # '*'
-135         break-if-!=
-136         result <- multiply second
-137         break $term:perform-op
-138       }
-139 #?       {
-140 #?         compare op, 0x2f  # '/'
-141 #?         break-if-!=
-142 #?         result <- divide second  # not in Mu yet
-143 #?         break $term:perform-op
-144 #?       }
-145     }
-146     loop
-147   }
-148 }
-149 
-150 fn factor _look: byte -> result/eax: int, look/esi: byte {
-151 $factor:body: {
-152   look <- copy _look  # should be a no-op
-153   look <- skip-spaces look
-154   # if next char is not '(', parse a number
-155   compare look, 0x28  # '('
-156   {
-157     break-if-=
-158     result, look <- num look
-159     break $factor:body
-160   }
-161   # otherwise recurse
-162   look <- get-char  # '('
-163   result, look <- expression look
-164   look <- skip-spaces look
-165   look <- get-char  # ')'
-166 }  # $factor:body
-167 }
-168 
-169 fn is-mul-or-div? c: byte -> result/eax: boolean {
-170 $is-mul-or-div?:body: {
-171   compare c, 0x2a  # '*'
-172   {
-173     break-if-!=
-174     result <- copy 1  # true
-175     break $is-mul-or-div?:body
-176   }
-177   compare c, 0x2f  # '/'
-178   {
-179     break-if-!=
-180     result <- copy 1  # true
-181     break $is-mul-or-div?:body
-182   }
-183   result <- copy 0  # false
-184 }  # $is-mul-or-div?:body
-185 }
-186 
-187 fn is-add-or-sub? c: byte -> result/eax: boolean {
-188 $is-add-or-sub?:body: {
-189   compare c, 0x2b  # '+'
-190   {
-191     break-if-!=
-192     result <- copy 1  # true
-193     break $is-add-or-sub?:body
-194   }
-195   compare c, 0x2d  # '-'
-196   {
-197     break-if-!=
-198     result <- copy 1  # true
-199     break $is-add-or-sub?:body
-200   }
-201   result <- copy 0  # false
-202 }  # $is-add-or-sub?:body
-203 }
-204 
-205 fn operator _look: byte -> op/ecx: byte, look/esi: byte {
-206   op <- copy _look
-207   look <- get-char
-208 }
-209 
-210 fn num _look: byte -> result/eax: int, look/esi: byte {
-211   look <- copy _look  # should be a no-op
-212   var out/edi: int <- copy 0
-213   {
-214     var first-digit/eax: int <- to-decimal-digit look
-215     out <- copy first-digit
-216   }
-217   {
-218     look <- get-char
-219     # done?
-220     var digit?/eax: boolean <- is-decimal-digit? look
-221     compare digit?, 0  # false
-222     break-if-=
-223     # out *= 10
-224     {
-225       var ten/eax: int <- copy 0xa
-226       out <- multiply ten
-227     }
-228     # out += digit(look)
-229     var digit/eax: int <- to-decimal-digit look
-230     out <- add digit
-231     loop
-232   }
-233   result <- copy out
-234 }
-235 
-236 fn skip-spaces _look: byte -> look/esi: byte {
-237   look <- copy _look  # should be a no-op
-238   {
-239     compare look, 0x20
-240     break-if-!=
-241     look <- get-char
-242     loop
-243   }
-244 }
-245 
-246 fn get-char -> look/esi: byte {
-247   var tmp/eax: byte <- read-key
-248   look <- copy tmp
-249   compare look, 0
-250   {
-251     break-if-!=
-252     print-string 0, "^D\n"
-253     syscall_exit
-254   }
-255 }
+  1 # Integer arithmetic using conventional precedence.
+  2 #
+  3 # Follows part 2 of Jack Crenshaw's "Let's build a compiler!"
+  4 #   https://compilers.iecc.com/crenshaw
+  5 #
+  6 # Limitations:
+  7 #   No division yet.
+  8 #
+  9 # To build:
+ 10 #   $ ./translate_mu apps/arith.mu
+ 11 #
+ 12 # Example session:
+ 13 #   $ ./a.elf
+ 14 #   press ctrl-c or ctrl-d to exit
+ 15 #   > 1
+ 16 #   1
+ 17 #   > 1+1
+ 18 #   2
+ 19 #   > 1 + 1
+ 20 #   2
+ 21 #   > 1+2 +3
+ 22 #   6
+ 23 #   > 1+2 *3
+ 24 #   7
+ 25 #   > (1+2) *3
+ 26 #   9
+ 27 #   > 1 + 3*4
+ 28 #   13
+ 29 #   > ^D
+ 30 #   $
+ 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 }
 
-- cgit 1.4.1-2-gfad0