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