deimos-lang/dmc-lib/src/compile_pipeline.rs

79 lines
2.6 KiB
Rust

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<str>;
pub type FileId = usize;
fn parse_compilation_units(
inputs: &HashMap<FileId, &str>,
) -> Result<HashMap<FileId, CompilationUnit>, 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<FileId, &str>) -> 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::<Vec<_>>();
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(())
}