https://github.com/akkartik/mu/blob/master/apps/braces.subx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 == code
52
53 Entry:
54
55 89/<- %ebp 4/r32/esp
56
57 (new-segment *Heap-size Heap)
58
59 81 7/subop/compare *ebp 1/imm32
60 7e/jump-if-<= $subx-braces-main:interactive/disp8
61
62 (kernel-string-equal? *(ebp+8) "test")
63 3d/compare-eax-and 0/imm32/false
64 74/jump-if-= $subx-braces-main:interactive/disp8
65
66 (run-tests)
67
68 8b/-> *Num-test-failures 3/r32/ebx
69 eb/jump $subx-braces-main:end/disp8
70 $subx-braces-main:interactive:
71 (subx-braces Stdin Stdout)
72
73 bb/copy-to-ebx 0/imm32
74 $subx-braces-main:end:
75 b8/copy-to-eax 1/imm32/exit
76 cd/syscall 0x80/imm8
77
78 subx-braces:
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115 55/push-ebp
116 89/<- %ebp 4/r32/esp
117
118 50/push-eax
119 51/push-ecx
120 52/push-edx
121 53/push-ebx
122 56/push-esi
123 57/push-edi
124
125 8b/-> *(ebp+8) 6/r32/esi
126
127 81 5/subop/subtract %esp 0x200/imm32
128 68/push 0x200/imm32/length
129 68/push 0/imm32/read
130 68/push 0/imm32/write
131 89/<- %ecx 4/r32/esp
132
133 81 5/subop/subtract %esp 0x80/imm32
134 68/push 0x80/imm32/length
135 68/push 0/imm32/top
136 89/<- %edx 4/r32/esp
137
138 c7 0/subop/copy %ebx 1/imm32
139
140 68/push 0/imm32/end
141 68/push 0/imm32/start
142 89/<- %edi 4/r32/esp
143 $subx-braces:line-loop:
144 (clear-stream %ecx)
145 (read-line-buffered %esi %ecx)
146 $subx-braces:check0:
147
148 81 7/subop/compare *ecx 0/imm32
149 0f 84/jump-if-= $subx-braces:break/disp32
150 (skip-chars-matching-whitespace %ecx)
151 $subx-braces:check-for-curly-open:
152
153
154 8b/-> *(ecx+4) 0/r32/eax
155 8a/copy-byte *(ecx+eax+0xc) 0/r32/AL
156 81 4/subop/and %eax 0xff/imm32
157
158 3d/compare-eax-and 0x7b/imm32/open-curly
159 0f 85/jump-if-!= $subx-braces:check-for-curly-closed/disp32
160 $subx-braces:emit-curly-open:
161
162 (write-buffered *(ebp+0xc) "_loop")
163 (print-int32-buffered *(ebp+0xc) %ebx)
164 (write-buffered *(ebp+0xc) ":")
165
166 (push %edx %ebx)
167
168 ff 0/subop/increment %ebx
169
170 e9/jump $subx-braces:next-line/disp32
171 $subx-braces:check-for-curly-closed:
172
173 3d/compare-eax-and 0x7d/imm32/close-curly
174 0f 85/jump-if-= $subx-braces:word-loop/disp32
175 $subx-braces:emit-curly-closed:
176
177 (pop %edx)
178
179 (write-buffered *(ebp+0xc) "_break")
180 (print-int32-buffered *(ebp+0xc) %eax)
181 (write-buffered *(ebp+0xc) ":")
182
183 e9/jump $subx-braces:next-line/disp32
184 $subx-braces:word-loop:
185 (next-word-or-string %ecx %edi)
186 $subx-braces:check1:
187
188 (slice-empty? %edi)
189 3d/compare-eax-and 0/imm32/false
190 0f 85/jump-if-!= $subx-braces:next-line/disp32
191 $subx-braces:check-for-comment:
192
193
194 8b/-> *edi 0/r32/eax
195 8a/copy-byte *eax 0/r32/AL
196 81 4/subop/and %eax 0xff/imm32
197
198 3d/compare-eax-and 0x23/imm32/hash
199 74/jump-if-= $subx-braces:word-loop/disp8
200 $subx-braces:check-for-break:
201
202
203 (slice-starts-with? %edi "break/")
204
205 3d/compare-eax-and 0/imm32/false
206 74/jump-if-= $subx-braces:check-for-loop/disp8
207 $subx-braces:emit-break:
208 (top %edx)
209
210 (write-buffered *(ebp+0xc) "_break")
211 (print-int32-buffered *(ebp+0xc) %eax)
212
213 81 0/subop/add *edi 5/imm32/strlen
214
215 eb/jump $subx-braces:emit-word-slice/disp8
216 $subx-braces:check-for-loop:
217
218
219 (slice-starts-with? %edi "loop/")
220
221 3d/compare-eax-and 0/imm32/false
222 74/jump-if-= $subx-braces:emit-word-slice/disp8
223 $subx-braces:emit-loop:
224 (top %edx)
225
226 (write-buffered *(ebp+0xc) "_loop")
227 (print-int32-buffered *(ebp+0xc) %eax)
228
229 81 0/subop/add *edi 4/imm32/strlen
230
231 $subx-braces:emit-word-slice:
232
233 (write-slice-buffered *(ebp+0xc) %edi)
234 (write-buffered *(ebp+0xc) Space)
235
236 e9/jump $subx-braces:word-loop/disp32
237 $subx-braces:next-line:
238
239 (write-buffered *(ebp+0xc) Newline)
240
241 e9/jump $subx-braces:line-loop/disp32
242 $subx-braces:break:
243 (flush *(ebp+0xc))
244 $subx-braces:end:
245
246 81 0/subop/add %esp 0x29c/imm32
247
248 5f/pop-to-edi
249 5e/pop-to-esi
250 5b/pop-to-ebx
251 5a/pop-to-edx
252 59/pop-to-ecx
253 58/pop-to-eax
254
255 89/<- %esp 5/r32/ebp
256 5d/pop-to-ebp
257 c3/return
258
259 test-subx-braces-passes-most-words-through:
260
261 55/push-ebp
262 89/<- %ebp 4/r32/esp
263
264 (clear-stream _test-input-stream)
265 (clear-stream _test-output-stream)
266 (clear-stream $_test-input-buffered-file->buffer)
267 (clear-stream $_test-output-buffered-file->buffer)
268
269 (write _test-input-stream "== abcd 0x1")
270 (subx-braces _test-input-buffered-file _test-output-buffered-file)
271
272 (flush _test-output-buffered-file)
273 +-- 5 lines: #? # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
278 (check-stream-equal _test-output-stream "== abcd 0x1 \n" "F - test-subx-braces-passes-most-words-through")
279
280 89/<- %esp 5/r32/ebp
281 5d/pop-to-ebp
282 c3/return
283
284 test-subx-braces-1:
285
286
287
288
289
290
291
292
293
294
295
296
297
298 55/push-ebp
299 89/<- %ebp 4/r32/esp
300
301 (clear-stream _test-input-stream)
302 (clear-stream _test-output-stream)
303 (clear-stream $_test-input-buffered-file->buffer)
304 (clear-stream $_test-output-buffered-file->buffer)
305
306 (write _test-input-stream "{\nab break/imm32\ncd loop/imm32\n}")
307 (subx-braces _test-input-buffered-file _test-output-buffered-file)
308
309 (flush _test-output-buffered-file)
310 +-- 5 lines: #? # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
315 (check-stream-equal _test-output-stream "_loop0x00000001:\nab _break0x00000001/imm32 \ncd _loop0x00000001/imm32 \n_break0x00000001:\n" "F - test-subx-braces-1")
316
317 89/<- %esp 5/r32/ebp
318 5d/pop-to-ebp
319 c3/return
320
321 test-subx-braces-2:
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339 55/push-ebp
340 89/<- %ebp 4/r32/esp
341
342 (clear-stream _test-input-stream)
343 (clear-stream _test-output-stream)
344 (clear-stream $_test-input-buffered-file->buffer)
345 (clear-stream $_test-output-buffered-file->buffer)
346
347 (write _test-input-stream "{\n{\nab break/imm32\n}\ncd loop/imm32\n}")
348 (subx-braces _test-input-buffered-file _test-output-buffered-file)
349
350 (flush _test-output-buffered-file)
351 +-- 5 lines: #? # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
356 (check-stream-equal _test-output-stream "_loop0x00000001:\n_loop0x00000002:\nab _break0x00000002/imm32 \n_break0x00000002:\ncd _loop0x00000001/imm32 \n_break0x00000001:\n" "F - test-subx-braces-2")
357
358 89/<- %esp 5/r32/ebp
359 5d/pop-to-ebp
360 c3/return