https://github.com/akkartik/mu/blob/main/shell/sandbox.mu
1 type sandbox {
2 data: (handle gap-buffer)
3 value: (handle stream byte)
4 trace: (handle trace)
5 cursor-in-trace?: boolean
6 }
7
8 fn initialize-sandbox _self: (addr sandbox) {
9 var self/esi: (addr sandbox) <- copy _self
10 var data-ah/eax: (addr handle gap-buffer) <- get self, data
11 allocate data-ah
12 var data/eax: (addr gap-buffer) <- lookup *data-ah
13 initialize-gap-buffer data, 0x1000/4KB
14 var value-ah/eax: (addr handle stream byte) <- get self, value
15 populate-stream value-ah, 0x1000/4KB
16 var trace-ah/eax: (addr handle trace) <- get self, trace
17 allocate trace-ah
18 var trace/eax: (addr trace) <- lookup *trace-ah
19 initialize-trace trace, 0x1000/lines, 0x80/visible-lines
20 }
21
22
23
24 fn initialize-sandbox-with _self: (addr sandbox), s: (addr array byte) {
25 var self/esi: (addr sandbox) <- copy _self
26 var data-ah/eax: (addr handle gap-buffer) <- get self, data
27 allocate data-ah
28 var data/eax: (addr gap-buffer) <- lookup *data-ah
29 initialize-gap-buffer-with data, s
30 }
31
32 fn allocate-sandbox-with _out: (addr handle sandbox), s: (addr array byte) {
33 var out/eax: (addr handle sandbox) <- copy _out
34 allocate out
35 var out-addr/eax: (addr sandbox) <- lookup *out
36 initialize-sandbox-with out-addr, s
37 }
38
39
40
41 fn render-sandbox screen: (addr screen), _self: (addr sandbox), xmin: int, ymin: int, xmax: int, ymax: int {
42 clear-screen screen
43 var self/esi: (addr sandbox) <- copy _self
44
45 var data-ah/eax: (addr handle gap-buffer) <- get self, data
46 var _data/eax: (addr gap-buffer) <- lookup *data-ah
47 var data/edx: (addr gap-buffer) <- copy _data
48 var x/eax: int <- copy xmin
49 var y/ecx: int <- copy ymin
50 var cursor-in-sandbox?/ebx: boolean <- copy 0/false
51 {
52 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
53 compare *cursor-in-trace?, 0/false
54 break-if-!=
55 cursor-in-sandbox? <- copy 1/true
56 }
57 x, y <- render-gap-buffer-wrapping-right-then-down screen, data, x, y, xmax, ymax, cursor-in-sandbox?
58 y <- increment
59
60 var trace-ah/eax: (addr handle trace) <- get self, trace
61 var _trace/eax: (addr trace) <- lookup *trace-ah
62 var trace/edx: (addr trace) <- copy _trace
63 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
64 y <- render-trace screen, trace, xmin, y, xmax, ymax, *cursor-in-trace?
65
66 $render-sandbox:value: {
67 var value-ah/eax: (addr handle stream byte) <- get self, value
68 var _value/eax: (addr stream byte) <- lookup *value-ah
69 var value/esi: (addr stream byte) <- copy _value
70 rewind-stream value
71 var done?/eax: boolean <- stream-empty? value
72 compare done?, 0/false
73 break-if-!=
74 var x/eax: int <- copy 0
75 x, y <- draw-text-wrapping-right-then-down screen, "=> ", xmin, y, xmax, ymax, xmin, y, 7/fg, 0/bg
76 var x2/edx: int <- copy x
77 var dummy/eax: int <- draw-stream-rightward screen, value, x2, xmax, y, 7/fg=grey, 0/bg
78 }
79
80 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
81 compare *cursor-in-trace?, 0/false
82 {
83 break-if-=
84 render-trace-menu screen
85 return
86 }
87 render-sandbox-menu screen
88 }
89
90 fn render-sandbox-menu screen: (addr screen) {
91 var width/eax: int <- copy 0
92 var height/ecx: int <- copy 0
93 width, height <- screen-size screen
94 var y/ecx: int <- copy height
95 y <- decrement
96 set-cursor-position screen, 0/x, y
97 draw-text-rightward-from-cursor screen, " ctrl-s ", width, 0/fg, 7/bg=grey
98 draw-text-rightward-from-cursor screen, " run sandbox ", width, 7/fg, 0/bg
99 draw-text-rightward-from-cursor screen, " tab ", width, 0/fg, 9/bg=blue
100 draw-text-rightward-from-cursor screen, " move to trace ", width, 7/fg, 0/bg
101 draw-text-rightward-from-cursor screen, " ctrl-d ", width, 0/fg, 7/bg=grey
102 draw-text-rightward-from-cursor screen, " down ", width, 7/fg, 0/bg
103 draw-text-rightward-from-cursor screen, " ctrl-u ", width, 0/fg, 7/bg=grey
104 draw-text-rightward-from-cursor screen, " up ", width, 7/fg, 0/bg
105 }
106
107 fn edit-sandbox _self: (addr sandbox), key: byte {
108 var self/esi: (addr sandbox) <- copy _self
109 var g/edx: grapheme <- copy key
110
111 {
112 compare g, 0x12/ctrl-r
113 break-if-!=
114
115
116
117 return
118 }
119 {
120 compare g, 0x13/ctrl-s
121 break-if-!=
122
123 var data-ah/eax: (addr handle gap-buffer) <- get self, data
124 var _data/eax: (addr gap-buffer) <- lookup *data-ah
125 var data/ecx: (addr gap-buffer) <- copy _data
126 var value-ah/eax: (addr handle stream byte) <- get self, value
127 var _value/eax: (addr stream byte) <- lookup *value-ah
128 var value/edx: (addr stream byte) <- copy _value
129 var trace-ah/eax: (addr handle trace) <- get self, trace
130 var trace/eax: (addr trace) <- lookup *trace-ah
131 clear-trace trace
132 run data, value, trace
133
134
135
136 return
137 }
138
139 var cursor-in-trace?/eax: (addr boolean) <- get self, cursor-in-trace?
140 {
141 compare g, 9/tab
142 break-if-!=
143
144 {
145 compare *cursor-in-trace?, 0/false
146 break-if-!=
147 copy-to *cursor-in-trace?, 1/true
148 return
149 }
150
151 copy-to *cursor-in-trace?, 0/false
152 return
153 }
154
155 {
156 compare *cursor-in-trace?, 0/false
157 break-if-=
158 var trace-ah/eax: (addr handle trace) <- get self, trace
159 var trace/eax: (addr trace) <- lookup *trace-ah
160 edit-trace trace, g
161 return
162 }
163
164 var data-ah/eax: (addr handle gap-buffer) <- get self, data
165 var data/eax: (addr gap-buffer) <- lookup *data-ah
166 edit-gap-buffer data, g
167 return
168 }
169
170 fn run in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
171 var read-result-storage: (handle cell)
172 var read-result/esi: (addr handle cell) <- address read-result-storage
173 read-cell in, read-result, trace
174 var error?/eax: boolean <- has-errors? trace
175 {
176 compare error?, 0/false
177 break-if-=
178 return
179 }
180 var nil-storage: (handle cell)
181 var nil-ah/eax: (addr handle cell) <- address nil-storage
182 allocate-pair nil-ah
183 var eval-result-storage: (handle cell)
184 var eval-result/edi: (addr handle cell) <- address eval-result-storage
185 evaluate read-result, eval-result, *nil-ah, trace
186 var error?/eax: boolean <- has-errors? trace
187 {
188 compare error?, 0/false
189 break-if-=
190 return
191 }
192 clear-stream out
193 print-cell eval-result, out, trace
194 mark-lines-dirty trace
195 }
196
197 fn test-run-integer {
198 var sandbox-storage: sandbox
199 var sandbox/esi: (addr sandbox) <- address sandbox-storage
200 initialize-sandbox sandbox
201
202 edit-sandbox sandbox, 0x31/1
203
204 edit-sandbox sandbox, 0x13/ctrl-s
205
206 var screen-on-stack: screen
207 var screen/edi: (addr screen) <- address screen-on-stack
208 initialize-screen screen, 0x80/width, 0x10/height
209
210 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height
211 check-screen-row screen, 0/y, "1 ", "F - test-run-integer/0"
212 check-screen-row screen, 1/y, "... ", "F - test-run-integer/1"
213 check-screen-row screen, 2/y, "=> 1 ", "F - test-run-integer/2"
214 }
215
216 fn test-run-with-spaces {
217 var sandbox-storage: sandbox
218 var sandbox/esi: (addr sandbox) <- address sandbox-storage
219 initialize-sandbox sandbox
220
221 edit-sandbox sandbox, 0x20/space
222 edit-sandbox sandbox, 0x31/1
223 edit-sandbox sandbox, 0x20/space
224 edit-sandbox sandbox, 0xa/newline
225
226 edit-sandbox sandbox, 0x13/ctrl-s
227
228 var screen-on-stack: screen
229 var screen/edi: (addr screen) <- address screen-on-stack
230 initialize-screen screen, 0x80/width, 0x10/height
231
232 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height
233 check-screen-row screen, 0/y, " 1 ", "F - test-run-with-spaces/0"
234 check-screen-row screen, 1/y, " ", "F - test-run-with-spaces/1"
235 check-screen-row screen, 2/y, "... ", "F - test-run-with-spaces/2"
236 check-screen-row screen, 3/y, "=> 1 ", "F - test-run-with-spaces/3"
237 }
238
239 fn test-run-error-invalid-integer {
240 var sandbox-storage: sandbox
241 var sandbox/esi: (addr sandbox) <- address sandbox-storage
242 initialize-sandbox sandbox
243
244 edit-sandbox sandbox, 0x31/1
245 edit-sandbox sandbox, 0x61/a
246
247 edit-sandbox sandbox, 0x13/ctrl-s
248
249 var screen-on-stack: screen
250 var screen/edi: (addr screen) <- address screen-on-stack
251 initialize-screen screen, 0x80/width, 0x10/height
252
253 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height
254 check-screen-row screen, 0/y, "1a ", "F - test-run-error-invalid-integer/0"
255 check-screen-row screen, 1/y, "... ", "F - test-run-error-invalid-integer/0"
256 check-screen-row screen, 2/y, "invalid number ", "F - test-run-error-invalid-integer/2"
257 }
258
259 fn test-run-move-cursor-into-trace {
260 var sandbox-storage: sandbox
261 var sandbox/esi: (addr sandbox) <- address sandbox-storage
262 initialize-sandbox sandbox
263
264 edit-sandbox sandbox, 0x31/1
265 edit-sandbox sandbox, 0x32/2
266
267 edit-sandbox sandbox, 0x13/ctrl-s
268
269 var screen-on-stack: screen
270 var screen/edi: (addr screen) <- address screen-on-stack
271 initialize-screen screen, 0x80/width, 0x10/height
272
273 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height
274 check-screen-row screen, 0/y, "12 ", "F - test-run-move-cursor-into-trace/pre-0"
275 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-run-move-cursor-into-trace/pre-0/cursor"
276 check-screen-row screen, 1/y, "... ", "F - test-run-move-cursor-into-trace/pre-1"
277 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-move-cursor-into-trace/pre-1/cursor"
278 check-screen-row screen, 2/y, "=> 12 ", "F - test-run-move-cursor-into-trace/pre-2"
279 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-move-cursor-into-trace/pre-2/cursor"
280
281 edit-sandbox sandbox, 9/tab
282
283 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height
284 check-screen-row screen, 0/y, "12 ", "F - test-run-move-cursor-into-trace/trace-0"
285 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " ", "F - test-run-move-cursor-into-trace/trace-0/cursor"
286 check-screen-row screen, 1/y, "... ", "F - test-run-move-cursor-into-trace/trace-1"
287 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, "||| ", "F - test-run-move-cursor-into-trace/trace-1/cursor"
288 check-screen-row screen, 2/y, "=> 12 ", "F - test-run-move-cursor-into-trace/trace-2"
289 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-move-cursor-into-trace/trace-2/cursor"
290
291 edit-sandbox sandbox, 9/tab
292
293 render-sandbox screen, sandbox, 0/x, 0/y, 0x80/width, 0x10/height
294 check-screen-row screen, 0/y, "12 ", "F - test-run-move-cursor-into-trace/input-0"
295 check-background-color-in-screen-row screen, 7/bg=cursor, 0/y, " | ", "F - test-run-move-cursor-into-trace/input-0/cursor"
296 check-screen-row screen, 1/y, "... ", "F - test-run-move-cursor-into-trace/input-1"
297 check-background-color-in-screen-row screen, 7/bg=cursor, 1/y, " ", "F - test-run-move-cursor-into-trace/input-1/cursor"
298 check-screen-row screen, 2/y, "=> 12 ", "F - test-run-move-cursor-into-trace/input-2"
299 check-background-color-in-screen-row screen, 7/bg=cursor, 2/y, " ", "F - test-run-move-cursor-into-trace/input-2/cursor"
300 }