1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
use std::process::Command; use std::path::PathBuf; use std::fs; use crate::{getvar, InitialOptions, CompileOptions}; use crate::engine::file::{FileOwner, SourceFile}; use crate::engine::fmt::{eprintln_err_vec, eprintln_err_loc_vec}; use crate::engine::parser::parse_lines; use crate::engine::state::State; use crate::engine::{il, codegen}; use lazy_static::lazy_static; use std::io::Write; lazy_static! { static ref COMPILE_DIR: PathBuf = dirs::data_dir().unwrap().join(getvar!("COMPILE_DIR_NAME")); } const TOML_PRELUDE: &str = "\ [package] name=\"fct-bin\" version=\"1.0.0\" edition=\"2018\" [dependencies] num=\"0.3.0\" "; pub fn compile(initial_options: InitialOptions, compile_options: CompileOptions) -> i32 { let InitialOptions { source_file: source_file_name, escape_filenames, } = initial_options; let CompileOptions { output_file: output_file_name, local_lib, silent, } = compile_options; let mut file_owner = FileOwner::init(); match SourceFile::from_arg(source_file_name, escape_filenames, &mut file_owner) { Ok(source_file) => { file_owner.files_mut()[source_file].read(); let mut ins_vec = vec![]; let mut err_vec = vec![]; let mut state = State::init(); let mut lines = parse_lines(file_owner.files()[source_file].handle(), &file_owner); il::gen_lines(&mut ins_vec, &mut err_vec, &mut lines, &mut state, &file_owner); if err_vec.is_empty() { let code = codegen::gen_rust(ins_vec); fs::create_dir_all(&*COMPILE_DIR).unwrap(); Command::new("cargo").current_dir(&*COMPILE_DIR).args(&["init", "--bin"]).output().unwrap(); fs::write((*COMPILE_DIR).join("src").join("main.rs"), code).unwrap(); let mut toml = fs::File::create((*COMPILE_DIR).join("Cargo.toml")).unwrap(); toml.write_all(TOML_PRELUDE.as_bytes()).unwrap(); match local_lib { Some(local_library) => { write!(toml, "fct={{path=\"{}\"}}\n", local_library).unwrap(); } None => { write!(toml, "fct=\"{}\"\n", env!("CARGO_PKG_VERSION")).unwrap(); } } toml.flush().unwrap(); let mut com = Command::new("cargo"); com.current_dir(&*COMPILE_DIR).args(&["build", "--release"]); if silent { com.output().unwrap(); } else { com.spawn().unwrap().wait().unwrap(); } if cfg!(windows) { fs::copy(COMPILE_DIR.join("target").join("release").join("fct-bin.exe"), &output_file_name).ok(); } else { fs::copy(COMPILE_DIR.join("target").join("release").join("fct-bin"), &output_file_name).ok(); } } else { eprintln_err_loc_vec(err_vec, &file_owner); } } source_file_result => { if let Err(err_vec) = source_file_result { eprintln_err_vec(err_vec, &file_owner) } } } 0 }