111 lines
3.3 KiB
Rust
111 lines
3.3 KiB
Rust
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_codegen::{isa, settings, CodegenError};
|
|
use cranelift_module::{default_libcall_names, ModuleError};
|
|
use cranelift_object::{object, ObjectBuilder, ObjectModule};
|
|
use ngr::asts::lil;
|
|
use ngr::passes::{run_front_end, BackendError};
|
|
use ngr::runtime::RuntimeFunctions;
|
|
use pretty::Arena;
|
|
use std::io;
|
|
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("Error parsing triple: {0}")]
|
|
Isa(#[from] isa::LookupError),
|
|
|
|
#[error("Code generation error: {0}")]
|
|
Codegen(#[from] CodegenError),
|
|
|
|
#[error("Module error: {0}")]
|
|
Module(#[from] ModuleError),
|
|
|
|
#[error("IO error: {0}")]
|
|
IO(#[from] io::Error),
|
|
|
|
#[error("Object write error: {0}")]
|
|
Object(#[from] object::write::Error),
|
|
|
|
#[error(transparent)]
|
|
Backend(#[from] BackendError),
|
|
}
|
|
|
|
fn main() -> Result<(), MainError> {
|
|
let args = CommandLineArguments::parse();
|
|
let mut file_database = SimpleFiles::new();
|
|
let initial_file_name = &args.file;
|
|
let mut hil_conversion_result = run_front_end(&mut file_database, initial_file_name);
|
|
|
|
let writer = StandardStream::stderr(ColorChoice::Auto);
|
|
let config = codespan_reporting::term::Config::default();
|
|
|
|
for error in hil_conversion_result.errors.drain(..) {
|
|
term::emit(
|
|
&mut writer.lock(),
|
|
&config,
|
|
&file_database,
|
|
&Diagnostic::from(error),
|
|
)
|
|
.unwrap();
|
|
}
|
|
for warning in hil_conversion_result.warnings.drain(..) {
|
|
term::emit(
|
|
&mut writer.lock(),
|
|
&config,
|
|
&file_database,
|
|
&Diagnostic::from(warning),
|
|
)
|
|
.unwrap();
|
|
}
|
|
|
|
if let Some((hil_tree, variable_map)) = hil_conversion_result.result {
|
|
let arena = Arena::new();
|
|
println!("HIL Tree:");
|
|
hil_tree
|
|
.pretty(&variable_map, &arena)
|
|
.into_doc()
|
|
.render_colored(72, StandardStream::stdout(ColorChoice::Auto))
|
|
.unwrap();
|
|
|
|
let lil_tree = lil::Program::convert(hil_tree, variable_map);
|
|
println!("LIL Tree:");
|
|
lil_tree
|
|
.pretty(&arena)
|
|
.into_doc()
|
|
.render_colored(72, StandardStream::stdout(ColorChoice::Auto))
|
|
.unwrap();
|
|
|
|
let platform = Triple::host();
|
|
let isa = isa::lookup(platform.clone())?.finish(settings::Flags::new(settings::builder()))?;
|
|
let object_builder = ObjectBuilder::new(isa, "example", default_libcall_names())?;
|
|
let mut object_module = ObjectModule::new(object_builder);
|
|
let rtfuns = RuntimeFunctions::new(&platform, &mut object_module)?;
|
|
|
|
let _compiled = lil_tree.into_cranelift(&mut object_module, &rtfuns)?;
|
|
|
|
// somethingvar?
|
|
|
|
let bytes = object_module.finish().emit()?;
|
|
|
|
std::fs::write("output.o", bytes)?;
|
|
}
|
|
|
|
Ok(())
|
|
}
|