Shift most of the meat of the compiler over into the library.
This commit is contained in:
@@ -1,17 +1,7 @@
|
||||
use clap::Parser;
|
||||
use codespan_reporting::diagnostic::Diagnostic;
|
||||
use codespan_reporting::files::SimpleFiles;
|
||||
use codespan_reporting::term;
|
||||
use codespan_reporting::term::termcolor::{ColorChoice, StandardStream};
|
||||
use cranelift_object::object;
|
||||
|
||||
use ngr::backend::Backend;
|
||||
use ngr::backend::BackendError;
|
||||
use ngr::ir::Program as IR;
|
||||
use ngr::syntax::{ParserError, Program as Syntax};
|
||||
use target_lexicon::Triple;
|
||||
use thiserror::Error;
|
||||
|
||||
/// Clap is great! Even though we don't have many command line arguments
|
||||
/// yet, this is just really neat.
|
||||
#[derive(Parser, Debug)]
|
||||
#[clap(author, version, about, long_about = None)]
|
||||
struct CommandLineArguments {
|
||||
@@ -23,76 +13,14 @@ struct CommandLineArguments {
|
||||
file: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum MainError {
|
||||
#[error(transparent)]
|
||||
Backend(#[from] BackendError),
|
||||
#[error("Parser error")]
|
||||
ParserError(#[from] ParserError),
|
||||
#[error("IO error")]
|
||||
IoError(#[from] std::io::Error),
|
||||
#[error("write error")]
|
||||
WriteError(#[from] object::write::Error),
|
||||
}
|
||||
|
||||
impl From<MainError> for Diagnostic<usize> {
|
||||
fn from(value: MainError) -> Self {
|
||||
match value {
|
||||
MainError::Backend(be) => be.into(),
|
||||
MainError::ParserError(pe) => (&pe).into(),
|
||||
MainError::IoError(e) => Diagnostic::error().with_message(format!("IO error: {}", e)),
|
||||
MainError::WriteError(e) => {
|
||||
Diagnostic::error().with_message(format!("Module write error: {}", e))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn compile(file_database: &mut SimpleFiles<String, String>) -> Result<(), MainError> {
|
||||
let args = CommandLineArguments::parse();
|
||||
|
||||
let syntax = Syntax::parse_file(file_database, &args.file)?;
|
||||
let (mut errors, mut warnings) = syntax.validate();
|
||||
let stop = !errors.is_empty();
|
||||
let messages = errors
|
||||
.drain(..)
|
||||
.map(Into::into)
|
||||
.chain(warnings.drain(..).map(Into::into));
|
||||
let writer = StandardStream::stderr(ColorChoice::Auto);
|
||||
let config = codespan_reporting::term::Config::default();
|
||||
|
||||
for message in messages {
|
||||
term::emit(&mut writer.lock(), &config, file_database, &message).unwrap();
|
||||
}
|
||||
|
||||
if stop {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let ir = IR::from(syntax.simplify());
|
||||
let mut backend = Backend::object_file(Triple::host())?;
|
||||
backend.compile_function("gogogo", ir)?;
|
||||
let bytes = backend.bytes()?;
|
||||
std::fs::write(args.output.unwrap_or_else(|| "output.o".to_string()), bytes)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut file_database = SimpleFiles::new();
|
||||
let args = CommandLineArguments::parse();
|
||||
let mut compiler = ngr::Compiler::default();
|
||||
|
||||
match compile(&mut file_database) {
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
let writer = StandardStream::stderr(ColorChoice::Auto);
|
||||
let config = codespan_reporting::term::Config::default();
|
||||
let output_file = args.output.unwrap_or("output.o".to_string());
|
||||
|
||||
term::emit(
|
||||
&mut writer.lock(),
|
||||
&config,
|
||||
&file_database,
|
||||
&Diagnostic::from(e),
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
if let Some(bytes) = compiler.compile(&args.file) {
|
||||
std::fs::write(&output_file, bytes)
|
||||
.unwrap_or_else(|x| eprintln!("Could not write to file {}: {}", output_file, x));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user