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) -> _/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 var result/eax: boolean <- gap-buffer-equal? data, s
104 return result
105 }
106
107 fn word-length _self: (addr word) -> _/eax: int {
108 var self/esi: (addr word) <- copy _self
109 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
110 var data/eax: (addr gap-buffer) <- lookup *data-ah
111 var result/eax: int <- gap-buffer-length data
112 return result
113 }
114
115 fn first-word _in: (addr handle word), out: (addr handle word) {
116 var curr-ah/esi: (addr handle word) <- copy _in
117 var curr/eax: (addr word) <- lookup *curr-ah
118 var prev/edi: (addr handle word) <- copy 0
119 {
120 prev <- get curr, prev
121 var curr/eax: (addr word) <- lookup *prev
122 compare curr, 0
123 break-if-=
124 copy-object prev, curr-ah
125 loop
126 }
127 copy-object curr-ah, out
128 }
129
130 fn final-word _in: (addr handle word), out: (addr handle word) {
131 var curr-h: (handle word)
132 var curr-ah/esi: (addr handle word) <- address curr-h
133 copy-object _in, curr-ah
134 var curr/eax: (addr word) <- copy 0
135 var next/edi: (addr handle word) <- copy 0
136 {
137 curr <- lookup *curr-ah
138 next <- get curr, next
139 curr <- lookup *next
140 compare curr, 0
141 break-if-=
142 copy-object next, curr-ah
143 loop
144 }
145 copy-object curr-ah, out
146 }
147
148 fn first-grapheme _self: (addr word) -> _/eax: grapheme {
149 var self/esi: (addr word) <- copy _self
150 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
151 var data/eax: (addr gap-buffer) <- lookup *data-ah
152 var result/eax: grapheme <- first-grapheme-in-gap-buffer data
153 return result
154 }
155
156 fn grapheme-before-cursor _self: (addr word) -> _/eax: grapheme {
157 var self/esi: (addr word) <- copy _self
158 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
159 var data/eax: (addr gap-buffer) <- lookup *data-ah
160 var result/eax: grapheme <- grapheme-before-cursor-in-gap-buffer data
161 return result
162 }
163
164 fn add-grapheme-to-word _self: (addr word), c: grapheme {
165 var self/esi: (addr word) <- copy _self
166 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
167 var data/eax: (addr gap-buffer) <- lookup *data-ah
168 add-grapheme-at-gap data, c
169 }
170
171 fn cursor-at-start? _self: (addr word) -> _/eax: boolean {
172 var self/esi: (addr word) <- copy _self
173 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
174 var data/eax: (addr gap-buffer) <- lookup *data-ah
175 var result/eax: boolean <- gap-at-start? data
176 return result
177 }
178
179 fn cursor-at-end? _self: (addr word) -> _/eax: boolean {
180 var self/esi: (addr word) <- copy _self
181 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
182 var data/eax: (addr gap-buffer) <- lookup *data-ah
183 var result/eax: boolean <- gap-at-end? data
184 return result
185 }
186
187 fn cursor-left _self: (addr word) {
188 var self/esi: (addr word) <- copy _self
189 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
190 var data/eax: (addr gap-buffer) <- lookup *data-ah
191 var dummy/eax: grapheme <- gap-left data
192 }
193
194 fn cursor-right _self: (addr word) {
195 var self/esi: (addr word) <- copy _self
196 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
197 var data/eax: (addr gap-buffer) <- lookup *data-ah
198 var dummy/eax: grapheme <- gap-right data
199 }
200
201 fn cursor-to-start _self: (addr word) {
202 var self/esi: (addr word) <- copy _self
203 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
204 var data/eax: (addr gap-buffer) <- lookup *data-ah
205 gap-to-start data
206 }
207
208 fn cursor-to-end _self: (addr word) {
209 var self/esi: (addr word) <- copy _self
210 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
211 var data/eax: (addr gap-buffer) <- lookup *data-ah
212 gap-to-end data
213 }
214
215 fn cursor-index _self: (addr word) -> _/eax: int {
216 var self/esi: (addr word) <- copy _self
217 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
218 var data/eax: (addr gap-buffer) <- lookup *data-ah
219 var result/eax: int <- gap-index data
220 return result
221 }
222
223 fn delete-before-cursor _self: (addr word) {
224 var self/esi: (addr word) <- copy _self
225 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
226 var data/eax: (addr gap-buffer) <- lookup *data-ah
227 delete-before-gap data
228 }
229
230 fn pop-after-cursor _self: (addr word) -> _/eax: grapheme {
231 var self/esi: (addr word) <- copy _self
232 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
233 var data/eax: (addr gap-buffer) <- lookup *data-ah
234 var result/eax: grapheme <- pop-after-gap data
235 return result
236 }
237
238 fn delete-next _self: (addr word) {
239 var self/esi: (addr word) <- copy _self
240 var next-ah/edi: (addr handle word) <- get self, next
241 var next/eax: (addr word) <- lookup *next-ah
242 compare next, 0
243 break-if-=
244 var next-next-ah/ecx: (addr handle word) <- get next, next
245 var self-ah/esi: (addr handle word) <- get next, prev
246 copy-object next-next-ah, next-ah
247 var new-next/eax: (addr word) <- lookup *next-next-ah
248 compare new-next, 0
249 break-if-=
250 var dest/eax: (addr handle word) <- get new-next, prev
251 copy-object self-ah, dest
252 }
253
254 fn print-word screen: (addr screen), _self: (addr word) {
255 var self/esi: (addr word) <- copy _self
256 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
257 var data/eax: (addr gap-buffer) <- lookup *data-ah
258 render-gap-buffer screen, data
259 }
260
261 fn print-words screen: (addr screen), _words-ah: (addr handle word) {
262 var words-ah/eax: (addr handle word) <- copy _words-ah
263 var words-a/eax: (addr word) <- lookup *words-ah
264 compare words-a, 0
265 break-if-=
266
267 print-word screen, words-a
268 print-string screen, " "
269
270 var next-ah/eax: (addr handle word) <- get words-a, next
271 print-words screen, next-ah
272 }
273
274 fn print-words-in-reverse screen: (addr screen), _words-ah: (addr handle word) {
275 var words-ah/eax: (addr handle word) <- copy _words-ah
276 var words-a/eax: (addr word) <- lookup *words-ah
277 compare words-a, 0
278 break-if-=
279
280 var next-ah/ecx: (addr handle word) <- get words-a, next
281 print-words screen, next-ah
282
283 print-word screen, words-a
284 print-string screen, " "
285 }
286
287
288
289
290 fn copy-words _src-ah: (addr handle word), _dest-ah: (addr handle word) {
291 var src-ah/eax: (addr handle word) <- copy _src-ah
292 var src-a/eax: (addr word) <- lookup *src-ah
293 compare src-a, 0
294 break-if-=
295
296 var dest-ah/edi: (addr handle word) <- copy _dest-ah
297 copy-word src-a, dest-ah
298
299 var rest: (handle word)
300 var rest-ah/ecx: (addr handle word) <- address rest
301 var next-src-ah/esi: (addr handle word) <- get src-a, next
302 copy-words next-src-ah, rest-ah
303 chain-words dest-ah, rest-ah
304 }
305
306 fn copy-words-in-reverse _src-ah: (addr handle word), _dest-ah: (addr handle word) {
307 var src-ah/eax: (addr handle word) <- copy _src-ah
308 var _src-a/eax: (addr word) <- lookup *src-ah
309 var src-a/esi: (addr word) <- copy _src-a
310 compare src-a, 0
311 break-if-=
312
313 var next-src-ah/ecx: (addr handle word) <- get src-a, next
314 var dest-ah/edi: (addr handle word) <- copy _dest-ah
315 copy-words-in-reverse next-src-ah, dest-ah
316
317 copy-word-at-end src-a, dest-ah
318 }
319
320 fn copy-word-at-end src: (addr word), _dest-ah: (addr handle word) {
321 var dest-ah/edi: (addr handle word) <- copy _dest-ah
322
323 var dest-a/eax: (addr word) <- lookup *dest-ah
324 compare dest-a, 0
325 {
326 break-if-!=
327 copy-word src, dest-ah
328 return
329 }
330
331 var new: (handle word)
332 var new-ah/ecx: (addr handle word) <- address new
333 copy-word src, new-ah
334
335 var curr-ah/edi: (addr handle word) <- copy dest-ah
336 {
337 var curr-a/eax: (addr word) <- lookup *curr-ah
338 var next-ah/ecx: (addr handle word) <- get curr-a, next
339 var next-a/eax: (addr word) <- lookup *next-ah
340 compare next-a, 0
341 break-if-=
342 curr-ah <- copy next-ah
343 loop
344 }
345 chain-words curr-ah, new-ah
346 }
347
348 fn append-word-at-end-with _dest-ah: (addr handle word), s: (addr array byte) {
349 var dest-ah/edi: (addr handle word) <- copy _dest-ah
350
351 var dest-a/eax: (addr word) <- lookup *dest-ah
352 compare dest-a, 0
353 {
354 break-if-!=
355 allocate-word-with dest-ah, s
356 return
357 }
358
359 var curr-ah/edi: (addr handle word) <- copy dest-ah
360 {
361 var curr-a/eax: (addr word) <- lookup *curr-ah
362 var next-ah/ecx: (addr handle word) <- get curr-a, next
363 var next-a/eax: (addr word) <- lookup *next-ah
364 compare next-a, 0
365 break-if-=
366 curr-ah <- copy next-ah
367 loop
368 }
369 append-word-with *curr-ah, s
370 }
371
372 fn copy-word _src-a: (addr word), _dest-ah: (addr handle word) {
373 var dest-ah/eax: (addr handle word) <- copy _dest-ah
374 allocate dest-ah
375 var _dest-a/eax: (addr word) <- lookup *dest-ah
376 var dest-a/eax: (addr word) <- copy _dest-a
377 initialize-word dest-a
378 var dest/edi: (addr handle gap-buffer) <- get dest-a, scalar-data
379 var src-a/eax: (addr word) <- copy _src-a
380 var src/eax: (addr handle gap-buffer) <- get src-a, scalar-data
381 copy-gap-buffer src, dest
382 }
383
384
385 fn append-word _self-ah: (addr handle word) {
386 var saved-self-storage: (handle word)
387 var saved-self/eax: (addr handle word) <- address saved-self-storage
388 copy-object _self-ah, saved-self
389
390
391
392
393
394
395 var self-ah/esi: (addr handle word) <- copy _self-ah
396 var _self/eax: (addr word) <- lookup *self-ah
397 var self/ebx: (addr word) <- copy _self
398
399
400
401
402
403
404
405
406
407 var new: (handle word)
408 var new-ah/ecx: (addr handle word) <- address new
409 allocate new-ah
410 var new-addr/eax: (addr word) <- lookup new
411 initialize-word new-addr
412
413
414
415
416
417
418
419 var src/esi: (addr handle word) <- get self, next
420
421
422
423
424
425
426 var dest/edi: (addr handle word) <- get new-addr, next
427 copy-object src, dest
428
429 {
430 var next-addr/eax: (addr word) <- lookup *src
431 compare next-addr, 0
432 break-if-=
433
434
435
436
437
438
439 dest <- get next-addr, prev
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458 copy-object new-ah, dest
459
460
461
462
463
464
465
466
467 }
468
469 dest <- get new-addr, prev
470
471
472
473
474
475
476
477
478
479
480
481 var saved-self-ah/eax: (addr handle word) <- address saved-self-storage
482 copy-object saved-self-ah, dest
483
484 dest <- get self, next
485 copy-object new-ah, dest
486 }
487
488 fn chain-words _self-ah: (addr handle word), _next: (addr handle word) {
489 var self-ah/esi: (addr handle word) <- copy _self-ah
490 var _self/eax: (addr word) <- lookup *self-ah
491 var self/ecx: (addr word) <- copy _self
492 var dest/edx: (addr handle word) <- get self, next
493 var next-ah/edi: (addr handle word) <- copy _next
494 copy-object next-ah, dest
495 var next/eax: (addr word) <- lookup *next-ah
496 compare next, 0
497 break-if-=
498 dest <- get next, prev
499 copy-object self-ah, dest
500 }
501
502 fn emit-word _self: (addr word), out: (addr stream byte) {
503 var self/esi: (addr word) <- copy _self
504 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
505 var data/eax: (addr gap-buffer) <- lookup *data-ah
506 emit-gap-buffer data, out
507 }
508
509 fn word-to-string _self: (addr word), out: (addr handle array byte) {
510 var self/esi: (addr word) <- copy _self
511 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
512 var data/eax: (addr gap-buffer) <- lookup *data-ah
513 gap-buffer-to-string data, out
514 }
515
516 fn word-is-decimal-integer? _self: (addr word) -> _/eax: boolean {
517 var self/eax: (addr word) <- copy _self
518 var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
519 var data/eax: (addr gap-buffer) <- lookup *data-ah
520 var result/eax: boolean <- gap-buffer-is-decimal-integer? data
521 return result
522 }
523
524
525 fn word-exists? _haystack-ah: (addr handle word), _needle: (addr word) -> _/ebx: boolean {
526 var needle-name-storage: (handle addr byte)
527 var needle-name-ah/eax: (addr handle array byte) <- address needle-name-storage
528 word-to-string _needle, needle-name-ah
529 var _needle-name/eax: (addr array byte) <- lookup *needle-name-ah
530 var needle-name/edi: (addr array byte) <- copy _needle-name
531
532 var haystack-ah/esi: (addr handle word) <- copy _haystack-ah
533 var curr/eax: (addr word) <- lookup *haystack-ah
534 compare curr, 0
535 {
536 break-if-!=
537 return 0
538 }
539
540 var curr-name-storage: (handle addr byte)
541 var curr-name-ah/ecx: (addr handle array byte) <- address curr-name-storage
542 word-to-string curr, curr-name-ah
543 var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
544 var found?/eax: boolean <- string-equal? needle-name, curr-name
545 compare found?, 0
546 {
547 break-if-=
548 return 1
549 }
550
551 var curr/eax: (addr word) <- lookup *haystack-ah
552 var next-haystack-ah/eax: (addr handle word) <- get curr, next
553 var result/ebx: boolean <- word-exists? next-haystack-ah, _needle
554 return result
555 }