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