use ecow::EcoString; use num_bigint::BigInt; use crate::cranelift::mir::ast::{Expression, Function, Module, Var}; pub trait Visit<'mir> { fn visit_module(&mut self, module: &'mir mut Module) { visit_module(self, module); } fn visit_function(&mut self, function: &'mir mut Function) { visit_function(self, function); } fn visit_expression(&mut self, expression: &'mir mut Expression) { visit_expression(self, expression); } fn visit_expression_block(&mut self, expressions: &'mir mut Vec) { visit_expression_block(self, expressions); } fn visit_expression_function_ref( &mut self, module: &mut EcoString, name: &mut EcoString, arity: &mut usize, ) { visit_expression_function_ref(self, module, name, arity); } fn visit_expression_var(&mut self, var: &'mir mut Var) { visit_expression_var(self, var); } fn visit_expression_int(&mut self, value: &'mir mut BigInt) { visit_expression_int(self, value); } fn visit_expression_float(&mut self, value: &'mir mut EcoString) { visit_expression_float(self, value); } fn visit_expression_bool(&mut self, value: &'mir mut bool) { visit_expression_bool(self, value); } fn visit_expression_string(&mut self, value: &'mir mut EcoString) { visit_expression_string(self, value); } fn visit_expression_equals(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_equals(self, lhs, rhs); } fn visit_expression_not_equals( &mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) { visit_expression_not_equals(self, lhs, rhs); } fn visit_expression_int_gt(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_int_gt(self, lhs, rhs); } fn visit_expression_int_gt_eq(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_int_gt_eq(self, lhs, rhs); } fn visit_expression_int_lt(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_int_lt(self, lhs, rhs); } fn visit_expression_int_lt_eq(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_int_lt_eq(self, lhs, rhs); } fn visit_expression_int_add(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_int_add(self, lhs, rhs); } fn visit_expression_int_sub(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_int_sub(self, lhs, rhs); } fn visit_expression_int_mul(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_int_mul(self, lhs, rhs); } fn visit_expression_int_div(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_int_div(self, lhs, rhs); } fn visit_expression_int_rem(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_int_rem(self, lhs, rhs); } fn visit_expression_float_gt(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_float_gt(self, lhs, rhs); } fn visit_expression_float_gt_eq( &mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) { visit_expression_float_gt_eq(self, lhs, rhs); } fn visit_expression_float_lt(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_float_lt(self, lhs, rhs); } fn visit_expression_float_lt_eq( &mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) { visit_expression_float_lt_eq(self, lhs, rhs); } fn visit_expression_float_add(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_float_add(self, lhs, rhs); } fn visit_expression_float_sub(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_float_sub(self, lhs, rhs); } fn visit_expression_float_mul(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_float_mul(self, lhs, rhs); } fn visit_expression_float_div(&mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression) { visit_expression_float_div(self, lhs, rhs); } fn visit_expression_string_concat( &mut self, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) { visit_expression_string_concat(self, lhs, rhs); } fn visit_expression_list( &mut self, items: &'mir mut Vec, tail: &'mir mut Option>, ) { visit_expression_list(self, items, tail); } fn visit_expression_struct( &mut self, tag: &'mir mut Option, items: &'mir mut Vec, ) { visit_expression_struct(self, tag, items); } fn visit_expression_struct_access( &mut self, value: &'mir mut Expression, index: &'mir mut u64, ) { visit_expression_struct_access(self, value, index); } fn visit_expression_set(&mut self, name: &'mir mut Var, value: &'mir mut Expression) { visit_expression_set(self, name, value); } fn visit_expression_if( &mut self, cond: &'mir mut Expression, then: &'mir mut Expression, else_: &'mir mut Expression, ) { visit_expression_if(self, cond, then, else_); } fn visit_expression_call( &mut self, target: &'mir mut Expression, args: &'mir mut Vec, ) { visit_expression_call(self, target, args); } } pub fn visit_module<'mir, V>(v: &mut V, module: &'mir mut Module) where V: Visit<'mir> + ?Sized, { for function in &mut module.functions { v.visit_function(function); } } pub fn visit_function<'mir, V>(v: &mut V, function: &'mir mut Function) where V: Visit<'mir> + ?Sized, { v.visit_expression(&mut function.body); } pub fn visit_expression<'mir, V>(v: &mut V, expression: &'mir mut Expression) where V: Visit<'mir> + ?Sized, { match expression { Expression::Block(expressions) => v.visit_expression_block(expressions), Expression::FunctionRef { module, name, arity, } => v.visit_expression_function_ref(module, name, arity), Expression::Var(var) => v.visit_expression_var(var), Expression::Int { value } => v.visit_expression_int(value), Expression::Float { value } => v.visit_expression_float(value), Expression::Bool { value } => v.visit_expression_bool(value), Expression::String { value } => v.visit_expression_string(value), Expression::Equals { lhs, rhs } => v.visit_expression_equals(lhs, rhs), Expression::NotEquals { lhs, rhs } => v.visit_expression_not_equals(lhs, rhs), Expression::IntGt { lhs, rhs } => v.visit_expression_int_gt(lhs, rhs), Expression::IntGtEq { lhs, rhs } => v.visit_expression_int_gt_eq(lhs, rhs), Expression::IntLt { lhs, rhs } => v.visit_expression_int_lt(lhs, rhs), Expression::IntLtEq { lhs, rhs } => v.visit_expression_int_lt_eq(lhs, rhs), Expression::IntAdd { lhs, rhs } => v.visit_expression_int_add(lhs, rhs), Expression::IntSub { lhs, rhs } => v.visit_expression_int_sub(lhs, rhs), Expression::IntMul { lhs, rhs } => v.visit_expression_int_mul(lhs, rhs), Expression::IntDiv { lhs, rhs } => v.visit_expression_int_div(lhs, rhs), Expression::IntRem { lhs, rhs } => v.visit_expression_int_rem(lhs, rhs), Expression::FloatGt { lhs, rhs } => v.visit_expression_float_gt(lhs, rhs), Expression::FloatGtEq { lhs, rhs } => v.visit_expression_float_gt_eq(lhs, rhs), Expression::FloatLt { lhs, rhs } => v.visit_expression_float_lt(lhs, rhs), Expression::FloatLtEq { lhs, rhs } => v.visit_expression_float_lt_eq(lhs, rhs), Expression::FloatAdd { lhs, rhs } => v.visit_expression_float_add(lhs, rhs), Expression::FloatSub { lhs, rhs } => v.visit_expression_float_sub(lhs, rhs), Expression::FloatMul { lhs, rhs } => v.visit_expression_float_mul(lhs, rhs), Expression::FloatDiv { lhs, rhs } => v.visit_expression_float_div(lhs, rhs), Expression::StringConcat { lhs, rhs } => v.visit_expression_string_concat(lhs, rhs), Expression::List { items, tail } => v.visit_expression_list(items, tail), Expression::Struct { tag, items } => v.visit_expression_struct(tag, items), Expression::StructAccess { value, index } => v.visit_expression_struct_access(value, index), Expression::Set { name, value } => v.visit_expression_set(name, value), Expression::If { cond, then, else_ } => v.visit_expression_if(cond, then, else_), Expression::Call { target, args } => v.visit_expression_call(target, args), } } pub fn visit_expression_block<'mir, V>(v: &mut V, expressions: &'mir mut Vec) where V: Visit<'mir> + ?Sized, { for expression in expressions { v.visit_expression(expression); } } pub fn visit_expression_function_ref<'mir, V>( _v: &mut V, _module: &mut EcoString, _name: &mut EcoString, _arity: &mut usize, ) where V: Visit<'mir> + ?Sized, { } pub fn visit_expression_var<'mir, V>(_v: &mut V, _var: &mut Var) where V: Visit<'mir> + ?Sized, { } pub fn visit_expression_int<'mir, V>(_v: &mut V, _value: &mut BigInt) where V: Visit<'mir> + ?Sized, { } pub fn visit_expression_float<'mir, V>(_v: &mut V, _value: &mut EcoString) where V: Visit<'mir> + ?Sized, { } pub fn visit_expression_bool<'mir, V>(_v: &mut V, _value: &mut bool) where V: Visit<'mir> + ?Sized, { } pub fn visit_expression_string<'mir, V>(_v: &mut V, _value: &mut EcoString) where V: Visit<'mir> + ?Sized, { } pub fn visit_expression_equals<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_not_equals<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_gt<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_gt_eq<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_lt<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_lt_eq<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_add<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_sub<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_mul<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_div<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_rem<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_gt<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_gt_eq<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_lt<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_lt_eq<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_add<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_sub<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_mul<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_div<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_string_concat<'mir, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_list<'mir, V>( v: &mut V, items: &'mir mut Vec, tail: &'mir mut Option>, ) where V: Visit<'mir> + ?Sized, { for item in items { v.visit_expression(item); } if let Some(tail) = tail { v.visit_expression(tail); } } pub fn visit_expression_struct<'mir, V>( v: &mut V, _tag: &'mir mut Option, items: &'mir mut Vec, ) where V: Visit<'mir> + ?Sized, { for item in items { v.visit_expression(item); } } pub fn visit_expression_struct_access<'mir, V>( v: &mut V, value: &'mir mut Expression, _index: &'mir mut u64, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(value); } pub fn visit_expression_set<'mir, V>(v: &mut V, _name: &'mir mut Var, value: &'mir mut Expression) where V: Visit<'mir> + ?Sized, { v.visit_expression(value); } pub fn visit_expression_if<'mir, V>( v: &mut V, cond: &'mir mut Expression, then: &'mir mut Expression, else_: &'mir mut Expression, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(cond); v.visit_expression(then); v.visit_expression(else_); } pub fn visit_expression_call<'mir, V>( v: &mut V, target: &'mir mut Expression, args: &'mir mut Vec, ) where V: Visit<'mir> + ?Sized, { v.visit_expression(target); for arg in args { v.visit_expression(arg); } }