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