leo_passes/storage_lowering/
visitor.rs1use crate::CompilerState;
18
19use leo_ast::*;
20use leo_span::{Span, Symbol, sym};
21
22use indexmap::IndexMap;
23
24pub struct StorageLoweringVisitor<'a> {
25 pub state: &'a mut CompilerState,
26 pub program: Symbol,
28 pub new_mappings: IndexMap<Symbol, Mapping>,
29}
30
31impl StorageLoweringVisitor<'_> {
32 pub fn generate_mapping_names_for_vector(&self, expr: &Expression) -> (Symbol, Symbol) {
35 let path = match expr {
36 Expression::Path(path) => path,
37 _ => panic!("Expected path expression for vector"),
38 };
39 let base_sym = path.identifier().name;
40 let vec_values_mapping_name = Symbol::intern(&format!("{base_sym}__"));
41 let vec_length_mapping_name = Symbol::intern(&format!("{base_sym}__len__"));
42 (vec_values_mapping_name, vec_length_mapping_name)
43 }
44
45 pub fn symbol_to_path_expr(&mut self, sym: Symbol) -> Expression {
47 Expression::Path(Path::from(Identifier::new(sym, self.state.node_builder.next_id())).into_absolute())
48 }
49
50 pub fn literal_false(&mut self) -> Expression {
52 Literal::boolean(false, Span::default(), self.state.node_builder.next_id()).into()
53 }
54
55 pub fn literal_zero_u32(&mut self) -> Expression {
56 Literal::integer(IntegerType::U32, "0".to_string(), Span::default(), self.state.node_builder.next_id()).into()
57 }
58
59 pub fn literal_one_u32(&mut self) -> Expression {
60 Literal::integer(IntegerType::U32, "1".to_string(), Span::default(), self.state.node_builder.next_id()).into()
61 }
62
63 pub fn get_vector_len_expr(&mut self, len_path_expr: Expression, span: Span) -> Expression {
65 AssociatedFunctionExpression {
66 variant: Identifier::new(sym::Mapping, self.state.node_builder.next_id()),
67 name: Identifier::new(Symbol::intern("get_or_use"), self.state.node_builder.next_id()),
68 type_parameters: vec![],
69 arguments: vec![len_path_expr, self.literal_false(), self.literal_zero_u32()],
70 span,
71 id: self.state.node_builder.next_id(),
72 }
73 .into()
74 }
75
76 pub fn set_mapping_expr(
78 &mut self,
79 path_expr: Expression,
80 key_expr: Expression,
81 value_expr: Expression,
82 span: Span,
83 ) -> Expression {
84 AssociatedFunctionExpression {
85 variant: Identifier::new(sym::Mapping, self.state.node_builder.next_id()),
86 name: Identifier::new(Symbol::intern("set"), self.state.node_builder.next_id()),
87 type_parameters: vec![],
88 arguments: vec![path_expr, key_expr, value_expr],
89 span,
90 id: self.state.node_builder.next_id(),
91 }
92 .into()
93 }
94
95 pub fn get_mapping_expr(&mut self, path_expr: Expression, key_expr: Expression, span: Span) -> Expression {
97 AssociatedFunctionExpression {
98 variant: Identifier::new(sym::Mapping, self.state.node_builder.next_id()),
99 name: Identifier::new(Symbol::intern("get"), self.state.node_builder.next_id()),
100 type_parameters: vec![],
101 arguments: vec![path_expr, key_expr],
102 span,
103 id: self.state.node_builder.next_id(),
104 }
105 .into()
106 }
107
108 pub fn get_or_use_mapping_expr(
110 &mut self,
111 path_expr: Expression,
112 key_expr: Expression,
113 default_expr: Expression,
114 span: Span,
115 ) -> Expression {
116 AssociatedFunctionExpression {
117 variant: Identifier::new(sym::Mapping, self.state.node_builder.next_id()),
118 name: Identifier::new(Symbol::intern("get_or_use"), self.state.node_builder.next_id()),
119 type_parameters: vec![],
120 arguments: vec![path_expr, key_expr, default_expr],
121 span,
122 id: self.state.node_builder.next_id(),
123 }
124 .into()
125 }
126
127 pub fn ternary_expr(
129 &mut self,
130 condition: Expression,
131 if_true: Expression,
132 if_false: Expression,
133 span: Span,
134 ) -> Expression {
135 TernaryExpression { condition, if_true, if_false, span, id: self.state.node_builder.next_id() }.into()
136 }
137
138 pub fn binary_expr(&mut self, left: Expression, op: BinaryOperation, right: Expression) -> Expression {
140 BinaryExpression { op, left, right, span: Span::default(), id: self.state.node_builder.next_id() }.into()
141 }
142
143 pub fn zero(&self, ty: &Type) -> Expression {
145 let symbol_table = &self.state.symbol_table;
147 let struct_lookup = |sym: &[Symbol]| {
148 symbol_table
149 .lookup_struct(sym)
150 .unwrap()
151 .members
152 .iter()
153 .map(|mem| (mem.identifier.name, mem.type_.clone()))
154 .collect()
155 };
156 Expression::zero(ty, Span::default(), &self.state.node_builder, &struct_lookup)
157 .expect("zero value generation failed")
158 }
159}