1use crate::expression_builders::build_anonymous_component;
2
3use super::ast::*;
4
5impl Expression {
6 pub fn get_meta(&self) -> &Meta {
7 use Expression::*;
8 match self {
9 InfixOp { meta, .. }
10 | PrefixOp { meta, .. }
11 | InlineSwitchOp { meta, .. }
12 | ParallelOp {meta, .. }
13 | Variable { meta, .. }
14 | Number(meta, ..)
15 | Call { meta, .. }
16 | AnonymousComp { meta, ..}
17 | ArrayInLine { meta, .. } => meta,
18 | UniformArray { meta, .. } => meta,
19 | Tuple {meta, ..} => meta,
20 }
21 }
22 pub fn get_mut_meta(&mut self) -> &mut Meta {
23 use Expression::*;
24 match self {
25 InfixOp { meta, .. }
26 | PrefixOp { meta, .. }
27 | InlineSwitchOp { meta, .. }
28 | ParallelOp {meta, .. }
29 | Variable { meta, .. }
30 | Number(meta, ..)
31 | Call { meta, .. }
32 | AnonymousComp {meta, ..}
33 | ArrayInLine { meta, .. } => meta,
34 | UniformArray { meta, .. } => meta,
35 | Tuple {meta, ..} => meta,
36 }
37 }
38
39 pub fn is_array(&self) -> bool {
40 use Expression::*;
41 if let ArrayInLine { .. } = self {
42 true
43 } else if let UniformArray { .. } = self{
44 true
45 } else {
46 false
47 }
48 }
49
50 pub fn is_infix(&self) -> bool {
51 use Expression::*;
52 if let InfixOp { .. } = self {
53 true
54 } else {
55 false
56 }
57 }
58
59 pub fn is_prefix(&self) -> bool {
60 use Expression::*;
61 if let PrefixOp { .. } = self {
62 true
63 } else {
64 false
65 }
66 }
67
68 pub fn is_tuple(&self) -> bool {
69 use Expression::*;
70 if let Tuple { .. } = self {
71 true
72 } else {
73 false
74 }
75 }
76 pub fn is_switch(&self) -> bool {
77 use Expression::*;
78 if let InlineSwitchOp { .. } = self {
79 true
80 } else {
81 false
82 }
83 }
84
85 pub fn is_parallel(&self) -> bool {
86 use Expression::*;
87 if let ParallelOp { .. } = self {
88 true
89 } else {
90 false
91 }
92 }
93
94 pub fn is_variable(&self) -> bool {
95 use Expression::*;
96 if let Variable { .. } = self {
97 true
98 } else {
99 false
100 }
101 }
102
103 pub fn is_number(&self) -> bool {
104 use Expression::*;
105 if let Number(..) = self {
106 true
107 } else {
108 false
109 }
110 }
111
112 pub fn is_call(&self) -> bool {
113 use Expression::*;
114 if let Call { .. } = self {
115 true
116 } else {
117 false
118 }
119 }
120
121 pub fn is_anonymous_comp(&self) -> bool {
122 use Expression::*;
123 if let AnonymousComp { .. } = self {
124 true
125 } else {
126 false
127 }
128 }
129
130 pub fn make_anonymous_parallel(self) -> Expression {
131 use Expression::*;
132 match self {
133 AnonymousComp { meta, id, params, signals, names, .. } => {
134 build_anonymous_component(meta, id, params, signals, names, true)
135 }
136 _ => self,
137 }
138 }
139
140 pub fn contains_anonymous_comp(&self) -> bool {
141 use Expression::*;
142 match &self {
143 InfixOp { lhe, rhe , ..} | UniformArray { value : lhe, dimension : rhe, .. } => {
144 lhe.contains_anonymous_comp() || rhe.contains_anonymous_comp()
145 },
146 PrefixOp { rhe, .. } => {
147 rhe.contains_anonymous_comp()
148 },
149 InlineSwitchOp { cond, if_true, if_false, .. } => {
150 cond.contains_anonymous_comp() || if_true.contains_anonymous_comp() || if_false.contains_anonymous_comp()
151 },
152 Call { args, .. } | Tuple {values: args, ..} | ArrayInLine { values : args, .. } => {
153 for arg in args{
154 if arg.contains_anonymous_comp() { return true;}
155 }
156 false
157 },
158 AnonymousComp { .. } => { true },
159 Variable { access, .. } => {
160 for ac in access{
161 match ac {
162 Access::ComponentAccess(_) => {},
163 Access::ArrayAccess( exp ) => if exp.contains_anonymous_comp() {return true;},
164 }
165 }
166 false
167 },
168 Number(_, _) => {false }
169 ParallelOp { rhe , .. } => { rhe.contains_anonymous_comp() },
170 }
171 }
172
173 pub fn contains_tuple(&self) -> bool {
174 use Expression::*;
175 match &self {
176 InfixOp { lhe, rhe , ..} | UniformArray { value : lhe, dimension : rhe, .. } => {
177 lhe.contains_tuple() || rhe.contains_tuple()
178 },
179 PrefixOp { rhe, .. } => {
180 rhe.contains_tuple()
181 },
182 InlineSwitchOp { cond, if_true, if_false, .. } => {
183 cond.contains_tuple() || if_true.contains_tuple() || if_false.contains_tuple()
184 },
185 Call { args, .. } | ArrayInLine { values : args, .. } => {
186 for arg in args{
187 if arg.contains_tuple() { return true;}
188 }
189 false
190 },
191 AnonymousComp { params, signals, .. } => {
192 for ac in params{
193 if ac.contains_tuple() {return true;}
194 }
195 for ac in signals{
196 if ac.contains_tuple() {return true;}
197 }
198 false
199 },
200 Variable { access, .. } => {
201 for ac in access{
202 match ac {
203 Access::ComponentAccess(_) => {},
204 Access::ArrayAccess( exp ) => if exp.contains_tuple() {return true;},
205 }
206 }
207 false
208 },
209 Number(_, _) => {false },
210 Tuple { .. } => {true},
211 ParallelOp { rhe, .. } => {rhe.contains_tuple()},
212 }
213 }
214}
215
216impl FillMeta for Expression {
217 fn fill(&mut self, file_id: usize, element_id: &mut usize) {
218 use Expression::*;
219 self.get_mut_meta().elem_id = *element_id;
220 *element_id += 1;
221 match self {
222 Number(meta, _) => fill_number(meta, file_id, element_id),
223 Variable { meta, access, .. } => fill_variable(meta, access, file_id, element_id),
224 InfixOp { meta, lhe, rhe, .. } => fill_infix(meta, lhe, rhe, file_id, element_id),
225 PrefixOp { meta, rhe, .. } => fill_prefix(meta, rhe, file_id, element_id),
226 ParallelOp{ meta, rhe, ..} => fill_parallel(meta, rhe, file_id, element_id),
227 InlineSwitchOp { meta, cond, if_false, if_true, .. } => {
228 fill_inline_switch_op(meta, cond, if_true, if_false, file_id, element_id)
229 }
230 Call { meta, args, .. } => fill_call(meta, args, file_id, element_id),
231 ArrayInLine { meta, values, .. } => {
232 fill_array_inline(meta, values, file_id, element_id)
233 }
234 UniformArray { meta, value, dimension, .. } => {
235 fill_uniform_array(meta, value, dimension, file_id, element_id)
236 }
237 AnonymousComp { meta, params, signals, .. } => {
238 fill_anonymous_comp(meta, params, signals, file_id, element_id)
239 },
240 Tuple { meta, values} => {fill_tuple(meta,values,file_id,element_id)}
241 }
242 }
243}
244
245fn fill_number(meta: &mut Meta, file_id: usize, _element_id: &mut usize) {
246 meta.set_file_id(file_id);
247}
248
249fn fill_variable(meta: &mut Meta, access: &mut [Access], file_id: usize, element_id: &mut usize) {
250 meta.set_file_id(file_id);
251 for acc in access {
252 if let Access::ArrayAccess(e) = acc {
253 e.fill(file_id, element_id)
254 }
255 }
256}
257
258fn fill_infix(
259 meta: &mut Meta,
260 lhe: &mut Expression,
261 rhe: &mut Expression,
262 file_id: usize,
263 element_id: &mut usize,
264) {
265 meta.set_file_id(file_id);
266 lhe.fill(file_id, element_id);
267 rhe.fill(file_id, element_id);
268}
269
270fn fill_prefix(meta: &mut Meta, rhe: &mut Expression, file_id: usize, element_id: &mut usize) {
271 meta.set_file_id(file_id);
272 rhe.fill(file_id, element_id);
273}
274
275fn fill_parallel(meta: &mut Meta, rhe: &mut Expression, file_id: usize, element_id: &mut usize) {
276 meta.set_file_id(file_id);
277 rhe.fill(file_id, element_id);
278}
279
280fn fill_inline_switch_op(
281 meta: &mut Meta,
282 cond: &mut Expression,
283 if_true: &mut Expression,
284 if_false: &mut Expression,
285 file_id: usize,
286 element_id: &mut usize,
287) {
288 meta.set_file_id(file_id);
289 cond.fill(file_id, element_id);
290 if_true.fill(file_id, element_id);
291 if_false.fill(file_id, element_id);
292}
293
294fn fill_call(meta: &mut Meta, args: &mut [Expression], file_id: usize, element_id: &mut usize) {
295 meta.set_file_id(file_id);
296 for a in args {
297 a.fill(file_id, element_id);
298 }
299}
300
301fn fill_anonymous_comp(meta: &mut Meta, params: &mut [Expression],signals: &mut [Expression], file_id: usize, element_id: &mut usize) {
302 meta.set_file_id(file_id);
303 for a in params {
304 a.fill(file_id, element_id);
305 }
306 for a in signals {
307 a.fill(file_id, element_id);
308 }
309}
310fn fill_array_inline(
311 meta: &mut Meta,
312 values: &mut [Expression],
313 file_id: usize,
314 element_id: &mut usize,
315) {
316 meta.set_file_id(file_id);
317 for v in values {
318 v.fill(file_id, element_id);
319 }
320}
321
322fn fill_tuple(
323 meta: &mut Meta,
324 values: &mut [Expression],
325 file_id: usize,
326 element_id: &mut usize,
327) {
328 meta.set_file_id(file_id);
329 for v in values {
330 v.fill(file_id, element_id);
331 }
332}
333
334fn fill_uniform_array(
335 meta: &mut Meta,
336 value: &mut Expression,
337 dimensions: &mut Expression,
338 file_id: usize,
339 element_id: &mut usize,
340) {
341 meta.set_file_id(file_id);
342 value.fill(file_id, element_id);
343 dimensions.fill(file_id, element_id);
344}