From 3350c34a74844e21ea69077e01efff3bae64bdcd Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 23 Mar 2021 17:31:08 -0700 Subject: . --- html/linux/tile/gap-buffer.mu.html | 406 +++++++++++++++++++++++++++++++++++++ 1 file changed, 406 insertions(+) create mode 100644 html/linux/tile/gap-buffer.mu.html (limited to 'html/linux/tile/gap-buffer.mu.html') diff --git a/html/linux/tile/gap-buffer.mu.html b/html/linux/tile/gap-buffer.mu.html new file mode 100644 index 00000000..f2995b6d --- /dev/null +++ b/html/linux/tile/gap-buffer.mu.html @@ -0,0 +1,406 @@ + + + + +Mu - linux/tile/gap-buffer.mu + + + + + + + + + + +https://github.com/akkartik/mu/blob/main/linux/tile/gap-buffer.mu +
+  1 type gap-buffer {
+  2   left: grapheme-stack
+  3   right: grapheme-stack
+  4 }
+  5 
+  6 fn initialize-gap-buffer _self: (addr gap-buffer) {
+  7   var self/esi: (addr gap-buffer) <- copy _self
+  8   var left/eax: (addr grapheme-stack) <- get self, left
+  9   initialize-grapheme-stack left, 0x10/max-word-size
+ 10   var right/eax: (addr grapheme-stack) <- get self, right
+ 11   initialize-grapheme-stack right, 0x10/max-word-size
+ 12 }
+ 13 
+ 14 # just for tests
+ 15 fn initialize-gap-buffer-with self: (addr gap-buffer), s: (addr array byte) {
+ 16   initialize-gap-buffer self
+ 17   var stream-storage: (stream byte 0x10/max-word-size)
+ 18   var stream/ecx: (addr stream byte) <- address stream-storage
+ 19   write stream, s
+ 20   {
+ 21     var done?/eax: boolean <- stream-empty? stream
+ 22     compare done?, 0/false
+ 23     break-if-!=
+ 24     var g/eax: grapheme <- read-grapheme stream
+ 25     add-grapheme-at-gap self, g
+ 26     loop
+ 27   }
+ 28 }
+ 29 
+ 30 fn gap-buffer-to-string self: (addr gap-buffer), out: (addr handle array byte) {
+ 31   var s-storage: (stream byte 0x100)
+ 32   var s/ecx: (addr stream byte) <- address s-storage
+ 33   emit-gap-buffer self, s
+ 34   stream-to-array s, out
+ 35 }
+ 36 
+ 37 fn emit-gap-buffer _self: (addr gap-buffer), out: (addr stream byte) {
+ 38   var self/esi: (addr gap-buffer) <- copy _self
+ 39   clear-stream out
+ 40   var left/eax: (addr grapheme-stack) <- get self, left
+ 41   emit-stack-from-bottom left, out
+ 42   var right/eax: (addr grapheme-stack) <- get self, right
+ 43   emit-stack-from-top right, out
+ 44 }
+ 45 
+ 46 # dump stack from bottom to top
+ 47 fn emit-stack-from-bottom _self: (addr grapheme-stack), out: (addr stream byte) {
+ 48   var self/esi: (addr grapheme-stack) <- copy _self
+ 49   var data-ah/edi: (addr handle array grapheme) <- get self, data
+ 50   var _data/eax: (addr array grapheme) <- lookup *data-ah
+ 51   var data/edi: (addr array grapheme) <- copy _data
+ 52   var top-addr/ecx: (addr int) <- get self, top
+ 53   var i/eax: int <- copy 0
+ 54   {
+ 55     compare i, *top-addr
+ 56     break-if->=
+ 57     var g/edx: (addr grapheme) <- index data, i
+ 58     write-grapheme out, *g
+ 59     i <- increment
+ 60     loop
+ 61   }
+ 62 }
+ 63 
+ 64 # dump stack from top to bottom
+ 65 fn emit-stack-from-top _self: (addr grapheme-stack), out: (addr stream byte) {
+ 66   var self/esi: (addr grapheme-stack) <- copy _self
+ 67   var data-ah/edi: (addr handle array grapheme) <- get self, data
+ 68   var _data/eax: (addr array grapheme) <- lookup *data-ah
+ 69   var data/edi: (addr array grapheme) <- copy _data
+ 70   var top-addr/ecx: (addr int) <- get self, top
+ 71   var i/eax: int <- copy *top-addr
+ 72   i <- decrement
+ 73   {
+ 74     compare i, 0
+ 75     break-if-<
+ 76     var g/edx: (addr grapheme) <- index data, i
+ 77     write-grapheme out, *g
+ 78     i <- decrement
+ 79     loop
+ 80   }
+ 81 }
+ 82 
+ 83 fn render-gap-buffer screen: (addr screen), _gap: (addr gap-buffer) {
+ 84   var gap/esi: (addr gap-buffer) <- copy _gap
+ 85   var left/eax: (addr grapheme-stack) <- get gap, left
+ 86   render-stack-from-bottom left, screen
+ 87   var right/eax: (addr grapheme-stack) <- get gap, right
+ 88   render-stack-from-top right, screen
+ 89 }
+ 90 
+ 91 fn gap-buffer-length _gap: (addr gap-buffer) -> _/eax: int {
+ 92   var gap/esi: (addr gap-buffer) <- copy _gap
+ 93   var left/eax: (addr grapheme-stack) <- get gap, left
+ 94   var tmp/eax: (addr int) <- get left, top
+ 95   var left-length/ecx: int <- copy *tmp
+ 96   var right/esi: (addr grapheme-stack) <- get gap, right
+ 97   tmp <- get right, top
+ 98   var result/eax: int <- copy *tmp
+ 99   result <- add left-length
+100   return result
+101 }
+102 
+103 fn add-grapheme-at-gap _self: (addr gap-buffer), g: grapheme {
+104   var self/esi: (addr gap-buffer) <- copy _self
+105   var left/eax: (addr grapheme-stack) <- get self, left
+106   push-grapheme-stack left, g
+107 }
+108 
+109 fn gap-to-start self: (addr gap-buffer) {
+110   {
+111     var curr/eax: grapheme <- gap-left self
+112     compare curr, -1
+113     loop-if-!=
+114   }
+115 }
+116 
+117 fn gap-to-end self: (addr gap-buffer) {
+118   {
+119     var curr/eax: grapheme <- gap-right self
+120     compare curr, -1
+121     loop-if-!=
+122   }
+123 }
+124 
+125 fn gap-at-start? _self: (addr gap-buffer) -> _/eax: boolean {
+126   var self/esi: (addr gap-buffer) <- copy _self
+127   var left/eax: (addr grapheme-stack) <- get self, left
+128   var result/eax: boolean <- grapheme-stack-empty? left
+129   return result
+130 }
+131 
+132 fn gap-at-end? _self: (addr gap-buffer) -> _/eax: boolean {
+133   var self/esi: (addr gap-buffer) <- copy _self
+134   var right/eax: (addr grapheme-stack) <- get self, right
+135   var result/eax: boolean <- grapheme-stack-empty? right
+136   return result
+137 }
+138 
+139 fn gap-right _self: (addr gap-buffer) -> _/eax: grapheme {
+140   var self/esi: (addr gap-buffer) <- copy _self
+141   var g/eax: grapheme <- copy 0
+142   var right/ecx: (addr grapheme-stack) <- get self, right
+143   g <- pop-grapheme-stack right
+144   compare g, -1
+145   {
+146     break-if-=
+147     var left/ecx: (addr grapheme-stack) <- get self, left
+148     push-grapheme-stack left, g
+149   }
+150   return g
+151 }
+152 
+153 fn gap-left _self: (addr gap-buffer) -> _/eax: grapheme {
+154   var self/esi: (addr gap-buffer) <- copy _self
+155   var g/eax: grapheme <- copy 0
+156   {
+157     var left/ecx: (addr grapheme-stack) <- get self, left
+158     g <- pop-grapheme-stack left
+159   }
+160   compare g, -1
+161   {
+162     break-if-=
+163     var right/ecx: (addr grapheme-stack) <- get self, right
+164     push-grapheme-stack right, g
+165   }
+166   return g
+167 }
+168 
+169 fn gap-index _self: (addr gap-buffer) -> _/eax: int {
+170   var self/eax: (addr gap-buffer) <- copy _self
+171   var left/eax: (addr grapheme-stack) <- get self, left
+172   var top-addr/eax: (addr int) <- get left, top
+173   var result/eax: int <- copy *top-addr
+174   return result
+175 }
+176 
+177 fn first-grapheme-in-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme {
+178   var self/esi: (addr gap-buffer) <- copy _self
+179   # try to read from left
+180   var left/eax: (addr grapheme-stack) <- get self, left
+181   var top-addr/ecx: (addr int) <- get left, top
+182   compare *top-addr, 0
+183   {
+184     break-if-<=
+185     var data-ah/eax: (addr handle array grapheme) <- get left, data
+186     var data/eax: (addr array grapheme) <- lookup *data-ah
+187     var result-addr/eax: (addr grapheme) <- index data, 0
+188     return *result-addr
+189   }
+190   # try to read from right
+191   var right/eax: (addr grapheme-stack) <- get self, right
+192   top-addr <- get right, top
+193   compare *top-addr, 0
+194   {
+195     break-if-<=
+196     var data-ah/eax: (addr handle array grapheme) <- get right, data
+197     var data/eax: (addr array grapheme) <- lookup *data-ah
+198     var top/ecx: int <- copy *top-addr
+199     top <- decrement
+200     var result-addr/eax: (addr grapheme) <- index data, top
+201     return *result-addr
+202   }
+203   # give up
+204   return -1
+205 }
+206 
+207 fn grapheme-before-cursor-in-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme {
+208   var self/esi: (addr gap-buffer) <- copy _self
+209   # try to read from left
+210   var left/ecx: (addr grapheme-stack) <- get self, left
+211   var top-addr/edx: (addr int) <- get left, top
+212   compare *top-addr, 0
+213   {
+214     break-if-<=
+215     var result/eax: grapheme <- pop-grapheme-stack left
+216     push-grapheme-stack left, result
+217     return result
+218   }
+219   # give up
+220   return -1
+221 }
+222 
+223 fn delete-before-gap _self: (addr gap-buffer) {
+224   var self/eax: (addr gap-buffer) <- copy _self
+225   var left/eax: (addr grapheme-stack) <- get self, left
+226   var dummy/eax: grapheme <- pop-grapheme-stack left
+227 }
+228 
+229 fn pop-after-gap _self: (addr gap-buffer) -> _/eax: grapheme {
+230   var self/eax: (addr gap-buffer) <- copy _self
+231   var right/eax: (addr grapheme-stack) <- get self, right
+232   var result/eax: grapheme <- pop-grapheme-stack right
+233   return result
+234 }
+235 
+236 fn gap-buffer-equal? _self: (addr gap-buffer), s: (addr array byte) -> _/eax: boolean {
+237   var self/esi: (addr gap-buffer) <- copy _self
+238   # complication: graphemes may be multiple bytes
+239   # so don't rely on length
+240   # instead turn the expected result into a stream and arrange to read from it in order
+241   var stream-storage: (stream byte 0x10/max-word-size)
+242   var expected-stream/ecx: (addr stream byte) <- address stream-storage
+243   write expected-stream, s
+244   # compare left
+245   var left/edx: (addr grapheme-stack) <- get self, left
+246   var result/eax: boolean <- prefix-match? left, expected-stream
+247   compare result, 0/false
+248   {
+249     break-if-!=
+250     return result
+251   }
+252   # compare right
+253   var right/edx: (addr grapheme-stack) <- get self, right
+254   result <- suffix-match? right, expected-stream
+255   compare result, 0/false
+256   {
+257     break-if-!=
+258     return result
+259   }
+260   # ensure there's nothing left over
+261   result <- stream-empty? expected-stream
+262   return result
+263 }
+264 
+265 fn test-gap-buffer-equal-from-end? {
+266   var _g: gap-buffer
+267   var g/esi: (addr gap-buffer) <- address _g
+268   initialize-gap-buffer g
+269   #
+270   var c/eax: grapheme <- copy 0x61/a
+271   add-grapheme-at-gap g, c
+272   add-grapheme-at-gap g, c
+273   add-grapheme-at-gap g, c
+274   # gap is at end (right is empty)
+275   var _result/eax: boolean <- gap-buffer-equal? g, "aaa"
+276   var result/eax: int <- copy _result
+277   check-ints-equal result, 1, "F - test-gap-buffer-equal-from-end?"
+278 }
+279 
+280 fn test-gap-buffer-equal-from-middle? {
+281   var _g: gap-buffer
+282   var g/esi: (addr gap-buffer) <- address _g
+283   initialize-gap-buffer g
+284   #
+285   var c/eax: grapheme <- copy 0x61/a
+286   add-grapheme-at-gap g, c
+287   add-grapheme-at-gap g, c
+288   add-grapheme-at-gap g, c
+289   var dummy/eax: grapheme <- gap-left g
+290   # gap is in the middle
+291   var _result/eax: boolean <- gap-buffer-equal? g, "aaa"
+292   var result/eax: int <- copy _result
+293   check-ints-equal result, 1, "F - test-gap-buffer-equal-from-middle?"
+294 }
+295 
+296 fn test-gap-buffer-equal-from-start? {
+297   var _g: gap-buffer
+298   var g/esi: (addr gap-buffer) <- address _g
+299   initialize-gap-buffer g
+300   #
+301   var c/eax: grapheme <- copy 0x61/a
+302   add-grapheme-at-gap g, c
+303   add-grapheme-at-gap g, c
+304   add-grapheme-at-gap g, c
+305   var dummy/eax: grapheme <- gap-left g
+306   dummy <- gap-left g
+307   dummy <- gap-left g
+308   # gap is at the start
+309   var _result/eax: boolean <- gap-buffer-equal? g, "aaa"
+310   var result/eax: int <- copy _result
+311   check-ints-equal result, 1, "F - test-gap-buffer-equal-from-start?"
+312 }
+313 
+314 fn copy-gap-buffer _src-ah: (addr handle gap-buffer), _dest-ah: (addr handle gap-buffer) {
+315   # obtain src-a, dest-a
+316   var src-ah/eax: (addr handle gap-buffer) <- copy _src-ah
+317   var _src-a/eax: (addr gap-buffer) <- lookup *src-ah
+318   var src-a/esi: (addr gap-buffer) <- copy _src-a
+319   var dest-ah/eax: (addr handle gap-buffer) <- copy _dest-ah
+320   var _dest-a/eax: (addr gap-buffer) <- lookup *dest-ah
+321   var dest-a/edi: (addr gap-buffer) <- copy _dest-a
+322   # copy left grapheme-stack
+323   var src/ecx: (addr grapheme-stack) <- get src-a, left
+324   var dest/edx: (addr grapheme-stack) <- get dest-a, left
+325   copy-grapheme-stack src, dest
+326   # copy right grapheme-stack
+327   src <- get src-a, right
+328   dest <- get dest-a, right
+329   copy-grapheme-stack src, dest
+330 }
+331 
+332 fn gap-buffer-is-decimal-integer? _self: (addr gap-buffer) -> _/eax: boolean {
+333   var self/esi: (addr gap-buffer) <- copy _self
+334   var curr/ecx: (addr grapheme-stack) <- get self, left
+335   var result/eax: boolean <- grapheme-stack-is-decimal-integer? curr
+336   {
+337     compare result, 0/false
+338     break-if-=
+339     curr <- get self, right
+340     result <- grapheme-stack-is-decimal-integer? curr
+341   }
+342   return result
+343 }
+
+ + + -- cgit 1.4.1-2-gfad0