use crate::ast::compilation_unit::CompilationUnit; use crate::diagnostic::Diagnostics; use crate::parser::parse_compilation_unit; use crate::symbol_table::SymbolTable; use crate::symbol_table::util::try_insert_symbols_into; use std::collections::HashMap; use std::rc::Rc; pub type Filename = Rc; pub type FileId = usize; fn parse_compilation_units( inputs: &HashMap, ) -> Result, Diagnostics> { let mut parse_diagnostics = Vec::new(); let mut compilation_units = HashMap::new(); for (file_id, source) in inputs { let (compilation_unit, mut ds) = parse_compilation_unit(source, Some(*file_id)); parse_diagnostics.append(&mut ds); compilation_units.insert(*file_id, compilation_unit); } if parse_diagnostics.is_empty() { Ok(compilation_units) } else { Err(parse_diagnostics) } } pub fn compile_compilation_units(inputs: &HashMap) -> Result<(), Diagnostics> { let mut compilation_units = parse_compilation_units(inputs)?; let mut symbol_table = SymbolTable::new(); // init scopes for compilation_unit in compilation_units.values_mut() { compilation_unit.init_scopes(&mut symbol_table); } // gather unordered symbols let all_symbols = compilation_units .values() .flat_map(|compilation_unit| compilation_unit.declared_symbols()) .collect::>(); try_insert_symbols_into(all_symbols, &mut symbol_table)?; // now we can just finish each compilation unit, since we have the symbols let mut diagnostics = Vec::new(); for compilation_unit in compilation_units.values() { let (nodes_to_symbols, mut ds) = compilation_unit.resolve_names(&mut symbol_table); // in the future, we'll ideally be able to *actually* continue with the following steps // instead of aborting here, but this needs to be tested :) if !ds.is_empty() { diagnostics.append(&mut ds); continue; } let (mut symbols_to_types, mut ds) = compilation_unit.declared_types(&nodes_to_symbols); if !ds.is_empty() { diagnostics.append(&mut ds); continue; } let (sts, resolved_types, mut ds) = compilation_unit.resolve_types(&nodes_to_symbols, &symbols_to_types); if !ds.is_empty() { diagnostics.append(&mut ds); continue; } // merge for (symbol, type_info) in sts { symbols_to_types.insert(symbol, type_info); } } Ok(()) }