mirror of
https://github.com/ProvableHQ/leo.git
synced 2024-11-24 07:48:04 +03:00
add constants to CPT and remove constant definitions from ST and AST
This commit is contained in:
parent
c249786f7c
commit
a7ee073f07
@ -70,4 +70,56 @@ impl ProgramReconstructor for Unroller<'_> {
|
|||||||
|
|
||||||
reconstructed_function
|
reconstructed_function
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn reconstruct_const(&mut self, input: DefinitionStatement) -> DefinitionStatement {
|
||||||
|
// Reconstruct the RHS expression to allow for constant propagation
|
||||||
|
let reconstructed_value_expression = self.reconstruct_expression(input.value.clone()).0;
|
||||||
|
|
||||||
|
// Helper function to add global constants to constant variable table
|
||||||
|
let insert_variable = |symbol: Symbol, value: &Expression| {
|
||||||
|
if let Literal(literal) = value {
|
||||||
|
if let Err(err) = self.constant_propagation_table.borrow_mut().insert_constant(symbol, literal.clone())
|
||||||
|
{
|
||||||
|
self.handler.emit_err(err);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unreachable!("Type checking guarantees that the value of a constant is a literal.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// No matter if doing multiple definitions in one line or not, insert all global constants into the constant propagation table
|
||||||
|
match &input.place {
|
||||||
|
Expression::Identifier(identifier) => {
|
||||||
|
insert_variable(identifier.name, &reconstructed_value_expression);
|
||||||
|
}
|
||||||
|
Expression::Tuple(tuple_expression) => {
|
||||||
|
let tuple_values: &Vec<Expression> = match &reconstructed_value_expression {
|
||||||
|
Expression::Tuple(tuple_value_expression) => &tuple_value_expression.elements,
|
||||||
|
_ => unreachable!(
|
||||||
|
"Definition statement that defines tuple of variables must be assigned to tuple of values"
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i, element) in tuple_expression.elements.iter().enumerate() {
|
||||||
|
let identifier = match element {
|
||||||
|
Expression::Identifier(identifier) => identifier,
|
||||||
|
_ => unreachable!("All elements of a definition tuple must be identifiers"),
|
||||||
|
};
|
||||||
|
insert_variable(identifier.name, &tuple_values[i].clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => unreachable!(
|
||||||
|
"Type checking guarantees that the lhs of a `DefinitionStatement` is either an identifier or tuple."
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
DefinitionStatement {
|
||||||
|
declaration_type: input.declaration_type,
|
||||||
|
place: input.place,
|
||||||
|
type_: input.type_,
|
||||||
|
value: reconstructed_value_expression,
|
||||||
|
span: input.span,
|
||||||
|
id: input.id,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,11 +40,7 @@ impl StatementReconstructor for Unroller<'_> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reconstruct_definition(&mut self, input: DefinitionStatement) -> (Statement, Self::AdditionalOutput) {
|
fn reconstruct_definition(&mut self, input: DefinitionStatement) -> (Statement, Self::AdditionalOutput) {
|
||||||
// If we are unrolling a loop, then we need to repopulate the symbol table.
|
// Helper function to add variables to symbol table
|
||||||
if self.is_unrolling {
|
|
||||||
let declaration =
|
|
||||||
if input.declaration_type == DeclarationType::Const { VariableType::Const } else { VariableType::Mut };
|
|
||||||
|
|
||||||
let insert_variable = |symbol: Symbol, type_: Type, span: Span, declaration: VariableType| {
|
let insert_variable = |symbol: Symbol, type_: Type, span: Span, declaration: VariableType| {
|
||||||
if let Err(err) =
|
if let Err(err) =
|
||||||
self.symbol_table.borrow_mut().insert_variable(symbol, VariableSymbol { type_, span, declaration })
|
self.symbol_table.borrow_mut().insert_variable(symbol, VariableSymbol { type_, span, declaration })
|
||||||
@ -53,10 +49,16 @@ impl StatementReconstructor for Unroller<'_> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Insert the variables in the into the symbol table.
|
let declaration =
|
||||||
|
if input.declaration_type == DeclarationType::Const { VariableType::Const } else { VariableType::Mut };
|
||||||
|
|
||||||
|
// If we are unrolling a loop, then we need to repopulate the symbol table.
|
||||||
|
// If we are not unrolling a loop, the we need to remove constants from the symbol table.
|
||||||
|
// We always need to add constant variables to the constant variable table.
|
||||||
|
if declaration == VariableType::Mut && self.is_unrolling {
|
||||||
match &input.place {
|
match &input.place {
|
||||||
Expression::Identifier(identifier) => {
|
Expression::Identifier(identifier) => {
|
||||||
insert_variable(identifier.name, input.type_.clone(), identifier.span, declaration)
|
insert_variable(identifier.name, input.type_.clone(), input.span, declaration);
|
||||||
}
|
}
|
||||||
Expression::Tuple(tuple_expression) => {
|
Expression::Tuple(tuple_expression) => {
|
||||||
let tuple_type = match input.type_ {
|
let tuple_type = match input.type_ {
|
||||||
@ -65,20 +67,34 @@ impl StatementReconstructor for Unroller<'_> {
|
|||||||
"Type checking guarantees that if the lhs is a tuple, its associated type is also a tuple."
|
"Type checking guarantees that if the lhs is a tuple, its associated type is also a tuple."
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
tuple_expression.elements.iter().zip_eq(tuple_type.0.iter()).for_each(|(expression, type_)| {
|
tuple_expression.elements.iter().zip_eq(tuple_type.0.iter()).for_each(|(expression, _type_)| {
|
||||||
let identifier = match expression {
|
let identifier = match expression {
|
||||||
Expression::Identifier(identifier) => identifier,
|
Expression::Identifier(identifier) => identifier,
|
||||||
_ => unreachable!("Type checking guarantees that if the lhs is a tuple, all of its elements are identifiers.")
|
_ => unreachable!("Type checking guarantees that if the lhs is a tuple, all of its elements are identifiers.")
|
||||||
};
|
};
|
||||||
insert_variable(identifier.name, type_.clone(), identifier.span, declaration)
|
insert_variable(identifier.name, input.type_.clone(), input.span, declaration);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_ => unreachable!(
|
_ => unreachable!(
|
||||||
"Type checking guarantees that the lhs of a `DefinitionStatement` is either an identifier or tuple."
|
"Type checking guarantees that the lhs of a `DefinitionStatement` is either an identifier or tuple."
|
||||||
),
|
),
|
||||||
}
|
}
|
||||||
|
} else if declaration == VariableType::Const {
|
||||||
|
return (Statement::Definition(self.reconstruct_const(input.clone())), true);
|
||||||
}
|
}
|
||||||
(Statement::Definition(input), Default::default())
|
|
||||||
|
// Reconstruct the expression and return
|
||||||
|
(
|
||||||
|
Statement::Definition(DefinitionStatement {
|
||||||
|
declaration_type: input.declaration_type,
|
||||||
|
place: input.place,
|
||||||
|
type_: input.type_,
|
||||||
|
value: self.reconstruct_expression(input.value).0,
|
||||||
|
span: input.span,
|
||||||
|
id: input.id,
|
||||||
|
}),
|
||||||
|
false,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reconstruct_iteration(&mut self, input: IterationStatement) -> (Statement, Self::AdditionalOutput) {
|
fn reconstruct_iteration(&mut self, input: IterationStatement) -> (Statement, Self::AdditionalOutput) {
|
||||||
|
Loading…
Reference in New Issue
Block a user