https://github.com/akkartik/mu/blob/master/apps/browse/main.mu
1 fn main args-on-stack: (addr array addr array byte) -> exit-status/ebx: int {
2 var args/eax: (addr array addr array byte) <- copy args-on-stack
3 var len/ecx: int <- length args
4 $main-body: {
5
6 compare len, 1
7 {
8 break-if->
9 print-string-to-real-screen "usage: browse [filename]\n"
10 print-string-to-real-screen " or browse test\n"
11 exit-status <- copy 1
12 break $main-body
13 }
14
15 var tmp/ecx: (addr addr array byte) <- index args, 1
16 var tmp2/eax: boolean <- string-equal? *tmp, "test"
17 compare tmp2, 0
18 {
19 break-if-=
20 run-tests
21 exit-status <- copy 0
22 break $main-body
23 }
24
25 exit-status <- interactive args-on-stack
26 }
27 }
28
29 fn interactive args: (addr array addr array byte) -> exit-status/ebx: int {
30 $interactive:body: {
31
32 var filename/eax: (addr array byte) <- first-arg args
33 var file-storage: (handle buffered-file)
34 var file-storage-addr/esi: (addr handle buffered-file) <- address file-storage
35 open filename, 0, file-storage-addr
36 var _fs/eax: (addr buffered-file) <- lookup file-storage
37 var fs/esi: (addr buffered-file) <- copy _fs
38
39 {
40 compare fs, 0
41 break-if-!=
42 print-string-to-real-screen "file not found\n"
43 exit-status <- copy 1
44 break $interactive:body
45 }
46
47 enable-screen-grid-mode
48 enable-keyboard-immediate-mode
49
50 var paginated-screen-storage: paginated-screen
51 var paginated-screen/eax: (addr paginated-screen) <- address paginated-screen-storage
52 initialize-paginated-screen paginated-screen, 0x40, 2, 5
53 normal-text paginated-screen
54
55 {
56 render paginated-screen, fs
57 var key/eax: byte <- read-key-from-real-keyboard
58 compare key, 0x71
59 loop-if-!=
60 }
61 enable-keyboard-type-mode
62 enable-screen-type-mode
63 exit-status <- copy 0
64 }
65 }
66
67 fn render screen: (addr paginated-screen), fs: (addr buffered-file) {
68 start-drawing screen
69 render-normal screen, fs
70 }
71
72 fn test-render-multicolumn-text {
73
74 var input-storage: (handle buffered-file)
75 var input-ah/eax: (addr handle buffered-file) <- address input-storage
76 populate-buffered-file-containing "abcdefgh", input-ah
77 var in/eax: (addr buffered-file) <- lookup input-storage
78
79 var pg: paginated-screen
80 var pg-addr/ecx: (addr paginated-screen) <- address pg
81 initialize-fake-paginated-screen pg-addr, 3, 6, 2, 1, 1
82
83 render pg-addr, in
84 var screen-ah/eax: (addr handle screen) <- get pg, screen
85 var screen/eax: (addr screen) <- lookup *screen-ah
86 check-screen-row screen, 1, " ", "F - test-render-multicolumn-text/row1"
87 check-screen-row screen, 2, " ab ef", "F - test-render-multicolumn-text/row2"
88 check-screen-row screen, 3, " cd gh", "F - test-render-multicolumn-text/row3"
89 }
90
91 fn test-render-heading-text {
92
93 var input-storage: (handle buffered-file)
94 var input-ah/eax: (addr handle buffered-file) <- address input-storage
95 populate-buffered-file-containing "# abc\n\ndef", input-ah
96 var in/eax: (addr buffered-file) <- lookup input-storage
97
98 var pg: paginated-screen
99 var pg-addr/ecx: (addr paginated-screen) <- address pg
100 initialize-fake-paginated-screen pg-addr, 8, 6, 5, 1, 1
101
102 render pg-addr, in
103 var screen-ah/eax: (addr handle screen) <- get pg, screen
104 var screen/eax: (addr screen) <- lookup *screen-ah
105 check-screen-row screen, 1, " ", "F - test-render-heading-text/row1"
106 check-screen-row-in-color screen, 0xa0, 2, " abc ", "F - test-render-heading-text/heading"
107 check-screen-row screen, 3, " ", "F - test-render-heading-text/row3"
108 check-screen-row screen, 4, " def ", "F - test-render-heading-text/row4"
109 }
110
111 fn test-render-bold-text {
112
113 var input-storage: (handle buffered-file)
114 var input-ah/eax: (addr handle buffered-file) <- address input-storage
115 populate-buffered-file-containing "a *b* c", input-ah
116 var in/eax: (addr buffered-file) <- lookup input-storage
117
118 var pg: paginated-screen
119 var pg-addr/ecx: (addr paginated-screen) <- address pg
120 initialize-fake-paginated-screen pg-addr, 8, 6, 5, 1, 1
121
122 render pg-addr, in
123 var screen-ah/eax: (addr handle screen) <- get pg, screen
124 var screen/eax: (addr screen) <- lookup *screen-ah
125 check-screen-row screen, 2, " a b c", "F - test-render-bold-text/text"
126 check-screen-row-in-bold screen, 2, " b ", "F - test-render-bold-text/bold"
127 }
128
129
130
131 fn test-render-pseudoitalic-text {
132
133 var input-storage: (handle buffered-file)
134 var input-ah/eax: (addr handle buffered-file) <- address input-storage
135 populate-buffered-file-containing "a _b_ c", input-ah
136 var in/eax: (addr buffered-file) <- lookup input-storage
137
138 var pg: paginated-screen
139 var pg-addr/ecx: (addr paginated-screen) <- address pg
140 initialize-fake-paginated-screen pg-addr, 8, 6, 5, 1, 1
141
142 render pg-addr, in
143 var screen-ah/eax: (addr handle screen) <- get pg, screen
144 var screen/eax: (addr screen) <- lookup *screen-ah
145 check-screen-row screen, 2, " a b c", "F - test-render-pseudoitalic-text/text"
146 check-screen-row-in-bold screen, 2, " b ", "F - test-render-pseudoitalic-text/bold"
147 }
148
149 fn test-render-asterisk-in-text {
150
151 var input-storage: (handle buffered-file)
152 var input-ah/eax: (addr handle buffered-file) <- address input-storage
153 populate-buffered-file-containing "a*b*c", input-ah
154 var in/eax: (addr buffered-file) <- lookup input-storage
155
156 var pg: paginated-screen
157 var pg-addr/ecx: (addr paginated-screen) <- address pg
158 initialize-fake-paginated-screen pg-addr, 8, 6, 5, 1, 1
159
160 render pg-addr, in
161 var screen-ah/eax: (addr handle screen) <- get pg, screen
162 var screen/eax: (addr screen) <- lookup *screen-ah
163 check-screen-row screen, 2, " a*b*c", "F - test-render-bold-text/text"
164 check-screen-row-in-bold screen, 2, " ", "F - test-render-bold-text/bold"
165 }
166
167 fn render-normal screen: (addr paginated-screen), fs: (addr buffered-file) {
168 var newline-seen?/esi: boolean <- copy 0
169 var start-of-paragraph?/edi: boolean <- copy 1
170 var previous-grapheme/ebx: grapheme <- copy 0
171 $render-normal:loop: {
172
173 var done?/eax: boolean <- done-drawing? screen
174 compare done?, 0
175 break-if-!=
176 var c/eax: grapheme <- read-grapheme-buffered fs
177 $render-normal:loop-body: {
178
179 compare c, 0xffffffff
180 break-if-= $render-normal:loop
181
182
183 compare c, 0xa
184 {
185 break-if-!=
186
187 compare newline-seen?, 0
188 {
189 break-if-!=
190 newline-seen? <- copy 1
191 break $render-normal:loop-body
192 }
193
194 {
195 break-if-=
196 add-grapheme screen, 0xa
197 add-grapheme screen, 0xa
198 newline-seen? <- copy 0
199 start-of-paragraph? <- copy 1
200 break $render-normal:loop-body
201 }
202 }
203
204 compare start-of-paragraph?, 0
205 {
206 break-if-=
207 compare c, 0x23
208 {
209 break-if-!=
210 render-header-line screen, fs
211 newline-seen? <- copy 1
212 break $render-normal:loop-body
213 }
214 }
215
216 start-of-paragraph? <- copy 0
217
218 compare c, 0x20
219 loop-if-< $render-normal:loop
220
221
222
223
224 compare newline-seen?, 0
225 $render-normal:flush-buffered-newline: {
226 break-if-=
227 newline-seen? <- copy 0
228 {
229 compare c, 0x20
230 break-if-!=
231 add-grapheme screen, 0xa
232 break $render-normal:flush-buffered-newline
233 }
234 add-grapheme screen, 0x20
235
236 }
237
238
239 $render-normal:whitespace-separated-regions: {
240
241 {
242 compare previous-grapheme, 0x20
243 break-if-=
244 compare previous-grapheme, 0xa
245 break-if-=
246 break $render-normal:whitespace-separated-regions
247 }
248
249 compare c, 0x2a
250 {
251 break-if-!=
252 start-color-on-paginated-screen screen, 0xec, 7
253 start-bold-on-paginated-screen screen
254 render-until-asterisk screen, fs
255 normal-text screen
256 break $render-normal:loop-body
257 }
258
259 compare c, 0x5f
260 {
261 break-if-!=
262 start-color-on-paginated-screen screen, 0xec, 7
263 start-bold-on-paginated-screen screen
264 render-until-underscore screen, fs
265 normal-text screen
266 break $render-normal:loop-body
267 }
268 }
269
270 add-grapheme screen, c
271 }
272 previous-grapheme <- copy c
273 loop
274 }
275 }
276
277 fn render-header-line screen: (addr paginated-screen), fs: (addr buffered-file) {
278 $render-header-line:body: {
279
280 var header-level/esi: int <- copy 1
281 var c/eax: grapheme <- copy 0
282 {
283
284 {
285 var done?/eax: boolean <- done-drawing? screen
286 compare done?, 0
287 break-if-!= $render-header-line:body
288 }
289
290 c <- read-grapheme-buffered fs
291
292 compare c, 0x23
293 break-if-!=
294
295 header-level <- increment
296
297 loop
298 }
299 start-heading screen, header-level
300 {
301
302 {
303 var done?/eax: boolean <- done-drawing? screen
304 compare done?, 0
305 break-if-!=
306 }
307
308 c <- read-grapheme-buffered fs
309
310 compare c, 0xffffffff
311 break-if-=
312
313 compare c, 0xa
314 break-if-=
315
316 add-grapheme screen, c
317
318 loop
319 }
320 normal-text screen
321 }
322 }
323
324
325 fn start-heading screen: (addr paginated-screen), header-level: int {
326 $start-heading:body: {
327 start-bold-on-paginated-screen screen
328 compare header-level, 1
329 {
330 break-if-!=
331 start-color-on-paginated-screen screen, 0xa0, 7
332 break $start-heading:body
333 }
334 compare header-level, 2
335 {
336 break-if-!=
337 start-color-on-paginated-screen screen, 0x7c, 7
338 break $start-heading:body
339 }
340 compare header-level, 3
341 {
342 break-if-!=
343 start-color-on-paginated-screen screen, 0x58, 7
344 break $start-heading:body
345 }
346 compare header-level, 4
347 {
348 break-if-!=
349 start-color-on-paginated-screen screen, 0x34, 7
350 break $start-heading:body
351 }
352 start-color-on-paginated-screen screen, 0xe8, 7
353 }
354 }
355
356 fn render-until-asterisk screen: (addr paginated-screen), fs: (addr buffered-file) {
357 {
358
359 var done?/eax: boolean <- done-drawing? screen
360 compare done?, 0
361 break-if-!=
362
363 var c/eax: grapheme <- read-grapheme-buffered fs
364
365 compare c, 0xffffffff
366 break-if-=
367
368 compare c, 0x2a
369 break-if-=
370
371 add-grapheme screen, c
372
373 loop
374 }
375 }
376
377 fn render-until-underscore screen: (addr paginated-screen), fs: (addr buffered-file) {
378 {
379
380 var done?/eax: boolean <- done-drawing? screen
381 compare done?, 0
382 break-if-!=
383
384 var c/eax: grapheme <- read-grapheme-buffered fs
385
386 compare c, 0xffffffff
387 break-if-=
388
389 compare c, 0x5f
390 break-if-=
391
392 add-grapheme screen, c
393
394 loop
395 }
396 }
397
398 fn first-arg args-on-stack: (addr array addr array byte) -> out/eax: (addr array byte) {
399 var args/eax: (addr array addr array byte) <- copy args-on-stack
400 var result/eax: (addr addr array byte) <- index args, 1
401 out <- copy *result
402 }
403
404 fn normal-text screen: (addr paginated-screen) {
405 reset-formatting-on-paginated-screen screen
406 start-color-on-paginated-screen screen, 0xec, 7
407 }