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, /// 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(()) }