leo_passes/static_single_assignment/
program.rs1use super::SsaFormingVisitor;
18
19use leo_ast::{
20 Block,
21 Composite,
22 Function,
23 FunctionConsumer,
24 Identifier,
25 Member,
26 Node as _,
27 Program,
28 ProgramConsumer,
29 ProgramScope,
30 ProgramScopeConsumer,
31 StatementConsumer,
32 StructConsumer,
33};
34use leo_span::{Symbol, sym};
35
36use indexmap::IndexMap;
37
38impl StructConsumer for SsaFormingVisitor<'_> {
39 type Output = Composite;
40
41 fn consume_struct(&mut self, struct_: Composite) -> Self::Output {
43 match struct_.is_record {
44 false => struct_,
45 true => {
46 let mut members = Vec::with_capacity(struct_.members.len());
47 let mut member_map: IndexMap<Symbol, Member> =
48 struct_.members.into_iter().map(|member| (member.identifier.name, member)).collect();
49
50 members.push(member_map.shift_remove(&sym::owner).unwrap());
53
54 members.extend(member_map.into_iter().map(|(_, member)| member));
56
57 Composite { members, ..struct_ }
58 }
59 }
60 }
61}
62
63impl FunctionConsumer for SsaFormingVisitor<'_> {
64 type Output = Function;
65
66 fn consume_function(&mut self, mut function: Function) -> Self::Output {
68 self.push();
70
71 if self.rename_defs {
72 for input_variable in function.input.iter_mut() {
74 let old_identifier = input_variable.identifier;
75 let new_symbol = self.state.assigner.unique_symbol(old_identifier, "$$");
76 let new_identifier = Identifier::new(new_symbol, self.state.node_builder.next_id());
77 input_variable.identifier = new_identifier;
78
79 self.state.type_table.insert(new_identifier.id(), input_variable.type_.clone());
81
82 self.rename_table.update(old_identifier.name, old_identifier.name, old_identifier.id);
84
85 self.rename_table.update(old_identifier.name, new_identifier.name, old_identifier.id);
87 }
88 }
89
90 function.block =
91 Block { span: function.block.span, id: function.block.id, statements: self.consume_block(function.block) };
92
93 self.pop();
95
96 function
97 }
98}
99
100impl ProgramScopeConsumer for SsaFormingVisitor<'_> {
101 type Output = ProgramScope;
102
103 fn consume_program_scope(&mut self, input: ProgramScope) -> Self::Output {
104 self.program = input.program_id.name.name;
105 ProgramScope {
106 program_id: input.program_id,
107 structs: input.structs.into_iter().map(|(i, s)| (i, self.consume_struct(s))).collect(),
108 mappings: input.mappings,
109 functions: input.functions.into_iter().map(|(i, f)| (i, self.consume_function(f))).collect(),
110 consts: input.consts,
111 span: input.span,
112 }
113 }
114}
115
116impl ProgramConsumer for SsaFormingVisitor<'_> {
117 type Output = Program;
118
119 fn consume_program(&mut self, input: Program) -> Self::Output {
120 Program {
121 imports: input
122 .imports
123 .into_iter()
124 .map(|(name, (import, span))| (name, (self.consume_program(import), span)))
125 .collect(),
126 stubs: input.stubs,
127 program_scopes: input
128 .program_scopes
129 .into_iter()
130 .map(|(name, scope)| (name, self.consume_program_scope(scope)))
131 .collect(),
132 }
133 }
134}