add pretty diagnostics

This commit is contained in:
Romain Paquet 2024-07-03 19:59:12 +02:00
parent e157bf036a
commit f415c4abbe
12 changed files with 1037 additions and 603 deletions

View file

@ -1,14 +1,20 @@
pub mod ast;
pub mod jit;
pub mod parsing;
pub mod source;
pub mod typing;
use clap::{Parser, Subcommand};
use std::default::Default;
use std::path::PathBuf;
use clap::{Parser as ClapParser, Subcommand};
use crate::ast::Module;
use crate::parsing::Parser;
use crate::source::SourceCache;
/// Experimental compiler for lila
#[derive(Parser, Debug)]
#[derive(ClapParser, Debug)]
#[command(author = "Romain P. <rpqt@rpqt.fr>")]
#[command(version, about, long_about = None)]
struct Cli {
@ -51,21 +57,27 @@ enum Commands {
},
}
fn parse(files: &Vec<String>) -> Vec<Module> {
fn parse(files: &[String]) -> Vec<Module> {
let mut parser = parsing::DefaultParser::default();
let paths = files.iter().map(std::path::Path::new);
paths
.map(|path| match parsing::parse_file(&path) {
.enumerate()
.map(|(i, path)| match parser.parse_file(path, i as u32) {
Ok(module) => module,
Err(e) => panic!("Parsing error: {:#?}", e),
})
.collect()
}
fn check(modules: &mut Vec<Module>) {
while let Some(module) = modules.pop() {
if let Err(e) = module.type_check() {
eprintln!("{}", e);
return;
fn check(modules: &mut Vec<Module>, source_cache: &mut SourceCache) {
for module in modules {
if let Err(errors) = module.type_check() {
for error in errors {
error
.to_report(module)
.eprint(&mut *source_cache)
.expect("cannot write error to stderr");
}
}
}
}
@ -83,20 +95,32 @@ fn main() {
}
println!("Parsing OK");
}
Commands::TypeCheck { files, dump_ast } => {
let mut source_cache = SourceCache {
paths: files.iter().map(PathBuf::from).collect(),
file_cache: ariadne::FileCache::default(),
};
let mut modules = parse(files);
check(&mut modules);
check(&mut modules, &mut source_cache);
if *dump_ast {
for module in &modules {
println!("{:#?}", &module);
}
}
}
Commands::Compile { files, dump_clir } | Commands::Run { files, dump_clir } => {
let mut source_cache = SourceCache {
paths: files.iter().map(PathBuf::from).collect(),
file_cache: ariadne::FileCache::default(),
};
let mut jit = jit::JIT::default();
jit.dump_clir = *dump_clir;
for file in files {
match jit.compile_file(file) {
for (id, file) in files.iter().enumerate() {
match jit.compile_file(file, id as u32, &mut source_cache) {
Err(e) => eprintln!("{}", e),
Ok(code) => {
println!("Compiled {}", file);