From 3350c34a74844e21ea69077e01efff3bae64bdcd Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 23 Mar 2021 17:31:08 -0700 Subject: . --- html/shell/grapheme-stack.mu.html | 343 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100644 html/shell/grapheme-stack.mu.html (limited to 'html/shell/grapheme-stack.mu.html') diff --git a/html/shell/grapheme-stack.mu.html b/html/shell/grapheme-stack.mu.html new file mode 100644 index 00000000..ccd4a88f --- /dev/null +++ b/html/shell/grapheme-stack.mu.html @@ -0,0 +1,343 @@ + + + + +Mu - shell/grapheme-stack.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/shell/grapheme-stack.mu +
+  1 # grapheme stacks are the smallest unit of editable text
+  2 
+  3 type grapheme-stack {
+  4   data: (handle array grapheme)
+  5   top: int
+  6 }
+  7 
+  8 fn initialize-grapheme-stack _self: (addr grapheme-stack), n: int {
+  9   var self/esi: (addr grapheme-stack) <- copy _self
+ 10   var d/edi: (addr handle array grapheme) <- get self, data
+ 11   populate d, n
+ 12   var top/eax: (addr int) <- get self, top
+ 13   copy-to *top, 0
+ 14 }
+ 15 
+ 16 fn clear-grapheme-stack _self: (addr grapheme-stack) {
+ 17   var self/esi: (addr grapheme-stack) <- copy _self
+ 18   var top/eax: (addr int) <- get self, top
+ 19   copy-to *top, 0
+ 20 }
+ 21 
+ 22 fn grapheme-stack-empty? _self: (addr grapheme-stack) -> _/eax: boolean {
+ 23   var self/esi: (addr grapheme-stack) <- copy _self
+ 24   var top/eax: (addr int) <- get self, top
+ 25   compare *top, 0
+ 26   {
+ 27     break-if-!=
+ 28     return 1/true
+ 29   }
+ 30   return 0/false
+ 31 }
+ 32 
+ 33 fn grapheme-stack-length _self: (addr grapheme-stack) -> _/eax: int {
+ 34   var self/esi: (addr grapheme-stack) <- copy _self
+ 35   var top/eax: (addr int) <- get self, top
+ 36   return *top
+ 37 }
+ 38 
+ 39 fn push-grapheme-stack _self: (addr grapheme-stack), _val: grapheme {
+ 40   var self/esi: (addr grapheme-stack) <- copy _self
+ 41   var top-addr/ecx: (addr int) <- get self, top
+ 42   var data-ah/edx: (addr handle array grapheme) <- get self, data
+ 43   var data/eax: (addr array grapheme) <- lookup *data-ah
+ 44   var top/edx: int <- copy *top-addr
+ 45   var dest-addr/edx: (addr grapheme) <- index data, top
+ 46   var val/eax: grapheme <- copy _val
+ 47   copy-to *dest-addr, val
+ 48   add-to *top-addr, 1
+ 49 }
+ 50 
+ 51 fn pop-grapheme-stack _self: (addr grapheme-stack) -> _/eax: grapheme {
+ 52   var self/esi: (addr grapheme-stack) <- copy _self
+ 53   var top-addr/ecx: (addr int) <- get self, top
+ 54   {
+ 55     compare *top-addr, 0
+ 56     break-if->
+ 57     return -1
+ 58   }
+ 59   subtract-from *top-addr, 1
+ 60   var data-ah/edx: (addr handle array grapheme) <- get self, data
+ 61   var data/eax: (addr array grapheme) <- lookup *data-ah
+ 62   var top/edx: int <- copy *top-addr
+ 63   var result-addr/eax: (addr grapheme) <- index data, top
+ 64   return *result-addr
+ 65 }
+ 66 
+ 67 fn copy-grapheme-stack _src: (addr grapheme-stack), dest: (addr grapheme-stack) {
+ 68   var src/esi: (addr grapheme-stack) <- copy _src
+ 69   var data-ah/edi: (addr handle array grapheme) <- get src, data
+ 70   var _data/eax: (addr array grapheme) <- lookup *data-ah
+ 71   var data/edi: (addr array grapheme) <- copy _data
+ 72   var top-addr/ecx: (addr int) <- get src, top
+ 73   var i/eax: int <- copy 0
+ 74   {
+ 75     compare i, *top-addr
+ 76     break-if->=
+ 77     var g/edx: (addr grapheme) <- index data, i
+ 78     push-grapheme-stack dest, *g
+ 79     i <- increment
+ 80     loop
+ 81   }
+ 82 }
+ 83 
+ 84 # dump stack to screen from bottom to top
+ 85 # colors hardcoded
+ 86 fn render-stack-from-bottom-wrapping-right-then-down screen: (addr screen), _self: (addr grapheme-stack), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int -> _/eax: int, _/ecx: int {
+ 87   var self/esi: (addr grapheme-stack) <- copy _self
+ 88   var data-ah/edi: (addr handle array grapheme) <- get self, data
+ 89   var _data/eax: (addr array grapheme) <- lookup *data-ah
+ 90   var data/edi: (addr array grapheme) <- copy _data
+ 91   var x/eax: int <- copy _x
+ 92   var y/ecx: int <- copy _y
+ 93   var top-addr/edx: (addr int) <- get self, top
+ 94   var i/ebx: int <- copy 0
+ 95   {
+ 96     compare i, *top-addr
+ 97     break-if->=
+ 98     {
+ 99       var g/edx: (addr grapheme) <- index data, i
+100       x, y <- render-grapheme screen, *g, xmin, ymin, xmax, ymax, x, y, 3/fg=cyan, 0/bg
+101     }
+102     i <- increment
+103     loop
+104   }
+105   return x, y
+106 }
+107 
+108 # helper for small words
+109 fn render-stack-from-bottom screen: (addr screen), self: (addr grapheme-stack), x: int, y: int -> _/eax: int {
+110   var _width/eax: int <- copy 0
+111   var _height/ecx: int <- copy 0
+112   _width, _height <- screen-size screen
+113   var width/edx: int <- copy _width
+114   var height/ebx: int <- copy _height
+115   var x2/eax: int <- copy 0
+116   var y2/ecx: int <- copy 0
+117   x2, y2 <- render-stack-from-bottom-wrapping-right-then-down screen, self, x, y, width, height, x, y
+118   return x2  # y2? yolo
+119 }
+120 
+121 # dump stack to screen from top to bottom
+122 # optionally render a 'cursor' with the top grapheme
+123 fn render-stack-from-top-wrapping-right-then-down screen: (addr screen), _self: (addr grapheme-stack), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, render-cursor?: boolean -> _/eax: int, _/ecx: int {
+124   var self/esi: (addr grapheme-stack) <- copy _self
+125   var data-ah/edi: (addr handle array grapheme) <- get self, data
+126   var _data/eax: (addr array grapheme) <- lookup *data-ah
+127   var data/edi: (addr array grapheme) <- copy _data
+128   var x/eax: int <- copy _x
+129   var y/ecx: int <- copy _y
+130   var top-addr/edx: (addr int) <- get self, top
+131   var i/ebx: int <- copy *top-addr
+132   i <- decrement
+133   # if render-cursor?, peel off first iteration
+134   {
+135     compare render-cursor?, 0/false
+136     break-if-=
+137     compare i, 0
+138     break-if-<
+139     {
+140       var g/edx: (addr grapheme) <- index data, i
+141       x, y <- render-grapheme screen, *g, xmin, ymin, xmax, ymax, x, y, 3/fg=cyan, 7/bg=cursor
+142     }
+143     i <- decrement
+144   }
+145   # remaining iterations
+146   {
+147     compare i, 0
+148     break-if-<
+149     {
+150       var g/edx: (addr grapheme) <- index data, i
+151       x, y <- render-grapheme screen, *g, xmin, ymin, xmax, ymax, x, y, 3/fg=cyan, 0/bg=cursor
+152     }
+153     i <- decrement
+154     loop
+155   }
+156   return x, y
+157 }
+158 
+159 # helper for small words
+160 fn render-stack-from-top screen: (addr screen), self: (addr grapheme-stack), x: int, y: int, render-cursor?: boolean -> _/eax: int {
+161   var _width/eax: int <- copy 0
+162   var _height/ecx: int <- copy 0
+163   _width, _height <- screen-size screen
+164   var width/edx: int <- copy _width
+165   var height/ebx: int <- copy _height
+166   var x2/eax: int <- copy 0
+167   var y2/ecx: int <- copy 0
+168   x2, y2 <- render-stack-from-top-wrapping-right-then-down screen, self, x, y, width, height, x, y, render-cursor?
+169   return x2  # y2? yolo
+170 }
+171 
+172 fn test-render-grapheme-stack {
+173   # setup: gs = "abc"
+174   var gs-storage: grapheme-stack
+175   var gs/edi: (addr grapheme-stack) <- address gs-storage
+176   initialize-grapheme-stack gs, 5
+177   var g/eax: grapheme <- copy 0x61/a
+178   push-grapheme-stack gs, g
+179   g <- copy 0x62/b
+180   push-grapheme-stack gs, g
+181   g <- copy 0x63/c
+182   push-grapheme-stack gs, g
+183   # setup: screen
+184   var screen-on-stack: screen
+185   var screen/esi: (addr screen) <- address screen-on-stack
+186   initialize-screen screen, 5, 4
+187   #
+188   var x/eax: int <- render-stack-from-bottom screen, gs, 0/x, 0/y
+189   check-screen-row screen, 0/y, "abc ", "F - test-render-grapheme-stack from bottom"
+190   check-ints-equal x, 3, "F - test-render-grapheme-stack from bottom: result"
+191   check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, "   ", "F - test-render-grapheme-stack from bottom: bg"
+192   #
+193   var x/eax: int <- render-stack-from-top screen, gs, 0/x, 1/y, 0/cursor=false
+194   check-screen-row screen, 1/y, "cba ", "F - test-render-grapheme-stack from top without cursor"
+195   check-ints-equal x, 3, "F - test-render-grapheme-stack from top without cursor: result"
+196   check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "   ", "F - test-render-grapheme-stack from top without cursor: bg"
+197   #
+198   var x/eax: int <- render-stack-from-top screen, gs, 0/x, 2/y, 1/cursor=true
+199   check-screen-row screen, 2/y, "cba ", "F - test-render-grapheme-stack from top with cursor"
+200   check-ints-equal x, 3, "F - test-render-grapheme-stack from top without cursor: result"
+201   check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, "|   ", "F - test-render-grapheme-stack from top with cursor: bg"
+202 }
+203 
+204 # compare from bottom
+205 # beware: modifies 'stream', which must be disposed of after a false result
+206 fn prefix-match? _self: (addr grapheme-stack), s: (addr stream byte) -> _/eax: boolean {
+207   var self/esi: (addr grapheme-stack) <- copy _self
+208   var data-ah/edi: (addr handle array grapheme) <- get self, data
+209   var _data/eax: (addr array grapheme) <- lookup *data-ah
+210   var data/edi: (addr array grapheme) <- copy _data
+211   var top-addr/ecx: (addr int) <- get self, top
+212   var i/ebx: int <- copy 0
+213   {
+214     compare i, *top-addr
+215     break-if->=
+216     # if curr != expected, return false
+217     {
+218       var curr-a/edx: (addr grapheme) <- index data, i
+219       var expected/eax: grapheme <- read-grapheme s
+220       {
+221         compare expected, *curr-a
+222         break-if-=
+223         return 0/false
+224       }
+225     }
+226     i <- increment
+227     loop
+228   }
+229   return 1   # true
+230 }
+231 
+232 # compare from bottom
+233 # beware: modifies 'stream', which must be disposed of after a false result
+234 fn suffix-match? _self: (addr grapheme-stack), s: (addr stream byte) -> _/eax: boolean {
+235   var self/esi: (addr grapheme-stack) <- copy _self
+236   var data-ah/edi: (addr handle array grapheme) <- get self, data
+237   var _data/eax: (addr array grapheme) <- lookup *data-ah
+238   var data/edi: (addr array grapheme) <- copy _data
+239   var top-addr/eax: (addr int) <- get self, top
+240   var i/ebx: int <- copy *top-addr
+241   i <- decrement
+242   {
+243     compare i, 0
+244     break-if-<
+245     {
+246       var curr-a/edx: (addr grapheme) <- index data, i
+247       var expected/eax: grapheme <- read-grapheme s
+248       # if curr != expected, return false
+249       {
+250         compare expected, *curr-a
+251         break-if-=
+252         return 0/false
+253       }
+254     }
+255     i <- decrement
+256     loop
+257   }
+258   return 1   # true
+259 }
+260 
+261 fn grapheme-stack-is-decimal-integer? _self: (addr grapheme-stack) -> _/eax: boolean {
+262   var self/esi: (addr grapheme-stack) <- copy _self
+263   var data-ah/eax: (addr handle array grapheme) <- get self, data
+264   var _data/eax: (addr array grapheme) <- lookup *data-ah
+265   var data/edx: (addr array grapheme) <- copy _data
+266   var top-addr/ecx: (addr int) <- get self, top
+267   var i/ebx: int <- copy 0
+268   var result/eax: boolean <- copy 1/true
+269   $grapheme-stack-is-integer?:loop: {
+270     compare i, *top-addr
+271     break-if->=
+272     var g/edx: (addr grapheme) <- index data, i
+273     result <- decimal-digit? *g
+274     compare result, 0/false
+275     break-if-=
+276     i <- increment
+277     loop
+278   }
+279   return result
+280 }
+
+ + + -- cgit 1.4.1-2-gfad0