From d409be9b29b4bbfdf10fa26620fa6abbe45a87da Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 20 Oct 2020 23:06:24 -0700 Subject: 7088 --- html/apps/tile/data.mu.html | 842 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 667 insertions(+), 175 deletions(-) (limited to 'html/apps/tile/data.mu.html') diff --git a/html/apps/tile/data.mu.html b/html/apps/tile/data.mu.html index 4e0c9f7d..6ead395a 100644 --- a/html/apps/tile/data.mu.html +++ b/html/apps/tile/data.mu.html @@ -14,6 +14,7 @@ pre { white-space: pre-wrap; font-family: monospace; color: #000000; background- body { font-size:12pt; font-family: monospace; color: #000000; background-color: #c6c6c6; } a { color:inherit; } * { font-size:12pt; font-size: 1em; } +.CommentedCode { color: #8a8a8a; } .muComment { color: #005faf; } .LineNr { } .SpecialChar { color: #d70000; } @@ -56,49 +57,49 @@ if ('onhashchange' in window) { https://github.com/akkartik/mu/blob/master/apps/tile/data.mu
-  1 type program {
-  2   defs: (handle function)
-  3   sandboxes: (handle sandbox)
-  4 }
-  5 
-  6 type sandbox {
-  7   setup: (handle line)
-  8   data: (handle line)
-  9   next: (handle sandbox)
- 10   prev: (handle sandbox)
- 11 }
- 12 
- 13 type function {
- 14   name: (handle array byte)
- 15   args: (handle word)  # in reverse order
- 16   body: (handle line)
- 17   # some sort of indication of spatial location
- 18   next: (handle function)
- 19 }
- 20 
- 21 type line {
- 22   name: (handle array byte)
- 23   data: (handle word)
- 24   result: (handle result)  # might be cached
- 25   next: (handle line)
- 26   prev: (handle line)
- 27 }
- 28 
- 29 type word {
- 30   # at most one of these will be non-null
- 31   scalar-data: (handle gap-buffer)
- 32   text-data: (handle array byte)
- 33   box-data: (handle line)  # recurse
- 34   # other metadata attached to this word
- 35   display-subsidiary-stack?: boolean
- 36   next: (handle word)
- 37   prev: (handle word)
+  1 type sandbox {
+  2   setup: (handle line)
+  3   data: (handle line)
+  4   # display data
+  5   cursor-call-path: (handle call-path-element)
+  6   expanded-words: (handle call-path)
+  7   partial-name-for-cursor-word: (handle word)  # only when renaming word
+  8   partial-name-for-function: (handle word)  # only when defining function
+  9   #
+ 10   next: (handle sandbox)
+ 11   prev: (handle sandbox)
+ 12 }
+ 13 
+ 14 type function {
+ 15   name: (handle array byte)
+ 16   args: (handle word)  # in reverse order
+ 17   body: (handle line)
+ 18   # some sort of indication of spatial location
+ 19   next: (handle function)
+ 20 }
+ 21 
+ 22 type line {
+ 23   name: (handle array byte)
+ 24   data: (handle word)
+ 25   result: (handle result)  # might be cached
+ 26   next: (handle line)
+ 27   prev: (handle line)
+ 28 }
+ 29 
+ 30 type word {
+ 31   # at most one of these will be non-null
+ 32   scalar-data: (handle gap-buffer)
+ 33   text-data: (handle array byte)
+ 34   box-data: (handle line)  # recurse
+ 35   #
+ 36   next: (handle word)
+ 37   prev: (handle word)
  38 }
  39 
  40 type value {
  41   scalar-data: int
  42   text-data: (handle array byte)
- 43   box-data: (handle line)
+ 43   box-data: (handle line)
  44 }
  45 
  46 type table {
@@ -111,151 +112,642 @@ if ('onhashchange' in window) {
  53   value: (handle value)  # I'd inline this but we sometimes want to return a specific value from a table
  54 }
  55 
- 56 type result {
- 57   data: value-stack
- 58   error: (handle array byte)  # single error message for now
- 59 }
- 60 
- 61 # if 'out' is non-null, save the first word of the program there
- 62 fn initialize-program _program: (addr program), out: (addr handle word) {
- 63   var program/esi: (addr program) <- copy _program
- 64   var defs/eax: (addr handle function) <- get program, defs
- 65   create-primitive-defs defs
- 66   var sandbox-ah/eax: (addr handle sandbox) <- get program, sandboxes
- 67   allocate sandbox-ah
- 68   var sandbox/eax: (addr sandbox) <- lookup *sandbox-ah
- 69   initialize-sandbox sandbox, out
- 70 }
- 71 
- 72 # if 'out' is non-null, save the first word of the sandbox there
- 73 fn initialize-sandbox _sandbox: (addr sandbox), out: (addr handle word) {
- 74   var sandbox/esi: (addr sandbox) <- copy _sandbox
- 75   var line-ah/eax: (addr handle line) <- get sandbox, data
- 76   allocate line-ah
- 77   var line/eax: (addr line) <- lookup *line-ah
- 78   initialize-line line, out
- 79 }
- 80 
- 81 # initialize line with a single empty word
- 82 # if 'out' is non-null, save the word there as well
- 83 fn initialize-line _line: (addr line), out: (addr handle word) {
- 84   var line/esi: (addr line) <- copy _line
- 85   var word-ah/eax: (addr handle word) <- get line, data
- 86   allocate word-ah
- 87   {
- 88     compare out, 0
- 89     break-if-=
- 90     var dest/edi: (addr handle word) <- copy out
- 91     copy-object word-ah, dest
- 92   }
- 93   var word/eax: (addr word) <- lookup *word-ah
- 94   initialize-word word
+ 56 # A call-path is a data structure that can unambiguously refer to any specific
+ 57 # call arbitrarily deep inside the call hierarchy of a program.
+ 58 type call-path {
+ 59   data: (handle call-path-element)
+ 60   next: (handle call-path)
+ 61 }
+ 62 
+ 63 # A call-path element is a list of elements, each of which corresponds to some call.
+ 64 type call-path-element {
+ 65   word: (handle word)
+ 66   next: (handle call-path-element)
+ 67 }
+ 68 
+ 69 type result {
+ 70   data: value-stack
+ 71   error: (handle array byte)  # single error message for now
+ 72 }
+ 73 
+ 74 fn initialize-sandbox _sandbox: (addr sandbox) {
+ 75   var sandbox/esi: (addr sandbox) <- copy _sandbox
+ 76   var line-ah/eax: (addr handle line) <- get sandbox, data
+ 77   allocate line-ah
+ 78   var line/eax: (addr line) <- lookup *line-ah
+ 79   initialize-line line
+ 80   var word-ah/ecx: (addr handle word) <- get line, data
+ 81   var cursor-call-path-ah/eax: (addr handle call-path-element) <- get sandbox, cursor-call-path
+ 82   allocate cursor-call-path-ah
+ 83   var cursor-call-path/eax: (addr call-path-element) <- lookup *cursor-call-path-ah
+ 84   var dest/eax: (addr handle word) <- get cursor-call-path, word
+ 85   copy-object word-ah, dest
+ 86 }
+ 87 
+ 88 # initialize line with a single empty word
+ 89 fn initialize-line _line: (addr line) {
+ 90   var line/esi: (addr line) <- copy _line
+ 91   var word-ah/eax: (addr handle word) <- get line, data
+ 92   allocate word-ah
+ 93   var word/eax: (addr word) <- lookup *word-ah
+ 94   initialize-word word
  95 }
  96 
- 97 fn create-primitive-defs _self: (addr handle function) {
+ 97 fn create-primitive-functions _self: (addr handle function) {
  98   # x 2* = x 2 *
- 99   var self/esi: (addr handle function) <- copy _self
+ 99   var self/esi: (addr handle function) <- copy _self
 100   allocate self
-101   var _f/eax: (addr function) <- lookup *self
-102   var f/esi: (addr function) <- copy _f
+101   var _f/eax: (addr function) <- lookup *self
+102   var f/esi: (addr function) <- copy _f
 103   var name-ah/eax: (addr handle array byte) <- get f, name
-104   populate-text-with name-ah, "2*"
-105   var args-ah/eax: (addr handle word) <- get f, args
+104   populate-text-with name-ah, "2*"
+105   var args-ah/eax: (addr handle word) <- get f, args
 106   allocate args-ah
-107   var args/eax: (addr word) <- lookup *args-ah
+107   var args/eax: (addr word) <- lookup *args-ah
 108   initialize-word-with args, "x"
-109   var body-ah/eax: (addr handle line) <- get f, body
+109   var body-ah/eax: (addr handle line) <- get f, body
 110   allocate body-ah
-111   var body/eax: (addr line) <- lookup *body-ah
-112   initialize-line body, 0
-113   var curr-word-ah/ecx: (addr handle word) <- get body, data
-114   allocate curr-word-ah
-115   var curr-word/eax: (addr word) <- lookup *curr-word-ah
-116   initialize-word-with curr-word, "x"
-117   curr-word-ah <- get curr-word, next
-118   allocate curr-word-ah
-119   curr-word <- lookup *curr-word-ah
-120   initialize-word-with curr-word, "2"
-121   curr-word-ah <- get curr-word, next
-122   allocate curr-word-ah
-123   curr-word <- lookup *curr-word-ah
-124   initialize-word-with curr-word, "*"
-125   # x 1+ = x 1 +
-126   var next/esi: (addr handle function) <- get f, next
-127   allocate next
-128   var _f/eax: (addr function) <- lookup *next
-129   var f/esi: (addr function) <- copy _f
-130   var name-ah/eax: (addr handle array byte) <- get f, name
-131   populate-text-with name-ah, "1+"
-132   var args-ah/eax: (addr handle word) <- get f, args
-133   allocate args-ah
-134   var args/eax: (addr word) <- lookup *args-ah
-135   initialize-word-with args, "x"
-136   var body-ah/eax: (addr handle line) <- get f, body
-137   allocate body-ah
-138   var body/eax: (addr line) <- lookup *body-ah
-139   initialize-line body, 0
-140   var curr-word-ah/ecx: (addr handle word) <- get body, data
-141   allocate curr-word-ah
-142   var curr-word/eax: (addr word) <- lookup *curr-word-ah
-143   initialize-word-with curr-word, "x"
-144   curr-word-ah <- get curr-word, next
-145   allocate curr-word-ah
-146   curr-word <- lookup *curr-word-ah
-147   initialize-word-with curr-word, "1"
-148   curr-word-ah <- get curr-word, next
-149   allocate curr-word-ah
-150   curr-word <- lookup *curr-word-ah
-151   initialize-word-with curr-word, "+"
-152   # x 2+ = x 1+ 1+
-153   var next/esi: (addr handle function) <- get f, next
-154   allocate next
-155   var _f/eax: (addr function) <- lookup *next
-156   var f/ecx: (addr function) <- copy _f
-157   var name-ah/eax: (addr handle array byte) <- get f, name
-158   populate-text-with name-ah, "2+"
-159   var args-ah/eax: (addr handle word) <- get f, args
-160   allocate args-ah
-161   var args/eax: (addr word) <- lookup *args-ah
-162   initialize-word-with args, "x"
-163   var body-ah/eax: (addr handle line) <- get f, body
-164   allocate body-ah
-165   var body/eax: (addr line) <- lookup *body-ah
-166   initialize-line body, 0
-167   var curr-word-ah/ecx: (addr handle word) <- get body, data
-168   allocate curr-word-ah
-169   var curr-word/eax: (addr word) <- lookup *curr-word-ah
-170   initialize-word-with curr-word, "x"
-171   curr-word-ah <- get curr-word, next
-172   allocate curr-word-ah
-173   curr-word <- lookup *curr-word-ah
-174   initialize-word-with curr-word, "1+"
-175   curr-word-ah <- get curr-word, next
-176   allocate curr-word-ah
-177   curr-word <- lookup *curr-word-ah
-178   initialize-word-with curr-word, "1+"
-179   # TODO: populate prev pointers
-180 }
-181 
-182 fn populate-text-with _out: (addr handle array byte), _in: (addr array byte) {
-183   var in/esi: (addr array byte) <- copy _in
-184   var n/ecx: int <- length in
-185   var out/edx: (addr handle array byte) <- copy _out
-186   populate out, n
-187   var _out-addr/eax: (addr array byte) <- lookup *out
-188   var out-addr/edx: (addr array byte) <- copy _out-addr
-189   var i/eax: int <- copy 0
-190   {
-191     compare i, n
-192     break-if->=
-193     var src/esi: (addr byte) <- index in, i
-194     var val/ecx: byte <- copy-byte *src
-195     var dest/edi: (addr byte) <- index out-addr, i
-196     copy-byte-to *dest, val
-197     i <- increment
-198     loop
-199   }
-200 }
+111   var body/eax: (addr line) <- lookup *body-ah
+112   initialize-line body
+113   var curr-word-ah/ecx: (addr handle word) <- get body, data
+114   # *curr-word = "x"
+115   allocate curr-word-ah
+116   var tmp/eax: (addr word) <- lookup *curr-word-ah
+117   var curr-word/edx: (addr word) <- copy tmp
+118   initialize-word-with curr-word, "x"
+119   # *curr-word->next = "2"
+120   var next-word-ah/ebx: (addr handle word) <- get curr-word, next
+121   allocate next-word-ah
+122   tmp <- lookup *next-word-ah
+123   initialize-word-with tmp, "2"
+124   # *curr-word->next->prev = curr-word
+125   var prev-word-ah/edi: (addr handle word) <- get tmp, prev
+126   copy-object curr-word-ah, prev-word-ah
+127   # curr-word = curr-word->next
+128   curr-word-ah <- copy next-word-ah
+129   curr-word <- copy tmp
+130   # *curr-word->next = "*"
+131   next-word-ah <- get curr-word, next
+132   allocate next-word-ah
+133   tmp <- lookup *next-word-ah
+134   initialize-word-with tmp, "*"
+135   # *curr-word->next->prev = curr-word
+136   prev-word-ah <- get tmp, prev
+137   copy-object curr-word-ah, prev-word-ah
+138   tmp <- lookup *prev-word-ah
+139   # x 1+ = x 1 +
+140   var next/esi: (addr handle function) <- get f, next
+141   allocate next
+142   var _f/eax: (addr function) <- lookup *next
+143   var f/esi: (addr function) <- copy _f
+144   var name-ah/eax: (addr handle array byte) <- get f, name
+145   populate-text-with name-ah, "1+"
+146   var args-ah/eax: (addr handle word) <- get f, args
+147   allocate args-ah
+148   var args/eax: (addr word) <- lookup *args-ah
+149   initialize-word-with args, "x"
+150   var body-ah/eax: (addr handle line) <- get f, body
+151   allocate body-ah
+152   var body/eax: (addr line) <- lookup *body-ah
+153   initialize-line body
+154   var curr-word-ah/ecx: (addr handle word) <- get body, data
+155   # *curr-word = "x"
+156   allocate curr-word-ah
+157   var tmp/eax: (addr word) <- lookup *curr-word-ah
+158   curr-word <- copy tmp
+159   initialize-word-with curr-word, "x"
+160   # *curr-word->next = "1"
+161   next-word-ah <- get curr-word, next
+162   allocate next-word-ah
+163   tmp <- lookup *next-word-ah
+164   initialize-word-with tmp, "1"
+165   # *curr-word->next->prev = curr-word
+166   prev-word-ah <- get tmp, prev
+167   copy-object curr-word-ah, prev-word-ah
+168   # curr-word = curr-word->next
+169   curr-word-ah <- copy next-word-ah
+170   curr-word <- copy tmp
+171   # *curr-word->next = "+"
+172   next-word-ah <- get curr-word, next
+173   allocate next-word-ah
+174   tmp <- lookup *next-word-ah
+175   initialize-word-with tmp, "+"
+176   # *curr-word->next->prev = curr-word
+177   prev-word-ah <- get tmp, prev
+178   copy-object curr-word-ah, prev-word-ah
+179   tmp <- lookup *prev-word-ah
+180   # x 2+ = x 1+ 1+
+181   var next/esi: (addr handle function) <- get f, next
+182   allocate next
+183   var _f/eax: (addr function) <- lookup *next
+184   var f/esi: (addr function) <- copy _f
+185   var name-ah/eax: (addr handle array byte) <- get f, name
+186   populate-text-with name-ah, "2+"
+187   var args-ah/eax: (addr handle word) <- get f, args
+188   allocate args-ah
+189   var args/eax: (addr word) <- lookup *args-ah
+190   initialize-word-with args, "x"
+191   var body-ah/eax: (addr handle line) <- get f, body
+192   allocate body-ah
+193   var body/eax: (addr line) <- lookup *body-ah
+194   initialize-line body
+195   var curr-word-ah/ecx: (addr handle word) <- get body, data
+196   # *curr-word = "x"
+197   allocate curr-word-ah
+198   var tmp/eax: (addr word) <- lookup *curr-word-ah
+199   curr-word <- copy tmp
+200   initialize-word-with curr-word, "x"
+201   # *curr-word->next = "1+"
+202   next-word-ah <- get curr-word, next
+203   allocate next-word-ah
+204   tmp <- lookup *next-word-ah
+205   initialize-word-with tmp, "1+"
+206   # *curr-word->next->prev = curr-word
+207   prev-word-ah <- get tmp, prev
+208   copy-object curr-word-ah, prev-word-ah
+209   # curr-word = curr-word->next
+210   curr-word-ah <- copy next-word-ah
+211   curr-word <- copy tmp
+212   # *curr-word->next = "1+"
+213   next-word-ah <- get curr-word, next
+214   allocate next-word-ah
+215   tmp <- lookup *next-word-ah
+216   initialize-word-with tmp, "1+"
+217   # *curr-word->next->prev = curr-word
+218   prev-word-ah <- get tmp, prev
+219   copy-object curr-word-ah, prev-word-ah
+220   tmp <- lookup *prev-word-ah
+221   # x square = x x *
+222   var next/esi: (addr handle function) <- get f, next
+223   allocate next
+224   var _f/eax: (addr function) <- lookup *next
+225   var f/esi: (addr function) <- copy _f
+226   var name-ah/eax: (addr handle array byte) <- get f, name
+227   populate-text-with name-ah, "square"
+228   var args-ah/eax: (addr handle word) <- get f, args
+229   allocate args-ah
+230   var args/eax: (addr word) <- lookup *args-ah
+231   initialize-word-with args, "x"
+232   var body-ah/eax: (addr handle line) <- get f, body
+233   allocate body-ah
+234   var body/eax: (addr line) <- lookup *body-ah
+235   initialize-line body
+236   var curr-word-ah/ecx: (addr handle word) <- get body, data
+237   # *curr-word = "x"
+238   allocate curr-word-ah
+239   var tmp/eax: (addr word) <- lookup *curr-word-ah
+240   var curr-word/edx: (addr word) <- copy tmp
+241   initialize-word-with curr-word, "x"
+242   # *curr-word->next = "x"
+243   var next-word-ah/ebx: (addr handle word) <- get curr-word, next
+244   allocate next-word-ah
+245   tmp <- lookup *next-word-ah
+246   initialize-word-with tmp, "x"
+247   # *curr-word->next->prev = curr-word
+248   var prev-word-ah/edi: (addr handle word) <- get tmp, prev
+249   copy-object curr-word-ah, prev-word-ah
+250   # curr-word = curr-word->next
+251   curr-word-ah <- copy next-word-ah
+252   curr-word <- copy tmp
+253   # *curr-word->next = "*"
+254   next-word-ah <- get curr-word, next
+255   allocate next-word-ah
+256   tmp <- lookup *next-word-ah
+257   initialize-word-with tmp, "*"
+258   # *curr-word->next->prev = curr-word
+259   prev-word-ah <- get tmp, prev
+260   copy-object curr-word-ah, prev-word-ah
+261   tmp <- lookup *prev-word-ah
+262   # x 1- = x 1 -
+263   var next/esi: (addr handle function) <- get f, next
+264   allocate next
+265   var _f/eax: (addr function) <- lookup *next
+266   var f/esi: (addr function) <- copy _f
+267   var name-ah/eax: (addr handle array byte) <- get f, name
+268   populate-text-with name-ah, "1-"
+269   var args-ah/eax: (addr handle word) <- get f, args
+270   allocate args-ah
+271   var args/eax: (addr word) <- lookup *args-ah
+272   initialize-word-with args, "x"
+273   var body-ah/eax: (addr handle line) <- get f, body
+274   allocate body-ah
+275   var body/eax: (addr line) <- lookup *body-ah
+276   initialize-line body
+277   var curr-word-ah/ecx: (addr handle word) <- get body, data
+278   # *curr-word = "x"
+279   allocate curr-word-ah
+280   var tmp/eax: (addr word) <- lookup *curr-word-ah
+281   curr-word <- copy tmp
+282   initialize-word-with curr-word, "x"
+283   # *curr-word->next = "1"
+284   next-word-ah <- get curr-word, next
+285   allocate next-word-ah
+286   tmp <- lookup *next-word-ah
+287   initialize-word-with tmp, "1"
+288   # *curr-word->next->prev = curr-word
+289   prev-word-ah <- get tmp, prev
+290   copy-object curr-word-ah, prev-word-ah
+291   # curr-word = curr-word->next
+292   curr-word-ah <- copy next-word-ah
+293   curr-word <- copy tmp
+294   # *curr-word->next = "-"
+295   next-word-ah <- get curr-word, next
+296   allocate next-word-ah
+297   tmp <- lookup *next-word-ah
+298   initialize-word-with tmp, "-"
+299   # *curr-word->next->prev = curr-word
+300   prev-word-ah <- get tmp, prev
+301   copy-object curr-word-ah, prev-word-ah
+302   tmp <- lookup *prev-word-ah
+303   # x y sub = x y -
+304   var next/esi: (addr handle function) <- get f, next
+305   allocate next
+306   var _f/eax: (addr function) <- lookup *next
+307   var f/esi: (addr function) <- copy _f
+308   var name-ah/eax: (addr handle array byte) <- get f, name
+309   populate-text-with name-ah, "sub"
+310   # critical lesson: args are stored in reverse order
+311   var args-ah/eax: (addr handle word) <- get f, args
+312   allocate args-ah
+313   var args/eax: (addr word) <- lookup *args-ah
+314   initialize-word-with args, "y"
+315   var next-arg-ah/eax: (addr handle word) <- get args, next
+316   allocate next-arg-ah
+317   var next-arg/eax: (addr word) <- lookup *next-arg-ah
+318   initialize-word-with next-arg, "x"
+319   var body-ah/eax: (addr handle line) <- get f, body
+320   allocate body-ah
+321   var body/eax: (addr line) <- lookup *body-ah
+322   initialize-line body
+323   var curr-word-ah/ecx: (addr handle word) <- get body, data
+324   # *curr-word = "x"
+325   allocate curr-word-ah
+326   var tmp/eax: (addr word) <- lookup *curr-word-ah
+327   curr-word <- copy tmp
+328   initialize-word-with curr-word, "x"
+329   # *curr-word->next = "y"
+330   next-word-ah <- get curr-word, next
+331   allocate next-word-ah
+332   tmp <- lookup *next-word-ah
+333   initialize-word-with tmp, "y"
+334   # *curr-word->next->prev = curr-word
+335   prev-word-ah <- get tmp, prev
+336   copy-object curr-word-ah, prev-word-ah
+337   # curr-word = curr-word->next
+338   curr-word-ah <- copy next-word-ah
+339   curr-word <- copy tmp
+340   # *curr-word->next = "-"
+341   next-word-ah <- get curr-word, next
+342   allocate next-word-ah
+343   tmp <- lookup *next-word-ah
+344   initialize-word-with tmp, "-"
+345   # *curr-word->next->prev = curr-word
+346   prev-word-ah <- get tmp, prev
+347   copy-object curr-word-ah, prev-word-ah
+348   tmp <- lookup *prev-word-ah
+349 }
+350 
+351 fn function-body functions: (addr handle function), _word: (addr handle word), out: (addr handle line) {
+352   var function-name-storage: (handle array byte)
+353   var function-name-ah/ecx: (addr handle array byte) <- address function-name-storage
+354   var word-ah/esi: (addr handle word) <- copy _word
+355   var word/eax: (addr word) <- lookup *word-ah
+356   var gap-ah/eax: (addr handle gap-buffer) <- get word, scalar-data
+357   var gap/eax: (addr gap-buffer) <- lookup *gap-ah
+358   gap-buffer-to-string gap, function-name-ah
+359   var _function-name/eax: (addr array byte) <- lookup *function-name-ah
+360   var function-name/esi: (addr array byte) <- copy _function-name
+361   var curr-ah/ecx: (addr handle function) <- copy functions
+362   $function-body:loop: {
+363     var _curr/eax: (addr function) <- lookup *curr-ah
+364     var curr/edx: (addr function) <- copy _curr
+365     compare curr, 0
+366     break-if-=
+367     var curr-name-ah/eax: (addr handle array byte) <- get curr, name
+368     var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
+369     var found?/eax: boolean <- string-equal? curr-name, function-name
+370     compare found?, 0  # false
+371     {
+372       break-if-=
+373       var src/eax: (addr handle line) <- get curr, body
+374       copy-object src, out
+375       break $function-body:loop
+376     }
+377     curr-ah <- get curr, next
+378     loop
+379   }
+380 }
+381 
+382 fn body-length functions: (addr handle function), function-name: (addr handle word) -> result/eax: int {
+383   var body-storage: (handle line)
+384   var body-ah/edi: (addr handle line) <- address body-storage
+385   function-body functions, function-name, body-ah
+386   var body/eax: (addr line) <- lookup *body-ah
+387   result <- line-length body
+388 }
+389 
+390 fn line-length _in: (addr line) -> result/eax: int {
+391   var in/esi: (addr line) <- copy _in
+392   var curr-ah/ecx: (addr handle word) <- get in, data
+393   var out/edi: int <- copy 0
+394   {
+395     var curr/eax: (addr word) <- lookup *curr-ah
+396     compare curr, 0
+397     break-if-=
+398     curr-ah <- get curr, next
+399     out <- increment
+400     loop
+401   }
+402   result <- copy out
+403 }
+404 
+405 fn populate-text-with _out: (addr handle array byte), _in: (addr array byte) {
+406   var in/esi: (addr array byte) <- copy _in
+407   var n/ecx: int <- length in
+408   var out/edx: (addr handle array byte) <- copy _out
+409   populate out, n
+410   var _out-addr/eax: (addr array byte) <- lookup *out
+411   var out-addr/edx: (addr array byte) <- copy _out-addr
+412   var i/eax: int <- copy 0
+413   {
+414     compare i, n
+415     break-if->=
+416     var src/esi: (addr byte) <- index in, i
+417     var val/ecx: byte <- copy-byte *src
+418     var dest/edi: (addr byte) <- index out-addr, i
+419     copy-byte-to *dest, val
+420     i <- increment
+421     loop
+422   }
+423 }
+424 
+425 fn initialize-path-from-sandbox _in: (addr sandbox), _out: (addr handle call-path-element) {
+426   var sandbox/esi: (addr sandbox) <- copy _in
+427   var line-ah/eax: (addr handle line) <- get sandbox, data
+428   var line/eax: (addr line) <- lookup *line-ah
+429   var src/esi: (addr handle word) <- get line, data
+430   var out-ah/edi: (addr handle call-path-element) <- copy _out
+431   var out/eax: (addr call-path-element) <- lookup *out-ah
+432   var dest/edi: (addr handle word) <- get out, word
+433   copy-object src, dest
+434 }
+435 
+436 fn initialize-path-from-line _line: (addr line), _out: (addr handle call-path-element) {
+437   var line/eax: (addr line) <- copy _line
+438   var src/esi: (addr handle word) <- get line, data
+439   var out-ah/edi: (addr handle call-path-element) <- copy _out
+440   var out/eax: (addr call-path-element) <- lookup *out-ah
+441   var dest/edi: (addr handle word) <- get out, word
+442   copy-object src, dest
+443 }
+444 
+445 fn find-in-call-paths call-paths: (addr handle call-path), needle: (addr handle call-path-element) -> result/eax: boolean {
+446   var curr-ah/esi: (addr handle call-path) <- copy call-paths
+447   var out/edi: boolean <- copy 0  # false
+448   $find-in-call-path:loop: {
+449     var curr/eax: (addr call-path) <- lookup *curr-ah
+450     compare curr, 0
+451     break-if-=
+452     {
+453       var curr-data/eax: (addr handle call-path-element) <- get curr, data
+454       var match?/eax: boolean <- call-path-element-match? curr-data, needle
+455       compare match?, 0  # false
+456       {
+457         break-if-=
+458         out <- copy 1  # true
+459         break $find-in-call-path:loop
+460       }
+461     }
+462     curr-ah <- get curr, next
+463     loop
+464   }
+465   result <- copy out
+466 }
+467 
+468 fn call-path-element-match? _x: (addr handle call-path-element), _y: (addr handle call-path-element) -> result/eax: boolean {
+469 $call-path-element-match?:body: {
+470   var x-ah/eax: (addr handle call-path-element) <- copy _x
+471   var x-a/eax: (addr call-path-element) <- lookup *x-ah
+472   var x/esi: (addr call-path-element) <- copy x-a
+473   var y-ah/eax: (addr handle call-path-element) <- copy _y
+474   var y-a/eax: (addr call-path-element) <- lookup *y-ah
+475   var y/edi: (addr call-path-element) <- copy y-a
+476   compare x, y
+477   {
+478     break-if-!=
+479     result <- copy 1  # true
+480     break $call-path-element-match?:body
+481   }
+482   compare x, 0
+483   {
+484     break-if-!=
+485     result <- copy 0  # false
+486     break $call-path-element-match?:body
+487   }
+488   compare y, 0
+489   {
+490     break-if-!=
+491     result <- copy 0  # false
+492     break $call-path-element-match?:body
+493   }
+494   # compare word addresses, not contents
+495   var x-data-ah/ecx: (addr handle word) <- get x, word
+496   var x-data-a/eax: (addr word) <- lookup *x-data-ah
+497   var x-data/ecx: int <- copy x-data-a
+498   var y-data-ah/eax: (addr handle word) <- get y, word
+499   var y-data-a/eax: (addr word) <- lookup *y-data-ah
+500   var y-data/eax: int <- copy y-data-a
+501 #?   print-string 0, "match? "
+502 #?   print-int32-hex 0, x-data
+503 #?   print-string 0, " vs "
+504 #?   print-int32-hex 0, y-data
+505 #?   print-string 0, "\n"
+506   compare x-data, y-data
+507   {
+508     break-if-=
+509     result <- copy 0  # false
+510     break $call-path-element-match?:body
+511   }
+512   var x-next/ecx: (addr handle call-path-element) <- get x, next
+513   var y-next/eax: (addr handle call-path-element) <- get y, next
+514   result <- call-path-element-match? x-next, y-next
+515 }
+516 }
+517 
+518 # order is irrelevant
+519 fn insert-in-call-path list: (addr handle call-path), new: (addr handle call-path-element) {
+520   var new-path-storage: (handle call-path)
+521   var new-path-ah/edi: (addr handle call-path) <- address new-path-storage
+522   allocate new-path-ah
+523   var new-path/eax: (addr call-path) <- lookup *new-path-ah
+524   var next/ecx: (addr handle call-path) <- get new-path, next
+525   copy-object list, next
+526   var dest/ecx: (addr handle call-path-element) <- get new-path, data
+527   deep-copy-call-path-element new, dest
+528   copy-object new-path-ah, list
+529 }
+530 
+531 # assumes dest is initially clear
+532 fn deep-copy-call-path-element _src: (addr handle call-path-element), _dest: (addr handle call-path-element) {
+533   var src/esi: (addr handle call-path-element) <- copy _src
+534   # if src is null, return
+535   var _src-addr/eax: (addr call-path-element) <- lookup *src
+536   compare _src-addr, 0
+537   break-if-=
+538   # allocate
+539   var src-addr/esi: (addr call-path-element) <- copy _src-addr
+540   var dest/eax: (addr handle call-path-element) <- copy _dest
+541   allocate dest
+542   # copy data
+543   var dest-addr/eax: (addr call-path-element) <- lookup *dest
+544   {
+545     var dest-data-addr/ecx: (addr handle word) <- get dest-addr, word
+546     var src-data-addr/eax: (addr handle word) <- get src-addr, word
+547     copy-object src-data-addr, dest-data-addr
+548   }
+549   # recurse
+550   var src-next/esi: (addr handle call-path-element) <- get src-addr, next
+551   var dest-next/eax: (addr handle call-path-element) <- get dest-addr, next
+552   deep-copy-call-path-element src-next, dest-next
+553 }
+554 
+555 fn delete-in-call-path list: (addr handle call-path), needle: (addr handle call-path-element) {
+556 $delete-in-call-path:body: {
+557   var curr-ah/esi: (addr handle call-path) <- copy list
+558   $delete-in-call-path:loop: {
+559     var _curr/eax: (addr call-path) <- lookup *curr-ah
+560     var curr/ecx: (addr call-path) <- copy _curr
+561     compare curr, 0
+562     break-if-=
+563     {
+564       var curr-data/eax: (addr handle call-path-element) <- get curr, data
+565       var match?/eax: boolean <- call-path-element-match? curr-data, needle
+566       compare match?, 0  # false
+567       {
+568         break-if-=
+569         var next-ah/ecx: (addr handle call-path) <- get curr, next
+570         copy-object next-ah, curr-ah
+571         loop $delete-in-call-path:loop
+572       }
+573     }
+574     curr-ah <- get curr, next
+575     loop
+576   }
+577 }
+578 }
+579 
+580 fn increment-final-element list: (addr handle call-path-element) {
+581   var final-ah/eax: (addr handle call-path-element) <- copy list
+582   var final/eax: (addr call-path-element) <- lookup *final-ah
+583   var val-ah/ecx: (addr handle word) <- get final, word
+584   var val/eax: (addr word) <- lookup *val-ah
+585   var new-ah/edx: (addr handle word) <- get val, next
+586   var target/eax: (addr word) <- lookup *new-ah
+587   compare target, 0
+588   break-if-=
+589   copy-object new-ah, val-ah
+590 }
+591 
+592 fn decrement-final-element list: (addr handle call-path-element) {
+593   var final-ah/eax: (addr handle call-path-element) <- copy list
+594   var final/eax: (addr call-path-element) <- lookup *final-ah
+595   var val-ah/ecx: (addr handle word) <- get final, word
+596   var val/eax: (addr word) <- lookup *val-ah
+597   var new-ah/edx: (addr handle word) <- get val, prev
+598   var target/eax: (addr word) <- lookup *new-ah
+599   compare target, 0
+600   break-if-=
+601   copy-object new-ah, val-ah
+602 }
+603 
+604 fn move-final-element-to-start-of-line list: (addr handle call-path-element) {
+605   var final-ah/eax: (addr handle call-path-element) <- copy list
+606   var final/eax: (addr call-path-element) <- lookup *final-ah
+607   var val-ah/ecx: (addr handle word) <- get final, word
+608   var val/eax: (addr word) <- lookup *val-ah
+609   var new-ah/edx: (addr handle word) <- get val, prev
+610   var target/eax: (addr word) <- lookup *new-ah
+611   compare target, 0
+612   break-if-=
+613   copy-object new-ah, val-ah
+614   move-final-element-to-start-of-line list
+615 }
+616 
+617 fn push-to-call-path-element list: (addr handle call-path-element), new: (addr handle word) {
+618   var new-element-storage: (handle call-path-element)
+619   var new-element-ah/edi: (addr handle call-path-element) <- address new-element-storage
+620   allocate new-element-ah
+621   var new-element/eax: (addr call-path-element) <- lookup *new-element-ah
+622   # save word
+623   var dest/ecx: (addr handle word) <- get new-element, word
+624   copy-object new, dest
+625   # save next
+626   var dest2/ecx: (addr handle call-path-element) <- get new-element, next
+627   copy-object list, dest2
+628   # return
+629   copy-object new-element-ah, list
+630 }
+631 
+632 fn drop-from-call-path-element _list: (addr handle call-path-element) {
+633   var list-ah/esi: (addr handle call-path-element) <- copy _list
+634   var list/eax: (addr call-path-element) <- lookup *list-ah
+635   var next/eax: (addr handle call-path-element) <- get list, next
+636   copy-object next, _list
+637 }
+638 
+639 fn drop-nested-calls _list: (addr handle call-path-element) {
+640   var list-ah/esi: (addr handle call-path-element) <- copy _list
+641   var list/eax: (addr call-path-element) <- lookup *list-ah
+642   var next-ah/edi: (addr handle call-path-element) <- get list, next
+643   var next/eax: (addr call-path-element) <- lookup *next-ah
+644   compare next, 0
+645   break-if-=
+646   copy-object next-ah, _list
+647   drop-nested-calls _list
+648 }
+649 
+650 fn dump-call-path-element screen: (addr screen), _x-ah: (addr handle call-path-element) {
+651 $dump-call-path-element:body: {
+652   var x-ah/ecx: (addr handle call-path-element) <- copy _x-ah
+653   var _x/eax: (addr call-path-element) <- lookup *x-ah
+654   var x/esi: (addr call-path-element) <- copy _x
+655   var word-ah/eax: (addr handle word) <- get x, word
+656   var word/eax: (addr word) <- lookup *word-ah
+657   print-word screen, word
+658   var next-ah/ecx: (addr handle call-path-element) <- get x, next
+659   var next/eax: (addr call-path-element) <- lookup *next-ah
+660   compare next, 0
+661   {
+662     break-if-=
+663     print-string screen, " "
+664     dump-call-path-element screen, next-ah
+665     break $dump-call-path-element:body
+666   }
+667   {
+668     break-if-!=
+669     print-string screen, "\n"
+670   }
+671 }
+672 }
+673 
+674 fn dump-call-paths screen: (addr screen), _x-ah: (addr handle call-path) {
+675 $dump-call-paths:body: {
+676   var x-ah/ecx: (addr handle call-path) <- copy _x-ah
+677   var x/eax: (addr call-path) <- lookup *x-ah
+678   compare x, 0
+679   break-if-=
+680   var src/ecx: (addr handle call-path-element) <- get x, data
+681   dump-call-path-element screen, src
+682   var next-ah/ecx: (addr handle call-path) <- get x, next
+683   var next/eax: (addr call-path) <- lookup *next-ah
+684   compare next, 0
+685   {
+686     break-if-=
+687     dump-call-paths screen, next-ah
+688     break $dump-call-paths:body
+689   }
+690 }
+691 }
 
-- cgit 1.4.1-2-gfad0