use std::io::Write; use std::path::Path; use dever_backend_bridge::{Target, emit_object}; use dever_core::source::SourceMap; use dever_runtime::config::Settings; fn main() -> Result<(), String> { let arguments = std::env::args_os().skip(1).collect::>(); let (project, output, ir) = match arguments.as_slice() { [project, output] => (project, output, None), [project, output, ir] => (project, output, Some(ir)), _ => { return Err("usage: api-json-object [new-ir-file]".into()); } }; let project = Path::new(project); let sources = SourceMap::load(&project.join("module")).map_err(|errors| format!("{errors:?}"))?; let settings = Settings::load_project(project).map_err(|error| error.to_string())?; let program = dever_core::check_with_settings(&sources, &settings).map_err(|errors| { errors .iter() .map(|error| error.render(&sources)) .collect::() })?; let errors = program.application_errors()?; if !errors.is_empty() { return Err(errors .iter() .map(|error| error.render(&sources)) .collect::()); } let module = dever_core::llvm::emit_executable(&program, &sources)?; if let Some(ir) = ir { let mut ir = std::fs::OpenOptions::new() .write(true) .create_new(true) .open(ir) .map_err(|error| error.to_string())?; ir.write_all(module.as_bytes()) .map_err(|error| error.to_string())?; } let object = emit_object(&module, Target::LinuxX86_64)?; let mut output = std::fs::OpenOptions::new() .write(true) .create_new(true) .open(output) .map_err(|error| error.to_string())?; output.write_all(&object).map_err(|error| error.to_string()) }