https://github.com/akkartik/mu/blob/master/apps/tile/word.mu
1 fn initialize-word _self: (addr word) {
2 var self/esi: (addr word) <- copy _self
3 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
4 allocate data-ah
5 var data/eax: (addr gap-buffer) <- lookup *data-ah
6 initialize-gap-buffer data
7
8 }
9
10
11
12 fn initialize-word-with _self: (addr word), s: (addr array byte) {
13 var self/esi: (addr word) <- copy _self
14 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
15 allocate data-ah
16 var data/eax: (addr gap-buffer) <- lookup *data-ah
17 initialize-gap-buffer-with data, s
18 }
19
20 fn allocate-word-with _out: (addr handle word), s: (addr array byte) {
21 var out/eax: (addr handle word) <- copy _out
22 allocate out
23 var out-addr/eax: (addr word) <- lookup *out
24 initialize-word-with out-addr, s
25 }
26
27
28
29
30 fn append-word-with self-h: (handle word), s: (addr array byte) {
31 var self/eax: (addr word) <- lookup self-h
32 var next-ah/eax: (addr handle word) <- get self, next
33 allocate-word-with next-ah, s
34 var next/eax: (addr word) <- lookup *next-ah
35 var prev-ah/eax: (addr handle word) <- get next, prev
36 copy-handle self-h, prev-ah
37 }
38
39
40
41 fn prepend-word-with self-h: (handle word), s: (addr array byte) {
42 var self/eax: (addr word) <- lookup self-h
43 var prev-ah/eax: (addr handle word) <- get self, prev
44 allocate-word-with prev-ah, s
45 var prev/eax: (addr word) <- lookup *prev-ah
46 var next-ah/eax: (addr handle word) <- get prev, next
47 copy-handle self-h, next-ah
48 }
49
50
51
52 fn move-word-contents _src-ah: (addr handle word), _dest-ah: (addr handle word) {
53 var dest-ah/eax: (addr handle word) <- copy _dest-ah
54 var _dest/eax: (addr word) <- lookup *dest-ah
55 var dest/edi: (addr word) <- copy _dest
56 var src-ah/eax: (addr handle word) <- copy _src-ah
57 var _src/eax: (addr word) <- lookup *src-ah
58 var src/esi: (addr word) <- copy _src
59 cursor-to-start src
60 var src-data-ah/eax: (addr handle gap-buffer) <- get src, scalar-data
61 var src-data/eax: (addr gap-buffer) <- lookup *src-data-ah
62 var src-stack/ecx: (addr grapheme-stack) <- get src-data, right
63 {
64 var done?/eax: boolean <- grapheme-stack-empty? src-stack
65 compare done?, 0
66 break-if-!=
67 var g/eax: grapheme <- pop-grapheme-stack src-stack
68
69
70 add-grapheme-to-word dest, g
71 loop
72 }
73 }
74
75 fn copy-word-contents-before-cursor _src-ah: (addr handle word), _dest-ah: (addr handle word) {
76 var dest-ah/eax: (addr handle word) <- copy _dest-ah
77 var _dest/eax: (addr word) <- lookup *dest-ah
78 var dest/edi: (addr word) <- copy _dest
79 var src-ah/eax: (addr handle word) <- copy _src-ah
80 var src/eax: (addr word) <- lookup *src-ah
81 var src-data-ah/eax: (addr handle gap-buffer) <- get src, scalar-data
82 var src-data/eax: (addr gap-buffer) <- lookup *src-data-ah
83 var src-stack/ecx: (addr grapheme-stack) <- get src-data, left
84 var src-stack-data-ah/eax: (addr handle array grapheme) <- get src-stack, data
85 var _src-stack-data/eax: (addr array grapheme) <- lookup *src-stack-data-ah
86 var src-stack-data/edx: (addr array grapheme) <- copy _src-stack-data
87 var top-addr/ecx: (addr int) <- get src-stack, top
88 var i/eax: int <- copy 0
89 {
90 compare i, *top-addr
91 break-if->=
92 var g/edx: (addr grapheme) <- index src-stack-data, i
93 add-grapheme-to-word dest, *g
94 i <- increment
95 loop
96 }
97 }
98
99 fn word-equal? _self: (addr word), s: (addr array byte) -> result/eax: boolean {
100 var self/esi: (addr word) <- copy _self
101 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
102 var data/eax: (addr gap-buffer) <- lookup *data-ah
103 result <- gap-buffer-equal? data, s
104 }
105
106 fn word-length _self: (addr word) -> result/eax: int {
107 var self/esi: (addr word) <- copy _self
108 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
109 var data/eax: (addr gap-buffer) <- lookup *data-ah
110 result <- gap-buffer-length data
111 }
112
113 fn first-word _in: (addr handle word), out: (addr handle word) {
114 var curr-ah/esi: (addr handle word) <- copy _in
115 var curr/eax: (addr word) <- lookup *curr-ah
116 var prev/edi: (addr handle word) <- copy 0
117 {
118 prev <- get curr, prev
119 var curr/eax: (addr word) <- lookup *prev
120 compare curr, 0
121 break-if-=
122 copy-object prev, curr-ah
123 loop
124 }
125 copy-object curr-ah, out
126 }
127
128 fn final-word _in: (addr handle word), out: (addr handle word) {
129 var curr-h: (handle word)
130 var curr-ah/esi: (addr handle word) <- address curr-h
131 copy-object _in, curr-ah
132 var curr/eax: (addr word) <- copy 0
133 var next/edi: (addr handle word) <- copy 0
134 {
135 curr <- lookup *curr-ah
136 next <- get curr, next
137 curr <- lookup *next
138 compare curr, 0
139 break-if-=
140 copy-object next, curr-ah
141 loop
142 }
143 copy-object curr-ah, out
144 }
145
146 fn first-grapheme _self: (addr word) -> result/eax: grapheme {
147 var self/esi: (addr word) <- copy _self
148 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
149 var data/eax: (addr gap-buffer) <- lookup *data-ah
150 result <- first-grapheme-in-gap-buffer data
151 }
152
153 fn add-grapheme-to-word _self: (addr word), c: grapheme {
154 var self/esi: (addr word) <- copy _self
155 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
156 var data/eax: (addr gap-buffer) <- lookup *data-ah
157 add-grapheme-at-gap data, c
158 }
159
160 fn cursor-at-start? _self: (addr word) -> result/eax: boolean {
161 var self/esi: (addr word) <- copy _self
162 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
163 var data/eax: (addr gap-buffer) <- lookup *data-ah
164 result <- gap-at-start? data
165 }
166
167 fn cursor-at-end? _self: (addr word) -> result/eax: boolean {
168 var self/esi: (addr word) <- copy _self
169 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
170 var data/eax: (addr gap-buffer) <- lookup *data-ah
171 result <- gap-at-end? data
172 }
173
174 fn cursor-left _self: (addr word) {
175 var self/esi: (addr word) <- copy _self
176 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
177 var data/eax: (addr gap-buffer) <- lookup *data-ah
178 var dummy/eax: grapheme <- gap-left data
179 }
180
181 fn cursor-right _self: (addr word) {
182 var self/esi: (addr word) <- copy _self
183 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
184 var data/eax: (addr gap-buffer) <- lookup *data-ah
185 var dummy/eax: grapheme <- gap-right data
186 }
187
188 fn cursor-to-start _self: (addr word) {
189 var self/esi: (addr word) <- copy _self
190 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
191 var data/eax: (addr gap-buffer) <- lookup *data-ah
192 gap-to-start data
193 }
194
195 fn cursor-to-end _self: (addr word) {
196 var self/esi: (addr word) <- copy _self
197 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
198 var data/eax: (addr gap-buffer) <- lookup *data-ah
199 gap-to-end data
200 }
201
202 fn cursor-index _self: (addr word) -> result/eax: int {
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 result <- gap-index data
207 }
208
209 fn delete-before-cursor _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 delete-before-gap data
214 }
215
216 fn delete-next _self: (addr word) {
217 $delete-next:body: {
218 var self/esi: (addr word) <- copy _self
219 var next-ah/edi: (addr handle word) <- get self, next
220 var next/eax: (addr word) <- lookup *next-ah
221 compare next, 0
222 break-if-= $delete-next:body
223 var next-next-ah/ecx: (addr handle word) <- get next, next
224 var self-ah/esi: (addr handle word) <- get next, prev
225 copy-object next-next-ah, next-ah
226 var new-next/eax: (addr word) <- lookup *next-next-ah
227 compare new-next, 0
228 break-if-= $delete-next:body
229 var dest/eax: (addr handle word) <- get new-next, prev
230 copy-object self-ah, dest
231 }
232 }
233
234 fn print-word screen: (addr screen), _self: (addr word) {
235 var self/esi: (addr word) <- copy _self
236 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
237 var data/eax: (addr gap-buffer) <- lookup *data-ah
238 render-gap-buffer screen, data
239 }
240
241 fn print-words screen: (addr screen), _words-ah: (addr handle word) {
242 var words-ah/eax: (addr handle word) <- copy _words-ah
243 var words-a/eax: (addr word) <- lookup *words-ah
244 compare words-a, 0
245 break-if-=
246
247 print-word screen, words-a
248 print-string screen, " "
249
250 var next-ah/eax: (addr handle word) <- get words-a, next
251 print-words screen, next-ah
252 }
253
254 fn print-words-in-reverse screen: (addr screen), _words-ah: (addr handle word) {
255 var words-ah/eax: (addr handle word) <- copy _words-ah
256 var words-a/eax: (addr word) <- lookup *words-ah
257 compare words-a, 0
258 break-if-=
259
260 var next-ah/ecx: (addr handle word) <- get words-a, next
261 print-words screen, next-ah
262
263 print-word screen, words-a
264 print-string screen, " "
265 }
266
267
268
269
270 fn copy-words _src-ah: (addr handle word), _dest-ah: (addr handle word) {
271 var src-ah/eax: (addr handle word) <- copy _src-ah
272 var src-a/eax: (addr word) <- lookup *src-ah
273 compare src-a, 0
274 break-if-=
275
276 var dest-ah/edi: (addr handle word) <- copy _dest-ah
277 copy-word src-a, dest-ah
278
279 var rest: (handle word)
280 var rest-ah/ecx: (addr handle word) <- address rest
281 var next-src-ah/esi: (addr handle word) <- get src-a, next
282 copy-words next-src-ah, rest-ah
283 chain-words dest-ah, rest-ah
284 }
285
286 fn copy-words-in-reverse _src-ah: (addr handle word), _dest-ah: (addr handle word) {
287 var src-ah/eax: (addr handle word) <- copy _src-ah
288 var _src-a/eax: (addr word) <- lookup *src-ah
289 var src-a/esi: (addr word) <- copy _src-a
290 compare src-a, 0
291 break-if-=
292
293 var next-src-ah/ecx: (addr handle word) <- get src-a, next
294 var dest-ah/edi: (addr handle word) <- copy _dest-ah
295 copy-words-in-reverse next-src-ah, dest-ah
296
297 copy-word-at-end src-a, dest-ah
298 }
299
300 fn copy-word-at-end src: (addr word), _dest-ah: (addr handle word) {
301 $copy-word-at-end:body: {
302 var dest-ah/edi: (addr handle word) <- copy _dest-ah
303
304 var dest-a/eax: (addr word) <- lookup *dest-ah
305 compare dest-a, 0
306 {
307 break-if-!=
308 copy-word src, dest-ah
309 break $copy-word-at-end:body
310 }
311
312 var new: (handle word)
313 var new-ah/ecx: (addr handle word) <- address new
314 copy-word src, new-ah
315
316 var curr-ah/edi: (addr handle word) <- copy dest-ah
317 {
318 var curr-a/eax: (addr word) <- lookup *curr-ah
319 var next-ah/ecx: (addr handle word) <- get curr-a, next
320 var next-a/eax: (addr word) <- lookup *next-ah
321 compare next-a, 0
322 break-if-=
323 curr-ah <- copy next-ah
324 loop
325 }
326 chain-words curr-ah, new-ah
327 }
328 }
329
330 fn append-word-at-end-with _dest-ah: (addr handle word), s: (addr array byte) {
331 $append-word-at-end-with:body: {
332 var dest-ah/edi: (addr handle word) <- copy _dest-ah
333
334 var dest-a/eax: (addr word) <- lookup *dest-ah
335 compare dest-a, 0
336 {
337 break-if-!=
338 allocate-word-with dest-ah, s
339 break $append-word-at-end-with:body
340 }
341
342 var curr-ah/edi: (addr handle word) <- copy dest-ah
343 {
344 var curr-a/eax: (addr word) <- lookup *curr-ah
345 var next-ah/ecx: (addr handle word) <- get curr-a, next
346 var next-a/eax: (addr word) <- lookup *next-ah
347 compare next-a, 0
348 break-if-=
349 curr-ah <- copy next-ah
350 loop
351 }
352 append-word-with *curr-ah, s
353 }
354 }
355
356 fn copy-word _src-a: (addr word), _dest-ah: (addr handle word) {
357 var dest-ah/eax: (addr handle word) <- copy _dest-ah
358 allocate dest-ah
359 var _dest-a/eax: (addr word) <- lookup *dest-ah
360 var dest-a/eax: (addr word) <- copy _dest-a
361 initialize-word dest-a
362 var dest/edi: (addr handle gap-buffer) <- get dest-a, scalar-data
363 var src-a/eax: (addr word) <- copy _src-a
364 var src/eax: (addr handle gap-buffer) <- get src-a, scalar-data
365 copy-gap-buffer src, dest
366 }
367
368
369 fn append-word _self-ah: (addr handle word) {
370 var self-ah/esi: (addr handle word) <- copy _self-ah
371 var _self/eax: (addr word) <- lookup *self-ah
372 var self/ebx: (addr word) <- copy _self
373
374 var new: (handle word)
375 var new-ah/ecx: (addr handle word) <- address new
376 allocate new-ah
377 var new-addr/eax: (addr word) <- lookup new
378 initialize-word new-addr
379
380 var src/esi: (addr handle word) <- get self, next
381 var dest/edi: (addr handle word) <- get new-addr, next
382 copy-object src, dest
383
384 {
385 var next-addr/eax: (addr word) <- lookup *src
386 compare next-addr, 0
387 break-if-=
388 dest <- get next-addr, prev
389 copy-object new-ah, dest
390 }
391
392 dest <- get new-addr, prev
393 copy-object _self-ah, dest
394
395 dest <- get self, next
396 copy-object new-ah, dest
397 }
398
399 fn chain-words _self-ah: (addr handle word), _next: (addr handle word) {
400 var self-ah/esi: (addr handle word) <- copy _self-ah
401 var _self/eax: (addr word) <- lookup *self-ah
402 var self/ecx: (addr word) <- copy _self
403 var dest/edx: (addr handle word) <- get self, next
404 var next-ah/edi: (addr handle word) <- copy _next
405 copy-object next-ah, dest
406 var next/eax: (addr word) <- lookup *next-ah
407 compare next, 0
408 break-if-=
409 dest <- get next, prev
410 copy-object self-ah, dest
411 }
412
413 fn emit-word _self: (addr word), out: (addr stream byte) {
414 var self/esi: (addr word) <- copy _self
415 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
416 var data/eax: (addr gap-buffer) <- lookup *data-ah
417 emit-gap-buffer data, out
418 }
419
420 fn word-to-string _self: (addr word), out: (addr handle array byte) {
421 var self/esi: (addr word) <- copy _self
422 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
423 var data/eax: (addr gap-buffer) <- lookup *data-ah
424 gap-buffer-to-string data, out
425 }
426
427 fn word-is-decimal-integer? _self: (addr word) -> result/eax: boolean {
428 var self/eax: (addr word) <- copy _self
429 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
430 var data/eax: (addr gap-buffer) <- lookup *data-ah
431 result <- gap-buffer-is-decimal-integer? data
432 }
433
434
435 fn word-exists? _haystack-ah: (addr handle word), _needle: (addr word) -> result/ebx: boolean {
436 var needle-name-storage: (handle addr byte)
437 var needle-name-ah/eax: (addr handle array byte) <- address needle-name-storage
438 word-to-string _needle, needle-name-ah
439 var _needle-name/eax: (addr array byte) <- lookup *needle-name-ah
440 var needle-name/edi: (addr array byte) <- copy _needle-name
441
442 result <- copy 0
443 var haystack-ah/esi: (addr handle word) <- copy _haystack-ah
444 var curr/eax: (addr word) <- lookup *haystack-ah
445 compare curr, 0
446 break-if-=
447
448 var curr-name-storage: (handle addr byte)
449 var curr-name-ah/ecx: (addr handle array byte) <- address curr-name-storage
450 word-to-string curr, curr-name-ah
451 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
452 var found?/eax: boolean <- string-equal? needle-name, curr-name
453 result <- copy found?
454 compare result, 0
455 break-if-!=
456
457 var curr/eax: (addr word) <- lookup *haystack-ah
458 var next-haystack-ah/eax: (addr handle word) <- get curr, next
459 result <- word-exists? next-haystack-ah, _needle
460 }