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/tile/rpn.mu.html | 284 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 284 insertions(+) create mode 100644 html/apps/tile/rpn.mu.html (limited to 'html/apps/tile/rpn.mu.html') diff --git a/html/apps/tile/rpn.mu.html b/html/apps/tile/rpn.mu.html new file mode 100644 index 00000000..39cbea35 --- /dev/null +++ b/html/apps/tile/rpn.mu.html @@ -0,0 +1,284 @@ + + + + +Mu - apps/tile/rpn.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/master/apps/tile/rpn.mu +
+  1 fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr value-stack) {
+  2   var line/eax: (addr line) <- copy scratch
+  3   var word-ah/eax: (addr handle word) <- get line, data
+  4   var curr/eax: (addr word) <- lookup *word-ah
+  5   var curr-stream-storage: (stream byte 0x10)
+  6   var curr-stream/edi: (addr stream byte) <- address curr-stream-storage
+  7   clear-value-stack out
+  8   $evaluate:loop: {
+  9     # precondition (should never hit)
+ 10     compare curr, 0
+ 11     break-if-=
+ 12     # update curr-stream
+ 13     emit-word curr, curr-stream
+ 14 #?     print-stream-to-real-screen curr-stream
+ 15 #?     print-string-to-real-screen "\n"
+ 16     $evaluate:process-word: {
+ 17       # if curr-stream is an operator, perform it
+ 18       {
+ 19         var is-add?/eax: boolean <- stream-data-equal? curr-stream, "+"
+ 20         compare is-add?, 0
+ 21         break-if-=
+ 22         var _b/eax: int <- pop-int-from-value-stack out
+ 23         var b/edx: int <- copy _b
+ 24         var a/eax: int <- pop-int-from-value-stack out
+ 25         a <- add b
+ 26         push-int-to-value-stack out, a
+ 27         break $evaluate:process-word
+ 28       }
+ 29       {
+ 30         var is-sub?/eax: boolean <- stream-data-equal? curr-stream, "-"
+ 31         compare is-sub?, 0
+ 32         break-if-=
+ 33         var _b/eax: int <- pop-int-from-value-stack out
+ 34         var b/edx: int <- copy _b
+ 35         var a/eax: int <- pop-int-from-value-stack out
+ 36         a <- subtract b
+ 37         push-int-to-value-stack out, a
+ 38         break $evaluate:process-word
+ 39       }
+ 40       {
+ 41         var is-mul?/eax: boolean <- stream-data-equal? curr-stream, "*"
+ 42         compare is-mul?, 0
+ 43         break-if-=
+ 44         var _b/eax: int <- pop-int-from-value-stack out
+ 45         var b/edx: int <- copy _b
+ 46         var a/eax: int <- pop-int-from-value-stack out
+ 47         a <- multiply b
+ 48         push-int-to-value-stack out, a
+ 49         break $evaluate:process-word
+ 50       }
+ 51       # if curr-stream is a known function name, call it appropriately
+ 52       {
+ 53         var callee-h: (handle function)
+ 54         var callee-ah/eax: (addr handle function) <- address callee-h
+ 55         find-function defs, curr-stream, callee-ah
+ 56         var callee/eax: (addr function) <- lookup *callee-ah
+ 57         compare callee, 0
+ 58         break-if-=
+ 59         perform-call callee, out, defs
+ 60         break $evaluate:process-word
+ 61       }
+ 62       # if it's a name, push its value
+ 63       {
+ 64         compare bindings, 0
+ 65         break-if-=
+ 66         var tmp: (handle array byte)
+ 67         var curr-string-ah/edx: (addr handle array byte) <- address tmp
+ 68         stream-to-string curr-stream, curr-string-ah  # unfortunate leak
+ 69         var curr-string/eax: (addr array byte) <- lookup *curr-string-ah
+ 70         var val-storage: (handle value)
+ 71         var val-ah/edi: (addr handle value) <- address val-storage
+ 72         lookup-binding bindings, curr-string, val-ah
+ 73         var val/eax: (addr value) <- lookup *val-ah
+ 74         compare val, 0
+ 75         break-if-=
+ 76 #?         print-string-to-real-screen "value of "
+ 77 #?         print-string-to-real-screen curr-string
+ 78 #?         print-string-to-real-screen " is "
+ 79 #?         print-int32-hex-to-real-screen result
+ 80 #?         print-string-to-real-screen "\n"
+ 81         push-value-stack out, val
+ 82         break $evaluate:process-word
+ 83       }
+ 84       # otherwise assume it's a literal int and push it
+ 85       {
+ 86         var n/eax: int <- parse-decimal-int-from-stream curr-stream
+ 87         push-int-to-value-stack out, n
+ 88       }
+ 89     }
+ 90     # termination check
+ 91     compare curr, end
+ 92     break-if-=
+ 93     # update
+ 94     var next-word-ah/edx: (addr handle word) <- get curr, next
+ 95     curr <- lookup *next-word-ah
+ 96     #
+ 97     loop
+ 98   }
+ 99 }
+100 
+101 fn find-function first: (addr handle function), name: (addr stream byte), out: (addr handle function) {
+102   var curr/esi: (addr handle function) <- copy first
+103   $find-function:loop: {
+104     var _f/eax: (addr function) <- lookup *curr
+105     var f/ecx: (addr function) <- copy _f
+106     compare f, 0
+107     break-if-=
+108     var curr-name-ah/eax: (addr handle array byte) <- get f, name
+109     var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
+110     var done?/eax: boolean <- stream-data-equal? name, curr-name
+111     compare done?, 0  # false
+112     {
+113       break-if-=
+114       copy-handle *curr, out
+115       break $find-function:loop
+116     }
+117     curr <- get f, next
+118     loop
+119   }
+120 }
+121 
+122 fn perform-call _callee: (addr function), caller-stack: (addr value-stack), defs: (addr handle function) {
+123   var callee/ecx: (addr function) <- copy _callee
+124   # create bindings for args
+125   var table-storage: table
+126   var table/esi: (addr table) <- address table-storage
+127   initialize-table table, 0x10
+128   bind-args callee, caller-stack, table
+129   # obtain body
+130   var body-ah/eax: (addr handle line) <- get callee, body
+131   var body/eax: (addr line) <- lookup *body-ah
+132   # perform call
+133   var stack-storage: value-stack
+134   var stack/edi: (addr value-stack) <- address stack-storage
+135   initialize-value-stack stack, 0x10
+136 #?   print-string-to-real-screen "about to enter recursive eval\n"
+137   evaluate defs, table, body, 0, stack
+138 #?   print-string-to-real-screen "exited recursive eval\n"
+139   # stitch result from stack into caller
+140   var result/eax: int <- pop-int-from-value-stack stack
+141   push-int-to-value-stack caller-stack, result
+142 }
+143 
+144 fn bind-args _callee: (addr function), caller-stack: (addr value-stack), table: (addr table) {
+145   var callee/ecx: (addr function) <- copy _callee
+146   var curr-arg-ah/eax: (addr handle word) <- get callee, args
+147   var curr-arg/eax: (addr word) <- lookup *curr-arg-ah
+148   #
+149   var curr-key-storage: (handle array byte)
+150   var curr-key/edx: (addr handle array byte) <- address curr-key-storage
+151   {
+152     compare curr-arg, 0
+153     break-if-=
+154     # create binding
+155     word-to-string curr-arg, curr-key
+156     {
+157 #?       var tmp/eax: (addr array byte) <- lookup *curr-key
+158 #?       print-string-to-real-screen "binding "
+159 #?       print-string-to-real-screen tmp
+160 #?       print-string-to-real-screen " to "
+161       var curr-val/eax: int <- pop-int-from-value-stack caller-stack
+162 #?       print-int32-decimal-to-real-screen curr-val
+163 #?       print-string-to-real-screen "\n"
+164       bind-int-in-table table, curr-key, curr-val
+165     }
+166     #
+167     var next-arg-ah/edx: (addr handle word) <- get curr-arg, next
+168     curr-arg <- lookup *next-arg-ah
+169     loop
+170   }
+171 }
+172 
+173 # Copy of 'simplify' that just tracks the maximum stack depth needed
+174 # Doesn't actually need to simulate the stack, since every word has a predictable effect.
+175 fn max-stack-depth first-word: (addr word), final-word: (addr word) -> result/edi: int {
+176   var curr-word/eax: (addr word) <- copy first-word
+177   var curr-depth/ecx: int <- copy 0
+178   result <- copy 0
+179   $max-stack-depth:loop: {
+180     $max-stack-depth:process-word: {
+181       # handle operators
+182       {
+183         var is-add?/eax: boolean <- word-equal? curr-word, "+"
+184         compare is-add?, 0
+185         break-if-=
+186         curr-depth <- decrement
+187         break $max-stack-depth:process-word
+188       }
+189       {
+190         var is-sub?/eax: boolean <- word-equal? curr-word, "-"
+191         compare is-sub?, 0
+192         break-if-=
+193         curr-depth <- decrement
+194         break $max-stack-depth:process-word
+195       }
+196       {
+197         var is-mul?/eax: boolean <- word-equal? curr-word, "*"
+198         compare is-mul?, 0
+199         break-if-=
+200         curr-depth <- decrement
+201         break $max-stack-depth:process-word
+202       }
+203       # otherwise it's an int (do we need error-checking?)
+204       curr-depth <- increment
+205       # update max depth if necessary
+206       {
+207         compare curr-depth, result
+208         break-if-<=
+209         result <- copy curr-depth
+210       }
+211     }
+212     # if curr-word == final-word break
+213     compare curr-word, final-word
+214     break-if-=
+215     # curr-word = curr-word->next
+216     var next-word-ah/edx: (addr handle word) <- get curr-word, next
+217     curr-word <- lookup *next-word-ah
+218     #
+219     loop
+220   }
+221 }
+
+ + + -- cgit 1.4.1-2-gfad0