1use super::Expression;
2
3impl Expression {
4 pub fn substitute_param(self, from_index: u32, substitute: &Expression) -> Expression {
9 macro_rules! sub {
10 ($e:expr) => {
11 Box::new((*$e).substitute_param(from_index, substitute))
12 };
13 }
14
15 macro_rules! binary {
16 ($variant:ident, $left:expr, $right:expr) => {
17 Expression::$variant {
18 left: sub!($left),
19 right: sub!($right),
20 }
21 };
22 }
23
24 macro_rules! unary {
25 ($variant:ident, $operand:expr) => {
26 Expression::$variant {
27 operand: sub!($operand),
28 }
29 };
30 }
31
32 match self {
33 Expression::Param { index } if index == from_index => substitute.clone(),
35 Expression::Param { index } => Expression::Param { index },
36
37 Expression::FieldAccess {
39 object,
40 class_name,
41 field_name,
42 field_type,
43 } => Expression::FieldAccess {
44 object: sub!(object),
45 class_name,
46 field_name,
47 field_type,
48 },
49
50 Expression::Eq { left, right } => binary!(Eq, left, right),
52 Expression::Ne { left, right } => binary!(Ne, left, right),
53 Expression::Lt { left, right } => binary!(Lt, left, right),
54 Expression::Le { left, right } => binary!(Le, left, right),
55 Expression::Gt { left, right } => binary!(Gt, left, right),
56 Expression::Ge { left, right } => binary!(Ge, left, right),
57
58 Expression::Eq64 { left, right } => binary!(Eq64, left, right),
60 Expression::Ne64 { left, right } => binary!(Ne64, left, right),
61 Expression::Lt64 { left, right } => binary!(Lt64, left, right),
62 Expression::Le64 { left, right } => binary!(Le64, left, right),
63 Expression::Gt64 { left, right } => binary!(Gt64, left, right),
64 Expression::Ge64 { left, right } => binary!(Ge64, left, right),
65
66 Expression::Add { left, right } => binary!(Add, left, right),
68 Expression::Sub { left, right } => binary!(Sub, left, right),
69 Expression::Mul { left, right } => binary!(Mul, left, right),
70 Expression::Div { left, right } => binary!(Div, left, right),
71
72 Expression::Add64 { left, right } => binary!(Add64, left, right),
74 Expression::Sub64 { left, right } => binary!(Sub64, left, right),
75 Expression::Mul64 { left, right } => binary!(Mul64, left, right),
76 Expression::Div64 { left, right } => binary!(Div64, left, right),
77
78 Expression::FloatAdd { left, right } => binary!(FloatAdd, left, right),
80 Expression::FloatSub { left, right } => binary!(FloatSub, left, right),
81 Expression::FloatMul { left, right } => binary!(FloatMul, left, right),
82 Expression::FloatDiv { left, right } => binary!(FloatDiv, left, right),
83
84 Expression::Sqrt { operand } => unary!(Sqrt, operand),
86 Expression::FloatAbs { operand } => unary!(FloatAbs, operand),
87 Expression::Round { operand } => unary!(Round, operand),
88 Expression::Floor { operand } => unary!(Floor, operand),
89 Expression::Ceil { operand } => unary!(Ceil, operand),
90 Expression::Sin { operand } => unary!(Sin, operand),
91 Expression::Cos { operand } => unary!(Cos, operand),
92 Expression::Asin { operand } => unary!(Asin, operand),
93 Expression::Acos { operand } => unary!(Acos, operand),
94 Expression::Atan { operand } => unary!(Atan, operand),
95 Expression::Radians { operand } => unary!(Radians, operand),
96 Expression::IntToFloat { operand } => unary!(IntToFloat, operand),
97 Expression::FloatToInt { operand } => unary!(FloatToInt, operand),
98
99 Expression::Atan2 { y, x } => Expression::Atan2 {
101 y: sub!(y),
102 x: sub!(x),
103 },
104
105 Expression::And { left, right } => binary!(And, left, right),
107 Expression::Or { left, right } => binary!(Or, left, right),
108 Expression::Not { operand } => unary!(Not, operand),
109 Expression::IsNull { operand } => unary!(IsNull, operand),
110 Expression::IsNotNull { operand } => unary!(IsNotNull, operand),
111 Expression::IsNull64 { operand } => unary!(IsNull64, operand),
112 Expression::IsNotNull64 { operand } => unary!(IsNotNull64, operand),
113
114 Expression::HostCall {
116 function_name,
117 args,
118 } => Expression::HostCall {
119 function_name,
120 args: args
121 .into_iter()
122 .map(|arg| arg.substitute_param(from_index, substitute))
123 .collect(),
124 },
125
126 Expression::ListContains { list, element } => Expression::ListContains {
128 list: sub!(list),
129 element: sub!(element),
130 },
131 Expression::Length { collection } => Expression::Length {
132 collection: sub!(collection),
133 },
134
135 Expression::Sum {
137 collection,
138 item_var_name,
139 item_param_index,
140 item_class_name,
141 accumulator_expr,
142 } => {
143 let new_index = if from_index < item_param_index {
144 item_param_index - 1
145 } else {
146 item_param_index
147 };
148
149 Expression::Sum {
150 collection: sub!(collection),
151 item_var_name,
152 item_param_index: new_index,
153 item_class_name,
154 accumulator_expr: sub!(accumulator_expr),
155 }
156 }
157
158 Expression::LastElement {
159 collection,
160 item_class_name,
161 } => Expression::LastElement {
162 collection: sub!(collection),
163 item_class_name,
164 },
165
166 Expression::IfThenElse {
168 condition,
169 then_branch,
170 else_branch,
171 } => Expression::IfThenElse {
172 condition: sub!(condition),
173 then_branch: sub!(then_branch),
174 else_branch: sub!(else_branch),
175 },
176 Expression::IfThenElse64 {
177 condition,
178 then_branch,
179 else_branch,
180 } => Expression::IfThenElse64 {
181 condition: sub!(condition),
182 then_branch: sub!(then_branch),
183 else_branch: sub!(else_branch),
184 },
185
186 Expression::I64ToI32 { operand } => unary!(I64ToI32, operand),
188 Expression::I32ToI64 { operand } => unary!(I32ToI64, operand),
189
190 Expression::Null
192 | Expression::BoolLiteral { .. }
193 | Expression::IntLiteral { .. }
194 | Expression::Int64Literal { .. }
195 | Expression::FloatLiteral { .. }
196 | Expression::StringLiteral { .. } => self,
197 }
198 }
199}