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/word.mu.html | 591 ++++++++++++++++++++++++++++++-------------- 1 file changed, 409 insertions(+), 182 deletions(-) (limited to 'html/apps/tile/word.mu.html') diff --git a/html/apps/tile/word.mu.html b/html/apps/tile/word.mu.html index 2b93eff1..64fc37c0 100644 --- a/html/apps/tile/word.mu.html +++ b/html/apps/tile/word.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; } @@ -107,189 +108,415 @@ if ('onhashchange' in window) { 49 50 ## real primitives 51 - 52 fn word-equal? _self: (addr word), s: (addr array byte) -> result/eax: boolean { - 53 var self/esi: (addr word) <- copy _self - 54 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data - 55 var data/eax: (addr gap-buffer) <- lookup *data-ah - 56 result <- gap-buffer-equal? data, s - 57 } - 58 - 59 fn word-length _self: (addr word) -> result/eax: int { - 60 var self/esi: (addr word) <- copy _self - 61 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data - 62 var data/eax: (addr gap-buffer) <- lookup *data-ah - 63 result <- gap-buffer-length data - 64 } - 65 - 66 fn first-word _self: (addr word) -> result/eax: (addr word) { - 67 var self/esi: (addr word) <- copy _self - 68 var out/edi: (addr word) <- copy self - 69 var prev/esi: (addr handle word) <- get self, prev - 70 { - 71 var curr/eax: (addr word) <- lookup *prev - 72 compare curr, 0 - 73 break-if-= - 74 out <- copy curr - 75 prev <- get curr, prev - 76 loop - 77 } - 78 result <- copy out - 79 } - 80 - 81 fn final-word _self: (addr word) -> result/eax: (addr word) { - 82 var self/esi: (addr word) <- copy _self - 83 var out/edi: (addr word) <- copy self - 84 var next/esi: (addr handle word) <- get self, next - 85 { - 86 var curr/eax: (addr word) <- lookup *next - 87 compare curr, 0 - 88 break-if-= - 89 out <- copy curr - 90 next <- get curr, next - 91 loop - 92 } - 93 result <- copy out - 94 } - 95 - 96 fn first-grapheme _self: (addr word) -> result/eax: grapheme { - 97 var self/esi: (addr word) <- copy _self - 98 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data - 99 var data/eax: (addr gap-buffer) <- lookup *data-ah -100 result <- first-grapheme-in-gap-buffer data -101 } -102 -103 fn add-grapheme-to-word _self: (addr word), c: grapheme { -104 var self/esi: (addr word) <- copy _self -105 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -106 var data/eax: (addr gap-buffer) <- lookup *data-ah -107 add-grapheme-at-gap data, c -108 } -109 -110 fn cursor-at-start? _self: (addr word) -> result/eax: boolean { -111 var self/esi: (addr word) <- copy _self -112 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -113 var data/eax: (addr gap-buffer) <- lookup *data-ah -114 result <- gap-at-start? data -115 } -116 -117 fn cursor-at-end? _self: (addr word) -> result/eax: boolean { -118 var self/esi: (addr word) <- copy _self -119 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -120 var data/eax: (addr gap-buffer) <- lookup *data-ah -121 result <- gap-at-end? data -122 } -123 -124 fn cursor-left _self: (addr word) { -125 var self/esi: (addr word) <- copy _self -126 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -127 var data/eax: (addr gap-buffer) <- lookup *data-ah -128 var dummy/eax: grapheme <- gap-left data -129 } -130 -131 fn cursor-right _self: (addr word) { -132 var self/esi: (addr word) <- copy _self -133 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -134 var data/eax: (addr gap-buffer) <- lookup *data-ah -135 var dummy/eax: grapheme <- gap-right data -136 } -137 -138 fn cursor-to-start _self: (addr word) { -139 var self/esi: (addr word) <- copy _self -140 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -141 var data/eax: (addr gap-buffer) <- lookup *data-ah -142 gap-to-start data -143 } -144 -145 fn cursor-to-end _self: (addr word) { -146 var self/esi: (addr word) <- copy _self -147 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -148 var data/eax: (addr gap-buffer) <- lookup *data-ah -149 gap-to-end data -150 } -151 -152 fn cursor-index _self: (addr word) -> result/eax: int { -153 var self/esi: (addr word) <- copy _self -154 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -155 var data/eax: (addr gap-buffer) <- lookup *data-ah -156 result <- gap-index data -157 } -158 -159 fn delete-before-cursor _self: (addr word) { -160 var self/esi: (addr word) <- copy _self -161 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -162 var data/eax: (addr gap-buffer) <- lookup *data-ah -163 delete-before-gap data -164 } -165 -166 fn delete-next _self: (addr word) { -167 $delete-next:body: { + 52 fn move-word-contents _src-ah: (addr handle word), _dest-ah: (addr handle word) { + 53 var dest-ah/eax: (addr handle word) <- copy _dest-ah + 54 var _dest/eax: (addr word) <- lookup *dest-ah + 55 var dest/edi: (addr word) <- copy _dest + 56 var src-ah/eax: (addr handle word) <- copy _src-ah + 57 var _src/eax: (addr word) <- lookup *src-ah + 58 var src/esi: (addr word) <- copy _src + 59 cursor-to-start src + 60 var src-data-ah/eax: (addr handle gap-buffer) <- get src, scalar-data + 61 var src-data/eax: (addr gap-buffer) <- lookup *src-data-ah + 62 var src-stack/ecx: (addr grapheme-stack) <- get src-data, right + 63 { + 64 var done?/eax: boolean <- grapheme-stack-empty? src-stack + 65 compare done?, 0 # false + 66 break-if-!= + 67 var g/eax: grapheme <- pop-grapheme-stack src-stack + 68 #? print-grapheme 0, g + 69 #? print-string 0, "\n" + 70 add-grapheme-to-word dest, g + 71 loop + 72 } + 73 } + 74 + 75 fn copy-word-contents-before-cursor _src-ah: (addr handle word), _dest-ah: (addr handle word) { + 76 var dest-ah/eax: (addr handle word) <- copy _dest-ah + 77 var _dest/eax: (addr word) <- lookup *dest-ah + 78 var dest/edi: (addr word) <- copy _dest + 79 var src-ah/eax: (addr handle word) <- copy _src-ah + 80 var src/eax: (addr word) <- lookup *src-ah + 81 var src-data-ah/eax: (addr handle gap-buffer) <- get src, scalar-data + 82 var src-data/eax: (addr gap-buffer) <- lookup *src-data-ah + 83 var src-stack/ecx: (addr grapheme-stack) <- get src-data, left + 84 var src-stack-data-ah/eax: (addr handle array grapheme) <- get src-stack, data + 85 var _src-stack-data/eax: (addr array grapheme) <- lookup *src-stack-data-ah + 86 var src-stack-data/edx: (addr array grapheme) <- copy _src-stack-data + 87 var top-addr/ecx: (addr int) <- get src-stack, top + 88 var i/eax: int <- copy 0 + 89 { + 90 compare i, *top-addr + 91 break-if->= + 92 var g/edx: (addr grapheme) <- index src-stack-data, i + 93 add-grapheme-to-word dest, *g + 94 i <- increment + 95 loop + 96 } + 97 } + 98 + 99 fn word-equal? _self: (addr word), s: (addr array byte) -> result/eax: boolean { +100 var self/esi: (addr word) <- copy _self +101 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +102 var data/eax: (addr gap-buffer) <- lookup *data-ah +103 result <- gap-buffer-equal? data, s +104 } +105 +106 fn word-length _self: (addr word) -> result/eax: int { +107 var self/esi: (addr word) <- copy _self +108 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +109 var data/eax: (addr gap-buffer) <- lookup *data-ah +110 result <- gap-buffer-length data +111 } +112 +113 fn first-word _in: (addr handle word), out: (addr handle word) { +114 var curr-ah/esi: (addr handle word) <- copy _in +115 var curr/eax: (addr word) <- lookup *curr-ah +116 var prev/edi: (addr handle word) <- copy 0 +117 { +118 prev <- get curr, prev +119 var curr/eax: (addr word) <- lookup *prev +120 compare curr, 0 +121 break-if-= +122 copy-object prev, curr-ah +123 loop +124 } +125 copy-object curr-ah, out +126 } +127 +128 fn final-word _in: (addr handle word), out: (addr handle word) { +129 var curr-h: (handle word) +130 var curr-ah/esi: (addr handle word) <- address curr-h +131 copy-object _in, curr-ah +132 var curr/eax: (addr word) <- copy 0 +133 var next/edi: (addr handle word) <- copy 0 +134 { +135 curr <- lookup *curr-ah +136 next <- get curr, next +137 curr <- lookup *next +138 compare curr, 0 +139 break-if-= +140 copy-object next, curr-ah +141 loop +142 } +143 copy-object curr-ah, out +144 } +145 +146 fn first-grapheme _self: (addr word) -> result/eax: grapheme { +147 var self/esi: (addr word) <- copy _self +148 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +149 var data/eax: (addr gap-buffer) <- lookup *data-ah +150 result <- first-grapheme-in-gap-buffer data +151 } +152 +153 fn add-grapheme-to-word _self: (addr word), c: grapheme { +154 var self/esi: (addr word) <- copy _self +155 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +156 var data/eax: (addr gap-buffer) <- lookup *data-ah +157 add-grapheme-at-gap data, c +158 } +159 +160 fn cursor-at-start? _self: (addr word) -> result/eax: boolean { +161 var self/esi: (addr word) <- copy _self +162 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +163 var data/eax: (addr gap-buffer) <- lookup *data-ah +164 result <- gap-at-start? data +165 } +166 +167 fn cursor-at-end? _self: (addr word) -> result/eax: boolean { 168 var self/esi: (addr word) <- copy _self -169 var next-ah/edi: (addr handle word) <- get self, next -170 var next/eax: (addr word) <- lookup *next-ah -171 compare next, 0 -172 break-if-= $delete-next:body -173 var next-next-ah/ecx: (addr handle word) <- get next, next -174 var self-ah/esi: (addr handle word) <- get next, prev -175 copy-object next-next-ah, next-ah -176 var new-next/eax: (addr word) <- lookup *next-next-ah -177 compare new-next, 0 -178 break-if-= $delete-next:body -179 var dest/eax: (addr handle word) <- get new-next, prev -180 copy-object self-ah, dest -181 } -182 } -183 -184 fn print-word screen: (addr screen), _self: (addr word) { -185 var self/esi: (addr word) <- copy _self -186 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -187 var data/eax: (addr gap-buffer) <- lookup *data-ah -188 render-gap-buffer screen, data -189 } -190 -191 # one implication of handles: append must take a handle -192 fn append-word _self-ah: (addr handle word) { -193 var self-ah/esi: (addr handle word) <- copy _self-ah -194 var _self/eax: (addr word) <- lookup *self-ah -195 var self/ebx: (addr word) <- copy _self -196 # allocate new handle -197 var new: (handle word) -198 var new-ah/ecx: (addr handle word) <- address new -199 allocate new-ah -200 var new-addr/eax: (addr word) <- lookup new -201 initialize-word new-addr -202 # new->next = self->next -203 var src/esi: (addr handle word) <- get self, next -204 var dest/edi: (addr handle word) <- get new-addr, next -205 copy-object src, dest -206 # new->next->prev = new -207 { -208 var next-addr/eax: (addr word) <- lookup *src -209 compare next-addr, 0 -210 break-if-= -211 dest <- get next-addr, prev -212 copy-object new-ah, dest -213 } -214 # new->prev = self -215 dest <- get new-addr, prev -216 copy-object _self-ah, dest -217 # self->next = new -218 dest <- get self, next -219 copy-object new-ah, dest -220 } -221 -222 fn emit-word _self: (addr word), out: (addr stream byte) { -223 var self/esi: (addr word) <- copy _self -224 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -225 var data/eax: (addr gap-buffer) <- lookup *data-ah -226 emit-gap-buffer data, out -227 } -228 -229 fn word-to-string _self: (addr word), out: (addr handle array byte) { -230 var self/esi: (addr word) <- copy _self -231 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -232 var data/eax: (addr gap-buffer) <- lookup *data-ah -233 gap-buffer-to-string data, out -234 } +169 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +170 var data/eax: (addr gap-buffer) <- lookup *data-ah +171 result <- gap-at-end? data +172 } +173 +174 fn cursor-left _self: (addr word) { +175 var self/esi: (addr word) <- copy _self +176 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +177 var data/eax: (addr gap-buffer) <- lookup *data-ah +178 var dummy/eax: grapheme <- gap-left data +179 } +180 +181 fn cursor-right _self: (addr word) { +182 var self/esi: (addr word) <- copy _self +183 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +184 var data/eax: (addr gap-buffer) <- lookup *data-ah +185 var dummy/eax: grapheme <- gap-right data +186 } +187 +188 fn cursor-to-start _self: (addr word) { +189 var self/esi: (addr word) <- copy _self +190 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +191 var data/eax: (addr gap-buffer) <- lookup *data-ah +192 gap-to-start data +193 } +194 +195 fn cursor-to-end _self: (addr word) { +196 var self/esi: (addr word) <- copy _self +197 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +198 var data/eax: (addr gap-buffer) <- lookup *data-ah +199 gap-to-end data +200 } +201 +202 fn cursor-index _self: (addr word) -> result/eax: int { +203 var self/esi: (addr word) <- copy _self +204 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +205 var data/eax: (addr gap-buffer) <- lookup *data-ah +206 result <- gap-index data +207 } +208 +209 fn delete-before-cursor _self: (addr word) { +210 var self/esi: (addr word) <- copy _self +211 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +212 var data/eax: (addr gap-buffer) <- lookup *data-ah +213 delete-before-gap data +214 } +215 +216 fn delete-next _self: (addr word) { +217 $delete-next:body: { +218 var self/esi: (addr word) <- copy _self +219 var next-ah/edi: (addr handle word) <- get self, next +220 var next/eax: (addr word) <- lookup *next-ah +221 compare next, 0 +222 break-if-= $delete-next:body +223 var next-next-ah/ecx: (addr handle word) <- get next, next +224 var self-ah/esi: (addr handle word) <- get next, prev +225 copy-object next-next-ah, next-ah +226 var new-next/eax: (addr word) <- lookup *next-next-ah +227 compare new-next, 0 +228 break-if-= $delete-next:body +229 var dest/eax: (addr handle word) <- get new-next, prev +230 copy-object self-ah, dest +231 } +232 } +233 +234 fn print-word screen: (addr screen), _self: (addr word) { +235 var self/esi: (addr word) <- copy _self +236 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +237 var data/eax: (addr gap-buffer) <- lookup *data-ah +238 render-gap-buffer screen, data +239 } +240 +241 fn print-words screen: (addr screen), _words-ah: (addr handle word) { +242 var words-ah/eax: (addr handle word) <- copy _words-ah +243 var words-a/eax: (addr word) <- lookup *words-ah +244 compare words-a, 0 +245 break-if-= +246 # print +247 print-word screen, words-a +248 print-string screen, " " +249 # recurse +250 var next-ah/eax: (addr handle word) <- get words-a, next +251 print-words screen, next-ah +252 } +253 +254 fn print-words-in-reverse screen: (addr screen), _words-ah: (addr handle word) { +255 var words-ah/eax: (addr handle word) <- copy _words-ah +256 var words-a/eax: (addr word) <- lookup *words-ah +257 compare words-a, 0 +258 break-if-= +259 # recurse +260 var next-ah/ecx: (addr handle word) <- get words-a, next +261 print-words screen, next-ah +262 # print +263 print-word screen, words-a +264 print-string screen, " " +265 } +266 +267 # Gotcha with some word operations: ensure dest-ah isn't in the middle of some +268 # existing chain of words. There are two pointers to patch, and you'll forget +269 # to do the other one. +270 fn copy-words _src-ah: (addr handle word), _dest-ah: (addr handle word) { +271 var src-ah/eax: (addr handle word) <- copy _src-ah +272 var src-a/eax: (addr word) <- lookup *src-ah +273 compare src-a, 0 +274 break-if-= +275 # copy +276 var dest-ah/edi: (addr handle word) <- copy _dest-ah +277 copy-word src-a, dest-ah +278 # recurse +279 var rest: (handle word) +280 var rest-ah/ecx: (addr handle word) <- address rest +281 var next-src-ah/esi: (addr handle word) <- get src-a, next +282 copy-words next-src-ah, rest-ah +283 chain-words dest-ah, rest-ah +284 } +285 +286 fn copy-words-in-reverse _src-ah: (addr handle word), _dest-ah: (addr handle word) { +287 var src-ah/eax: (addr handle word) <- copy _src-ah +288 var _src-a/eax: (addr word) <- lookup *src-ah +289 var src-a/esi: (addr word) <- copy _src-a +290 compare src-a, 0 +291 break-if-= +292 # recurse +293 var next-src-ah/ecx: (addr handle word) <- get src-a, next +294 var dest-ah/edi: (addr handle word) <- copy _dest-ah +295 copy-words-in-reverse next-src-ah, dest-ah +296 # +297 copy-word-at-end src-a, dest-ah +298 } +299 +300 fn copy-word-at-end src: (addr word), _dest-ah: (addr handle word) { +301 $copy-word-at-end:body: { +302 var dest-ah/edi: (addr handle word) <- copy _dest-ah +303 # if dest is null, copy and return +304 var dest-a/eax: (addr word) <- lookup *dest-ah +305 compare dest-a, 0 +306 { +307 break-if-!= +308 copy-word src, dest-ah +309 break $copy-word-at-end:body +310 } +311 # copy current word +312 var new: (handle word) +313 var new-ah/ecx: (addr handle word) <- address new +314 copy-word src, new-ah +315 # append it at the end +316 var curr-ah/edi: (addr handle word) <- copy dest-ah +317 { +318 var curr-a/eax: (addr word) <- lookup *curr-ah # curr-a guaranteed not to be null +319 var next-ah/ecx: (addr handle word) <- get curr-a, next +320 var next-a/eax: (addr word) <- lookup *next-ah +321 compare next-a, 0 +322 break-if-= +323 curr-ah <- copy next-ah +324 loop +325 } +326 chain-words curr-ah, new-ah +327 } +328 } +329 +330 fn append-word-at-end-with _dest-ah: (addr handle word), s: (addr array byte) { +331 $append-word-at-end-with:body: { +332 var dest-ah/edi: (addr handle word) <- copy _dest-ah +333 # if dest is null, copy and return +334 var dest-a/eax: (addr word) <- lookup *dest-ah +335 compare dest-a, 0 +336 { +337 break-if-!= +338 allocate-word-with dest-ah, s +339 break $append-word-at-end-with:body +340 } +341 # otherwise append at end +342 var curr-ah/edi: (addr handle word) <- copy dest-ah +343 { +344 var curr-a/eax: (addr word) <- lookup *curr-ah # curr-a guaranteed not to be null +345 var next-ah/ecx: (addr handle word) <- get curr-a, next +346 var next-a/eax: (addr word) <- lookup *next-ah +347 compare next-a, 0 +348 break-if-= +349 curr-ah <- copy next-ah +350 loop +351 } +352 append-word-with *curr-ah, s +353 } +354 } +355 +356 fn copy-word _src-a: (addr word), _dest-ah: (addr handle word) { +357 var dest-ah/eax: (addr handle word) <- copy _dest-ah +358 allocate dest-ah +359 var _dest-a/eax: (addr word) <- lookup *dest-ah +360 var dest-a/eax: (addr word) <- copy _dest-a +361 initialize-word dest-a +362 var dest/edi: (addr handle gap-buffer) <- get dest-a, scalar-data +363 var src-a/eax: (addr word) <- copy _src-a +364 var src/eax: (addr handle gap-buffer) <- get src-a, scalar-data +365 copy-gap-buffer src, dest +366 } +367 +368 # one implication of handles: append must take a handle +369 fn append-word _self-ah: (addr handle word) { +370 var self-ah/esi: (addr handle word) <- copy _self-ah +371 var _self/eax: (addr word) <- lookup *self-ah +372 var self/ebx: (addr word) <- copy _self +373 # allocate new handle +374 var new: (handle word) +375 var new-ah/ecx: (addr handle word) <- address new +376 allocate new-ah +377 var new-addr/eax: (addr word) <- lookup new +378 initialize-word new-addr +379 # new->next = self->next +380 var src/esi: (addr handle word) <- get self, next +381 var dest/edi: (addr handle word) <- get new-addr, next +382 copy-object src, dest +383 # new->next->prev = new +384 { +385 var next-addr/eax: (addr word) <- lookup *src +386 compare next-addr, 0 +387 break-if-= +388 dest <- get next-addr, prev +389 copy-object new-ah, dest +390 } +391 # new->prev = self +392 dest <- get new-addr, prev +393 copy-object _self-ah, dest +394 # self->next = new +395 dest <- get self, next +396 copy-object new-ah, dest +397 } +398 +399 fn chain-words _self-ah: (addr handle word), _next: (addr handle word) { +400 var self-ah/esi: (addr handle word) <- copy _self-ah +401 var _self/eax: (addr word) <- lookup *self-ah +402 var self/ecx: (addr word) <- copy _self +403 var dest/edx: (addr handle word) <- get self, next +404 var next-ah/edi: (addr handle word) <- copy _next +405 copy-object next-ah, dest +406 var next/eax: (addr word) <- lookup *next-ah +407 compare next, 0 +408 break-if-= +409 dest <- get next, prev +410 copy-object self-ah, dest +411 } +412 +413 fn emit-word _self: (addr word), out: (addr stream byte) { +414 var self/esi: (addr word) <- copy _self +415 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +416 var data/eax: (addr gap-buffer) <- lookup *data-ah +417 emit-gap-buffer data, out +418 } +419 +420 fn word-to-string _self: (addr word), out: (addr handle array byte) { +421 var self/esi: (addr word) <- copy _self +422 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +423 var data/eax: (addr gap-buffer) <- lookup *data-ah +424 gap-buffer-to-string data, out +425 } +426 +427 fn word-is-decimal-integer? _self: (addr word) -> result/eax: boolean { +428 var self/eax: (addr word) <- copy _self +429 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +430 var data/eax: (addr gap-buffer) <- lookup *data-ah +431 result <- gap-buffer-is-decimal-integer? data +432 } +433 +434 # ABSOLUTELY GHASTLY +435 fn word-exists? _haystack-ah: (addr handle word), _needle: (addr word) -> result/ebx: boolean { +436 var needle-name-storage: (handle addr byte) +437 var needle-name-ah/eax: (addr handle array byte) <- address needle-name-storage +438 word-to-string _needle, needle-name-ah # profligate leak +439 var _needle-name/eax: (addr array byte) <- lookup *needle-name-ah +440 var needle-name/edi: (addr array byte) <- copy _needle-name +441 # base case +442 result <- copy 0 # false +443 var haystack-ah/esi: (addr handle word) <- copy _haystack-ah +444 var curr/eax: (addr word) <- lookup *haystack-ah +445 compare curr, 0 +446 break-if-= +447 # check curr +448 var curr-name-storage: (handle addr byte) +449 var curr-name-ah/ecx: (addr handle array byte) <- address curr-name-storage +450 word-to-string curr, curr-name-ah # profligate leak +451 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah +452 var found?/eax: boolean <- string-equal? needle-name, curr-name +453 result <- copy found? +454 compare result, 0 +455 break-if-!= +456 # recurse +457 var curr/eax: (addr word) <- lookup *haystack-ah +458 var next-haystack-ah/eax: (addr handle word) <- get curr, next +459 result <- word-exists? next-haystack-ah, _needle +460 } -- cgit 1.4.1-2-gfad0