diff --git a/Cargo.lock b/Cargo.lock index 53e2048..5cd11fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,6 +26,12 @@ version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + [[package]] name = "clap" version = "2.33.3" @@ -41,6 +47,17 @@ dependencies = [ "vec_map", ] +[[package]] +name = "getrandom" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "heck" version = "0.3.1" @@ -71,6 +88,12 @@ version = "0.2.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" +[[package]] +name = "ppv-lite86" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" + [[package]] name = "proc-macro-error" version = "1.0.4" @@ -113,6 +136,62 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom", + "libc", + "rand_chacha", + "rand_core", + "rand_hc", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core", +] + +[[package]] +name = "redox_syscall" +version = "0.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "remove_dir_all" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" +dependencies = [ + "winapi", +] + [[package]] name = "rust-embed" version = "5.7.0" @@ -147,10 +226,11 @@ dependencies = [ [[package]] name = "sabre" -version = "0.0.1" +version = "0.0.3" dependencies = [ "rust-embed", "structopt", + "tempfile", ] [[package]] @@ -203,6 +283,20 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "tempfile" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" +dependencies = [ + "cfg-if", + "libc", + "rand", + "redox_syscall", + "remove_dir_all", + "winapi", +] + [[package]] name = "textwrap" version = "0.11.0" @@ -253,6 +347,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index d846aba..55e925f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "sabre" -version = "0.0.1" +version = "0.0.3" authors = ["Garrit Franke "] edition = "2018" @@ -10,8 +10,9 @@ edition = "2018" backend_c = [] backend_node = [] -default = ["backend_c"] +default = ["backend_node"] [dependencies] structopt = "0.3.21" rust-embed = "5.7.0" +tempfile = "3.1.0" diff --git a/src/command/build.rs b/src/command/build.rs index 7eae61b..d562d75 100644 --- a/src/command/build.rs +++ b/src/command/build.rs @@ -22,7 +22,7 @@ use std::io::Read; use std::io::Write; use std::path::PathBuf; -pub fn build(in_file: PathBuf, out_file: PathBuf) -> Result<(), String> { +pub fn build(in_file: &PathBuf, out_file: &PathBuf) -> Result<(), String> { let mut file = File::open(in_file).expect("Could not open file"); let mut contents = String::new(); @@ -39,7 +39,7 @@ pub fn build(in_file: PathBuf, out_file: PathBuf) -> Result<(), String> { let output = generator::generate(program); let mut file = std::fs::File::create(out_file).expect("create failed"); - file.write_all(output.as_bytes()).expect("write failed"); + file.write(output.as_bytes()).expect("write failed"); file.flush().expect("Could not flush file"); Ok(()) diff --git a/src/command/mod.rs b/src/command/mod.rs index b4badde..9288df9 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -14,3 +14,4 @@ * limitations under the License. */ pub mod build; +pub mod run; diff --git a/src/command/run.rs b/src/command/run.rs new file mode 100644 index 0000000..c1ea563 --- /dev/null +++ b/src/command/run.rs @@ -0,0 +1,56 @@ +use crate::command::build; +use std::io::Write; +use std::path::PathBuf; +use std::process::Command; +use std::process::Stdio; +use tempfile::tempdir; + +pub fn run(in_file: PathBuf) -> Result<(), String> { + let out_dir = tempdir() + .expect("Could not create temporary file") + .into_path(); + + let intermediate_out_file_path = out_dir.join("intermediate.c"); + build::build(&in_file, &intermediate_out_file_path)?; + let out_file = out_dir.join("out"); + if cfg!(feature = "backend_c") { + let comp = Command::new("/usr/bin/cc") + .arg(&intermediate_out_file_path) + .arg("-o") + .arg(&out_file) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .output() + .expect("Could not spawn compilation process"); + + let out = Command::new(out_file) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .output() + .expect("Could not spawn run process"); + + std::io::stdout() + .write_all(&out.stdout) + .expect("Could not write to stdout"); + + std::io::stderr() + .write_all(&out.stderr) + .expect("Could not write to stderr"); + } else if cfg!(feature = "backend_node") { + let out = Command::new("node") + .arg(&intermediate_out_file_path) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .output() + .expect("Could not spawn run process"); + + std::io::stdout() + .write_all(&out.stdout) + .expect("Could not write to stdout"); + + std::io::stderr() + .write_all(&out.stderr) + .expect("Could not write to stderr"); + } + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index f1c6d0c..d42de32 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,4 @@ +extern crate cc; /** * Copyright 2020 Garrit Franke * @@ -15,8 +16,8 @@ */ extern crate rust_embed; extern crate structopt; +extern crate tempfile; -use crate::Opt::Build; use std::path::PathBuf; use structopt::StructOpt; @@ -45,13 +46,16 @@ enum Opt { #[structopt(short, long)] out_file: PathBuf, }, + #[structopt()] + Run { in_file: PathBuf }, } fn main() -> Result<(), String> { let opts = Opt::from_args(); match opts { - Build { in_file, out_file } => command::build::build(in_file, out_file)?, + Opt::Build { in_file, out_file } => command::build::build(&in_file, &out_file)?, + Opt::Run { in_file } => command::run::run(in_file)?, }; Ok(())