https://github.com/akkartik/mu/blob/main/shell/print.mu
1 fn print-cell _in: (addr handle cell), out: (addr stream byte), trace: (addr trace) {
2 trace-text trace, "print", "print"
3 trace-lower trace
4 var in/eax: (addr handle cell) <- copy _in
5 var in-addr/eax: (addr cell) <- lookup *in
6 {
7 compare in-addr, 0
8 break-if-!=
9 write out, "NULL"
10 trace-higher trace
11 return
12 }
13 {
14 var nil?/eax: boolean <- nil? in-addr
15 compare nil?, 0/false
16 break-if-=
17 write out, "()"
18 trace-higher trace
19 return
20 }
21 var in-type/ecx: (addr int) <- get in-addr, type
22 compare *in-type, 0/pair
23 {
24 break-if-!=
25 print-list in-addr, out, trace
26 trace-higher trace
27 return
28 }
29 compare *in-type, 1/number
30 {
31 break-if-!=
32 print-number in-addr, out, trace
33 trace-higher trace
34 return
35 }
36 compare *in-type, 2/symbol
37 {
38 break-if-!=
39 print-symbol in-addr, out, trace
40 trace-higher trace
41 return
42 }
43 compare *in-type, 3/stream
44 {
45 break-if-!=
46 print-stream in-addr, out, trace
47 trace-higher trace
48 return
49 }
50 compare *in-type, 4/primitive
51 {
52 break-if-!=
53 write out, "[primitive]"
54 trace-higher trace
55 return
56 }
57 compare *in-type, 5/primitive
58 {
59 break-if-!=
60 write out, "[screen "
61 var screen-ah/eax: (addr handle screen) <- get in-addr, screen-data
62 var screen/eax: (addr screen) <- lookup *screen-ah
63 var screen-addr/eax: int <- copy screen
64 write-int32-decimal out, screen-addr
65 write out, "]"
66 trace-higher trace
67 return
68 }
69 }
70
71
72 fn dump-cell in-ah: (addr handle cell) {
73 var stream-storage: (stream byte 0x40)
74 var stream/edx: (addr stream byte) <- address stream-storage
75 print-cell in-ah, stream, 0/no-trace
76 var d1/eax: int <- copy 0
77 var d2/ecx: int <- copy 0
78 d1, d2 <- draw-stream-wrapping-right-then-down 0/screen, stream, 0/xmin, 0/ymin, 0x80/xmax, 0x30/ymax, 0/x, 0/y, 7/fg, 0/bg
79 }
80
81 fn print-symbol _in: (addr cell), out: (addr stream byte), trace: (addr trace) {
82 trace-text trace, "print", "symbol"
83 var in/esi: (addr cell) <- copy _in
84 var data-ah/eax: (addr handle stream byte) <- get in, text-data
85 var _data/eax: (addr stream byte) <- lookup *data-ah
86 var data/esi: (addr stream byte) <- copy _data
87 rewind-stream data
88 write-stream out, data
89
90 rewind-stream data
91 var stream-storage: (stream byte 0x40)
92 var stream/ecx: (addr stream byte) <- address stream-storage
93 write stream, "=> symbol "
94 write-stream stream, data
95 trace trace, "print", stream
96 }
97
98 fn print-stream _in: (addr cell), out: (addr stream byte), trace: (addr trace) {
99 trace-text trace, "print", "stream"
100 var in/esi: (addr cell) <- copy _in
101 var data-ah/eax: (addr handle stream byte) <- get in, text-data
102 var _data/eax: (addr stream byte) <- lookup *data-ah
103 var data/esi: (addr stream byte) <- copy _data
104 rewind-stream data
105 write out, "["
106 write-stream out, data
107 write out, "]"
108
109 rewind-stream data
110 var stream-storage: (stream byte 0x40)
111 var stream/ecx: (addr stream byte) <- address stream-storage
112 write stream, "=> stream "
113 write-stream stream, data
114 trace trace, "print", stream
115 }
116
117 fn print-number _in: (addr cell), out: (addr stream byte), trace: (addr trace) {
118 var in/esi: (addr cell) <- copy _in
119 var val/eax: (addr float) <- get in, number-data
120 write-float-decimal-approximate out, *val, 3/precision
121
122 var stream-storage: (stream byte 0x40)
123 var stream/ecx: (addr stream byte) <- address stream-storage
124 write stream, "=> number "
125 write-float-decimal-approximate stream, *val, 3/precision
126 trace trace, "print", stream
127 }
128
129 fn print-list _in: (addr cell), out: (addr stream byte), trace: (addr trace) {
130 var curr/esi: (addr cell) <- copy _in
131 write out, "("
132 $print-list:loop: {
133 var left/ecx: (addr handle cell) <- get curr, left
134 print-cell left, out, trace
135 var right/ecx: (addr handle cell) <- get curr, right
136 var right-addr/eax: (addr cell) <- lookup *right
137 {
138 compare right-addr, 0
139 break-if-!=
140 abort "null encountered"
141 }
142 {
143 var right-nil?/eax: boolean <- nil? right-addr
144 compare right-nil?, 0/false
145 {
146 break-if-=
147 trace-text trace, "print", "right is null"
148 break $print-list:loop
149 }
150 }
151 write out, " "
152 var right-type-addr/edx: (addr int) <- get right-addr, type
153 {
154 compare *right-type-addr, 0/pair
155 break-if-=
156 write out, ". "
157 print-cell right, out, trace
158 break $print-list:loop
159 }
160 curr <- copy right-addr
161 loop
162 }
163 write out, ")"
164 }
165
166
167
168 fn nil? _in: (addr cell) -> _/eax: boolean {
169 var in/esi: (addr cell) <- copy _in
170
171 var type/eax: (addr int) <- get in, type
172 compare *type, 0/pair
173 {
174 break-if-=
175 return 0/false
176 }
177
178 var left-ah/eax: (addr handle cell) <- get in, left
179 var left/eax: (addr cell) <- lookup *left-ah
180 compare left, 0
181 {
182 break-if-=
183 return 0/false
184 }
185
186 var right-ah/eax: (addr handle cell) <- get in, right
187 var right/eax: (addr cell) <- lookup *right-ah
188 compare right, 0
189 {
190 break-if-=
191 return 0/false
192 }
193 return 1/true
194 }
195
196 fn test-print-cell-zero {
197 var num-storage: (handle cell)
198 var num/esi: (addr handle cell) <- address num-storage
199 new-integer num, 0
200 var out-storage: (stream byte 0x40)
201 var out/edi: (addr stream byte) <- address out-storage
202 print-cell num, out, 0/no-trace
203 check-stream-equal out, "0", "F - test-print-cell-zero"
204 }
205
206 fn test-print-cell-integer {
207 var num-storage: (handle cell)
208 var num/esi: (addr handle cell) <- address num-storage
209 new-integer num, 1
210 var out-storage: (stream byte 0x40)
211 var out/edi: (addr stream byte) <- address out-storage
212 print-cell num, out, 0/no-trace
213 check-stream-equal out, "1", "F - test-print-cell-integer"
214 }
215
216 fn test-print-cell-integer-2 {
217 var num-storage: (handle cell)
218 var num/esi: (addr handle cell) <- address num-storage
219 new-integer num, 0x30
220 var out-storage: (stream byte 0x40)
221 var out/edi: (addr stream byte) <- address out-storage
222 print-cell num, out, 0/no-trace
223 check-stream-equal out, "48", "F - test-print-cell-integer-2"
224 }
225
226 fn test-print-cell-fraction {
227 var num-storage: (handle cell)
228 var num/esi: (addr handle cell) <- address num-storage
229 var val/xmm0: float <- rational 1, 2
230 new-float num, val
231 var out-storage: (stream byte 0x40)
232 var out/edi: (addr stream byte) <- address out-storage
233 print-cell num, out, 0/no-trace
234 check-stream-equal out, "0.5", "F - test-print-cell-fraction"
235 }
236
237 fn test-print-cell-symbol {
238 var sym-storage: (handle cell)
239 var sym/esi: (addr handle cell) <- address sym-storage
240 new-symbol sym, "abc"
241 var out-storage: (stream byte 0x40)
242 var out/edi: (addr stream byte) <- address out-storage
243 print-cell sym, out, 0/no-trace
244 check-stream-equal out, "abc", "F - test-print-cell-symbol"
245 }
246
247 fn test-print-cell-nil-list {
248 var nil-storage: (handle cell)
249 var nil/esi: (addr handle cell) <- address nil-storage
250 allocate-pair nil
251 var out-storage: (stream byte 0x40)
252 var out/edi: (addr stream byte) <- address out-storage
253 print-cell nil, out, 0/no-trace
254 check-stream-equal out, "()", "F - test-print-cell-nil-list"
255 }
256
257 fn test-print-cell-singleton-list {
258
259 var left-storage: (handle cell)
260 var left/ecx: (addr handle cell) <- address left-storage
261 new-symbol left, "abc"
262 var nil-storage: (handle cell)
263 var nil/edx: (addr handle cell) <- address nil-storage
264 allocate-pair nil
265 var list-storage: (handle cell)
266 var list/esi: (addr handle cell) <- address list-storage
267 new-pair list, *left, *nil
268
269 var out-storage: (stream byte 0x40)
270 var out/edi: (addr stream byte) <- address out-storage
271 print-cell list, out, 0/no-trace
272 check-stream-equal out, "(abc)", "F - test-print-cell-singleton-list"
273 }
274
275 fn test-print-cell-list {
276
277 var left-storage: (handle cell)
278 var left/ecx: (addr handle cell) <- address left-storage
279 new-symbol left, "abc"
280 var nil-storage: (handle cell)
281 var nil/edx: (addr handle cell) <- address nil-storage
282 allocate-pair nil
283 var list-storage: (handle cell)
284 var list/esi: (addr handle cell) <- address list-storage
285 new-pair list, *left, *nil
286
287 new-integer left, 0x40
288 new-pair list, *left, *list
289
290 var out-storage: (stream byte 0x40)
291 var out/edi: (addr stream byte) <- address out-storage
292 print-cell list, out, 0/no-trace
293 check-stream-equal out, "(64 abc)", "F - test-print-cell-list"
294 }
295
296 fn test-print-cell-list-of-nil {
297
298 var left-storage: (handle cell)
299 var left/ecx: (addr handle cell) <- address left-storage
300 allocate-pair left
301 var nil-storage: (handle cell)
302 var nil/edx: (addr handle cell) <- address nil-storage
303 allocate-pair nil
304 var list-storage: (handle cell)
305 var list/esi: (addr handle cell) <- address list-storage
306 new-pair list, *left, *nil
307
308 new-integer left, 0x40
309 new-pair list, *left, *list
310
311 var out-storage: (stream byte 0x40)
312 var out/edi: (addr stream byte) <- address out-storage
313 print-cell list, out, 0/no-trace
314 check-stream-equal out, "(64 ())", "F - test-print-cell-list-nil"
315 }
316
317 fn test-print-dotted-list {
318
319 var left-storage: (handle cell)
320 var left/ecx: (addr handle cell) <- address left-storage
321 new-symbol left, "abc"
322 var right-storage: (handle cell)
323 var right/edx: (addr handle cell) <- address right-storage
324 new-integer right, 0x40
325 var list-storage: (handle cell)
326 var list/esi: (addr handle cell) <- address list-storage
327 new-pair list, *left, *right
328
329 var out-storage: (stream byte 0x40)
330 var out/edi: (addr stream byte) <- address out-storage
331 print-cell list, out, 0/no-trace
332 check-stream-equal out, "(abc . 64)", "F - test-print-dotted-list"
333 }