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