leo_passes/static_single_assignment/
program.rs1use super::SsaFormingVisitor;
18
19use leo_ast::{
20 Block,
21 Composite,
22 Constructor,
23 ConstructorConsumer,
24 Function,
25 FunctionConsumer,
26 Identifier,
27 Member,
28 Module,
29 ModuleConsumer,
30 Node as _,
31 Program,
32 ProgramConsumer,
33 ProgramScope,
34 ProgramScopeConsumer,
35 StatementConsumer,
36 StructConsumer,
37};
38use leo_span::{Symbol, sym};
39
40use indexmap::IndexMap;
41
42impl StructConsumer for SsaFormingVisitor<'_> {
43 type Output = Composite;
44
45 fn consume_struct(&mut self, struct_: Composite) -> Self::Output {
47 match struct_.is_record {
48 false => struct_,
49 true => {
50 let mut members = Vec::with_capacity(struct_.members.len());
51 let mut member_map: IndexMap<Symbol, Member> =
52 struct_.members.into_iter().map(|member| (member.identifier.name, member)).collect();
53
54 members.push(member_map.shift_remove(&sym::owner).unwrap());
57
58 members.extend(member_map.into_iter().map(|(_, member)| member));
60
61 Composite { members, ..struct_ }
62 }
63 }
64 }
65}
66
67impl FunctionConsumer for SsaFormingVisitor<'_> {
68 type Output = Function;
69
70 fn consume_function(&mut self, mut function: Function) -> Self::Output {
72 self.push();
74
75 if self.rename_defs {
76 for input_variable in function.input.iter_mut() {
78 let old_identifier = input_variable.identifier;
79 let new_symbol = self.state.assigner.unique_symbol(old_identifier, "$$");
80 let new_identifier = Identifier::new(new_symbol, self.state.node_builder.next_id());
81 input_variable.identifier = new_identifier;
82
83 self.state.type_table.insert(new_identifier.id(), input_variable.type_.clone());
85
86 self.rename_table.update(old_identifier.name, old_identifier.name, old_identifier.id);
88
89 self.rename_table.update(old_identifier.name, new_identifier.name, old_identifier.id);
91 }
92 }
93
94 function.block =
95 Block { span: function.block.span, id: function.block.id, statements: self.consume_block(function.block) };
96
97 self.pop();
99
100 function
101 }
102}
103
104impl ConstructorConsumer for SsaFormingVisitor<'_> {
105 type Output = Constructor;
106
107 fn consume_constructor(&mut self, mut constructor: Constructor) -> Self::Output {
109 self.push();
111 constructor.block = Block {
113 span: constructor.block.span,
114 id: constructor.block.id,
115 statements: self.consume_block(constructor.block),
116 };
117 self.pop();
119
120 constructor
121 }
122}
123
124impl ProgramScopeConsumer for SsaFormingVisitor<'_> {
125 type Output = ProgramScope;
126
127 fn consume_program_scope(&mut self, input: ProgramScope) -> Self::Output {
128 self.program = input.program_id.name.name;
129 ProgramScope {
130 program_id: input.program_id,
131 consts: input.consts,
132 structs: input.structs.into_iter().map(|(i, s)| (i, self.consume_struct(s))).collect(),
133 mappings: input.mappings,
134 functions: input.functions.into_iter().map(|(i, f)| (i, self.consume_function(f))).collect(),
135 constructor: input.constructor.map(|c| self.consume_constructor(c)),
136 span: input.span,
137 }
138 }
139}
140
141impl ProgramConsumer for SsaFormingVisitor<'_> {
142 type Output = Program;
143
144 fn consume_program(&mut self, input: Program) -> Self::Output {
145 Program {
146 modules: input.modules.into_iter().map(|(path, module)| (path, self.consume_module(module))).collect(),
147 imports: input
148 .imports
149 .into_iter()
150 .map(|(name, (import, span))| (name, (self.consume_program(import), span)))
151 .collect(),
152 stubs: input.stubs,
153 program_scopes: input
154 .program_scopes
155 .into_iter()
156 .map(|(name, scope)| (name, self.consume_program_scope(scope)))
157 .collect(),
158 }
159 }
160}
161
162impl ModuleConsumer for SsaFormingVisitor<'_> {
163 type Output = Module;
164
165 fn consume_module(&mut self, input: Module) -> Self::Output {
166 Module {
167 path: input.path,
168 program_name: self.program,
169 structs: input.structs.into_iter().map(|(i, s)| (i, self.consume_struct(s))).collect(),
170 functions: input.functions.into_iter().map(|(i, f)| (i, self.consume_function(f))).collect(),
171 consts: input.consts,
172 }
173 }
174}