Fork of daniellemaywood.uk/gleam — Wasm codegen work
18 kB
690 lines
1use ecow::EcoString;
2use num_bigint::BigInt;
3
4use crate::cranelift::mir::ast::{Expression, Function, Module, Var};
5
6pub trait Visit<'mir, T> {
7 fn visit_module(&mut self, module: &'mir mut Module<T>) {
8 visit_module(self, module);
9 }
10
11 fn visit_function(&mut self, function: &'mir mut Function<T>) {
12 visit_function(self, function);
13 }
14
15 fn visit_expression(&mut self, expression: &'mir mut Expression<T>) {
16 visit_expression(self, expression);
17 }
18
19 fn visit_expression_block(&mut self, expressions: &'mir mut Vec<Expression<T>>) {
20 visit_expression_block(self, expressions);
21 }
22
23 fn visit_expression_function_ref(
24 &mut self,
25 module: &mut EcoString,
26 name: &mut EcoString,
27 arity: &mut usize,
28 type_: &mut T,
29 ) {
30 visit_expression_function_ref(self, module, name, arity, type_);
31 }
32
33 fn visit_expression_var(&mut self, var: &'mir mut Var<T>) {
34 visit_expression_var(self, var);
35 }
36
37 fn visit_expression_int(&mut self, value: &'mir mut BigInt) {
38 visit_expression_int(self, value);
39 }
40
41 fn visit_expression_float(&mut self, value: &'mir mut EcoString) {
42 visit_expression_float(self, value);
43 }
44
45 fn visit_expression_bool(&mut self, value: &'mir mut bool) {
46 visit_expression_bool(self, value);
47 }
48
49 fn visit_expression_string(&mut self, value: &'mir mut EcoString) {
50 visit_expression_string(self, value);
51 }
52
53 fn visit_expression_equals(
54 &mut self,
55 lhs: &'mir mut Expression<T>,
56 rhs: &'mir mut Expression<T>,
57 ) {
58 visit_expression_equals(self, lhs, rhs);
59 }
60
61 fn visit_expression_not_equals(
62 &mut self,
63 lhs: &'mir mut Expression<T>,
64 rhs: &'mir mut Expression<T>,
65 ) {
66 visit_expression_not_equals(self, lhs, rhs);
67 }
68
69 fn visit_expression_int_gt(
70 &mut self,
71 lhs: &'mir mut Expression<T>,
72 rhs: &'mir mut Expression<T>,
73 ) {
74 visit_expression_int_gt(self, lhs, rhs);
75 }
76
77 fn visit_expression_int_gt_eq(
78 &mut self,
79 lhs: &'mir mut Expression<T>,
80 rhs: &'mir mut Expression<T>,
81 ) {
82 visit_expression_int_gt_eq(self, lhs, rhs);
83 }
84
85 fn visit_expression_int_lt(
86 &mut self,
87 lhs: &'mir mut Expression<T>,
88 rhs: &'mir mut Expression<T>,
89 ) {
90 visit_expression_int_lt(self, lhs, rhs);
91 }
92
93 fn visit_expression_int_lt_eq(
94 &mut self,
95 lhs: &'mir mut Expression<T>,
96 rhs: &'mir mut Expression<T>,
97 ) {
98 visit_expression_int_lt_eq(self, lhs, rhs);
99 }
100
101 fn visit_expression_int_add(
102 &mut self,
103 lhs: &'mir mut Expression<T>,
104 rhs: &'mir mut Expression<T>,
105 ) {
106 visit_expression_int_add(self, lhs, rhs);
107 }
108
109 fn visit_expression_int_sub(
110 &mut self,
111 lhs: &'mir mut Expression<T>,
112 rhs: &'mir mut Expression<T>,
113 ) {
114 visit_expression_int_sub(self, lhs, rhs);
115 }
116
117 fn visit_expression_int_mul(
118 &mut self,
119 lhs: &'mir mut Expression<T>,
120 rhs: &'mir mut Expression<T>,
121 ) {
122 visit_expression_int_mul(self, lhs, rhs);
123 }
124
125 fn visit_expression_int_div(
126 &mut self,
127 lhs: &'mir mut Expression<T>,
128 rhs: &'mir mut Expression<T>,
129 ) {
130 visit_expression_int_div(self, lhs, rhs);
131 }
132
133 fn visit_expression_int_rem(
134 &mut self,
135 lhs: &'mir mut Expression<T>,
136 rhs: &'mir mut Expression<T>,
137 ) {
138 visit_expression_int_rem(self, lhs, rhs);
139 }
140
141 fn visit_expression_float_gt(
142 &mut self,
143 lhs: &'mir mut Expression<T>,
144 rhs: &'mir mut Expression<T>,
145 ) {
146 visit_expression_float_gt(self, lhs, rhs);
147 }
148
149 fn visit_expression_float_gt_eq(
150 &mut self,
151 lhs: &'mir mut Expression<T>,
152 rhs: &'mir mut Expression<T>,
153 ) {
154 visit_expression_float_gt_eq(self, lhs, rhs);
155 }
156
157 fn visit_expression_float_lt(
158 &mut self,
159 lhs: &'mir mut Expression<T>,
160 rhs: &'mir mut Expression<T>,
161 ) {
162 visit_expression_float_lt(self, lhs, rhs);
163 }
164
165 fn visit_expression_float_lt_eq(
166 &mut self,
167 lhs: &'mir mut Expression<T>,
168 rhs: &'mir mut Expression<T>,
169 ) {
170 visit_expression_float_lt_eq(self, lhs, rhs);
171 }
172
173 fn visit_expression_float_add(
174 &mut self,
175 lhs: &'mir mut Expression<T>,
176 rhs: &'mir mut Expression<T>,
177 ) {
178 visit_expression_float_add(self, lhs, rhs);
179 }
180
181 fn visit_expression_float_sub(
182 &mut self,
183 lhs: &'mir mut Expression<T>,
184 rhs: &'mir mut Expression<T>,
185 ) {
186 visit_expression_float_sub(self, lhs, rhs);
187 }
188
189 fn visit_expression_float_mul(
190 &mut self,
191 lhs: &'mir mut Expression<T>,
192 rhs: &'mir mut Expression<T>,
193 ) {
194 visit_expression_float_mul(self, lhs, rhs);
195 }
196
197 fn visit_expression_float_div(
198 &mut self,
199 lhs: &'mir mut Expression<T>,
200 rhs: &'mir mut Expression<T>,
201 ) {
202 visit_expression_float_div(self, lhs, rhs);
203 }
204
205 fn visit_expression_string_concat(
206 &mut self,
207 lhs: &'mir mut Expression<T>,
208 rhs: &'mir mut Expression<T>,
209 ) {
210 visit_expression_string_concat(self, lhs, rhs);
211 }
212
213 fn visit_expression_list(
214 &mut self,
215 items: &'mir mut Vec<Expression<T>>,
216 tail: &'mir mut Option<Box<Expression<T>>>,
217 type_: &'mir mut T,
218 ) {
219 visit_expression_list(self, items, tail, type_);
220 }
221
222 fn visit_expression_struct(
223 &mut self,
224 tag: &'mir mut Option<u32>,
225 items: &'mir mut Vec<Expression<T>>,
226 type_: &'mir mut T,
227 ) {
228 visit_expression_struct(self, tag, items, type_);
229 }
230
231 fn visit_expression_struct_tag(&mut self, value: &'mir mut Expression<T>) {
232 visit_expression_struct_tag(self, value);
233 }
234
235 fn visit_expression_struct_access(
236 &mut self,
237 value: &'mir mut Expression<T>,
238 index: &'mir mut u64,
239 type_: &'mir mut T,
240 ) {
241 visit_expression_struct_access(self, value, index, type_);
242 }
243
244 fn visit_expression_set(&mut self, name: &'mir mut Var<T>, value: &'mir mut Expression<T>) {
245 visit_expression_set(self, name, value);
246 }
247
248 fn visit_expression_if(
249 &mut self,
250 cond: &'mir mut Expression<T>,
251 then: &'mir mut Expression<T>,
252 else_: &'mir mut Expression<T>,
253 ) {
254 visit_expression_if(self, cond, then, else_);
255 }
256
257 fn visit_expression_call(
258 &mut self,
259 target: &'mir mut Expression<T>,
260 args: &'mir mut Vec<Expression<T>>,
261 type_: &'mir mut T,
262 ) {
263 visit_expression_call(self, target, args, type_);
264 }
265}
266
267pub fn visit_module<'mir, T, V>(v: &mut V, module: &'mir mut Module<T>)
268where
269 V: Visit<'mir, T> + ?Sized,
270{
271 for function in &mut module.functions {
272 v.visit_function(function);
273 }
274}
275
276pub fn visit_function<'mir, T, V>(v: &mut V, function: &'mir mut Function<T>)
277where
278 V: Visit<'mir, T> + ?Sized,
279{
280 v.visit_expression(&mut function.body);
281}
282
283pub fn visit_expression<'mir, T, V>(v: &mut V, expression: &'mir mut Expression<T>)
284where
285 V: Visit<'mir, T> + ?Sized,
286{
287 match expression {
288 Expression::Block(expressions) => v.visit_expression_block(expressions),
289 Expression::FunctionRef {
290 module,
291 name,
292 arity,
293 type_,
294 } => v.visit_expression_function_ref(module, name, arity, type_),
295 Expression::Var(var) => v.visit_expression_var(var),
296 Expression::Int { value } => v.visit_expression_int(value),
297 Expression::Float { value } => v.visit_expression_float(value),
298 Expression::Bool { value } => v.visit_expression_bool(value),
299 Expression::String { value } => v.visit_expression_string(value),
300 Expression::Equals { lhs, rhs } => v.visit_expression_equals(lhs, rhs),
301 Expression::NotEquals { lhs, rhs } => v.visit_expression_not_equals(lhs, rhs),
302 Expression::IntGt { lhs, rhs } => v.visit_expression_int_gt(lhs, rhs),
303 Expression::IntGtEq { lhs, rhs } => v.visit_expression_int_gt_eq(lhs, rhs),
304 Expression::IntLt { lhs, rhs } => v.visit_expression_int_lt(lhs, rhs),
305 Expression::IntLtEq { lhs, rhs } => v.visit_expression_int_lt_eq(lhs, rhs),
306 Expression::IntAdd { lhs, rhs } => v.visit_expression_int_add(lhs, rhs),
307 Expression::IntSub { lhs, rhs } => v.visit_expression_int_sub(lhs, rhs),
308 Expression::IntMul { lhs, rhs } => v.visit_expression_int_mul(lhs, rhs),
309 Expression::IntDiv { lhs, rhs } => v.visit_expression_int_div(lhs, rhs),
310 Expression::IntRem { lhs, rhs } => v.visit_expression_int_rem(lhs, rhs),
311 Expression::FloatGt { lhs, rhs } => v.visit_expression_float_gt(lhs, rhs),
312 Expression::FloatGtEq { lhs, rhs } => v.visit_expression_float_gt_eq(lhs, rhs),
313 Expression::FloatLt { lhs, rhs } => v.visit_expression_float_lt(lhs, rhs),
314 Expression::FloatLtEq { lhs, rhs } => v.visit_expression_float_lt_eq(lhs, rhs),
315 Expression::FloatAdd { lhs, rhs } => v.visit_expression_float_add(lhs, rhs),
316 Expression::FloatSub { lhs, rhs } => v.visit_expression_float_sub(lhs, rhs),
317 Expression::FloatMul { lhs, rhs } => v.visit_expression_float_mul(lhs, rhs),
318 Expression::FloatDiv { lhs, rhs } => v.visit_expression_float_div(lhs, rhs),
319 Expression::StringConcat { lhs, rhs } => v.visit_expression_string_concat(lhs, rhs),
320 Expression::List { items, tail, type_ } => v.visit_expression_list(items, tail, type_),
321 Expression::Struct { tag, items, type_ } => v.visit_expression_struct(tag, items, type_),
322 Expression::StructTag { value } => v.visit_expression_struct_tag(value),
323 Expression::StructAccess {
324 value,
325 index,
326 type_,
327 } => v.visit_expression_struct_access(value, index, type_),
328 Expression::Set { name, value } => v.visit_expression_set(name, value),
329 Expression::If { cond, then, else_ } => v.visit_expression_if(cond, then, else_),
330 Expression::Call {
331 target,
332 args,
333 type_,
334 } => v.visit_expression_call(target, args, type_),
335 }
336}
337
338pub fn visit_expression_block<'mir, T, V>(v: &mut V, expressions: &'mir mut Vec<Expression<T>>)
339where
340 V: Visit<'mir, T> + ?Sized,
341{
342 for expression in expressions {
343 v.visit_expression(expression);
344 }
345}
346
347pub fn visit_expression_function_ref<'mir, T, V>(
348 _v: &mut V,
349 _module: &mut EcoString,
350 _name: &mut EcoString,
351 _arity: &mut usize,
352 _type: &mut T,
353) where
354 V: Visit<'mir, T> + ?Sized,
355{
356}
357
358pub fn visit_expression_var<'mir, T, V>(_v: &mut V, _var: &mut Var<T>)
359where
360 V: Visit<'mir, T> + ?Sized,
361{
362}
363
364pub fn visit_expression_int<'mir, T, V>(_v: &mut V, _value: &mut BigInt)
365where
366 V: Visit<'mir, T> + ?Sized,
367{
368}
369
370pub fn visit_expression_float<'mir, T, V>(_v: &mut V, _value: &mut EcoString)
371where
372 V: Visit<'mir, T> + ?Sized,
373{
374}
375
376pub fn visit_expression_bool<'mir, T, V>(_v: &mut V, _value: &mut bool)
377where
378 V: Visit<'mir, T> + ?Sized,
379{
380}
381
382pub fn visit_expression_string<'mir, T, V>(_v: &mut V, _value: &mut EcoString)
383where
384 V: Visit<'mir, T> + ?Sized,
385{
386}
387
388pub fn visit_expression_equals<'mir, T, V>(
389 v: &mut V,
390 lhs: &'mir mut Expression<T>,
391 rhs: &'mir mut Expression<T>,
392) where
393 V: Visit<'mir, T> + ?Sized,
394{
395 v.visit_expression(lhs);
396 v.visit_expression(rhs);
397}
398
399pub fn visit_expression_not_equals<'mir, T, V>(
400 v: &mut V,
401 lhs: &'mir mut Expression<T>,
402 rhs: &'mir mut Expression<T>,
403) where
404 V: Visit<'mir, T> + ?Sized,
405{
406 v.visit_expression(lhs);
407 v.visit_expression(rhs);
408}
409
410pub fn visit_expression_int_gt<'mir, T, V>(
411 v: &mut V,
412 lhs: &'mir mut Expression<T>,
413 rhs: &'mir mut Expression<T>,
414) where
415 V: Visit<'mir, T> + ?Sized,
416{
417 v.visit_expression(lhs);
418 v.visit_expression(rhs);
419}
420
421pub fn visit_expression_int_gt_eq<'mir, T, V>(
422 v: &mut V,
423 lhs: &'mir mut Expression<T>,
424 rhs: &'mir mut Expression<T>,
425) where
426 V: Visit<'mir, T> + ?Sized,
427{
428 v.visit_expression(lhs);
429 v.visit_expression(rhs);
430}
431
432pub fn visit_expression_int_lt<'mir, T, V>(
433 v: &mut V,
434 lhs: &'mir mut Expression<T>,
435 rhs: &'mir mut Expression<T>,
436) where
437 V: Visit<'mir, T> + ?Sized,
438{
439 v.visit_expression(lhs);
440 v.visit_expression(rhs);
441}
442
443pub fn visit_expression_int_lt_eq<'mir, T, V>(
444 v: &mut V,
445 lhs: &'mir mut Expression<T>,
446 rhs: &'mir mut Expression<T>,
447) where
448 V: Visit<'mir, T> + ?Sized,
449{
450 v.visit_expression(lhs);
451 v.visit_expression(rhs);
452}
453
454pub fn visit_expression_int_add<'mir, T, V>(
455 v: &mut V,
456 lhs: &'mir mut Expression<T>,
457 rhs: &'mir mut Expression<T>,
458) where
459 V: Visit<'mir, T> + ?Sized,
460{
461 v.visit_expression(lhs);
462 v.visit_expression(rhs);
463}
464
465pub fn visit_expression_int_sub<'mir, T, V>(
466 v: &mut V,
467 lhs: &'mir mut Expression<T>,
468 rhs: &'mir mut Expression<T>,
469) where
470 V: Visit<'mir, T> + ?Sized,
471{
472 v.visit_expression(lhs);
473 v.visit_expression(rhs);
474}
475
476pub fn visit_expression_int_mul<'mir, T, V>(
477 v: &mut V,
478 lhs: &'mir mut Expression<T>,
479 rhs: &'mir mut Expression<T>,
480) where
481 V: Visit<'mir, T> + ?Sized,
482{
483 v.visit_expression(lhs);
484 v.visit_expression(rhs);
485}
486
487pub fn visit_expression_int_div<'mir, T, V>(
488 v: &mut V,
489 lhs: &'mir mut Expression<T>,
490 rhs: &'mir mut Expression<T>,
491) where
492 V: Visit<'mir, T> + ?Sized,
493{
494 v.visit_expression(lhs);
495 v.visit_expression(rhs);
496}
497
498pub fn visit_expression_int_rem<'mir, T, V>(
499 v: &mut V,
500 lhs: &'mir mut Expression<T>,
501 rhs: &'mir mut Expression<T>,
502) where
503 V: Visit<'mir, T> + ?Sized,
504{
505 v.visit_expression(lhs);
506 v.visit_expression(rhs);
507}
508
509pub fn visit_expression_float_gt<'mir, T, V>(
510 v: &mut V,
511 lhs: &'mir mut Expression<T>,
512 rhs: &'mir mut Expression<T>,
513) where
514 V: Visit<'mir, T> + ?Sized,
515{
516 v.visit_expression(lhs);
517 v.visit_expression(rhs);
518}
519
520pub fn visit_expression_float_gt_eq<'mir, T, V>(
521 v: &mut V,
522 lhs: &'mir mut Expression<T>,
523 rhs: &'mir mut Expression<T>,
524) where
525 V: Visit<'mir, T> + ?Sized,
526{
527 v.visit_expression(lhs);
528 v.visit_expression(rhs);
529}
530
531pub fn visit_expression_float_lt<'mir, T, V>(
532 v: &mut V,
533 lhs: &'mir mut Expression<T>,
534 rhs: &'mir mut Expression<T>,
535) where
536 V: Visit<'mir, T> + ?Sized,
537{
538 v.visit_expression(lhs);
539 v.visit_expression(rhs);
540}
541
542pub fn visit_expression_float_lt_eq<'mir, T, V>(
543 v: &mut V,
544 lhs: &'mir mut Expression<T>,
545 rhs: &'mir mut Expression<T>,
546) where
547 V: Visit<'mir, T> + ?Sized,
548{
549 v.visit_expression(lhs);
550 v.visit_expression(rhs);
551}
552
553pub fn visit_expression_float_add<'mir, T, V>(
554 v: &mut V,
555 lhs: &'mir mut Expression<T>,
556 rhs: &'mir mut Expression<T>,
557) where
558 V: Visit<'mir, T> + ?Sized,
559{
560 v.visit_expression(lhs);
561 v.visit_expression(rhs);
562}
563
564pub fn visit_expression_float_sub<'mir, T, V>(
565 v: &mut V,
566 lhs: &'mir mut Expression<T>,
567 rhs: &'mir mut Expression<T>,
568) where
569 V: Visit<'mir, T> + ?Sized,
570{
571 v.visit_expression(lhs);
572 v.visit_expression(rhs);
573}
574
575pub fn visit_expression_float_mul<'mir, T, V>(
576 v: &mut V,
577 lhs: &'mir mut Expression<T>,
578 rhs: &'mir mut Expression<T>,
579) where
580 V: Visit<'mir, T> + ?Sized,
581{
582 v.visit_expression(lhs);
583 v.visit_expression(rhs);
584}
585
586pub fn visit_expression_float_div<'mir, T, V>(
587 v: &mut V,
588 lhs: &'mir mut Expression<T>,
589 rhs: &'mir mut Expression<T>,
590) where
591 V: Visit<'mir, T> + ?Sized,
592{
593 v.visit_expression(lhs);
594 v.visit_expression(rhs);
595}
596
597pub fn visit_expression_string_concat<'mir, T, V>(
598 v: &mut V,
599 lhs: &'mir mut Expression<T>,
600 rhs: &'mir mut Expression<T>,
601) where
602 V: Visit<'mir, T> + ?Sized,
603{
604 v.visit_expression(lhs);
605 v.visit_expression(rhs);
606}
607
608pub fn visit_expression_list<'mir, T, V>(
609 v: &mut V,
610 items: &'mir mut Vec<Expression<T>>,
611 tail: &'mir mut Option<Box<Expression<T>>>,
612 _type_: &'mir mut T,
613) where
614 V: Visit<'mir, T> + ?Sized,
615{
616 for item in items {
617 v.visit_expression(item);
618 }
619 if let Some(tail) = tail {
620 v.visit_expression(tail);
621 }
622}
623
624pub fn visit_expression_struct<'mir, T, V>(
625 v: &mut V,
626 _tag: &'mir mut Option<u32>,
627 items: &'mir mut Vec<Expression<T>>,
628 _type: &'mir mut T,
629) where
630 V: Visit<'mir, T> + ?Sized,
631{
632 for item in items {
633 v.visit_expression(item);
634 }
635}
636
637pub fn visit_expression_struct_tag<'mir, T, V>(v: &mut V, value: &'mir mut Expression<T>)
638where
639 V: Visit<'mir, T> + ?Sized,
640{
641 v.visit_expression(value);
642}
643
644pub fn visit_expression_struct_access<'mir, T, V>(
645 v: &mut V,
646 value: &'mir mut Expression<T>,
647 _index: &'mir mut u64,
648 _type: &'mir mut T,
649) where
650 V: Visit<'mir, T> + ?Sized,
651{
652 v.visit_expression(value);
653}
654
655pub fn visit_expression_set<'mir, T, V>(
656 v: &mut V,
657 _name: &'mir mut Var<T>,
658 value: &'mir mut Expression<T>,
659) where
660 V: Visit<'mir, T> + ?Sized,
661{
662 v.visit_expression(value);
663}
664
665pub fn visit_expression_if<'mir, T, V>(
666 v: &mut V,
667 cond: &'mir mut Expression<T>,
668 then: &'mir mut Expression<T>,
669 else_: &'mir mut Expression<T>,
670) where
671 V: Visit<'mir, T> + ?Sized,
672{
673 v.visit_expression(cond);
674 v.visit_expression(then);
675 v.visit_expression(else_);
676}
677
678pub fn visit_expression_call<'mir, T, V>(
679 v: &mut V,
680 target: &'mir mut Expression<T>,
681 args: &'mir mut Vec<Expression<T>>,
682 _type_: &'mir mut T,
683) where
684 V: Visit<'mir, T> + ?Sized,
685{
686 v.visit_expression(target);
687 for arg in args {
688 v.visit_expression(arg);
689 }
690}