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