From 74ed21ab147a7ea6b6bcc37162c52405c80a3257 Mon Sep 17 00:00:00 2001
From: Kartik Agaram
- 1 type line { + 1 type line { 2 name: (handle array byte) - 3 data: (handle word) - 4 cursor: (handle word) - 5 next: (handle line) - 6 prev: (handle line) + 3 data: (handle word) + 4 cursor: (handle word) + 5 next: (handle line) + 6 prev: (handle line) 7 } 8 9 # initialize line with a single empty word - 10 fn initialize-line _line: (addr line) { - 11 var line/esi: (addr line) <- copy _line - 12 var word-ah/eax: (addr handle word) <- get line, data - 13 allocate word-ah - 14 var cursor-ah/ecx: (addr handle word) <- get line, cursor + 10 fn initialize-line _line: (addr line) { + 11 var line/esi: (addr line) <- copy _line + 12 var word-ah/eax: (addr handle word) <- get line, data + 13 allocate word-ah + 14 var cursor-ah/ecx: (addr handle word) <- get line, cursor 15 copy-object word-ah, cursor-ah - 16 var word/eax: (addr word) <- lookup *word-ah - 17 initialize-word word + 16 var word/eax: (addr word) <- lookup *word-ah + 17 initialize-word word 18 } 19 - 20 fn num-words-in-line _in: (addr line) -> _/eax: int { - 21 var in/esi: (addr line) <- copy _in - 22 var curr-ah/ecx: (addr handle word) <- get in, data + 20 fn num-words-in-line _in: (addr line) -> _/eax: int { + 21 var in/esi: (addr line) <- copy _in + 22 var curr-ah/ecx: (addr handle word) <- get in, data 23 var result/edi: int <- copy 0 24 { - 25 var curr/eax: (addr word) <- lookup *curr-ah + 25 var curr/eax: (addr word) <- lookup *curr-ah 26 compare curr, 0 27 break-if-= - 28 curr-ah <- get curr, next + 28 curr-ah <- get curr, next 29 result <- increment 30 loop 31 } 32 return result 33 } 34 - 35 fn line-list-length lines: (addr handle line) -> _/eax: int { - 36 var curr-ah/esi: (addr handle line) <- copy lines + 35 fn line-list-length lines: (addr handle line) -> _/eax: int { + 36 var curr-ah/esi: (addr handle line) <- copy lines 37 var result/edi: int <- copy 0 38 { - 39 var curr/eax: (addr line) <- lookup *curr-ah + 39 var curr/eax: (addr line) <- lookup *curr-ah 40 compare curr, 0 41 break-if-= - 42 curr-ah <- get curr, next + 42 curr-ah <- get curr, next 43 result <- increment 44 loop 45 } 46 return result 47 } 48 - 49 fn render-line screen: (addr screen), _line: (addr line), x: int, y: int, render-cursor?: boolean -> _/eax: int { - 50 var line/eax: (addr line) <- copy _line - 51 var first-word-ah/esi: (addr handle word) <- get line, data + 49 fn render-line screen: (addr screen), _line: (addr line), x: int, y: int, render-cursor?: boolean -> _/eax: int { + 50 var line/eax: (addr line) <- copy _line + 51 var first-word-ah/esi: (addr handle word) <- get line, data 52 # cursor-word 53 var cursor-word/edi: int <- copy 0 54 compare render-cursor?, 0/false 55 { 56 break-if-= - 57 var cursor-word-ah/eax: (addr handle word) <- get line, cursor - 58 var _cursor-word/eax: (addr word) <- lookup *cursor-word-ah + 57 var cursor-word-ah/eax: (addr handle word) <- get line, cursor + 58 var _cursor-word/eax: (addr word) <- lookup *cursor-word-ah 59 cursor-word <- copy _cursor-word 60 } 61 # - 62 var result/eax: int <- render-words screen, first-word-ah, x, y, cursor-word + 62 var result/eax: int <- render-words screen, first-word-ah, x, y, cursor-word 63 return result 64 } 65 - 66 fn parse-line in: (addr array byte), _out: (addr line) { - 67 var out/edi: (addr line) <- copy _out - 68 initialize-line out - 69 var dest/eax: (addr handle word) <- get out, data - 70 parse-words in, dest + 66 fn parse-line in: (addr array byte), _out: (addr line) { + 67 var out/edi: (addr line) <- copy _out + 68 initialize-line out + 69 var dest/eax: (addr handle word) <- get out, data + 70 parse-words in, dest 71 } 72 73 #? fn main { @@ -146,28 +146,28 @@ if ('onhashchange' in window) { 86 #? var dummy/eax: int <- render-line 0/screen, line-addr, 0/x, 0/y, 1/render-cursor 87 #? } 88 - 89 fn render-line-with-stack screen: (addr screen), _line: (addr line), x: int, y: int, render-cursor?: boolean -> _/eax: int, _/ecx: int { - 90 var line/esi: (addr line) <- copy _line + 89 fn render-line-with-stack screen: (addr screen), _line: (addr line), x: int, y: int, render-cursor?: boolean -> _/eax: int, _/ecx: int { + 90 var line/esi: (addr line) <- copy _line 91 # cursor-word 92 var cursor-word/edi: int <- copy 0 93 compare render-cursor?, 0/false 94 { 95 break-if-= - 96 var cursor-word-ah/eax: (addr handle word) <- get line, cursor - 97 var _cursor-word/eax: (addr word) <- lookup *cursor-word-ah + 96 var cursor-word-ah/eax: (addr handle word) <- get line, cursor + 97 var _cursor-word/eax: (addr word) <- lookup *cursor-word-ah 98 cursor-word <- copy _cursor-word 99 } 100 # -101 var curr-word-ah/eax: (addr handle word) <- get line, data -102 var _curr-word/eax: (addr word) <- lookup *curr-word-ah -103 var curr-word/edx: (addr word) <- copy _curr-word +101 var curr-word-ah/eax: (addr handle word) <- get line, data +102 var _curr-word/eax: (addr word) <- lookup *curr-word-ah +103 var curr-word/edx: (addr word) <- copy _curr-word 104 var new-x/eax: int <- copy x # increases each iteration 105 var new-y/ebx: int <- copy y # compute max across all iterations 106 { 107 compare curr-word, 0 108 break-if-= 109 var curr-y/ecx: int <- copy 0 -110 new-x, curr-y <- render-word-with-stack-and-cursor screen, line, curr-word, new-x, y, cursor-word +110 new-x, curr-y <- render-word-with-stack-and-cursor screen, line, curr-word, new-x, y, cursor-word 111 compare curr-y, new-y 112 { 113 break-if-<= @@ -175,15 +175,15 @@ if ('onhashchange' in window) { 115 } 116 new-x <- add 1/inter-word-spacing 117 # update -118 var next-word-ah/eax: (addr handle word) <- get curr-word, next -119 var next-word/eax: (addr word) <- lookup *next-word-ah -120 curr-word <- copy next-word +118 var next-word-ah/eax: (addr handle word) <- get curr-word, next +119 var next-word/eax: (addr word) <- lookup *next-word-ah +120 curr-word <- copy next-word 121 loop 122 } 123 return new-x, new-y 124 } 125 -126 fn render-word-with-stack-and-cursor screen: (addr screen), line: (addr line), curr-word: (addr word), x: int, y: int, _cursor-word-addr: int -> _/eax: int, _/ecx: int { +126 fn render-word-with-stack-and-cursor screen: (addr screen), line: (addr line), curr-word: (addr word), x: int, y: int, _cursor-word-addr: int -> _/eax: int, _/ecx: int { 127 # print curr-word, with cursor if necessary 128 var render-cursor?/eax: boolean <- copy 0/false 129 var cursor-word-addr/ecx: int <- copy _cursor-word-addr @@ -192,16 +192,16 @@ if ('onhashchange' in window) { 132 break-if-!= 133 render-cursor? <- copy 1/true 134 } -135 var new-x/eax: int <- render-word screen, curr-word, x, y, render-cursor? +135 var new-x/eax: int <- render-word screen, curr-word, x, y, render-cursor? 136 var new-x-saved/edx: int <- copy new-x 137 add-to y, 2/word-stack-spacing 138 # compute stack until word -139 var stack-storage: value-stack -140 var stack/edi: (addr value-stack) <- address stack-storage -141 evaluate line, curr-word, stack +139 var stack-storage: value-stack +140 var stack/edi: (addr value-stack) <- address stack-storage +141 evaluate line, curr-word, stack 142 # render stack 143 var new-y/ecx: int <- copy 0 -144 new-x, new-y <- render-value-stack screen, stack, x, y +144 new-x, new-y <- render-value-stack screen, stack, x, y 145 #? draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, new-x, 0xc/fg, 0/bg 146 #? draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, new-y, 3/fg, 0/bg 147 compare new-x, new-x-saved @@ -213,81 +213,81 @@ if ('onhashchange' in window) { 153 return new-x, new-y 154 } 155 -156 fn test-render-line-with-stack-singleton { +156 fn test-render-line-with-stack-singleton { 157 # line = [1] -158 var line-storage: line -159 var line/esi: (addr line) <- address line-storage -160 parse-line "1", line +158 var line-storage: line +159 var line/esi: (addr line) <- address line-storage +160 parse-line "1", line 161 # setup: screen -162 var screen-on-stack: screen -163 var screen/edi: (addr screen) <- address screen-on-stack -164 initialize-screen screen, 0x20, 4 +162 var screen-on-stack: screen +163 var screen/edi: (addr screen) <- address screen-on-stack +164 initialize-screen screen, 0x20, 4 165 # 166 var new-x/eax: int <- copy 0 167 var new-y/ecx: int <- copy 0 -168 new-x, new-y <- render-line-with-stack screen, line, 0/x, 0/y, 0/no-cursor -169 check-screen-row screen, 0/y, "1 ", "F - test-render-line-with-stack-singleton/0" -170 check-screen-row screen, 1/y, " ", "F - test-render-line-with-stack-singleton/1" -171 check-screen-row screen, 2/y, " 1 ", "F - test-render-line-with-stack-singleton/2" +168 new-x, new-y <- render-line-with-stack screen, line, 0/x, 0/y, 0/no-cursor +169 check-screen-row screen, 0/y, "1 ", "F - test-render-line-with-stack-singleton/0" +170 check-screen-row screen, 1/y, " ", "F - test-render-line-with-stack-singleton/1" +171 check-screen-row screen, 2/y, " 1 ", "F - test-render-line-with-stack-singleton/2" 172 # not bothering to test hash colors for numbers 173 } 174 -175 fn test-render-line-with-stack { +175 fn test-render-line-with-stack { 176 # line = [1 2] -177 var line-storage: line -178 var line/esi: (addr line) <- address line-storage -179 parse-line "1 2", line +177 var line-storage: line +178 var line/esi: (addr line) <- address line-storage +179 parse-line "1 2", line 180 # setup: screen -181 var screen-on-stack: screen -182 var screen/edi: (addr screen) <- address screen-on-stack -183 initialize-screen screen, 0x20, 4 +181 var screen-on-stack: screen +182 var screen/edi: (addr screen) <- address screen-on-stack +183 initialize-screen screen, 0x20, 4 184 # 185 var new-x/eax: int <- copy 0 186 var new-y/ecx: int <- copy 0 -187 new-x, new-y <- render-line-with-stack screen, line, 0/x, 0/y, 0/no-cursor -188 check-screen-row screen, 0/y, "1 2 ", "F - test-render-line-with-stack/0" -189 check-screen-row screen, 1/y, " ", "F - test-render-line-with-stack/1" +187 new-x, new-y <- render-line-with-stack screen, line, 0/x, 0/y, 0/no-cursor +188 check-screen-row screen, 0/y, "1 2 ", "F - test-render-line-with-stack/0" +189 check-screen-row screen, 1/y, " ", "F - test-render-line-with-stack/1" 190 #___ ___ -191 check-screen-row screen, 2/y, " 1 2 ", "F - test-render-line-with-stack/2" -192 check-screen-row screen, 3/y, " 1 ", "F - test-render-line-with-stack/3" +191 check-screen-row screen, 2/y, " 1 2 ", "F - test-render-line-with-stack/2" +192 check-screen-row screen, 3/y, " 1 ", "F - test-render-line-with-stack/3" 193 # not bothering to test hash colors for numbers 194 } 195 -196 fn edit-line _self: (addr line), key: byte { -197 var self/esi: (addr line) <- copy _self -198 var cursor-word-ah/edx: (addr handle word) <- get self, cursor -199 var _cursor-word/eax: (addr word) <- lookup *cursor-word-ah -200 var cursor-word/ecx: (addr word) <- copy _cursor-word +196 fn edit-line _self: (addr line), key: byte { +197 var self/esi: (addr line) <- copy _self +198 var cursor-word-ah/edx: (addr handle word) <- get self, cursor +199 var _cursor-word/eax: (addr word) <- lookup *cursor-word-ah +200 var cursor-word/ecx: (addr word) <- copy _cursor-word 201 compare key, 0x20/space 202 $edit-line:space: { 203 break-if-!= -204 append-word cursor-word-ah -205 var next-word-ah/eax: (addr handle word) <- get cursor-word, next +204 append-word cursor-word-ah +205 var next-word-ah/eax: (addr handle word) <- get cursor-word, next 206 copy-object next-word-ah, cursor-word-ah 207 return 208 } 209 # otherwise insert key within current word 210 var g/edx: grapheme <- copy key -211 add-grapheme-to-word cursor-word, g +211 add-grapheme-to-word cursor-word, g 212 # silently ignore other hotkeys 213 } 214 -215 fn main { -216 var line-storage: line -217 var line/esi: (addr line) <- address line-storage -218 initialize-line line +215 fn main { +216 var line-storage: line +217 var line/esi: (addr line) <- address line-storage +218 initialize-line line 219 $main:loop: { -220 clear-screen 0/screen +220 clear-screen 0/screen 221 var dummy1/eax: int <- copy 0 222 var dummy2/ecx: int <- copy 0 -223 dummy1, dummy2 <- render-line-with-stack 0/screen, line, 2/x, 2/y, 1/show-cursor +223 dummy1, dummy2 <- render-line-with-stack 0/screen, line, 2/x, 2/y, 1/show-cursor 224 { -225 var key/eax: byte <- read-key 0/keyboard +225 var key/eax: byte <- read-key 0/keyboard 226 compare key, 0 227 loop-if-= 228 compare key, 0x71/q 229 break-if-= $main:loop -230 edit-line line, key +230 edit-line line, key 231 } 232 loop 233 } diff --git a/html/baremetal/shell/value-stack.mu.html b/html/baremetal/shell/value-stack.mu.html index 1174da46..2b167886 100644 --- a/html/baremetal/shell/value-stack.mu.html +++ b/html/baremetal/shell/value-stack.mu.html @@ -60,155 +60,155 @@ if ('onhashchange' in window) { 1 # value stacks encode the result of a program at a single point in time 2 # they are typically rendered vertically 3 - 4 type value-stack { - 5 data: (handle array value) - 6 top: int + 4 type value-stack { + 5 data: (handle array value) + 6 top: int 7 } 8 - 9 fn initialize-value-stack _self: (addr value-stack), n: int { - 10 var self/esi: (addr value-stack) <- copy _self - 11 var d/edi: (addr handle array value) <- get self, data + 9 fn initialize-value-stack _self: (addr value-stack), n: int { + 10 var self/esi: (addr value-stack) <- copy _self + 11 var d/edi: (addr handle array value) <- get self, data 12 populate d, n - 13 var top/eax: (addr int) <- get self, top + 13 var top/eax: (addr int) <- get self, top 14 copy-to *top, 0 15 } 16 - 17 fn clear-value-stack _self: (addr value-stack) { - 18 var self/esi: (addr value-stack) <- copy _self - 19 var top/eax: (addr int) <- get self, top + 17 fn clear-value-stack _self: (addr value-stack) { + 18 var self/esi: (addr value-stack) <- copy _self + 19 var top/eax: (addr int) <- get self, top 20 copy-to *top, 0 21 } 22 - 23 fn push-number-to-value-stack _self: (addr value-stack), _val: float { - 24 var self/esi: (addr value-stack) <- copy _self - 25 var top-addr/ecx: (addr int) <- get self, top - 26 var data-ah/edx: (addr handle array value) <- get self, data - 27 var data/eax: (addr array value) <- lookup *data-ah - 28 var top/edx: int <- copy *top-addr - 29 var dest-offset/edx: (offset value) <- compute-offset data, top - 30 var dest-addr/edx: (addr value) <- index data, dest-offset - 31 var dest-addr2/eax: (addr float) <- get dest-addr, number-data + 23 fn push-number-to-value-stack _self: (addr value-stack), _val: float { + 24 var self/esi: (addr value-stack) <- copy _self + 25 var top-addr/ecx: (addr int) <- get self, top + 26 var data-ah/edx: (addr handle array value) <- get self, data + 27 var data/eax: (addr array value) <- lookup *data-ah + 28 var top/edx: int <- copy *top-addr + 29 var dest-offset/edx: (offset value) <- compute-offset data, top + 30 var dest-addr/edx: (addr value) <- index data, dest-offset + 31 var dest-addr2/eax: (addr float) <- get dest-addr, number-data 32 var val/xmm0: float <- copy _val 33 copy-to *dest-addr2, val 34 increment *top-addr - 35 var type-addr/eax: (addr int) <- get dest-addr, type + 35 var type-addr/eax: (addr int) <- get dest-addr, type 36 copy-to *type-addr, 0/number 37 } 38 - 39 fn push-int-to-value-stack _self: (addr value-stack), _val: int { - 40 var self/esi: (addr value-stack) <- copy _self - 41 var top-addr/ecx: (addr int) <- get self, top - 42 var data-ah/edx: (addr handle array value) <- get self, data - 43 var data/eax: (addr array value) <- lookup *data-ah - 44 var top/edx: int <- copy *top-addr - 45 var dest-offset/edx: (offset value) <- compute-offset data, top - 46 var dest-addr/edx: (addr value) <- index data, dest-offset - 47 var dest-addr2/eax: (addr float) <- get dest-addr, number-data + 39 fn push-int-to-value-stack _self: (addr value-stack), _val: int { + 40 var self/esi: (addr value-stack) <- copy _self + 41 var top-addr/ecx: (addr int) <- get self, top + 42 var data-ah/edx: (addr handle array value) <- get self, data + 43 var data/eax: (addr array value) <- lookup *data-ah + 44 var top/edx: int <- copy *top-addr + 45 var dest-offset/edx: (offset value) <- compute-offset data, top + 46 var dest-addr/edx: (addr value) <- index data, dest-offset + 47 var dest-addr2/eax: (addr float) <- get dest-addr, number-data 48 var val/xmm0: float <- convert _val 49 copy-to *dest-addr2, val 50 increment *top-addr - 51 var type-addr/eax: (addr int) <- get dest-addr, type + 51 var type-addr/eax: (addr int) <- get dest-addr, type 52 copy-to *type-addr, 0/number 53 } 54 - 55 fn push-string-to-value-stack _self: (addr value-stack), val: (handle array byte) { - 56 var self/esi: (addr value-stack) <- copy _self - 57 var top-addr/ecx: (addr int) <- get self, top - 58 var data-ah/edx: (addr handle array value) <- get self, data - 59 var data/eax: (addr array value) <- lookup *data-ah - 60 var top/edx: int <- copy *top-addr - 61 var dest-offset/edx: (offset value) <- compute-offset data, top - 62 var dest-addr/edx: (addr value) <- index data, dest-offset - 63 var dest-addr2/eax: (addr handle array byte) <- get dest-addr, text-data - 64 copy-handle val, dest-addr2 - 65 var dest-addr3/eax: (addr int) <- get dest-addr, type + 55 fn push-string-to-value-stack _self: (addr value-stack), val: (handle array byte) { + 56 var self/esi: (addr value-stack) <- copy _self + 57 var top-addr/ecx: (addr int) <- get self, top + 58 var data-ah/edx: (addr handle array value) <- get self, data + 59 var data/eax: (addr array value) <- lookup *data-ah + 60 var top/edx: int <- copy *top-addr + 61 var dest-offset/edx: (offset value) <- compute-offset data, top + 62 var dest-addr/edx: (addr value) <- index data, dest-offset + 63 var dest-addr2/eax: (addr handle array byte) <- get dest-addr, text-data + 64 copy-handle val, dest-addr2 + 65 var dest-addr3/eax: (addr int) <- get dest-addr, type 66 copy-to *dest-addr3, 1/string 67 increment *top-addr 68 } 69 - 70 fn push-array-to-value-stack _self: (addr value-stack), val: (handle array value) { - 71 var self/esi: (addr value-stack) <- copy _self - 72 var top-addr/ecx: (addr int) <- get self, top - 73 var data-ah/edx: (addr handle array value) <- get self, data - 74 var data/eax: (addr array value) <- lookup *data-ah - 75 var top/edx: int <- copy *top-addr - 76 var dest-offset/edx: (offset value) <- compute-offset data, top - 77 var dest-addr/edx: (addr value) <- index data, dest-offset - 78 var dest-addr2/eax: (addr handle array value) <- get dest-addr, array-data - 79 copy-handle val, dest-addr2 + 70 fn push-array-to-value-stack _self: (addr value-stack), val: (handle array value) { + 71 var self/esi: (addr value-stack) <- copy _self + 72 var top-addr/ecx: (addr int) <- get self, top + 73 var data-ah/edx: (addr handle array value) <- get self, data + 74 var data/eax: (addr array value) <- lookup *data-ah + 75 var top/edx: int <- copy *top-addr + 76 var dest-offset/edx: (offset value) <- compute-offset data, top + 77 var dest-addr/edx: (addr value) <- index data, dest-offset + 78 var dest-addr2/eax: (addr handle array value) <- get dest-addr, array-data + 79 copy-handle val, dest-addr2 80 # update type - 81 var dest-addr3/eax: (addr int) <- get dest-addr, type + 81 var dest-addr3/eax: (addr int) <- get dest-addr, type 82 copy-to *dest-addr3, 2/array 83 increment *top-addr 84 } 85 - 86 fn push-boolean-to-value-stack _self: (addr value-stack), _val: boolean { - 87 var self/esi: (addr value-stack) <- copy _self - 88 var top-addr/ecx: (addr int) <- get self, top - 89 var data-ah/edx: (addr handle array value) <- get self, data - 90 var data/eax: (addr array value) <- lookup *data-ah - 91 var top/edx: int <- copy *top-addr - 92 var dest-offset/edx: (offset value) <- compute-offset data, top - 93 var dest-addr/edx: (addr value) <- index data, dest-offset - 94 var dest-addr2/eax: (addr boolean) <- get dest-addr, boolean-data + 86 fn push-boolean-to-value-stack _self: (addr value-stack), _val: boolean { + 87 var self/esi: (addr value-stack) <- copy _self + 88 var top-addr/ecx: (addr int) <- get self, top + 89 var data-ah/edx: (addr handle array value) <- get self, data + 90 var data/eax: (addr array value) <- lookup *data-ah + 91 var top/edx: int <- copy *top-addr + 92 var dest-offset/edx: (offset value) <- compute-offset data, top + 93 var dest-addr/edx: (addr value) <- index data, dest-offset + 94 var dest-addr2/eax: (addr boolean) <- get dest-addr, boolean-data 95 var val/esi: boolean <- copy _val 96 copy-to *dest-addr2, val 97 increment *top-addr - 98 var type-addr/eax: (addr int) <- get dest-addr, type + 98 var type-addr/eax: (addr int) <- get dest-addr, type 99 copy-to *type-addr, 3/boolean 100 } 101 -102 fn push-value-stack _self: (addr value-stack), val: (addr value) { -103 var self/esi: (addr value-stack) <- copy _self -104 var top-addr/ecx: (addr int) <- get self, top -105 var data-ah/edx: (addr handle array value) <- get self, data -106 var data/eax: (addr array value) <- lookup *data-ah -107 var top/edx: int <- copy *top-addr -108 var dest-offset/edx: (offset value) <- compute-offset data, top -109 var dest-addr/edx: (addr value) <- index data, dest-offset +102 fn push-value-stack _self: (addr value-stack), val: (addr value) { +103 var self/esi: (addr value-stack) <- copy _self +104 var top-addr/ecx: (addr int) <- get self, top +105 var data-ah/edx: (addr handle array value) <- get self, data +106 var data/eax: (addr array value) <- lookup *data-ah +107 var top/edx: int <- copy *top-addr +108 var dest-offset/edx: (offset value) <- compute-offset data, top +109 var dest-addr/edx: (addr value) <- index data, dest-offset 110 copy-object val, dest-addr 111 increment *top-addr 112 } 113 -114 fn pop-number-from-value-stack _self: (addr value-stack) -> _/xmm0: float { -115 var self/esi: (addr value-stack) <- copy _self -116 var top-addr/ecx: (addr int) <- get self, top +114 fn pop-number-from-value-stack _self: (addr value-stack) -> _/xmm0: float { +115 var self/esi: (addr value-stack) <- copy _self +116 var top-addr/ecx: (addr int) <- get self, top 117 { 118 compare *top-addr, 0 119 break-if-> -120 abort "pop number: empty stack" +120 abort "pop number: empty stack" 121 } 122 decrement *top-addr -123 var data-ah/edx: (addr handle array value) <- get self, data -124 var data/eax: (addr array value) <- lookup *data-ah -125 var top/edx: int <- copy *top-addr -126 var dest-offset/edx: (offset value) <- compute-offset data, top -127 var result-addr/eax: (addr value) <- index data, dest-offset -128 var result-addr2/eax: (addr float) <- get result-addr, number-data +123 var data-ah/edx: (addr handle array value) <- get self, data +124 var data/eax: (addr array value) <- lookup *data-ah +125 var top/edx: int <- copy *top-addr +126 var dest-offset/edx: (offset value) <- compute-offset data, top +127 var result-addr/eax: (addr value) <- index data, dest-offset +128 var result-addr2/eax: (addr float) <- get result-addr, number-data 129 return *result-addr2 130 } 131 -132 fn pop-boolean-from-value-stack _self: (addr value-stack) -> _/eax: boolean { -133 var self/esi: (addr value-stack) <- copy _self -134 var top-addr/ecx: (addr int) <- get self, top +132 fn pop-boolean-from-value-stack _self: (addr value-stack) -> _/eax: boolean { +133 var self/esi: (addr value-stack) <- copy _self +134 var top-addr/ecx: (addr int) <- get self, top 135 { 136 compare *top-addr, 0 137 break-if-> -138 abort "pop boolean: empty stack" +138 abort "pop boolean: empty stack" 139 } 140 decrement *top-addr -141 var data-ah/edx: (addr handle array value) <- get self, data -142 var data/eax: (addr array value) <- lookup *data-ah -143 var top/edx: int <- copy *top-addr -144 var dest-offset/edx: (offset value) <- compute-offset data, top -145 var result-addr/eax: (addr value) <- index data, dest-offset -146 var result-addr2/eax: (addr boolean) <- get result-addr, boolean-data +141 var data-ah/edx: (addr handle array value) <- get self, data +142 var data/eax: (addr array value) <- lookup *data-ah +143 var top/edx: int <- copy *top-addr +144 var dest-offset/edx: (offset value) <- compute-offset data, top +145 var result-addr/eax: (addr value) <- index data, dest-offset +146 var result-addr2/eax: (addr boolean) <- get result-addr, boolean-data 147 return *result-addr2 148 } 149 -150 fn value-stack-empty? _self: (addr value-stack) -> _/eax: boolean { -151 var self/esi: (addr value-stack) <- copy _self -152 var top/eax: (addr int) <- get self, top +150 fn value-stack-empty? _self: (addr value-stack) -> _/eax: boolean { +151 var self/esi: (addr value-stack) <- copy _self +152 var top/eax: (addr int) <- get self, top 153 compare *top, 0 154 { 155 break-if-!= @@ -217,60 +217,60 @@ if ('onhashchange' in window) { 158 return 0/false 159 } 160 -161 fn value-stack-length _self: (addr value-stack) -> _/eax: int { -162 var self/esi: (addr value-stack) <- copy _self -163 var top-addr/eax: (addr int) <- get self, top +161 fn value-stack-length _self: (addr value-stack) -> _/eax: int { +162 var self/esi: (addr value-stack) <- copy _self +163 var top-addr/eax: (addr int) <- get self, top 164 return *top-addr 165 } 166 -167 fn test-boolean { -168 var stack-storage: value-stack -169 var stack/esi: (addr value-stack) <- address stack-storage -170 push-boolean-to-value-stack stack, 0/false -171 var result/eax: boolean <- pop-boolean-from-value-stack stack -172 check-not result, "F - test-boolean/false" -173 push-boolean-to-value-stack stack, 1/true -174 var result/eax: boolean <- pop-boolean-from-value-stack stack -175 check result, "F - test-boolean/true" +167 fn test-boolean { +168 var stack-storage: value-stack +169 var stack/esi: (addr value-stack) <- address stack-storage +170 push-boolean-to-value-stack stack, 0/false +171 var result/eax: boolean <- pop-boolean-from-value-stack stack +172 check-not result, "F - test-boolean/false" +173 push-boolean-to-value-stack stack, 1/true +174 var result/eax: boolean <- pop-boolean-from-value-stack stack +175 check result, "F - test-boolean/true" 176 } 177 -178 fn dump-stack _self: (addr value-stack) { -179 var self/esi: (addr value-stack) <- copy _self -180 var data-ah/eax: (addr handle array value) <- get self, data -181 var _data/eax: (addr array value) <- lookup *data-ah -182 var data/edi: (addr array value) <- copy _data -183 var top-addr/ecx: (addr int) <- get self, top -184 var top/ecx: int <- copy *top-addr -185 top <- decrement +178 fn dump-stack _self: (addr value-stack) { +179 var self/esi: (addr value-stack) <- copy _self +180 var data-ah/eax: (addr handle array value) <- get self, data +181 var _data/eax: (addr array value) <- lookup *data-ah +182 var data/edi: (addr array value) <- copy _data +183 var top-addr/ecx: (addr int) <- get self, top +184 var top/ecx: int <- copy *top-addr +185 top <- decrement 186 var y/edx: int <- copy 0xa -187 var dummy/eax: int <- draw-text-rightward-over-full-screen 0/screen, "==", 0/x, 9/y, 0xc/red, 0/bg +187 var dummy/eax: int <- draw-text-rightward-over-full-screen 0/screen, "==", 0/x, 9/y, 0xc/red, 0/bg 188 { -189 compare top, 0 +189 compare top, 0 190 break-if-< -191 var dest-offset/eax: (offset value) <- compute-offset data, top -192 var curr/eax: (addr value) <- index data, dest-offset -193 var dummy/eax: int <- render-value 0/screen, curr, 0/x, y, 0/no-color -194 top <- decrement +191 var dest-offset/eax: (offset value) <- compute-offset data, top +192 var curr/eax: (addr value) <- index data, dest-offset +193 var dummy/eax: int <- render-value 0/screen, curr, 0/x, y, 0/no-color +194 top <- decrement 195 y <- increment 196 loop 197 } 198 } 199 -200 fn render-value-stack screen: (addr screen), _self: (addr value-stack), x: int, y: int -> _/eax: int, _/ecx: int { -201 var self/ecx: (addr value-stack) <- copy _self -202 var data-ah/eax: (addr handle array value) <- get self, data -203 var _data/eax: (addr array value) <- lookup *data-ah -204 var data/edi: (addr array value) <- copy _data -205 var top-addr/eax: (addr int) <- get self, top +200 fn render-value-stack screen: (addr screen), _self: (addr value-stack), x: int, y: int -> _/eax: int, _/ecx: int { +201 var self/ecx: (addr value-stack) <- copy _self +202 var data-ah/eax: (addr handle array value) <- get self, data +203 var _data/eax: (addr array value) <- lookup *data-ah +204 var data/edi: (addr array value) <- copy _data +205 var top-addr/eax: (addr int) <- get self, top 206 var curr-idx/ecx: int <- copy *top-addr 207 curr-idx <- decrement 208 var new-x/edx: int <- copy 0 209 { 210 compare curr-idx, 0 211 break-if-< -212 var dest-offset/eax: (offset value) <- compute-offset data, curr-idx -213 var curr/eax: (addr value) <- index data, dest-offset -214 var curr-x/eax: int <- render-value screen, curr, x, y, 1/top-level +212 var dest-offset/eax: (offset value) <- compute-offset data, curr-idx +213 var curr/eax: (addr value) <- index data, dest-offset +214 var curr-x/eax: int <- render-value screen, curr, x, y, 1/top-level 215 { 216 compare curr-x, new-x 217 break-if-<= @@ -283,20 +283,20 @@ if ('onhashchange' in window) { 224 return new-x, y 225 } 226 -227 fn test-render-value-stack { -228 var stack-storage: value-stack -229 var stack/esi: (addr value-stack) <- address stack-storage -230 push-int-to-value-stack stack, 3 +227 fn test-render-value-stack { +228 var stack-storage: value-stack +229 var stack/esi: (addr value-stack) <- address stack-storage +230 push-int-to-value-stack stack, 3 231 # setup: screen -232 var screen-on-stack: screen -233 var screen/edi: (addr screen) <- address screen-on-stack -234 initialize-screen screen, 0x20, 4 +232 var screen-on-stack: screen +233 var screen/edi: (addr screen) <- address screen-on-stack +234 initialize-screen screen, 0x20, 4 235 # 236 var final-x/eax: int <- copy 0 237 var final-y/ecx: int <- copy 0 -238 final-x, final-y <- render-value-stack screen, stack, 0/x, 0/y -239 check-ints-equal final-y, 1, "F - test-render-value-stack y" -240 check-ints-equal final-x, 3, "F - test-render-value-stack x" +238 final-x, final-y <- render-value-stack screen, stack, 0/x, 0/y +239 check-ints-equal final-y, 1, "F - test-render-value-stack y" +240 check-ints-equal final-x, 3, "F - test-render-value-stack x" 241 }https://github.com/akkartik/mu/blob/main/baremetal/shell/word.mu
- 1 type word { - 2 scalar-data: (handle gap-buffer) - 3 next: (handle word) - 4 prev: (handle word) + 1 type word { + 2 scalar-data: (handle gap-buffer) + 3 next: (handle word) + 4 prev: (handle word) 5 } 6 - 7 fn initialize-word _self: (addr word) { - 8 var self/esi: (addr word) <- copy _self - 9 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data - 10 allocate data-ah - 11 var data/eax: (addr gap-buffer) <- lookup *data-ah - 12 initialize-gap-buffer data + 7 fn initialize-word _self: (addr word) { + 8 var self/esi: (addr word) <- copy _self + 9 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data + 10 allocate data-ah + 11 var data/eax: (addr gap-buffer) <- lookup *data-ah + 12 initialize-gap-buffer data 13 } 14 15 ## some helpers for creating words. mostly for tests 16 - 17 fn initialize-word-with _self: (addr word), s: (addr array byte) { - 18 var self/esi: (addr word) <- copy _self - 19 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data - 20 allocate data-ah - 21 var data/eax: (addr gap-buffer) <- lookup *data-ah - 22 initialize-gap-buffer-with data, s + 17 fn initialize-word-with _self: (addr word), s: (addr array byte) { + 18 var self/esi: (addr word) <- copy _self + 19 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data + 20 allocate data-ah + 21 var data/eax: (addr gap-buffer) <- lookup *data-ah + 22 initialize-gap-buffer-with data, s 23 } 24 - 25 fn allocate-word-with _out: (addr handle word), s: (addr array byte) { - 26 var out/eax: (addr handle word) <- copy _out - 27 allocate out - 28 var out-addr/eax: (addr word) <- lookup *out - 29 initialize-word-with out-addr, s + 25 fn allocate-word-with _out: (addr handle word), s: (addr array byte) { + 26 var out/eax: (addr handle word) <- copy _out + 27 allocate out + 28 var out-addr/eax: (addr word) <- lookup *out + 29 initialize-word-with out-addr, s 30 } 31 32 # just for tests for now 33 # TODO: handle existing next 34 # one implication of handles: append must take a handle - 35 fn append-word-with self-h: (handle word), s: (addr array byte) { - 36 var self/eax: (addr word) <- lookup self-h - 37 var next-ah/eax: (addr handle word) <- get self, next - 38 allocate-word-with next-ah, s - 39 var next/eax: (addr word) <- lookup *next-ah - 40 var prev-ah/eax: (addr handle word) <- get next, prev - 41 copy-handle self-h, prev-ah + 35 fn append-word-with self-h: (handle word), s: (addr array byte) { + 36 var self/eax: (addr word) <- lookup self-h + 37 var next-ah/eax: (addr handle word) <- get self, next + 38 allocate-word-with next-ah, s + 39 var next/eax: (addr word) <- lookup *next-ah + 40 var prev-ah/eax: (addr handle word) <- get next, prev + 41 copy-handle self-h, prev-ah 42 } 43 44 # just for tests for now 45 # TODO: handle existing prev - 46 fn prepend-word-with self-h: (handle word), s: (addr array byte) { - 47 var self/eax: (addr word) <- lookup self-h - 48 var prev-ah/eax: (addr handle word) <- get self, prev - 49 allocate-word-with prev-ah, s - 50 var prev/eax: (addr word) <- lookup *prev-ah - 51 var next-ah/eax: (addr handle word) <- get prev, next - 52 copy-handle self-h, next-ah + 46 fn prepend-word-with self-h: (handle word), s: (addr array byte) { + 47 var self/eax: (addr word) <- lookup self-h + 48 var prev-ah/eax: (addr handle word) <- get self, prev + 49 allocate-word-with prev-ah, s + 50 var prev/eax: (addr word) <- lookup *prev-ah + 51 var next-ah/eax: (addr handle word) <- get prev, next + 52 copy-handle self-h, next-ah 53 } 54 55 ## real primitives 56 - 57 fn move-word-contents _src-ah: (addr handle word), _dest-ah: (addr handle word) { - 58 var dest-ah/eax: (addr handle word) <- copy _dest-ah - 59 var _dest/eax: (addr word) <- lookup *dest-ah - 60 var dest/edi: (addr word) <- copy _dest - 61 var src-ah/eax: (addr handle word) <- copy _src-ah - 62 var _src/eax: (addr word) <- lookup *src-ah - 63 var src/esi: (addr word) <- copy _src - 64 cursor-to-start src - 65 var src-data-ah/eax: (addr handle gap-buffer) <- get src, scalar-data - 66 var src-data/eax: (addr gap-buffer) <- lookup *src-data-ah - 67 var src-stack/ecx: (addr grapheme-stack) <- get src-data, right + 57 fn move-word-contents _src-ah: (addr handle word), _dest-ah: (addr handle word) { + 58 var dest-ah/eax: (addr handle word) <- copy _dest-ah + 59 var _dest/eax: (addr word) <- lookup *dest-ah + 60 var dest/edi: (addr word) <- copy _dest + 61 var src-ah/eax: (addr handle word) <- copy _src-ah + 62 var _src/eax: (addr word) <- lookup *src-ah + 63 var src/esi: (addr word) <- copy _src + 64 cursor-to-start src + 65 var src-data-ah/eax: (addr handle gap-buffer) <- get src, scalar-data + 66 var src-data/eax: (addr gap-buffer) <- lookup *src-data-ah + 67 var src-stack/ecx: (addr grapheme-stack) <- get src-data, right 68 { - 69 var done?/eax: boolean <- grapheme-stack-empty? src-stack + 69 var done?/eax: boolean <- grapheme-stack-empty? src-stack 70 compare done?, 0/false 71 break-if-!= - 72 var g/eax: grapheme <- pop-grapheme-stack src-stack - 73 add-grapheme-to-word dest, g + 72 var g/eax: grapheme <- pop-grapheme-stack src-stack + 73 add-grapheme-to-word dest, g 74 loop 75 } 76 } 77 - 78 fn copy-word-contents-before-cursor _src-ah: (addr handle word), _dest-ah: (addr handle word) { - 79 var dest-ah/eax: (addr handle word) <- copy _dest-ah - 80 var _dest/eax: (addr word) <- lookup *dest-ah - 81 var dest/edi: (addr word) <- copy _dest - 82 var src-ah/eax: (addr handle word) <- copy _src-ah - 83 var src/eax: (addr word) <- lookup *src-ah - 84 var src-data-ah/eax: (addr handle gap-buffer) <- get src, scalar-data - 85 var src-data/eax: (addr gap-buffer) <- lookup *src-data-ah - 86 var src-stack/ecx: (addr grapheme-stack) <- get src-data, left - 87 var src-stack-data-ah/eax: (addr handle array grapheme) <- get src-stack, data - 88 var _src-stack-data/eax: (addr array grapheme) <- lookup *src-stack-data-ah + 78 fn copy-word-contents-before-cursor _src-ah: (addr handle word), _dest-ah: (addr handle word) { + 79 var dest-ah/eax: (addr handle word) <- copy _dest-ah + 80 var _dest/eax: (addr word) <- lookup *dest-ah + 81 var dest/edi: (addr word) <- copy _dest + 82 var src-ah/eax: (addr handle word) <- copy _src-ah + 83 var src/eax: (addr word) <- lookup *src-ah + 84 var src-data-ah/eax: (addr handle gap-buffer) <- get src, scalar-data + 85 var src-data/eax: (addr gap-buffer) <- lookup *src-data-ah + 86 var src-stack/ecx: (addr grapheme-stack) <- get src-data, left + 87 var src-stack-data-ah/eax: (addr handle array grapheme) <- get src-stack, data + 88 var _src-stack-data/eax: (addr array grapheme) <- lookup *src-stack-data-ah 89 var src-stack-data/edx: (addr array grapheme) <- copy _src-stack-data - 90 var top-addr/ecx: (addr int) <- get src-stack, top + 90 var top-addr/ecx: (addr int) <- get src-stack, top 91 var i/eax: int <- copy 0 92 { 93 compare i, *top-addr 94 break-if->= 95 var g/edx: (addr grapheme) <- index src-stack-data, i - 96 add-grapheme-to-word dest, *g + 96 add-grapheme-to-word dest, *g 97 i <- increment 98 loop 99 } 100 } 101 -102 fn word-equal? _self: (addr word), s: (addr array byte) -> _/eax: boolean { -103 var self/esi: (addr word) <- copy _self -104 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -105 var data/eax: (addr gap-buffer) <- lookup *data-ah -106 var result/eax: boolean <- gap-buffer-equal? data, s +102 fn word-equal? _self: (addr word), s: (addr array byte) -> _/eax: boolean { +103 var self/esi: (addr word) <- copy _self +104 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +105 var data/eax: (addr gap-buffer) <- lookup *data-ah +106 var result/eax: boolean <- gap-buffer-equal? data, s 107 return result 108 } 109 -110 fn words-equal? _self: (addr word), _w: (addr word) -> _/eax: boolean { -111 var self/eax: (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 var data/ecx: (addr gap-buffer) <- copy _data -115 var w/eax: (addr word) <- copy _w -116 var w-data-ah/eax: (addr handle gap-buffer) <- get w, scalar-data -117 var w-data/eax: (addr gap-buffer) <- lookup *w-data-ah -118 var result/eax: boolean <- gap-buffers-equal? data, w-data +110 fn words-equal? _self: (addr word), _w: (addr word) -> _/eax: boolean { +111 var self/eax: (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 var data/ecx: (addr gap-buffer) <- copy _data +115 var w/eax: (addr word) <- copy _w +116 var w-data-ah/eax: (addr handle gap-buffer) <- get w, scalar-data +117 var w-data/eax: (addr gap-buffer) <- lookup *w-data-ah +118 var result/eax: boolean <- gap-buffers-equal? data, w-data 119 return result 120 } 121 -122 fn word-length _self: (addr word) -> _/eax: int { -123 var self/esi: (addr word) <- copy _self -124 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -125 var data/eax: (addr gap-buffer) <- lookup *data-ah -126 var result/eax: int <- gap-buffer-length data +122 fn word-length _self: (addr word) -> _/eax: int { +123 var self/esi: (addr word) <- copy _self +124 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +125 var data/eax: (addr gap-buffer) <- lookup *data-ah +126 var result/eax: int <- gap-buffer-length data 127 return result 128 } 129 -130 fn first-word _in: (addr handle word), out: (addr handle word) { -131 var curr-ah/esi: (addr handle word) <- copy _in -132 var curr/eax: (addr word) <- lookup *curr-ah -133 var prev/edi: (addr handle word) <- copy 0 +130 fn first-word _in: (addr handle word), out: (addr handle word) { +131 var curr-ah/esi: (addr handle word) <- copy _in +132 var curr/eax: (addr word) <- lookup *curr-ah +133 var prev/edi: (addr handle word) <- copy 0 134 { -135 prev <- get curr, prev -136 var curr/eax: (addr word) <- lookup *prev +135 prev <- get curr, prev +136 var curr/eax: (addr word) <- lookup *prev 137 compare curr, 0 138 break-if-= 139 copy-object prev, curr-ah @@ -201,16 +201,16 @@ if ('onhashchange' in window) { 142 copy-object curr-ah, out 143 } 144 -145 fn final-word _in: (addr handle word), out: (addr handle word) { -146 var curr-h: (handle word) -147 var curr-ah/esi: (addr handle word) <- address curr-h +145 fn final-word _in: (addr handle word), out: (addr handle word) { +146 var curr-h: (handle word) +147 var curr-ah/esi: (addr handle word) <- address curr-h 148 copy-object _in, curr-ah -149 var curr/eax: (addr word) <- copy 0 -150 var next/edi: (addr handle word) <- copy 0 +149 var curr/eax: (addr word) <- copy 0 +150 var next/edi: (addr handle word) <- copy 0 151 { -152 curr <- lookup *curr-ah -153 next <- get curr, next -154 curr <- lookup *next +152 curr <- lookup *curr-ah +153 next <- get curr, next +154 curr <- lookup *next 155 compare curr, 0 156 break-if-= 157 copy-object next, curr-ah @@ -219,124 +219,124 @@ if ('onhashchange' in window) { 160 copy-object curr-ah, out # modify 'out' right at the end, just in case it's same as 'in' 161 } 162 -163 fn first-grapheme _self: (addr word) -> _/eax: grapheme { -164 var self/esi: (addr word) <- copy _self -165 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -166 var data/eax: (addr gap-buffer) <- lookup *data-ah -167 var result/eax: grapheme <- first-grapheme-in-gap-buffer data +163 fn first-grapheme _self: (addr word) -> _/eax: grapheme { +164 var self/esi: (addr word) <- copy _self +165 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +166 var data/eax: (addr gap-buffer) <- lookup *data-ah +167 var result/eax: grapheme <- first-grapheme-in-gap-buffer data 168 return result 169 } 170 -171 fn grapheme-before-cursor _self: (addr word) -> _/eax: grapheme { -172 var self/esi: (addr word) <- copy _self -173 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -174 var data/eax: (addr gap-buffer) <- lookup *data-ah -175 var result/eax: grapheme <- grapheme-before-cursor-in-gap-buffer data +171 fn grapheme-before-cursor _self: (addr word) -> _/eax: grapheme { +172 var self/esi: (addr word) <- copy _self +173 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +174 var data/eax: (addr gap-buffer) <- lookup *data-ah +175 var result/eax: grapheme <- grapheme-before-cursor-in-gap-buffer data 176 return result 177 } 178 -179 fn add-grapheme-to-word _self: (addr word), c: grapheme { -180 var self/esi: (addr word) <- copy _self -181 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -182 var data/eax: (addr gap-buffer) <- lookup *data-ah -183 add-grapheme-at-gap data, c +179 fn add-grapheme-to-word _self: (addr word), c: grapheme { +180 var self/esi: (addr word) <- copy _self +181 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +182 var data/eax: (addr gap-buffer) <- lookup *data-ah +183 add-grapheme-at-gap data, c 184 } 185 -186 fn cursor-at-start? _self: (addr word) -> _/eax: boolean { -187 var self/esi: (addr word) <- copy _self -188 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -189 var data/eax: (addr gap-buffer) <- lookup *data-ah -190 var result/eax: boolean <- gap-at-start? data +186 fn cursor-at-start? _self: (addr word) -> _/eax: boolean { +187 var self/esi: (addr word) <- copy _self +188 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +189 var data/eax: (addr gap-buffer) <- lookup *data-ah +190 var result/eax: boolean <- gap-at-start? data 191 return result 192 } 193 -194 fn cursor-at-end? _self: (addr word) -> _/eax: boolean { -195 var self/esi: (addr word) <- copy _self -196 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -197 var data/eax: (addr gap-buffer) <- lookup *data-ah -198 var result/eax: boolean <- gap-at-end? data +194 fn cursor-at-end? _self: (addr word) -> _/eax: boolean { +195 var self/esi: (addr word) <- copy _self +196 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +197 var data/eax: (addr gap-buffer) <- lookup *data-ah +198 var result/eax: boolean <- gap-at-end? data 199 return result 200 } 201 -202 fn cursor-left _self: (addr word) { -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 var dummy/eax: grapheme <- gap-left data +202 fn cursor-left _self: (addr word) { +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 var dummy/eax: grapheme <- gap-left data 207 } 208 -209 fn cursor-right _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 var dummy/eax: grapheme <- gap-right data +209 fn cursor-right _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 var dummy/eax: grapheme <- gap-right data 214 } 215 -216 fn cursor-to-start _self: (addr word) { -217 var self/esi: (addr word) <- copy _self -218 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -219 var data/eax: (addr gap-buffer) <- lookup *data-ah -220 gap-to-start data +216 fn cursor-to-start _self: (addr word) { +217 var self/esi: (addr word) <- copy _self +218 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +219 var data/eax: (addr gap-buffer) <- lookup *data-ah +220 gap-to-start data 221 } 222 -223 fn cursor-to-end _self: (addr word) { -224 var self/esi: (addr word) <- copy _self -225 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -226 var data/eax: (addr gap-buffer) <- lookup *data-ah -227 gap-to-end data +223 fn cursor-to-end _self: (addr word) { +224 var self/esi: (addr word) <- copy _self +225 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +226 var data/eax: (addr gap-buffer) <- lookup *data-ah +227 gap-to-end data 228 } 229 -230 fn cursor-index _self: (addr word) -> _/eax: int { -231 var self/esi: (addr word) <- copy _self -232 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -233 var data/eax: (addr gap-buffer) <- lookup *data-ah -234 var result/eax: int <- index-of-gap data +230 fn cursor-index _self: (addr word) -> _/eax: int { +231 var self/esi: (addr word) <- copy _self +232 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +233 var data/eax: (addr gap-buffer) <- lookup *data-ah +234 var result/eax: int <- index-of-gap data 235 return result 236 } 237 -238 fn delete-before-cursor _self: (addr word) { -239 var self/esi: (addr word) <- copy _self -240 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -241 var data/eax: (addr gap-buffer) <- lookup *data-ah -242 delete-before-gap data +238 fn delete-before-cursor _self: (addr word) { +239 var self/esi: (addr word) <- copy _self +240 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +241 var data/eax: (addr gap-buffer) <- lookup *data-ah +242 delete-before-gap data 243 } 244 -245 fn pop-after-cursor _self: (addr word) -> _/eax: grapheme { -246 var self/esi: (addr word) <- copy _self -247 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -248 var data/eax: (addr gap-buffer) <- lookup *data-ah -249 var result/eax: grapheme <- pop-after-gap data +245 fn pop-after-cursor _self: (addr word) -> _/eax: grapheme { +246 var self/esi: (addr word) <- copy _self +247 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +248 var data/eax: (addr gap-buffer) <- lookup *data-ah +249 var result/eax: grapheme <- pop-after-gap data 250 return result 251 } 252 -253 fn delete-next _self: (addr word) { -254 var self/esi: (addr word) <- copy _self -255 var next-ah/edi: (addr handle word) <- get self, next -256 var next/eax: (addr word) <- lookup *next-ah +253 fn delete-next _self: (addr word) { +254 var self/esi: (addr word) <- copy _self +255 var next-ah/edi: (addr handle word) <- get self, next +256 var next/eax: (addr word) <- lookup *next-ah 257 compare next, 0 258 break-if-= -259 var next-next-ah/ecx: (addr handle word) <- get next, next -260 var self-ah/esi: (addr handle word) <- get next, prev +259 var next-next-ah/ecx: (addr handle word) <- get next, next +260 var self-ah/esi: (addr handle word) <- get next, prev 261 copy-object next-next-ah, next-ah -262 var new-next/eax: (addr word) <- lookup *next-next-ah +262 var new-next/eax: (addr word) <- lookup *next-next-ah 263 compare new-next, 0 264 break-if-= -265 var dest/eax: (addr handle word) <- get new-next, prev +265 var dest/eax: (addr handle word) <- get new-next, prev 266 copy-object self-ah, dest 267 } 268 -269 fn render-word screen: (addr screen), _self: (addr word), x: int, y: int, render-cursor?: boolean -> _/eax: int { -270 var self/esi: (addr word) <- copy _self -271 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -272 var data/eax: (addr gap-buffer) <- lookup *data-ah -273 var result/eax: int <- render-gap-buffer screen, data, x, y, render-cursor? +269 fn render-word screen: (addr screen), _self: (addr word), x: int, y: int, render-cursor?: boolean -> _/eax: int { +270 var self/esi: (addr word) <- copy _self +271 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +272 var data/eax: (addr gap-buffer) <- lookup *data-ah +273 var result/eax: int <- render-gap-buffer screen, data, x, y, render-cursor? 274 return result 275 } 276 -277 fn render-words screen: (addr screen), _words-ah: (addr handle word), x: int, y: int, cursor-word-addr: int -> _/eax: int { -278 var words-ah/eax: (addr handle word) <- copy _words-ah -279 var _words-a/eax: (addr word) <- lookup *words-ah -280 var words-a/ecx: (addr word) <- copy _words-a +277 fn render-words screen: (addr screen), _words-ah: (addr handle word), x: int, y: int, cursor-word-addr: int -> _/eax: int { +278 var words-ah/eax: (addr handle word) <- copy _words-ah +279 var _words-a/eax: (addr word) <- lookup *words-ah +280 var words-a/ecx: (addr word) <- copy _words-a 281 compare words-a, 0 282 { 283 break-if-!= @@ -349,97 +349,97 @@ if ('onhashchange' in window) { 290 break-if-!= 291 render-cursor? <- copy 1/true 292 } -293 var next-x/eax: int <- render-word screen, words-a, x, y, render-cursor? +293 var next-x/eax: int <- render-word screen, words-a, x, y, render-cursor? 294 var space/edx: grapheme <- copy 0x20/space -295 draw-grapheme screen, space, next-x, y, 3/fg=cyan, 0/bg +295 draw-grapheme screen, space, next-x, y, 3/fg=cyan, 0/bg 296 next-x <- increment 297 # recurse -298 var next-ah/ecx: (addr handle word) <- get words-a, next -299 next-x <- render-words screen, next-ah, next-x, y, cursor-word-addr +298 var next-ah/ecx: (addr handle word) <- get words-a, next +299 next-x <- render-words screen, next-ah, next-x, y, cursor-word-addr 300 return next-x 301 } 302 -303 fn test-render-words { +303 fn test-render-words { 304 # words = [aaa, bbb, ccc, ddd] -305 var w-storage: (handle word) -306 var w-ah/esi: (addr handle word) <- address w-storage -307 allocate-word-with w-ah, "aaa" -308 append-word-at-end-with w-ah, "bbb" -309 append-word-at-end-with w-ah, "ccc" -310 append-word-at-end-with w-ah, "ddd" +305 var w-storage: (handle word) +306 var w-ah/esi: (addr handle word) <- address w-storage +307 allocate-word-with w-ah, "aaa" +308 append-word-at-end-with w-ah, "bbb" +309 append-word-at-end-with w-ah, "ccc" +310 append-word-at-end-with w-ah, "ddd" 311 # setup: screen -312 var screen-on-stack: screen -313 var screen/edi: (addr screen) <- address screen-on-stack -314 initialize-screen screen, 0x20, 4 +312 var screen-on-stack: screen +313 var screen/edi: (addr screen) <- address screen-on-stack +314 initialize-screen screen, 0x20, 4 315 # -316 var _w/eax: (addr word) <- lookup *w-ah -317 var w/ecx: (addr word) <- copy _w +316 var _w/eax: (addr word) <- lookup *w-ah +317 var w/ecx: (addr word) <- copy _w 318 var cursor-word/eax: int <- copy w -319 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word -320 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" -321 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words/0 cursor" +319 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word +320 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" +321 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words/0 cursor" 322 # - start moving cursor left through final word -323 cursor-left w +323 cursor-left w 324 var cursor-word/eax: int <- copy w -325 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word -326 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" -327 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words/1 cursor" +325 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word +326 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" +327 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words/1 cursor" 328 # -329 cursor-left w +329 cursor-left w 330 var cursor-word/eax: int <- copy w -331 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word -332 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" -333 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words/2 cursor" +331 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word +332 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" +333 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words/2 cursor" 334 # -335 cursor-left w +335 cursor-left w 336 var cursor-word/eax: int <- copy w -337 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word -338 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" -339 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "| ", "F - test-render-words/3 cursor" +337 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word +338 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" +339 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "| ", "F - test-render-words/3 cursor" 340 # further moves left within the word change nothing -341 cursor-left w +341 cursor-left w 342 var cursor-word/eax: int <- copy w -343 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word -344 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" -345 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "| ", "F - test-render-words/4 cursor" +343 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word +344 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" +345 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "| ", "F - test-render-words/4 cursor" 346 # - switch to next word -347 var w2-ah/eax: (addr handle word) <- get w, next -348 var _w/eax: (addr word) <- lookup *w2-ah -349 var w/ecx: (addr word) <- copy _w +347 var w2-ah/eax: (addr handle word) <- get w, next +348 var _w/eax: (addr word) <- lookup *w2-ah +349 var w/ecx: (addr word) <- copy _w 350 var cursor-word/eax: int <- copy w -351 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word -352 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" -353 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words/5 cursor" +351 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word +352 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" +353 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words/5 cursor" 354 # now speed up a little -355 cursor-left w -356 cursor-left w +355 cursor-left w +356 cursor-left w 357 var cursor-word/eax: int <- copy w -358 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word -359 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" -360 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words/6 cursor" +358 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word +359 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" +360 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words/6 cursor" 361 # -362 var w2-ah/eax: (addr handle word) <- get w, next -363 var _w/eax: (addr word) <- lookup *w2-ah -364 var w/ecx: (addr word) <- copy _w -365 cursor-left w +362 var w2-ah/eax: (addr handle word) <- get w, next +363 var _w/eax: (addr word) <- lookup *w2-ah +364 var w/ecx: (addr word) <- copy _w +365 cursor-left w 366 var cursor-word/eax: int <- copy w -367 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word -368 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" -369 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words/7 cursor" +367 var new-x/eax: int <- render-words screen, w-ah, 0/x, 0/y, cursor-word +368 check-screen-row screen, 0/y, "aaa bbb ccc ddd ", "F - test-render-words/0" +369 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words/7 cursor" 370 } 371 -372 fn render-words-in-reverse screen: (addr screen), _words-ah: (addr handle word), x: int, y: int, cursor-word-addr: int -> _/eax: int { -373 var words-ah/eax: (addr handle word) <- copy _words-ah -374 var _words-a/eax: (addr word) <- lookup *words-ah -375 var words-a/ecx: (addr word) <- copy _words-a +372 fn render-words-in-reverse screen: (addr screen), _words-ah: (addr handle word), x: int, y: int, cursor-word-addr: int -> _/eax: int { +373 var words-ah/eax: (addr handle word) <- copy _words-ah +374 var _words-a/eax: (addr word) <- lookup *words-ah +375 var words-a/ecx: (addr word) <- copy _words-a 376 compare words-a, 0 377 { 378 break-if-!= 379 return x 380 } 381 # recurse -382 var next-ah/eax: (addr handle word) <- get words-a, next -383 var next-x/eax: int <- render-words-in-reverse screen, next-ah, x, y, cursor-word-addr +382 var next-ah/eax: (addr handle word) <- get words-a, next +383 var next-x/eax: int <- render-words-in-reverse screen, next-ah, x, y, cursor-word-addr 384 # print 385 var render-cursor?/edx: boolean <- copy 0/false 386 { @@ -447,244 +447,244 @@ if ('onhashchange' in window) { 388 break-if-!= 389 render-cursor? <- copy 1/true 390 } -391 next-x <- render-word screen, words-a, next-x, y, render-cursor? +391 next-x <- render-word screen, words-a, next-x, y, render-cursor? 392 var space/ecx: grapheme <- copy 0x20/space -393 draw-grapheme screen, space, next-x, y, 3/fg=cyan, 0/bg +393 draw-grapheme screen, space, next-x, y, 3/fg=cyan, 0/bg 394 next-x <- increment 395 return next-x 396 } 397 -398 fn test-render-words-in-reverse { +398 fn test-render-words-in-reverse { 399 # words = [aaa, bbb, ccc, ddd] -400 var w-storage: (handle word) -401 var w-ah/esi: (addr handle word) <- address w-storage -402 allocate-word-with w-ah, "aaa" -403 append-word-at-end-with w-ah, "bbb" -404 append-word-at-end-with w-ah, "ccc" -405 append-word-at-end-with w-ah, "ddd" +400 var w-storage: (handle word) +401 var w-ah/esi: (addr handle word) <- address w-storage +402 allocate-word-with w-ah, "aaa" +403 append-word-at-end-with w-ah, "bbb" +404 append-word-at-end-with w-ah, "ccc" +405 append-word-at-end-with w-ah, "ddd" 406 # setup: screen -407 var screen-on-stack: screen -408 var screen/edi: (addr screen) <- address screen-on-stack -409 initialize-screen screen, 0x20, 4 +407 var screen-on-stack: screen +408 var screen/edi: (addr screen) <- address screen-on-stack +409 initialize-screen screen, 0x20, 4 410 # -411 var _w/eax: (addr word) <- lookup *w-ah -412 var w/ecx: (addr word) <- copy _w +411 var _w/eax: (addr word) <- lookup *w-ah +412 var w/ecx: (addr word) <- copy _w 413 var cursor-word/eax: int <- copy w -414 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word -415 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/0" -416 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/0 cursor" +414 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word +415 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/0" +416 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/0 cursor" 417 # - start moving cursor left through final word -418 cursor-left w +418 cursor-left w 419 var cursor-word/eax: int <- copy w -420 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word -421 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/1" -422 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/1 cursor" +420 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word +421 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/1" +422 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/1 cursor" 423 # -424 cursor-left w +424 cursor-left w 425 var cursor-word/eax: int <- copy w -426 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word -427 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/2" -428 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/2 cursor" +426 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word +427 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/2" +428 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/2 cursor" 429 # -430 cursor-left w +430 cursor-left w 431 var cursor-word/eax: int <- copy w -432 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word -433 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/3" -434 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/3 cursor" +432 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word +433 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/3" +434 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/3 cursor" 435 # further moves left within the word change nothing -436 cursor-left w +436 cursor-left w 437 var cursor-word/eax: int <- copy w -438 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word -439 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/4" -440 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/4 cursor" +438 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word +439 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/4" +440 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/4 cursor" 441 # - switch to next word -442 var w2-ah/eax: (addr handle word) <- get w, next -443 var _w/eax: (addr word) <- lookup *w2-ah -444 var w/ecx: (addr word) <- copy _w +442 var w2-ah/eax: (addr handle word) <- get w, next +443 var _w/eax: (addr word) <- lookup *w2-ah +444 var w/ecx: (addr word) <- copy _w 445 var cursor-word/eax: int <- copy w -446 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word -447 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/5" -448 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/5 cursor" +446 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word +447 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/5" +448 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/5 cursor" 449 # now speed up a little -450 cursor-left w -451 cursor-left w +450 cursor-left w +451 cursor-left w 452 var cursor-word/eax: int <- copy w -453 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word -454 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/6" -455 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/6 cursor" +453 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word +454 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/6" +455 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/6 cursor" 456 # -457 var w2-ah/eax: (addr handle word) <- get w, next -458 var _w/eax: (addr word) <- lookup *w2-ah -459 var w/ecx: (addr word) <- copy _w -460 cursor-left w +457 var w2-ah/eax: (addr handle word) <- get w, next +458 var _w/eax: (addr word) <- lookup *w2-ah +459 var w/ecx: (addr word) <- copy _w +460 cursor-left w 461 var cursor-word/eax: int <- copy w -462 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word -463 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/7" -464 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/7 cursor" +462 var new-x/eax: int <- render-words-in-reverse screen, w-ah, 0/x, 0/y, cursor-word +463 check-screen-row screen, 0/y, "ddd ccc bbb aaa ", "F - test-render-words-in-reverse/7" +464 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-render-words-in-reverse/7 cursor" 465 } 466 467 # Gotcha with some word operations: ensure dest-ah isn't in the middle of some 468 # existing chain of words. There are two pointers to patch, and you'll forget 469 # to do the other one. -470 fn copy-words _src-ah: (addr handle word), _dest-ah: (addr handle word) { -471 var src-ah/eax: (addr handle word) <- copy _src-ah -472 var src-a/eax: (addr word) <- lookup *src-ah +470 fn copy-words _src-ah: (addr handle word), _dest-ah: (addr handle word) { +471 var src-ah/eax: (addr handle word) <- copy _src-ah +472 var src-a/eax: (addr word) <- lookup *src-ah 473 compare src-a, 0 474 break-if-= 475 # copy -476 var dest-ah/edi: (addr handle word) <- copy _dest-ah -477 copy-word src-a, dest-ah +476 var dest-ah/edi: (addr handle word) <- copy _dest-ah +477 copy-word src-a, dest-ah 478 # recurse -479 var rest: (handle word) -480 var rest-ah/ecx: (addr handle word) <- address rest -481 var next-src-ah/esi: (addr handle word) <- get src-a, next -482 copy-words next-src-ah, rest-ah -483 chain-words dest-ah, rest-ah +479 var rest: (handle word) +480 var rest-ah/ecx: (addr handle word) <- address rest +481 var next-src-ah/esi: (addr handle word) <- get src-a, next +482 copy-words next-src-ah, rest-ah +483 chain-words dest-ah, rest-ah 484 } 485 -486 fn copy-words-in-reverse _src-ah: (addr handle word), _dest-ah: (addr handle word) { -487 var src-ah/eax: (addr handle word) <- copy _src-ah -488 var _src-a/eax: (addr word) <- lookup *src-ah -489 var src-a/esi: (addr word) <- copy _src-a +486 fn copy-words-in-reverse _src-ah: (addr handle word), _dest-ah: (addr handle word) { +487 var src-ah/eax: (addr handle word) <- copy _src-ah +488 var _src-a/eax: (addr word) <- lookup *src-ah +489 var src-a/esi: (addr word) <- copy _src-a 490 compare src-a, 0 491 break-if-= 492 # recurse -493 var next-src-ah/ecx: (addr handle word) <- get src-a, next -494 var dest-ah/edi: (addr handle word) <- copy _dest-ah -495 copy-words-in-reverse next-src-ah, dest-ah +493 var next-src-ah/ecx: (addr handle word) <- get src-a, next +494 var dest-ah/edi: (addr handle word) <- copy _dest-ah +495 copy-words-in-reverse next-src-ah, dest-ah 496 # -497 copy-word-at-end src-a, dest-ah +497 copy-word-at-end src-a, dest-ah 498 } 499 -500 fn copy-word-at-end src: (addr word), _dest-ah: (addr handle word) { -501 var dest-ah/edi: (addr handle word) <- copy _dest-ah +500 fn copy-word-at-end src: (addr word), _dest-ah: (addr handle word) { +501 var dest-ah/edi: (addr handle word) <- copy _dest-ah 502 # if dest is null, copy and return -503 var dest-a/eax: (addr word) <- lookup *dest-ah +503 var dest-a/eax: (addr word) <- lookup *dest-ah 504 compare dest-a, 0 505 { 506 break-if-!= -507 copy-word src, dest-ah +507 copy-word src, dest-ah 508 return 509 } 510 # copy current word -511 var new: (handle word) -512 var new-ah/ecx: (addr handle word) <- address new -513 copy-word src, new-ah +511 var new: (handle word) +512 var new-ah/ecx: (addr handle word) <- address new +513 copy-word src, new-ah 514 # append it at the end -515 var curr-ah/edi: (addr handle word) <- copy dest-ah +515 var curr-ah/edi: (addr handle word) <- copy dest-ah 516 { -517 var curr-a/eax: (addr word) <- lookup *curr-ah # curr-a guaranteed not to be null -518 var next-ah/ecx: (addr handle word) <- get curr-a, next -519 var next-a/eax: (addr word) <- lookup *next-ah +517 var curr-a/eax: (addr word) <- lookup *curr-ah # curr-a guaranteed not to be null +518 var next-ah/ecx: (addr handle word) <- get curr-a, next +519 var next-a/eax: (addr word) <- lookup *next-ah 520 compare next-a, 0 521 break-if-= 522 curr-ah <- copy next-ah 523 loop 524 } -525 chain-words curr-ah, new-ah +525 chain-words curr-ah, new-ah 526 } 527 -528 fn append-word-at-end-with _dest-ah: (addr handle word), s: (addr array byte) { -529 var dest-ah/edi: (addr handle word) <- copy _dest-ah +528 fn append-word-at-end-with _dest-ah: (addr handle word), s: (addr array byte) { +529 var dest-ah/edi: (addr handle word) <- copy _dest-ah 530 # if dest is null, copy and return -531 var dest-a/eax: (addr word) <- lookup *dest-ah +531 var dest-a/eax: (addr word) <- lookup *dest-ah 532 compare dest-a, 0 533 { 534 break-if-!= -535 allocate-word-with dest-ah, s +535 allocate-word-with dest-ah, s 536 return 537 } 538 # otherwise append at end -539 var curr-ah/edi: (addr handle word) <- copy dest-ah +539 var curr-ah/edi: (addr handle word) <- copy dest-ah 540 { -541 var curr-a/eax: (addr word) <- lookup *curr-ah # curr-a guaranteed not to be null -542 var next-ah/ecx: (addr handle word) <- get curr-a, next -543 var next-a/eax: (addr word) <- lookup *next-ah +541 var curr-a/eax: (addr word) <- lookup *curr-ah # curr-a guaranteed not to be null +542 var next-ah/ecx: (addr handle word) <- get curr-a, next +543 var next-a/eax: (addr word) <- lookup *next-ah 544 compare next-a, 0 545 break-if-= 546 curr-ah <- copy next-ah 547 loop 548 } -549 append-word-with *curr-ah, s +549 append-word-with *curr-ah, s 550 } 551 -552 fn copy-word _src-a: (addr word), _dest-ah: (addr handle word) { -553 var dest-ah/eax: (addr handle word) <- copy _dest-ah -554 allocate dest-ah -555 var _dest-a/eax: (addr word) <- lookup *dest-ah -556 var dest-a/eax: (addr word) <- copy _dest-a -557 initialize-word dest-a -558 var dest/edi: (addr handle gap-buffer) <- get dest-a, scalar-data -559 var src-a/eax: (addr word) <- copy _src-a -560 var src/eax: (addr handle gap-buffer) <- get src-a, scalar-data -561 copy-gap-buffer src, dest +552 fn copy-word _src-a: (addr word), _dest-ah: (addr handle word) { +553 var dest-ah/eax: (addr handle word) <- copy _dest-ah +554 allocate dest-ah +555 var _dest-a/eax: (addr word) <- lookup *dest-ah +556 var dest-a/eax: (addr word) <- copy _dest-a +557 initialize-word dest-a +558 var dest/edi: (addr handle gap-buffer) <- get dest-a, scalar-data +559 var src-a/eax: (addr word) <- copy _src-a +560 var src/eax: (addr handle gap-buffer) <- get src-a, scalar-data +561 copy-gap-buffer src, dest 562 } 563 564 # one implication of handles: append must take a handle -565 fn append-word _self-ah: (addr handle word) { -566 var saved-self-storage: (handle word) -567 var saved-self/eax: (addr handle word) <- address saved-self-storage +565 fn append-word _self-ah: (addr handle word) { +566 var saved-self-storage: (handle word) +567 var saved-self/eax: (addr handle word) <- address saved-self-storage 568 copy-object _self-ah, saved-self -569 var self-ah/esi: (addr handle word) <- copy _self-ah -570 var _self/eax: (addr word) <- lookup *self-ah -571 var self/ebx: (addr word) <- copy _self +569 var self-ah/esi: (addr handle word) <- copy _self-ah +570 var _self/eax: (addr word) <- lookup *self-ah +571 var self/ebx: (addr word) <- copy _self 572 # allocate new handle -573 var new: (handle word) -574 var new-ah/ecx: (addr handle word) <- address new -575 allocate new-ah -576 var new-addr/eax: (addr word) <- lookup new -577 initialize-word new-addr +573 var new: (handle word) +574 var new-ah/ecx: (addr handle word) <- address new +575 allocate new-ah +576 var new-addr/eax: (addr word) <- lookup new +577 initialize-word new-addr 578 # new->next = self->next -579 var src/esi: (addr handle word) <- get self, next -580 var dest/edi: (addr handle word) <- get new-addr, next +579 var src/esi: (addr handle word) <- get self, next +580 var dest/edi: (addr handle word) <- get new-addr, next 581 copy-object src, dest 582 # new->next->prev = new 583 { -584 var next-addr/eax: (addr word) <- lookup *src +584 var next-addr/eax: (addr word) <- lookup *src 585 compare next-addr, 0 586 break-if-= -587 dest <- get next-addr, prev +587 dest <- get next-addr, prev 588 copy-object new-ah, dest 589 } 590 # new->prev = saved-self -591 dest <- get new-addr, prev -592 var saved-self-ah/eax: (addr handle word) <- address saved-self-storage +591 dest <- get new-addr, prev +592 var saved-self-ah/eax: (addr handle word) <- address saved-self-storage 593 copy-object saved-self-ah, dest 594 # self->next = new -595 dest <- get self, next +595 dest <- get self, next 596 copy-object new-ah, dest 597 } 598 -599 fn chain-words _self-ah: (addr handle word), _next: (addr handle word) { -600 var self-ah/esi: (addr handle word) <- copy _self-ah -601 var _self/eax: (addr word) <- lookup *self-ah -602 var self/ecx: (addr word) <- copy _self -603 var dest/edx: (addr handle word) <- get self, next -604 var next-ah/edi: (addr handle word) <- copy _next +599 fn chain-words _self-ah: (addr handle word), _next: (addr handle word) { +600 var self-ah/esi: (addr handle word) <- copy _self-ah +601 var _self/eax: (addr word) <- lookup *self-ah +602 var self/ecx: (addr word) <- copy _self +603 var dest/edx: (addr handle word) <- get self, next +604 var next-ah/edi: (addr handle word) <- copy _next 605 copy-object next-ah, dest -606 var next/eax: (addr word) <- lookup *next-ah +606 var next/eax: (addr word) <- lookup *next-ah 607 compare next, 0 608 break-if-= -609 dest <- get next, prev +609 dest <- get next, prev 610 copy-object self-ah, dest 611 } 612 -613 fn emit-word _self: (addr word), out: (addr stream byte) { -614 var self/esi: (addr word) <- copy _self -615 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -616 var data/eax: (addr gap-buffer) <- lookup *data-ah -617 emit-gap-buffer data, out +613 fn emit-word _self: (addr word), out: (addr stream byte) { +614 var self/esi: (addr word) <- copy _self +615 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +616 var data/eax: (addr gap-buffer) <- lookup *data-ah +617 emit-gap-buffer data, out 618 } 619 -620 fn word-is-decimal-integer? _self: (addr word) -> _/eax: boolean { -621 var self/eax: (addr word) <- copy _self -622 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data -623 var data/eax: (addr gap-buffer) <- lookup *data-ah -624 var result/eax: boolean <- gap-buffer-is-decimal-integer? data +620 fn word-is-decimal-integer? _self: (addr word) -> _/eax: boolean { +621 var self/eax: (addr word) <- copy _self +622 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data +623 var data/eax: (addr gap-buffer) <- lookup *data-ah +624 var result/eax: boolean <- gap-buffer-is-decimal-integer? data 625 return result 626 } 627 -628 fn word-exists? haystack: (addr word), needle: (addr word) -> _/eax: boolean { +628 fn word-exists? haystack: (addr word), needle: (addr word) -> _/eax: boolean { 629 # base case 630 compare haystack, 0 631 { @@ -692,89 +692,89 @@ if ('onhashchange' in window) { 633 return 0/false 634 } 635 # check current word -636 var found?/eax: boolean <- words-equal? haystack, needle +636 var found?/eax: boolean <- words-equal? haystack, needle 637 compare found?, 0/false 638 { 639 break-if-= 640 return 1/true 641 } 642 # recurse -643 var curr/eax: (addr word) <- copy haystack -644 var next-ah/eax: (addr handle word) <- get curr, next -645 var next/eax: (addr word) <- lookup *next-ah -646 var result/eax: boolean <- word-exists? next, needle +643 var curr/eax: (addr word) <- copy haystack +644 var next-ah/eax: (addr handle word) <- get curr, next +645 var next/eax: (addr word) <- lookup *next-ah +646 var result/eax: boolean <- word-exists? next, needle 647 return result 648 } 649 -650 fn test-word-exists? { -651 var needle-storage: word -652 var needle/esi: (addr word) <- address needle-storage -653 initialize-word-with needle, "abc" -654 var w-storage: (handle word) -655 var w-ah/edi: (addr handle word) <- address w-storage -656 allocate w-ah -657 var _w/eax: (addr word) <- lookup *w-ah -658 var w/ecx: (addr word) <- copy _w -659 initialize-word-with w, "aaa" +650 fn test-word-exists? { +651 var needle-storage: word +652 var needle/esi: (addr word) <- address needle-storage +653 initialize-word-with needle, "abc" +654 var w-storage: (handle word) +655 var w-ah/edi: (addr handle word) <- address w-storage +656 allocate w-ah +657 var _w/eax: (addr word) <- lookup *w-ah +658 var w/ecx: (addr word) <- copy _w +659 initialize-word-with w, "aaa" 660 # -661 var result/eax: boolean <- word-exists? w, w -662 check result, "F - test-word-exists? reflexive" -663 result <- word-exists? w, needle -664 check-not result, "F - test-word-exists? 1" -665 append-word-at-end-with w-ah, "bbb" -666 result <- word-exists? w, needle -667 check-not result, "F - test-word-exists? 2" -668 append-word-at-end-with w-ah, "abc" -669 result <- word-exists? w, needle -670 check result, "F - test-word-exists? 3" -671 append-word-at-end-with w-ah, "ddd" -672 result <- word-exists? w, needle -673 check result, "F - test-word-exists? 4" +661 var result/eax: boolean <- word-exists? w, w +662 check result, "F - test-word-exists? reflexive" +663 result <- word-exists? w, needle +664 check-not result, "F - test-word-exists? 1" +665 append-word-at-end-with w-ah, "bbb" +666 result <- word-exists? w, needle +667 check-not result, "F - test-word-exists? 2" +668 append-word-at-end-with w-ah, "abc" +669 result <- word-exists? w, needle +670 check result, "F - test-word-exists? 3" +671 append-word-at-end-with w-ah, "ddd" +672 result <- word-exists? w, needle +673 check result, "F - test-word-exists? 4" 674 } 675 -676 fn word-list-length words: (addr handle word) -> _/eax: int { -677 var curr-ah/esi: (addr handle word) <- copy words +676 fn word-list-length words: (addr handle word) -> _/eax: int { +677 var curr-ah/esi: (addr handle word) <- copy words 678 var result/edi: int <- copy 0 679 { -680 var curr/eax: (addr word) <- lookup *curr-ah +680 var curr/eax: (addr word) <- lookup *curr-ah 681 compare curr, 0 682 break-if-= 683 { -684 var word-len/eax: int <- word-length curr +684 var word-len/eax: int <- word-length curr 685 result <- add word-len 686 result <- add 1/inter-word-margin 687 } -688 curr-ah <- get curr, next +688 curr-ah <- get curr, next 689 loop 690 } 691 return result 692 } 693 694 # out-ah already has a word allocated and initialized -695 fn parse-words in: (addr array byte), out-ah: (addr handle word) { +695 fn parse-words in: (addr array byte), out-ah: (addr handle word) { 696 var in-stream: (stream byte 0x100) 697 var in-stream-a/esi: (addr stream byte) <- address in-stream -698 write in-stream-a, in -699 var cursor-word-ah/ebx: (addr handle word) <- copy out-ah +698 write in-stream-a, in +699 var cursor-word-ah/ebx: (addr handle word) <- copy out-ah 700 $parse-words:loop: { -701 var done?/eax: boolean <- stream-empty? in-stream-a +701 var done?/eax: boolean <- stream-empty? in-stream-a 702 compare done?, 0/false 703 break-if-!= -704 var _g/eax: grapheme <- read-grapheme in-stream-a +704 var _g/eax: grapheme <- read-grapheme in-stream-a 705 var g/ecx: grapheme <- copy _g 706 # if not space, insert 707 compare g, 0x20/space 708 { 709 break-if-= -710 var cursor-word/eax: (addr word) <- lookup *cursor-word-ah -711 add-grapheme-to-word cursor-word, g +710 var cursor-word/eax: (addr word) <- lookup *cursor-word-ah +711 add-grapheme-to-word cursor-word, g 712 loop $parse-words:loop 713 } 714 # otherwise insert word after and move cursor to it -715 append-word cursor-word-ah -716 var cursor-word/eax: (addr word) <- lookup *cursor-word-ah -717 cursor-to-start cursor-word # reset cursor in each function -718 cursor-word-ah <- get cursor-word, next +715 append-word cursor-word-ah +716 var cursor-word/eax: (addr word) <- lookup *cursor-word-ah +717 cursor-to-start cursor-word # reset cursor in each function +718 cursor-word-ah <- get cursor-word, next 719 loop 720 } 721 } -- cgit 1.4.1-2-gfad0