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 IntrinsicExpression {
66 name: sym::_mapping_get_or_use,
67 type_parameters: vec![],
68 arguments: vec![len_path_expr, self.literal_false(), self.literal_zero_u32()],
69 span,
70 id: self.state.node_builder.next_id(),
71 }
72 .into()
73 }
74
75 pub fn set_mapping_expr(
77 &mut self,
78 path_expr: Expression,
79 key_expr: Expression,
80 value_expr: Expression,
81 span: Span,
82 ) -> Expression {
83 IntrinsicExpression {
84 name: sym::_mapping_set,
85 type_parameters: vec![],
86 arguments: vec![path_expr, key_expr, value_expr],
87 span,
88 id: self.state.node_builder.next_id(),
89 }
90 .into()
91 }
92
93 pub fn get_mapping_expr(&mut self, path_expr: Expression, key_expr: Expression, span: Span) -> Expression {
95 IntrinsicExpression {
96 name: sym::_mapping_get,
97 type_parameters: vec![],
98 arguments: vec![path_expr, key_expr],
99 span,
100 id: self.state.node_builder.next_id(),
101 }
102 .into()
103 }
104
105 pub fn get_or_use_mapping_expr(
107 &mut self,
108 path_expr: Expression,
109 key_expr: Expression,
110 default_expr: Expression,
111 span: Span,
112 ) -> Expression {
113 IntrinsicExpression {
114 name: sym::_mapping_get_or_use,
115 type_parameters: vec![],
116 arguments: vec![path_expr, key_expr, default_expr],
117 span,
118 id: self.state.node_builder.next_id(),
119 }
120 .into()
121 }
122
123 pub fn ternary_expr(
125 &mut self,
126 condition: Expression,
127 if_true: Expression,
128 if_false: Expression,
129 span: Span,
130 ) -> Expression {
131 TernaryExpression { condition, if_true, if_false, span, id: self.state.node_builder.next_id() }.into()
132 }
133
134 pub fn binary_expr(&mut self, left: Expression, op: BinaryOperation, right: Expression) -> Expression {
136 BinaryExpression { op, left, right, span: Span::default(), id: self.state.node_builder.next_id() }.into()
137 }
138
139 pub fn zero(&self, ty: &Type) -> Expression {
141 let symbol_table = &self.state.symbol_table;
143 let struct_lookup = |sym: &[Symbol]| {
144 symbol_table
145 .lookup_struct(sym)
146 .unwrap()
147 .members
148 .iter()
149 .map(|mem| (mem.identifier.name, mem.type_.clone()))
150 .collect()
151 };
152 Expression::zero(ty, Span::default(), &self.state.node_builder, &struct_lookup)
153 .expect("zero value generation failed")
154 }
155}