Fork of daniellemaywood.uk/gleam — Wasm codegen work
19 kB
743 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_tuple(&mut self, items: &'mir mut Vec<Expression<T>>, type_: &'mir mut T) {
223 visit_expression_tuple(self, items, type_);
224 }
225
226 fn visit_expression_tuple_access(
227 &mut self,
228 value: &'mir mut Expression<T>,
229 index: &'mir mut u64,
230 type_: &'mir mut T,
231 ) {
232 visit_expression_tuple_access(self, value, index, type_);
233 }
234
235 fn visit_expression_struct(
236 &mut self,
237 tag: &'mir mut u32,
238 items: &'mir mut Vec<Expression<T>>,
239 type_: &'mir mut T,
240 ) {
241 visit_expression_struct(self, tag, items, type_);
242 }
243
244 fn visit_expression_struct_tag(&mut self, value: &'mir mut Expression<T>) {
245 visit_expression_struct_tag(self, value);
246 }
247
248 fn visit_expression_struct_access(
249 &mut self,
250 value: &'mir mut Expression<T>,
251 index: &'mir mut u64,
252 type_: &'mir mut T,
253 ) {
254 visit_expression_struct_access(self, value, index, type_);
255 }
256
257 fn visit_expression_set(&mut self, name: &'mir mut Var<T>, value: &'mir mut Expression<T>) {
258 visit_expression_set(self, name, value);
259 }
260
261 fn visit_expression_if(
262 &mut self,
263 cond: &'mir mut Expression<T>,
264 then: &'mir mut Expression<T>,
265 else_: &'mir mut Expression<T>,
266 ) {
267 visit_expression_if(self, cond, then, else_);
268 }
269
270 fn visit_expression_call(
271 &mut self,
272 target: &'mir mut Expression<T>,
273 args: &'mir mut Vec<Expression<T>>,
274 type_: &'mir mut T,
275 ) {
276 visit_expression_call(self, target, args, type_);
277 }
278
279 fn visit_expression_panic(&mut self, type_: &'mir mut T) {
280 visit_expression_panic(self, type_);
281 }
282}
283
284pub fn visit_module<'mir, T, V>(v: &mut V, module: &'mir mut Module<T>)
285where
286 V: Visit<'mir, T> + ?Sized,
287{
288 for function in &mut module.functions {
289 v.visit_function(function);
290 }
291}
292
293pub fn visit_function<'mir, T, V>(v: &mut V, function: &'mir mut Function<T>)
294where
295 V: Visit<'mir, T> + ?Sized,
296{
297 v.visit_expression(&mut function.body);
298}
299
300pub fn visit_expression<'mir, T, V>(v: &mut V, expression: &'mir mut Expression<T>)
301where
302 V: Visit<'mir, T> + ?Sized,
303{
304 match expression {
305 Expression::Block(expressions) => v.visit_expression_block(expressions),
306 Expression::FunctionRef {
307 module,
308 name,
309 arity,
310 type_,
311 } => v.visit_expression_function_ref(module, name, arity, type_),
312 Expression::Var(var) => v.visit_expression_var(var),
313 Expression::Int { value } => v.visit_expression_int(value),
314 Expression::Float { value } => v.visit_expression_float(value),
315 Expression::Bool { value } => v.visit_expression_bool(value),
316 Expression::String { value } => v.visit_expression_string(value),
317 Expression::Equals { lhs, rhs } => v.visit_expression_equals(lhs, rhs),
318 Expression::NotEquals { lhs, rhs } => v.visit_expression_not_equals(lhs, rhs),
319 Expression::IntGt { lhs, rhs } => v.visit_expression_int_gt(lhs, rhs),
320 Expression::IntGtEq { lhs, rhs } => v.visit_expression_int_gt_eq(lhs, rhs),
321 Expression::IntLt { lhs, rhs } => v.visit_expression_int_lt(lhs, rhs),
322 Expression::IntLtEq { lhs, rhs } => v.visit_expression_int_lt_eq(lhs, rhs),
323 Expression::IntAdd { lhs, rhs } => v.visit_expression_int_add(lhs, rhs),
324 Expression::IntSub { lhs, rhs } => v.visit_expression_int_sub(lhs, rhs),
325 Expression::IntMul { lhs, rhs } => v.visit_expression_int_mul(lhs, rhs),
326 Expression::IntDiv { lhs, rhs } => v.visit_expression_int_div(lhs, rhs),
327 Expression::IntRem { lhs, rhs } => v.visit_expression_int_rem(lhs, rhs),
328 Expression::FloatGt { lhs, rhs } => v.visit_expression_float_gt(lhs, rhs),
329 Expression::FloatGtEq { lhs, rhs } => v.visit_expression_float_gt_eq(lhs, rhs),
330 Expression::FloatLt { lhs, rhs } => v.visit_expression_float_lt(lhs, rhs),
331 Expression::FloatLtEq { lhs, rhs } => v.visit_expression_float_lt_eq(lhs, rhs),
332 Expression::FloatAdd { lhs, rhs } => v.visit_expression_float_add(lhs, rhs),
333 Expression::FloatSub { lhs, rhs } => v.visit_expression_float_sub(lhs, rhs),
334 Expression::FloatMul { lhs, rhs } => v.visit_expression_float_mul(lhs, rhs),
335 Expression::FloatDiv { lhs, rhs } => v.visit_expression_float_div(lhs, rhs),
336 Expression::StringConcat { lhs, rhs } => v.visit_expression_string_concat(lhs, rhs),
337 Expression::List { items, tail, type_ } => v.visit_expression_list(items, tail, type_),
338 Expression::Tuple { items, type_ } => v.visit_expression_tuple(items, type_),
339 Expression::TupleAccess {
340 value,
341 index,
342 type_,
343 } => v.visit_expression_tuple_access(value, index, type_),
344 Expression::Struct { tag, items, type_ } => v.visit_expression_struct(tag, items, type_),
345 Expression::StructTag { value } => v.visit_expression_struct_tag(value),
346 Expression::StructAccess {
347 value,
348 index,
349 type_,
350 } => v.visit_expression_struct_access(value, index, type_),
351 Expression::Set { name, value } => v.visit_expression_set(name, value),
352 Expression::If { cond, then, else_ } => v.visit_expression_if(cond, then, else_),
353 Expression::Call {
354 target,
355 args,
356 type_,
357 } => v.visit_expression_call(target, args, type_),
358 Expression::Panic { type_ } => v.visit_expression_panic(type_),
359 }
360}
361
362pub fn visit_expression_block<'mir, T, V>(v: &mut V, expressions: &'mir mut Vec<Expression<T>>)
363where
364 V: Visit<'mir, T> + ?Sized,
365{
366 for expression in expressions {
367 v.visit_expression(expression);
368 }
369}
370
371pub fn visit_expression_function_ref<'mir, T, V>(
372 _v: &mut V,
373 _module: &mut EcoString,
374 _name: &mut EcoString,
375 _arity: &mut usize,
376 _type: &mut T,
377) where
378 V: Visit<'mir, T> + ?Sized,
379{
380}
381
382pub fn visit_expression_var<'mir, T, V>(_v: &mut V, _var: &mut Var<T>)
383where
384 V: Visit<'mir, T> + ?Sized,
385{
386}
387
388pub fn visit_expression_int<'mir, T, V>(_v: &mut V, _value: &mut BigInt)
389where
390 V: Visit<'mir, T> + ?Sized,
391{
392}
393
394pub fn visit_expression_float<'mir, T, V>(_v: &mut V, _value: &mut EcoString)
395where
396 V: Visit<'mir, T> + ?Sized,
397{
398}
399
400pub fn visit_expression_bool<'mir, T, V>(_v: &mut V, _value: &mut bool)
401where
402 V: Visit<'mir, T> + ?Sized,
403{
404}
405
406pub fn visit_expression_string<'mir, T, V>(_v: &mut V, _value: &mut EcoString)
407where
408 V: Visit<'mir, T> + ?Sized,
409{
410}
411
412pub fn visit_expression_equals<'mir, T, V>(
413 v: &mut V,
414 lhs: &'mir mut Expression<T>,
415 rhs: &'mir mut Expression<T>,
416) where
417 V: Visit<'mir, T> + ?Sized,
418{
419 v.visit_expression(lhs);
420 v.visit_expression(rhs);
421}
422
423pub fn visit_expression_not_equals<'mir, T, V>(
424 v: &mut V,
425 lhs: &'mir mut Expression<T>,
426 rhs: &'mir mut Expression<T>,
427) where
428 V: Visit<'mir, T> + ?Sized,
429{
430 v.visit_expression(lhs);
431 v.visit_expression(rhs);
432}
433
434pub fn visit_expression_int_gt<'mir, T, V>(
435 v: &mut V,
436 lhs: &'mir mut Expression<T>,
437 rhs: &'mir mut Expression<T>,
438) where
439 V: Visit<'mir, T> + ?Sized,
440{
441 v.visit_expression(lhs);
442 v.visit_expression(rhs);
443}
444
445pub fn visit_expression_int_gt_eq<'mir, T, V>(
446 v: &mut V,
447 lhs: &'mir mut Expression<T>,
448 rhs: &'mir mut Expression<T>,
449) where
450 V: Visit<'mir, T> + ?Sized,
451{
452 v.visit_expression(lhs);
453 v.visit_expression(rhs);
454}
455
456pub fn visit_expression_int_lt<'mir, T, V>(
457 v: &mut V,
458 lhs: &'mir mut Expression<T>,
459 rhs: &'mir mut Expression<T>,
460) where
461 V: Visit<'mir, T> + ?Sized,
462{
463 v.visit_expression(lhs);
464 v.visit_expression(rhs);
465}
466
467pub fn visit_expression_int_lt_eq<'mir, T, V>(
468 v: &mut V,
469 lhs: &'mir mut Expression<T>,
470 rhs: &'mir mut Expression<T>,
471) where
472 V: Visit<'mir, T> + ?Sized,
473{
474 v.visit_expression(lhs);
475 v.visit_expression(rhs);
476}
477
478pub fn visit_expression_int_add<'mir, T, V>(
479 v: &mut V,
480 lhs: &'mir mut Expression<T>,
481 rhs: &'mir mut Expression<T>,
482) where
483 V: Visit<'mir, T> + ?Sized,
484{
485 v.visit_expression(lhs);
486 v.visit_expression(rhs);
487}
488
489pub fn visit_expression_int_sub<'mir, T, V>(
490 v: &mut V,
491 lhs: &'mir mut Expression<T>,
492 rhs: &'mir mut Expression<T>,
493) where
494 V: Visit<'mir, T> + ?Sized,
495{
496 v.visit_expression(lhs);
497 v.visit_expression(rhs);
498}
499
500pub fn visit_expression_int_mul<'mir, T, V>(
501 v: &mut V,
502 lhs: &'mir mut Expression<T>,
503 rhs: &'mir mut Expression<T>,
504) where
505 V: Visit<'mir, T> + ?Sized,
506{
507 v.visit_expression(lhs);
508 v.visit_expression(rhs);
509}
510
511pub fn visit_expression_int_div<'mir, T, V>(
512 v: &mut V,
513 lhs: &'mir mut Expression<T>,
514 rhs: &'mir mut Expression<T>,
515) where
516 V: Visit<'mir, T> + ?Sized,
517{
518 v.visit_expression(lhs);
519 v.visit_expression(rhs);
520}
521
522pub fn visit_expression_int_rem<'mir, T, V>(
523 v: &mut V,
524 lhs: &'mir mut Expression<T>,
525 rhs: &'mir mut Expression<T>,
526) where
527 V: Visit<'mir, T> + ?Sized,
528{
529 v.visit_expression(lhs);
530 v.visit_expression(rhs);
531}
532
533pub fn visit_expression_float_gt<'mir, T, V>(
534 v: &mut V,
535 lhs: &'mir mut Expression<T>,
536 rhs: &'mir mut Expression<T>,
537) where
538 V: Visit<'mir, T> + ?Sized,
539{
540 v.visit_expression(lhs);
541 v.visit_expression(rhs);
542}
543
544pub fn visit_expression_float_gt_eq<'mir, T, V>(
545 v: &mut V,
546 lhs: &'mir mut Expression<T>,
547 rhs: &'mir mut Expression<T>,
548) where
549 V: Visit<'mir, T> + ?Sized,
550{
551 v.visit_expression(lhs);
552 v.visit_expression(rhs);
553}
554
555pub fn visit_expression_float_lt<'mir, T, V>(
556 v: &mut V,
557 lhs: &'mir mut Expression<T>,
558 rhs: &'mir mut Expression<T>,
559) where
560 V: Visit<'mir, T> + ?Sized,
561{
562 v.visit_expression(lhs);
563 v.visit_expression(rhs);
564}
565
566pub fn visit_expression_float_lt_eq<'mir, T, V>(
567 v: &mut V,
568 lhs: &'mir mut Expression<T>,
569 rhs: &'mir mut Expression<T>,
570) where
571 V: Visit<'mir, T> + ?Sized,
572{
573 v.visit_expression(lhs);
574 v.visit_expression(rhs);
575}
576
577pub fn visit_expression_float_add<'mir, T, V>(
578 v: &mut V,
579 lhs: &'mir mut Expression<T>,
580 rhs: &'mir mut Expression<T>,
581) where
582 V: Visit<'mir, T> + ?Sized,
583{
584 v.visit_expression(lhs);
585 v.visit_expression(rhs);
586}
587
588pub fn visit_expression_float_sub<'mir, T, V>(
589 v: &mut V,
590 lhs: &'mir mut Expression<T>,
591 rhs: &'mir mut Expression<T>,
592) where
593 V: Visit<'mir, T> + ?Sized,
594{
595 v.visit_expression(lhs);
596 v.visit_expression(rhs);
597}
598
599pub fn visit_expression_float_mul<'mir, T, V>(
600 v: &mut V,
601 lhs: &'mir mut Expression<T>,
602 rhs: &'mir mut Expression<T>,
603) where
604 V: Visit<'mir, T> + ?Sized,
605{
606 v.visit_expression(lhs);
607 v.visit_expression(rhs);
608}
609
610pub fn visit_expression_float_div<'mir, T, V>(
611 v: &mut V,
612 lhs: &'mir mut Expression<T>,
613 rhs: &'mir mut Expression<T>,
614) where
615 V: Visit<'mir, T> + ?Sized,
616{
617 v.visit_expression(lhs);
618 v.visit_expression(rhs);
619}
620
621pub fn visit_expression_string_concat<'mir, T, V>(
622 v: &mut V,
623 lhs: &'mir mut Expression<T>,
624 rhs: &'mir mut Expression<T>,
625) where
626 V: Visit<'mir, T> + ?Sized,
627{
628 v.visit_expression(lhs);
629 v.visit_expression(rhs);
630}
631
632pub fn visit_expression_list<'mir, T, V>(
633 v: &mut V,
634 items: &'mir mut Vec<Expression<T>>,
635 tail: &'mir mut Option<Box<Expression<T>>>,
636 _type_: &'mir mut T,
637) where
638 V: Visit<'mir, T> + ?Sized,
639{
640 for item in items {
641 v.visit_expression(item);
642 }
643 if let Some(tail) = tail {
644 v.visit_expression(tail);
645 }
646}
647
648pub fn visit_expression_tuple<'mir, T, V>(
649 v: &mut V,
650 items: &'mir mut Vec<Expression<T>>,
651 _type: &'mir mut T,
652) where
653 V: Visit<'mir, T> + ?Sized,
654{
655 for item in items {
656 v.visit_expression(item);
657 }
658}
659
660pub fn visit_expression_tuple_access<'mir, T, V>(
661 v: &mut V,
662 value: &'mir mut Expression<T>,
663 _index: &'mir mut u64,
664 _type: &'mir mut T,
665) where
666 V: Visit<'mir, T> + ?Sized,
667{
668 v.visit_expression(value);
669}
670
671pub fn visit_expression_struct<'mir, T, V>(
672 v: &mut V,
673 _tag: &'mir mut u32,
674 items: &'mir mut Vec<Expression<T>>,
675 _type: &'mir mut T,
676) where
677 V: Visit<'mir, T> + ?Sized,
678{
679 for item in items {
680 v.visit_expression(item);
681 }
682}
683
684pub fn visit_expression_struct_tag<'mir, T, V>(v: &mut V, value: &'mir mut Expression<T>)
685where
686 V: Visit<'mir, T> + ?Sized,
687{
688 v.visit_expression(value);
689}
690
691pub fn visit_expression_struct_access<'mir, T, V>(
692 v: &mut V,
693 value: &'mir mut Expression<T>,
694 _index: &'mir mut u64,
695 _type: &'mir mut T,
696) where
697 V: Visit<'mir, T> + ?Sized,
698{
699 v.visit_expression(value);
700}
701
702pub fn visit_expression_set<'mir, T, V>(
703 v: &mut V,
704 _name: &'mir mut Var<T>,
705 value: &'mir mut Expression<T>,
706) where
707 V: Visit<'mir, T> + ?Sized,
708{
709 v.visit_expression(value);
710}
711
712pub fn visit_expression_if<'mir, T, V>(
713 v: &mut V,
714 cond: &'mir mut Expression<T>,
715 then: &'mir mut Expression<T>,
716 else_: &'mir mut Expression<T>,
717) where
718 V: Visit<'mir, T> + ?Sized,
719{
720 v.visit_expression(cond);
721 v.visit_expression(then);
722 v.visit_expression(else_);
723}
724
725pub fn visit_expression_call<'mir, T, V>(
726 v: &mut V,
727 target: &'mir mut Expression<T>,
728 args: &'mir mut Vec<Expression<T>>,
729 _type_: &'mir mut T,
730) where
731 V: Visit<'mir, T> + ?Sized,
732{
733 v.visit_expression(target);
734 for arg in args {
735 v.visit_expression(arg);
736 }
737}
738
739pub fn visit_expression_panic<'mir, T, V>(_v: &mut V, _type_: &'mir mut T)
740where
741 V: Visit<'mir, T> + ?Sized,
742{
743}