use ecow::EcoString; use num_bigint::BigInt; use crate::cranelift::mir::ast::{Expression, Function, Module, Var}; pub trait Visit<'mir, T> { 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, type_: &mut T, ) { visit_expression_function_ref(self, module, name, arity, type_); } 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>>, type_: &'mir mut T, ) { visit_expression_list(self, items, tail, type_); } fn visit_expression_tuple(&mut self, items: &'mir mut Vec>, type_: &'mir mut T) { visit_expression_tuple(self, items, type_); } fn visit_expression_tuple_access( &mut self, value: &'mir mut Expression, index: &'mir mut u64, type_: &'mir mut T, ) { visit_expression_tuple_access(self, value, index, type_); } fn visit_expression_struct( &mut self, tag: &'mir mut u32, items: &'mir mut Vec>, type_: &'mir mut T, ) { visit_expression_struct(self, tag, items, type_); } fn visit_expression_struct_tag(&mut self, value: &'mir mut Expression) { visit_expression_struct_tag(self, value); } fn visit_expression_struct_access( &mut self, value: &'mir mut Expression, index: &'mir mut u64, type_: &'mir mut T, ) { visit_expression_struct_access(self, value, index, type_); } 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>, type_: &'mir mut T, ) { visit_expression_call(self, target, args, type_); } fn visit_expression_panic(&mut self, type_: &'mir mut T) { visit_expression_panic(self, type_); } } pub fn visit_module<'mir, T, V>(v: &mut V, module: &'mir mut Module) where V: Visit<'mir, T> + ?Sized, { for function in &mut module.functions { v.visit_function(function); } } pub fn visit_function<'mir, T, V>(v: &mut V, function: &'mir mut Function) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(&mut function.body); } pub fn visit_expression<'mir, T, V>(v: &mut V, expression: &'mir mut Expression) where V: Visit<'mir, T> + ?Sized, { match expression { Expression::Block(expressions) => v.visit_expression_block(expressions), Expression::FunctionRef { module, name, arity, type_, } => v.visit_expression_function_ref(module, name, arity, type_), 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, type_ } => v.visit_expression_list(items, tail, type_), Expression::Tuple { items, type_ } => v.visit_expression_tuple(items, type_), Expression::TupleAccess { value, index, type_, } => v.visit_expression_tuple_access(value, index, type_), Expression::Struct { tag, items, type_ } => v.visit_expression_struct(tag, items, type_), Expression::StructTag { value } => v.visit_expression_struct_tag(value), Expression::StructAccess { value, index, type_, } => v.visit_expression_struct_access(value, index, type_), 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, type_, } => v.visit_expression_call(target, args, type_), Expression::Panic { type_ } => v.visit_expression_panic(type_), } } pub fn visit_expression_block<'mir, T, V>(v: &mut V, expressions: &'mir mut Vec>) where V: Visit<'mir, T> + ?Sized, { for expression in expressions { v.visit_expression(expression); } } pub fn visit_expression_function_ref<'mir, T, V>( _v: &mut V, _module: &mut EcoString, _name: &mut EcoString, _arity: &mut usize, _type: &mut T, ) where V: Visit<'mir, T> + ?Sized, { } pub fn visit_expression_var<'mir, T, V>(_v: &mut V, _var: &mut Var) where V: Visit<'mir, T> + ?Sized, { } pub fn visit_expression_int<'mir, T, V>(_v: &mut V, _value: &mut BigInt) where V: Visit<'mir, T> + ?Sized, { } pub fn visit_expression_float<'mir, T, V>(_v: &mut V, _value: &mut EcoString) where V: Visit<'mir, T> + ?Sized, { } pub fn visit_expression_bool<'mir, T, V>(_v: &mut V, _value: &mut bool) where V: Visit<'mir, T> + ?Sized, { } pub fn visit_expression_string<'mir, T, V>(_v: &mut V, _value: &mut EcoString) where V: Visit<'mir, T> + ?Sized, { } pub fn visit_expression_equals<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_not_equals<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_gt<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_gt_eq<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_lt<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_lt_eq<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_add<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_sub<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_mul<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_div<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_int_rem<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_gt<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_gt_eq<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_lt<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_lt_eq<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_add<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_sub<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_mul<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_float_div<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_string_concat<'mir, T, V>( v: &mut V, lhs: &'mir mut Expression, rhs: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(lhs); v.visit_expression(rhs); } pub fn visit_expression_list<'mir, T, V>( v: &mut V, items: &'mir mut Vec>, tail: &'mir mut Option>>, _type_: &'mir mut T, ) where V: Visit<'mir, T> + ?Sized, { for item in items { v.visit_expression(item); } if let Some(tail) = tail { v.visit_expression(tail); } } pub fn visit_expression_tuple<'mir, T, V>( v: &mut V, items: &'mir mut Vec>, _type: &'mir mut T, ) where V: Visit<'mir, T> + ?Sized, { for item in items { v.visit_expression(item); } } pub fn visit_expression_tuple_access<'mir, T, V>( v: &mut V, value: &'mir mut Expression, _index: &'mir mut u64, _type: &'mir mut T, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(value); } pub fn visit_expression_struct<'mir, T, V>( v: &mut V, _tag: &'mir mut u32, items: &'mir mut Vec>, _type: &'mir mut T, ) where V: Visit<'mir, T> + ?Sized, { for item in items { v.visit_expression(item); } } pub fn visit_expression_struct_tag<'mir, T, V>(v: &mut V, value: &'mir mut Expression) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(value); } pub fn visit_expression_struct_access<'mir, T, V>( v: &mut V, value: &'mir mut Expression, _index: &'mir mut u64, _type: &'mir mut T, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(value); } pub fn visit_expression_set<'mir, T, V>( v: &mut V, _name: &'mir mut Var, value: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(value); } pub fn visit_expression_if<'mir, T, V>( v: &mut V, cond: &'mir mut Expression, then: &'mir mut Expression, else_: &'mir mut Expression, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(cond); v.visit_expression(then); v.visit_expression(else_); } pub fn visit_expression_call<'mir, T, V>( v: &mut V, target: &'mir mut Expression, args: &'mir mut Vec>, _type_: &'mir mut T, ) where V: Visit<'mir, T> + ?Sized, { v.visit_expression(target); for arg in args { v.visit_expression(arg); } } pub fn visit_expression_panic<'mir, T, V>(_v: &mut V, _type_: &'mir mut T) where V: Visit<'mir, T> + ?Sized, { }