Fork of daniellemaywood.uk/gleam — Wasm codegen work
16 kB
592 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_access(
165 &mut self,
166 value: &'mir mut Expression,
167 index: &'mir mut u64,
168 ) {
169 visit_expression_struct_access(self, value, index);
170 }
171
172 fn visit_expression_set(&mut self, name: &'mir mut Var, value: &'mir mut Expression) {
173 visit_expression_set(self, name, value);
174 }
175
176 fn visit_expression_if(
177 &mut self,
178 cond: &'mir mut Expression,
179 then: &'mir mut Expression,
180 else_: &'mir mut Expression,
181 ) {
182 visit_expression_if(self, cond, then, else_);
183 }
184
185 fn visit_expression_call(
186 &mut self,
187 target: &'mir mut Expression,
188 args: &'mir mut Vec<Expression>,
189 ) {
190 visit_expression_call(self, target, args);
191 }
192}
193
194pub fn visit_module<'mir, V>(v: &mut V, module: &'mir mut Module)
195where
196 V: Visit<'mir> + ?Sized,
197{
198 for function in &mut module.functions {
199 v.visit_function(function);
200 }
201}
202
203pub fn visit_function<'mir, V>(v: &mut V, function: &'mir mut Function)
204where
205 V: Visit<'mir> + ?Sized,
206{
207 v.visit_expression(&mut function.body);
208}
209
210pub fn visit_expression<'mir, V>(v: &mut V, expression: &'mir mut Expression)
211where
212 V: Visit<'mir> + ?Sized,
213{
214 match expression {
215 Expression::Block(expressions) => v.visit_expression_block(expressions),
216 Expression::FunctionRef {
217 module,
218 name,
219 arity,
220 } => v.visit_expression_function_ref(module, name, arity),
221 Expression::Var(var) => v.visit_expression_var(var),
222 Expression::Int { value } => v.visit_expression_int(value),
223 Expression::Float { value } => v.visit_expression_float(value),
224 Expression::Bool { value } => v.visit_expression_bool(value),
225 Expression::String { value } => v.visit_expression_string(value),
226 Expression::Equals { lhs, rhs } => v.visit_expression_equals(lhs, rhs),
227 Expression::NotEquals { lhs, rhs } => v.visit_expression_not_equals(lhs, rhs),
228 Expression::IntGt { lhs, rhs } => v.visit_expression_int_gt(lhs, rhs),
229 Expression::IntGtEq { lhs, rhs } => v.visit_expression_int_gt_eq(lhs, rhs),
230 Expression::IntLt { lhs, rhs } => v.visit_expression_int_lt(lhs, rhs),
231 Expression::IntLtEq { lhs, rhs } => v.visit_expression_int_lt_eq(lhs, rhs),
232 Expression::IntAdd { lhs, rhs } => v.visit_expression_int_add(lhs, rhs),
233 Expression::IntSub { lhs, rhs } => v.visit_expression_int_sub(lhs, rhs),
234 Expression::IntMul { lhs, rhs } => v.visit_expression_int_mul(lhs, rhs),
235 Expression::IntDiv { lhs, rhs } => v.visit_expression_int_div(lhs, rhs),
236 Expression::IntRem { lhs, rhs } => v.visit_expression_int_rem(lhs, rhs),
237 Expression::FloatGt { lhs, rhs } => v.visit_expression_float_gt(lhs, rhs),
238 Expression::FloatGtEq { lhs, rhs } => v.visit_expression_float_gt_eq(lhs, rhs),
239 Expression::FloatLt { lhs, rhs } => v.visit_expression_float_lt(lhs, rhs),
240 Expression::FloatLtEq { lhs, rhs } => v.visit_expression_float_lt_eq(lhs, rhs),
241 Expression::FloatAdd { lhs, rhs } => v.visit_expression_float_add(lhs, rhs),
242 Expression::FloatSub { lhs, rhs } => v.visit_expression_float_sub(lhs, rhs),
243 Expression::FloatMul { lhs, rhs } => v.visit_expression_float_mul(lhs, rhs),
244 Expression::FloatDiv { lhs, rhs } => v.visit_expression_float_div(lhs, rhs),
245 Expression::StringConcat { lhs, rhs } => v.visit_expression_string_concat(lhs, rhs),
246 Expression::List { items, tail } => v.visit_expression_list(items, tail),
247 Expression::Struct { tag, items } => v.visit_expression_struct(tag, items),
248 Expression::StructAccess { value, index } => v.visit_expression_struct_access(value, index),
249 Expression::Set { name, value } => v.visit_expression_set(name, value),
250 Expression::If { cond, then, else_ } => v.visit_expression_if(cond, then, else_),
251 Expression::Call { target, args } => v.visit_expression_call(target, args),
252 }
253}
254
255pub fn visit_expression_block<'mir, V>(v: &mut V, expressions: &'mir mut Vec<Expression>)
256where
257 V: Visit<'mir> + ?Sized,
258{
259 for expression in expressions {
260 v.visit_expression(expression);
261 }
262}
263
264pub fn visit_expression_function_ref<'mir, V>(
265 _v: &mut V,
266 _module: &mut EcoString,
267 _name: &mut EcoString,
268 _arity: &mut usize,
269) where
270 V: Visit<'mir> + ?Sized,
271{
272}
273
274pub fn visit_expression_var<'mir, V>(_v: &mut V, _var: &mut Var)
275where
276 V: Visit<'mir> + ?Sized,
277{
278}
279
280pub fn visit_expression_int<'mir, V>(_v: &mut V, _value: &mut BigInt)
281where
282 V: Visit<'mir> + ?Sized,
283{
284}
285
286pub fn visit_expression_float<'mir, V>(_v: &mut V, _value: &mut EcoString)
287where
288 V: Visit<'mir> + ?Sized,
289{
290}
291
292pub fn visit_expression_bool<'mir, V>(_v: &mut V, _value: &mut bool)
293where
294 V: Visit<'mir> + ?Sized,
295{
296}
297
298pub fn visit_expression_string<'mir, V>(_v: &mut V, _value: &mut EcoString)
299where
300 V: Visit<'mir> + ?Sized,
301{
302}
303
304pub fn visit_expression_equals<'mir, V>(
305 v: &mut V,
306 lhs: &'mir mut Expression,
307 rhs: &'mir mut Expression,
308) where
309 V: Visit<'mir> + ?Sized,
310{
311 v.visit_expression(lhs);
312 v.visit_expression(rhs);
313}
314
315pub fn visit_expression_not_equals<'mir, V>(
316 v: &mut V,
317 lhs: &'mir mut Expression,
318 rhs: &'mir mut Expression,
319) where
320 V: Visit<'mir> + ?Sized,
321{
322 v.visit_expression(lhs);
323 v.visit_expression(rhs);
324}
325
326pub fn visit_expression_int_gt<'mir, V>(
327 v: &mut V,
328 lhs: &'mir mut Expression,
329 rhs: &'mir mut Expression,
330) where
331 V: Visit<'mir> + ?Sized,
332{
333 v.visit_expression(lhs);
334 v.visit_expression(rhs);
335}
336
337pub fn visit_expression_int_gt_eq<'mir, V>(
338 v: &mut V,
339 lhs: &'mir mut Expression,
340 rhs: &'mir mut Expression,
341) where
342 V: Visit<'mir> + ?Sized,
343{
344 v.visit_expression(lhs);
345 v.visit_expression(rhs);
346}
347
348pub fn visit_expression_int_lt<'mir, V>(
349 v: &mut V,
350 lhs: &'mir mut Expression,
351 rhs: &'mir mut Expression,
352) where
353 V: Visit<'mir> + ?Sized,
354{
355 v.visit_expression(lhs);
356 v.visit_expression(rhs);
357}
358
359pub fn visit_expression_int_lt_eq<'mir, V>(
360 v: &mut V,
361 lhs: &'mir mut Expression,
362 rhs: &'mir mut Expression,
363) where
364 V: Visit<'mir> + ?Sized,
365{
366 v.visit_expression(lhs);
367 v.visit_expression(rhs);
368}
369
370pub fn visit_expression_int_add<'mir, V>(
371 v: &mut V,
372 lhs: &'mir mut Expression,
373 rhs: &'mir mut Expression,
374) where
375 V: Visit<'mir> + ?Sized,
376{
377 v.visit_expression(lhs);
378 v.visit_expression(rhs);
379}
380
381pub fn visit_expression_int_sub<'mir, V>(
382 v: &mut V,
383 lhs: &'mir mut Expression,
384 rhs: &'mir mut Expression,
385) where
386 V: Visit<'mir> + ?Sized,
387{
388 v.visit_expression(lhs);
389 v.visit_expression(rhs);
390}
391
392pub fn visit_expression_int_mul<'mir, V>(
393 v: &mut V,
394 lhs: &'mir mut Expression,
395 rhs: &'mir mut Expression,
396) where
397 V: Visit<'mir> + ?Sized,
398{
399 v.visit_expression(lhs);
400 v.visit_expression(rhs);
401}
402
403pub fn visit_expression_int_div<'mir, V>(
404 v: &mut V,
405 lhs: &'mir mut Expression,
406 rhs: &'mir mut Expression,
407) where
408 V: Visit<'mir> + ?Sized,
409{
410 v.visit_expression(lhs);
411 v.visit_expression(rhs);
412}
413
414pub fn visit_expression_int_rem<'mir, V>(
415 v: &mut V,
416 lhs: &'mir mut Expression,
417 rhs: &'mir mut Expression,
418) where
419 V: Visit<'mir> + ?Sized,
420{
421 v.visit_expression(lhs);
422 v.visit_expression(rhs);
423}
424
425pub fn visit_expression_float_gt<'mir, V>(
426 v: &mut V,
427 lhs: &'mir mut Expression,
428 rhs: &'mir mut Expression,
429) where
430 V: Visit<'mir> + ?Sized,
431{
432 v.visit_expression(lhs);
433 v.visit_expression(rhs);
434}
435
436pub fn visit_expression_float_gt_eq<'mir, V>(
437 v: &mut V,
438 lhs: &'mir mut Expression,
439 rhs: &'mir mut Expression,
440) where
441 V: Visit<'mir> + ?Sized,
442{
443 v.visit_expression(lhs);
444 v.visit_expression(rhs);
445}
446
447pub fn visit_expression_float_lt<'mir, V>(
448 v: &mut V,
449 lhs: &'mir mut Expression,
450 rhs: &'mir mut Expression,
451) where
452 V: Visit<'mir> + ?Sized,
453{
454 v.visit_expression(lhs);
455 v.visit_expression(rhs);
456}
457
458pub fn visit_expression_float_lt_eq<'mir, V>(
459 v: &mut V,
460 lhs: &'mir mut Expression,
461 rhs: &'mir mut Expression,
462) where
463 V: Visit<'mir> + ?Sized,
464{
465 v.visit_expression(lhs);
466 v.visit_expression(rhs);
467}
468
469pub fn visit_expression_float_add<'mir, V>(
470 v: &mut V,
471 lhs: &'mir mut Expression,
472 rhs: &'mir mut Expression,
473) where
474 V: Visit<'mir> + ?Sized,
475{
476 v.visit_expression(lhs);
477 v.visit_expression(rhs);
478}
479
480pub fn visit_expression_float_sub<'mir, V>(
481 v: &mut V,
482 lhs: &'mir mut Expression,
483 rhs: &'mir mut Expression,
484) where
485 V: Visit<'mir> + ?Sized,
486{
487 v.visit_expression(lhs);
488 v.visit_expression(rhs);
489}
490
491pub fn visit_expression_float_mul<'mir, V>(
492 v: &mut V,
493 lhs: &'mir mut Expression,
494 rhs: &'mir mut Expression,
495) where
496 V: Visit<'mir> + ?Sized,
497{
498 v.visit_expression(lhs);
499 v.visit_expression(rhs);
500}
501
502pub fn visit_expression_float_div<'mir, V>(
503 v: &mut V,
504 lhs: &'mir mut Expression,
505 rhs: &'mir mut Expression,
506) where
507 V: Visit<'mir> + ?Sized,
508{
509 v.visit_expression(lhs);
510 v.visit_expression(rhs);
511}
512
513pub fn visit_expression_string_concat<'mir, V>(
514 v: &mut V,
515 lhs: &'mir mut Expression,
516 rhs: &'mir mut Expression,
517) where
518 V: Visit<'mir> + ?Sized,
519{
520 v.visit_expression(lhs);
521 v.visit_expression(rhs);
522}
523
524pub fn visit_expression_list<'mir, V>(
525 v: &mut V,
526 items: &'mir mut Vec<Expression>,
527 tail: &'mir mut Option<Box<Expression>>,
528) where
529 V: Visit<'mir> + ?Sized,
530{
531 for item in items {
532 v.visit_expression(item);
533 }
534 if let Some(tail) = tail {
535 v.visit_expression(tail);
536 }
537}
538
539pub fn visit_expression_struct<'mir, V>(
540 v: &mut V,
541 _tag: &'mir mut Option<u32>,
542 items: &'mir mut Vec<Expression>,
543) where
544 V: Visit<'mir> + ?Sized,
545{
546 for item in items {
547 v.visit_expression(item);
548 }
549}
550
551pub fn visit_expression_struct_access<'mir, V>(
552 v: &mut V,
553 value: &'mir mut Expression,
554 _index: &'mir mut u64,
555) where
556 V: Visit<'mir> + ?Sized,
557{
558 v.visit_expression(value);
559}
560
561pub fn visit_expression_set<'mir, V>(v: &mut V, _name: &'mir mut Var, value: &'mir mut Expression)
562where
563 V: Visit<'mir> + ?Sized,
564{
565 v.visit_expression(value);
566}
567
568pub fn visit_expression_if<'mir, V>(
569 v: &mut V,
570 cond: &'mir mut Expression,
571 then: &'mir mut Expression,
572 else_: &'mir mut Expression,
573) where
574 V: Visit<'mir> + ?Sized,
575{
576 v.visit_expression(cond);
577 v.visit_expression(then);
578 v.visit_expression(else_);
579}
580
581pub fn visit_expression_call<'mir, V>(
582 v: &mut V,
583 target: &'mir mut Expression,
584 args: &'mir mut Vec<Expression>,
585) where
586 V: Visit<'mir> + ?Sized,
587{
588 v.visit_expression(target);
589 for arg in args {
590 v.visit_expression(arg);
591 }
592}