Very weirdly organized, but it JITs!

This commit is contained in:
2023-03-24 10:28:32 -05:00
parent ff8412acca
commit 4aa3a9419a
14 changed files with 441 additions and 81 deletions

97
src/bin/ngrc.rs Normal file
View File

@@ -0,0 +1,97 @@
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::BackendError;
use ngr::backend::Program as Cranelift;
use ngr::ir::Program as IR;
use ngr::syntax::{ParserError, Program as Syntax};
use target_lexicon::Triple;
use thiserror::Error;
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct CommandLineArguments {
/// Optional output file name
#[clap(short, long)]
output: Option<String>,
/// The file to parse
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 compiled = Cranelift::new(Triple::host(), ir)?;
let bytes = compiled.bytes()?;
std::fs::write(args.output.unwrap_or_else(|| "output.o".to_string()), bytes)?;
Ok(())
}
fn main() {
let mut file_database = SimpleFiles::new();
match compile(&mut file_database) {
Ok(()) => {}
Err(e) => {
let writer = StandardStream::stderr(ColorChoice::Auto);
let config = codespan_reporting::term::Config::default();
term::emit(
&mut writer.lock(),
&config,
&file_database,
&Diagnostic::from(e),
)
.unwrap();
}
}
}