deimos-lang/src/bin/dmc/name_analysis.rs

48 lines
1.7 KiB
Rust

use codespan_reporting::files::SimpleFiles;
use codespan_reporting::term;
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
use deimos::ast::build::build_ast;
use deimos::name_analysis::analyze_names;
use deimos::name_analysis::symbol_table::SymbolTable;
use deimos::parser::{DeimosParser, Rule};
use deimos::std_core::add_std_core_symbols;
use pest::Parser;
use std::path::PathBuf;
pub fn name_analysis(paths: &Vec<PathBuf>) -> Result<(), Box<dyn std::error::Error>> {
let mut compilation_units = vec![];
let mut files: SimpleFiles<String, String> = SimpleFiles::new();
for path in paths {
let src = std::fs::read_to_string(path).unwrap();
let parse_result = DeimosParser::parse(Rule::CompilationUnit, &src);
let file_id = files.add(path.display().to_string(), src.clone()); // I don't love this clone
match parse_result {
Ok(mut pairs) => {
let compilation_unit = build_ast(file_id, &mut pairs);
compilation_units.push(compilation_unit);
Ok::<(), Box<dyn std::error::Error>>(())
}
Err(e) => Err(e.into()),
}?;
}
let mut symbol_table = SymbolTable::new();
add_std_core_symbols(&mut symbol_table).expect("Failed to add std::core symbols.");
let diagnostics = analyze_names(&compilation_units, &files, &mut symbol_table);
if diagnostics.is_empty() {
println!("Name analysis complete.");
println!("{}", symbol_table);
} else {
let writer = StandardStream::stderr(ColorChoice::Always);
let config = term::Config::default();
for diagnostic in diagnostics {
term::emit(&mut writer.lock(), &config, &files, &diagnostic)?;
}
}
Ok(())
}