https://github.com/akkartik/mu/blob/main/linux/tile/grapheme-stack.mu
1 type grapheme-stack {
2 data: (handle array code-point-utf8)
3 top: int
4 }
5
6 fn initialize-grapheme-stack _self: (addr grapheme-stack), n: int {
7 var self/esi: (addr grapheme-stack) <- copy _self
8 var d/edi: (addr handle array code-point-utf8) <- get self, data
9 populate d, n
10 var top/eax: (addr int) <- get self, top
11 copy-to *top, 0
12 }
13
14 fn clear-grapheme-stack _self: (addr grapheme-stack) {
15 var self/esi: (addr grapheme-stack) <- copy _self
16 var top/eax: (addr int) <- get self, top
17 copy-to *top, 0
18 }
19
20 fn grapheme-stack-empty? _self: (addr grapheme-stack) -> _/eax: boolean {
21 var self/esi: (addr grapheme-stack) <- copy _self
22 var top/eax: (addr int) <- get self, top
23 compare *top, 0
24 {
25 break-if-!=
26 return 1/true
27 }
28 return 0/false
29 }
30
31 fn push-grapheme-stack _self: (addr grapheme-stack), _val: code-point-utf8 {
32 var self/esi: (addr grapheme-stack) <- copy _self
33 var top-addr/ecx: (addr int) <- get self, top
34 var data-ah/edx: (addr handle array code-point-utf8) <- get self, data
35 var data/eax: (addr array code-point-utf8) <- lookup *data-ah
36 var top/edx: int <- copy *top-addr
37 var dest-addr/edx: (addr code-point-utf8) <- index data, top
38 var val/eax: code-point-utf8 <- copy _val
39 copy-to *dest-addr, val
40 add-to *top-addr, 1
41 }
42
43 fn pop-grapheme-stack _self: (addr grapheme-stack) -> _/eax: code-point-utf8 {
44 var self/esi: (addr grapheme-stack) <- copy _self
45 var top-addr/ecx: (addr int) <- get self, top
46 {
47 compare *top-addr, 0
48 break-if->
49 return -1
50 }
51 subtract-from *top-addr, 1
52 var data-ah/edx: (addr handle array code-point-utf8) <- get self, data
53 var data/eax: (addr array code-point-utf8) <- lookup *data-ah
54 var top/edx: int <- copy *top-addr
55 var result-addr/eax: (addr code-point-utf8) <- index data, top
56 return *result-addr
57 }
58
59 fn copy-grapheme-stack _src: (addr grapheme-stack), dest: (addr grapheme-stack) {
60 var src/esi: (addr grapheme-stack) <- copy _src
61 var data-ah/edi: (addr handle array code-point-utf8) <- get src, data
62 var _data/eax: (addr array code-point-utf8) <- lookup *data-ah
63 var data/edi: (addr array code-point-utf8) <- copy _data
64 var top-addr/ecx: (addr int) <- get src, top
65 var i/eax: int <- copy 0
66 {
67 compare i, *top-addr
68 break-if->=
69 var g/edx: (addr code-point-utf8) <- index data, i
70 push-grapheme-stack dest, *g
71 i <- increment
72 loop
73 }
74 }
75
76
77
78 fn render-stack-from-bottom _self: (addr grapheme-stack), screen: (addr screen) {
79 var self/esi: (addr grapheme-stack) <- copy _self
80 var data-ah/edi: (addr handle array code-point-utf8) <- get self, data
81 var _data/eax: (addr array code-point-utf8) <- lookup *data-ah
82 var data/edi: (addr array code-point-utf8) <- copy _data
83 var top-addr/ecx: (addr int) <- get self, top
84 var i/eax: int <- copy 0
85 {
86 compare i, *top-addr
87 break-if->=
88 var g/edx: (addr code-point-utf8) <- index data, i
89 print-code-point-utf8 screen, *g
90 i <- increment
91 loop
92 }
93 }
94
95
96
97 fn render-stack-from-top _self: (addr grapheme-stack), screen: (addr screen) {
98 var self/esi: (addr grapheme-stack) <- copy _self
99 var data-ah/edi: (addr handle array code-point-utf8) <- get self, data
100 var _data/eax: (addr array code-point-utf8) <- lookup *data-ah
101 var data/edi: (addr array code-point-utf8) <- copy _data
102 var top-addr/ecx: (addr int) <- get self, top
103 var i/eax: int <- copy *top-addr
104 i <- decrement
105 {
106 compare i, 0
107 break-if-<
108 var g/edx: (addr code-point-utf8) <- index data, i
109 print-code-point-utf8 screen, *g
110 i <- decrement
111 loop
112 }
113 }
114
115
116
117 fn prefix-match? _self: (addr grapheme-stack), s: (addr stream byte) -> _/eax: boolean {
118 var self/esi: (addr grapheme-stack) <- copy _self
119 var data-ah/edi: (addr handle array code-point-utf8) <- get self, data
120 var _data/eax: (addr array code-point-utf8) <- lookup *data-ah
121 var data/edi: (addr array code-point-utf8) <- copy _data
122 var top-addr/ecx: (addr int) <- get self, top
123 var i/ebx: int <- copy 0
124 {
125 compare i, *top-addr
126 break-if->=
127
128 {
129 var curr-a/edx: (addr code-point-utf8) <- index data, i
130 var expected/eax: code-point-utf8 <- read-code-point-utf8 s
131 {
132 compare expected, *curr-a
133 break-if-=
134 return 0/false
135 }
136 }
137 i <- increment
138 loop
139 }
140 return 1
141 }
142
143
144
145 fn suffix-match? _self: (addr grapheme-stack), s: (addr stream byte) -> _/eax: boolean {
146 var self/esi: (addr grapheme-stack) <- copy _self
147 var data-ah/edi: (addr handle array code-point-utf8) <- get self, data
148 var _data/eax: (addr array code-point-utf8) <- lookup *data-ah
149 var data/edi: (addr array code-point-utf8) <- copy _data
150 var top-addr/eax: (addr int) <- get self, top
151 var i/ebx: int <- copy *top-addr
152 i <- decrement
153 {
154 compare i, 0
155 break-if-<
156 {
157 var curr-a/edx: (addr code-point-utf8) <- index data, i
158 var expected/eax: code-point-utf8 <- read-code-point-utf8 s
159
160 {
161 compare expected, *curr-a
162 break-if-=
163 return 0/false
164 }
165 }
166 i <- decrement
167 loop
168 }
169 return 1
170 }
171
172 fn grapheme-stack-is-decimal-integer? _self: (addr grapheme-stack) -> _/eax: boolean {
173 var self/esi: (addr grapheme-stack) <- copy _self
174 var data-ah/eax: (addr handle array code-point-utf8) <- get self, data
175 var _data/eax: (addr array code-point-utf8) <- lookup *data-ah
176 var data/edx: (addr array code-point-utf8) <- copy _data
177 var top-addr/ecx: (addr int) <- get self, top
178 var i/ebx: int <- copy 0
179 var result/eax: boolean <- copy 1/true
180 $grapheme-stack-is-integer?:loop: {
181 compare i, *top-addr
182 break-if->=
183 var g/edx: (addr code-point-utf8) <- index data, i
184 result <- decimal-digit? *g
185 compare result, 0/false
186 break-if-=
187 i <- increment
188 loop
189 }
190 return result
191 }