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