This commit is contained in:
Pranav Gaddamadugu 2023-10-04 00:44:59 -04:00 committed by evan-schott
parent 184c306688
commit 70e0c26ad1

View File

@ -15,38 +15,35 @@
// along with the Leo library. If not, see <https://www.gnu.org/licenses/>.
use crate::FunctionInliner;
use indexmap::{IndexMap, IndexSet};
use leo_ast::{Function, ProgramReconstructor, ProgramScope};
use leo_span::Symbol;
use indexmap::IndexMap;
impl ProgramReconstructor for FunctionInliner<'_> {
fn reconstruct_program_scope(&mut self, mut input: ProgramScope) -> ProgramScope {
fn reconstruct_program_scope(&mut self, input: ProgramScope) -> ProgramScope {
// Get the post-order ordering of the call graph.
// Note that the post-order always contains all nodes in the call graph.
// Note that the unwrap is safe since type checking guarantees that the call graph is acyclic.
let order = self.call_graph.post_order().unwrap();
// Construct map to provide faster lookup of functions
let mut function_map: IndexMap<Symbol, Function> = input.functions.clone().into_iter().collect();
// Construct set to keep track of the remaining functions that still need to be processed.
let mut function_set: IndexSet<Symbol> = function_map.keys().cloned().collect();
let mut function_map: IndexMap<Symbol, Function> = input.functions.into_iter().collect();
// Reconstruct and accumulate each of the functions in post-order.
for function_name in order.into_iter() {
for function_name in &order {
// None: If `function_name` is not in `input.functions`, then it must be an external function.
// TODO: Check that this is indeed an external function. Requires a redesign of the symbol table.
if let Some(function) = function_map.remove(&function_name) {
if let Some(function) = function_map.remove(function_name) {
// Reconstruct the function.
let reconstructed_function = self.reconstruct_function(function);
// Add the reconstructed function to the mapping.
self.reconstructed_functions.insert(function_name, reconstructed_function);
self.reconstructed_functions.insert(*function_name, reconstructed_function);
}
}
// This is a sanity check to ensure that functions in the program scope have been processed.
assert!(function_set.is_empty(), "All functions in the program scope should have been processed.");
input.functions.clear();
assert!(function_map.is_empty(), "All functions in the program scope should have been processed.");
// Note that this intentionally clears `self.reconstructed_functions` for the next program scope.
let functions = core::mem::take(&mut self.reconstructed_functions).into_iter().collect();