circom_lsp_program_structure/abstract_syntax_tree/
statement_impl.rs

1use super::ast::*;
2
3impl Statement {
4    pub fn get_meta(&self) -> &Meta {
5        use Statement::*;
6        match self {
7            IfThenElse { meta, .. }
8            | While { meta, .. }
9            | Return { meta, .. }
10            | Declaration { meta, .. }
11            | Substitution { meta, .. }
12            | LogCall { meta, .. }
13            | Block { meta, .. }
14            | Assert { meta, .. }
15            | ConstraintEquality { meta, .. }
16            | InitializationBlock { meta, .. } => meta,
17            | MultSubstitution { meta, ..} => meta,
18            | UnderscoreSubstitution { meta, .. } => meta,
19        }
20    }
21    pub fn get_mut_meta(&mut self) -> &mut Meta {
22        use Statement::*;
23        match self {
24            IfThenElse { meta, .. }
25            | While { meta, .. }
26            | Return { meta, .. }
27            | Declaration { meta, .. }
28            | Substitution { meta, .. }
29            | LogCall { meta, .. }
30            | Block { meta, .. }
31            | Assert { meta, .. }
32            | ConstraintEquality { meta, .. }
33            | InitializationBlock { meta, .. } => meta,
34            | MultSubstitution { meta, ..} => meta,
35            | UnderscoreSubstitution { meta, .. } => meta,
36        }
37    }
38
39    pub fn is_if_then_else(&self) -> bool {
40        use Statement::IfThenElse;
41        if let IfThenElse { .. } = self {
42            true
43        } else {
44            false
45        }
46    }
47    pub fn is_while(&self) -> bool {
48        use Statement::While;
49        if let While { .. } = self {
50            true
51        } else {
52            false
53        }
54    }
55    pub fn is_return(&self) -> bool {
56        use Statement::Return;
57        if let Return { .. } = self {
58            true
59        } else {
60            false
61        }
62    }
63    pub fn is_initialization_block(&self) -> bool {
64        use Statement::InitializationBlock;
65        if let InitializationBlock { .. } = self {
66            true
67        } else {
68            false
69        }
70    }
71    pub fn is_declaration(&self) -> bool {
72        use Statement::Declaration;
73        if let Declaration { .. } = self {
74            true
75        } else {
76            false
77        }
78    }
79    pub fn is_substitution(&self) -> bool {
80        use Statement::Substitution;
81        if let Substitution { .. } = self {
82            true
83        } else {
84            false
85        }
86    }
87
88    pub fn is_underscore_substitution(&self) -> bool {
89        use Statement::UnderscoreSubstitution;
90        if let UnderscoreSubstitution { .. } = self {
91            true
92        } else {
93            false
94        }
95    }
96    pub fn is_constraint_equality(&self) -> bool {
97        use Statement::ConstraintEquality;
98        if let ConstraintEquality { .. } = self {
99            true
100        } else {
101            false
102        }
103    }
104    pub fn is_log_call(&self) -> bool {
105        use Statement::LogCall;
106        if let LogCall { .. } = self {
107            true
108        } else {
109            false
110        }
111    }
112    pub fn is_block(&self) -> bool {
113        use Statement::Block;
114        if let Block { .. } = self {
115            true
116        } else {
117            false
118        }
119    }
120    pub fn is_assert(&self) -> bool {
121        use Statement::Assert;
122        if let Assert { .. } = self {
123            true
124        } else {
125            false
126        }
127    }
128}
129
130impl FillMeta for Statement {
131    fn fill(&mut self, file_id: usize, element_id: &mut usize) {
132        use Statement::*;
133        self.get_mut_meta().elem_id = *element_id;
134        *element_id += 1;
135        match self {
136            IfThenElse { meta, cond, if_case, else_case, .. } => {
137                fill_conditional(meta, cond, if_case, else_case, file_id, element_id)
138            }
139            While { meta, cond, stmt } => fill_while(meta, cond, stmt, file_id, element_id),
140            Return { meta, value } => fill_return(meta, value, file_id, element_id),
141            InitializationBlock { meta, initializations, .. } => {
142                fill_initialization(meta, initializations, file_id, element_id)
143            }
144            Declaration { meta, dimensions, .. } => {
145                fill_declaration(meta, dimensions, file_id, element_id)
146            }
147            Substitution { meta, access, rhe, .. } => {
148                fill_substitution(meta, access, rhe, file_id, element_id)
149            }
150            MultSubstitution { meta, lhe, rhe, .. }
151            => {
152                fill_mult_substitution(meta, lhe, rhe, file_id, element_id);
153            }
154            ConstraintEquality { meta, lhe, rhe } => {
155                fill_constraint_equality(meta, lhe, rhe, file_id, element_id)
156            }
157            LogCall { meta, args, .. } => fill_log_call(meta, args, file_id, element_id),
158            Block { meta, stmts, .. } => fill_block(meta, stmts, file_id, element_id),
159            Assert { meta, arg, .. } => fill_assert(meta, arg, file_id, element_id),
160            UnderscoreSubstitution { meta, rhe, .. } => {
161                fill_underscore_substitution(meta, rhe, file_id, element_id);
162            },
163            
164        }
165    }
166}
167
168
169fn fill_conditional(
170    meta: &mut Meta,
171    cond: &mut Expression,
172    if_case: &mut Statement,
173    else_case: &mut Option<Box<Statement>>,
174    file_id: usize,
175    element_id: &mut usize,
176) {
177    meta.set_file_id(file_id);
178    cond.fill(file_id, element_id);
179    if_case.fill(file_id, element_id);
180    if let Option::Some(s) = else_case {
181        s.fill(file_id, element_id);
182    }
183}
184
185fn fill_while(
186    meta: &mut Meta,
187    cond: &mut Expression,
188    stmt: &mut Statement,
189    file_id: usize,
190    element_id: &mut usize,
191) {
192    meta.set_file_id(file_id);
193    cond.fill(file_id, element_id);
194    stmt.fill(file_id, element_id);
195}
196
197fn fill_return(meta: &mut Meta, value: &mut Expression, file_id: usize, element_id: &mut usize) {
198    meta.set_file_id(file_id);
199    value.fill(file_id, element_id);
200}
201
202fn fill_initialization(
203    meta: &mut Meta,
204    initializations: &mut [Statement],
205    file_id: usize,
206    element_id: &mut usize,
207) {
208    meta.set_file_id(file_id);
209    for init in initializations {
210        init.fill(file_id, element_id);
211    }
212}
213
214fn fill_declaration(
215    meta: &mut Meta,
216    dimensions: &mut [Expression],
217    file_id: usize,
218    element_id: &mut usize,
219) {
220    meta.set_file_id(file_id);
221    for d in dimensions {
222        d.fill(file_id, element_id);
223    }
224}
225
226fn fill_substitution(
227    meta: &mut Meta,
228    access: &mut [Access],
229    rhe: &mut Expression,
230    file_id: usize,
231    element_id: &mut usize,
232) {
233    meta.set_file_id(file_id);
234    rhe.fill(file_id, element_id);
235    for a in access {
236        if let Access::ArrayAccess(e) = a {
237            e.fill(file_id, element_id);
238        }
239    }
240}
241
242fn fill_mult_substitution(
243    meta: &mut Meta,
244    lhe: &mut Expression,
245    rhe: &mut Expression,
246    file_id: usize,
247    element_id: &mut usize,
248) {
249    meta.set_file_id(file_id);
250    rhe.fill(file_id, element_id);
251    lhe.fill(file_id,element_id);
252}
253
254fn fill_constraint_equality(
255    meta: &mut Meta,
256    lhe: &mut Expression,
257    rhe: &mut Expression,
258    file_id: usize,
259    element_id: &mut usize,
260) {
261    meta.set_file_id(file_id);
262    lhe.fill(file_id, element_id);
263    rhe.fill(file_id, element_id);
264}
265
266fn fill_log_call(meta: &mut Meta, args: &mut Vec<LogArgument>, file_id: usize, element_id: &mut usize) {
267    meta.set_file_id(file_id);
268    for arg in args {
269        if let LogArgument::LogExp(e) = arg {
270            e.fill(file_id, element_id);
271        }
272    }
273}
274
275fn fill_block(meta: &mut Meta, stmts: &mut [Statement], file_id: usize, element_id: &mut usize) {
276    meta.set_file_id(file_id);
277    for s in stmts {
278        s.fill(file_id, element_id);
279    }
280}
281
282fn fill_assert(meta: &mut Meta, arg: &mut Expression, file_id: usize, element_id: &mut usize) {
283    meta.set_file_id(file_id);
284    arg.fill(file_id, element_id);
285}
286
287fn fill_underscore_substitution(meta: &mut Meta, rhe: &mut Expression, file_id: usize, element_id: &mut usize) {
288    meta.set_file_id(file_id);
289    rhe.fill(file_id, element_id);
290
291}