leo_passes/const_propagation/
visitor.rs1use crate::CompilerState;
18
19use leo_ast::{Expression, Node, NodeID, interpreter_value::Value};
20use leo_errors::StaticAnalyzerError;
21use leo_span::{Span, Symbol};
22
23pub struct ConstPropagationVisitor<'a> {
24 pub state: &'a mut CompilerState,
25 pub program: Symbol,
27 pub module: Vec<Symbol>,
29 pub changed: bool,
31 pub const_not_evaluated: Option<Span>,
33 pub array_index_not_evaluated: Option<Span>,
35 pub array_length_not_evaluated: Option<Span>,
37 pub repeat_count_not_evaluated: Option<Span>,
39}
40
41impl ConstPropagationVisitor<'_> {
42 pub fn in_scope<T>(&mut self, id: NodeID, func: impl FnOnce(&mut Self) -> T) -> T {
44 self.state.symbol_table.enter_scope(Some(id));
45 let result = func(self);
46 self.state.symbol_table.enter_parent();
47 result
48 }
49
50 pub fn in_module_scope<T>(&mut self, module: &[Symbol], func: impl FnOnce(&mut Self) -> T) -> T {
52 let parent_module = self.module.clone();
53 self.module = module.to_vec();
54 let result = func(self);
55 self.module = parent_module;
56 result
57 }
58
59 pub fn emit_err(&self, err: StaticAnalyzerError) {
61 self.state.handler.emit_err(err);
62 }
63
64 pub fn value_to_expression(&self, value: &Value, span: Span, id: NodeID) -> Option<Expression> {
65 let ty = self.state.type_table.get(&id)?;
66 let symbol_table = &self.state.symbol_table;
67 let struct_lookup = |sym: &[Symbol]| {
68 symbol_table
69 .lookup_struct(sym)
70 .unwrap()
71 .members
72 .iter()
73 .map(|mem| (mem.identifier.name, mem.type_.clone()))
74 .collect()
75 };
76 value.to_expression(span, &self.state.node_builder, &ty, &struct_lookup)
77 }
78
79 pub fn value_to_expression_node(&self, value: &Value, previous: &impl Node) -> Option<Expression> {
80 self.value_to_expression(value, previous.span(), previous.id())
81 }
82}