diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-09-22 21:54:38 -0700 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-09-22 21:54:38 -0700 |
commit | 4b3461fa0ad4aaa7a29cf914614dab7a6cdcacfc (patch) | |
tree | 0f1119c4ef060e23011df463f87d9c7eed820d3e /apps/tile/grapheme-stack.mu | |
parent | abfdb26cd3b3625142cfe72aa32445944d72c4f6 (diff) | |
download | mu-4b3461fa0ad4aaa7a29cf914614dab7a6cdcacfc.tar.gz |
6837
Diffstat (limited to 'apps/tile/grapheme-stack.mu')
-rw-r--r-- | apps/tile/grapheme-stack.mu | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/apps/tile/grapheme-stack.mu b/apps/tile/grapheme-stack.mu new file mode 100644 index 00000000..2b7c8a87 --- /dev/null +++ b/apps/tile/grapheme-stack.mu @@ -0,0 +1,159 @@ +type grapheme-stack { + data: (handle array grapheme) + top: int +} + +fn initialize-grapheme-stack _self: (addr grapheme-stack), n: int { + var self/esi: (addr grapheme-stack) <- copy _self + var d/edi: (addr handle array grapheme) <- get self, data + populate d, n + var top/eax: (addr int) <- get self, top + copy-to *top, 0 +} + +fn grapheme-stack-empty? _self: (addr grapheme-stack) -> result/eax: boolean { +$grapheme-stack-empty?:body: { + var self/esi: (addr grapheme-stack) <- copy _self + var top/eax: (addr int) <- get self, top + compare *top, 0 + { + break-if-= + result <- copy 1 # false + break $grapheme-stack-empty?:body + } + result <- copy 0 # false +} +} + +fn push-grapheme-stack _self: (addr grapheme-stack), _val: grapheme { + var self/esi: (addr grapheme-stack) <- copy _self + var top-addr/ecx: (addr int) <- get self, top + var data-ah/edx: (addr handle array grapheme) <- get self, data + var data/eax: (addr array grapheme) <- lookup *data-ah + var top/edx: int <- copy *top-addr + var dest-addr/edx: (addr grapheme) <- index data, top + var val/eax: grapheme <- copy _val + copy-to *dest-addr, val + add-to *top-addr, 1 +} + +fn pop-grapheme-stack _self: (addr grapheme-stack) -> val/eax: grapheme { +$pop-grapheme-stack:body: { + var self/esi: (addr grapheme-stack) <- copy _self + var top-addr/ecx: (addr int) <- get self, top + { + compare *top-addr, 0 + break-if-> + val <- copy -1 + break $pop-grapheme-stack:body + } + subtract-from *top-addr, 1 + var data-ah/edx: (addr handle array grapheme) <- get self, data + var data/eax: (addr array grapheme) <- lookup *data-ah + var top/edx: int <- copy *top-addr + var result-addr/eax: (addr grapheme) <- index data, top + val <- copy *result-addr +} +} + +# dump stack to screen from bottom to top +# don't move the cursor or anything +fn render-stack-from-bottom _self: (addr grapheme-stack), screen: (addr screen) { + var self/esi: (addr grapheme-stack) <- copy _self + var data-ah/edi: (addr handle array grapheme) <- get self, data + var _data/eax: (addr array grapheme) <- lookup *data-ah + var data/edi: (addr array grapheme) <- copy _data + var top-addr/ecx: (addr int) <- get self, top + var i/eax: int <- copy 0 + { + compare i, *top-addr + break-if->= + var g/edx: (addr grapheme) <- index data, i + print-grapheme screen, *g + i <- increment + loop + } +} + +# dump stack to screen from top to bottom +# don't move the cursor or anything +fn render-stack-from-top _self: (addr grapheme-stack), screen: (addr screen) { + var self/esi: (addr grapheme-stack) <- copy _self + var data-ah/edi: (addr handle array grapheme) <- get self, data + var _data/eax: (addr array grapheme) <- lookup *data-ah + var data/edi: (addr array grapheme) <- copy _data + var top-addr/ecx: (addr int) <- get self, top + var i/eax: int <- copy *top-addr + i <- decrement + { + compare i, 0 + break-if-< + var g/edx: (addr grapheme) <- index data, i + print-grapheme screen, *g + i <- decrement + loop + } +} + +# compare from bottom +# beware: modifies 'stream', which must be disposed of after a false result +fn prefix-match? _self: (addr grapheme-stack), s: (addr stream byte) -> result/eax: boolean { +$prefix-match?:body: { + var self/esi: (addr grapheme-stack) <- copy _self + var data-ah/edi: (addr handle array grapheme) <- get self, data + var _data/eax: (addr array grapheme) <- lookup *data-ah + var data/edi: (addr array grapheme) <- copy _data + var top-addr/ecx: (addr int) <- get self, top + var i/ebx: int <- copy 0 + { + compare i, *top-addr + break-if->= + # if curr != expected, return false + { + var curr-a/edx: (addr grapheme) <- index data, i + var expected/eax: grapheme <- read-grapheme s + { + compare expected, *curr-a + break-if-= + result <- copy 0 # false + break $prefix-match?:body + } + } + i <- increment + loop + } + result <- copy 1 # true +} +} + +# compare from bottom +# beware: modifies 'stream', which must be disposed of after a false result +fn suffix-match? _self: (addr grapheme-stack), s: (addr stream byte) -> result/eax: boolean { +$suffix-match?:body: { + var self/esi: (addr grapheme-stack) <- copy _self + var data-ah/edi: (addr handle array grapheme) <- get self, data + var _data/eax: (addr array grapheme) <- lookup *data-ah + var data/edi: (addr array grapheme) <- copy _data + var top-addr/eax: (addr int) <- get self, top + var i/ebx: int <- copy *top-addr + i <- decrement + { + compare i, 0 + break-if-< + { + var curr-a/edx: (addr grapheme) <- index data, i + var expected/eax: grapheme <- read-grapheme s + # if curr != expected, return false + { + compare expected, *curr-a + break-if-= + result <- copy 0 # false + break $suffix-match?:body + } + } + i <- decrement + loop + } + result <- copy 1 # true +} +} |