#![allow(unused)] use std::{ collections::HashMap, fmt::format, fs::{read_to_string, File}, io::{BufWriter, Write}, process::exit, }; use {error_stack::Report, hblang::Options}; use crate::Error; pub struct Package { name: String, binaries: Vec, build_cmd: String, args: HashMap, } impl Package { pub fn load_from_file(path: String) -> Self { let contents = match std::fs::read_to_string(path.clone()) { // If successful return the files text as `contents`. // `c` is a local variable. Ok(c) => c, // Handle the `error` case. Err(_) => { // Write `msg` to `stderr`. eprintln!("Could not read file `{}`", path); // Exit the program with exit code `1`. exit(1); } }; use toml::Value; let mut data: Value = toml::from_str(&contents).unwrap(); let mut name = data .get("package") .unwrap() .get("name") .unwrap() .to_string(); name.pop(); name.remove(0); let dependants = data.get("dependants").unwrap(); let bin_table = dependants.get("binaries").unwrap().as_table().unwrap(); let mut binaries = vec![]; for (count, (name, table)) in bin_table.into_iter().enumerate() { binaries.push(name.clone()); } let build_table = data.get("build").unwrap(); let mut build_cmd: String = build_table.get("command").unwrap().as_str().unwrap().into(); build_cmd.remove(0); let mut args: HashMap = match build_table.get("args") { None => HashMap::new(), Some(v) => v .as_table() .unwrap() .into_iter() .map(|(k, v)| (k.clone(), v.to_string())) .collect::>(), }; Self { name, binaries, build_cmd, args, } } pub fn build(&self, out: &mut Vec) -> std::io::Result<()> { if self.binaries.contains(&"hblang".to_string()) { let file = self.build_cmd.split_ascii_whitespace().last().unwrap(); let in_house_regalloc = self .args .get("use_new_regalloc") .map_or(false, |str| str.parse().expect("must be a boolean")); let path = format!("sysdata/programs/{}/{}", self.name, file); // compile here hblang::run_compiler( &path, Options { fmt: true, in_house_regalloc, ..Default::default() }, out, )?; match std::fs::create_dir("target/programs") { Ok(_) => (), Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => (), Err(e) => panic!("{}", e), } hblang::run_compiler( &path, Options { in_house_regalloc, ..Default::default() }, out, )?; std::fs::write(format!("target/programs/{}.hbf", self.name), &out)?; out.clear(); hblang::run_compiler( &path, Options { dump_asm: true, in_house_regalloc, ..Default::default() }, out, )?; std::fs::write(format!("target/programs/{}.hba", self.name), &out)?; out.clear(); } Ok(()) } }