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