commit 10b1417e03ec87a955e16a54866e5e288a70e920 Author: jude Date: Sun Feb 18 16:09:21 2024 +0000 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c403c34 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +.idea/ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..d8f3a5a --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "qroc" +version = "0.1.0" +dependencies = [ + "md5", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..7d0cb7b --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "qroc" +version = "0.1.0" +edition = "2021" + +[lib] +proc-macro = true + +[[bin]] +name = "bin" +path = "src/bin.rs" + +[dependencies] +md5 = "0.7.0" diff --git a/src/bin.rs b/src/bin.rs new file mode 100644 index 0000000..6835ce0 --- /dev/null +++ b/src/bin.rs @@ -0,0 +1,12 @@ +use qroc::perl; + +fn main() { + println!("{}", add(1, 2)); +} + +#[perl { + $_ =~ s/populate/a + b/g; +}] +fn add(a: isize, b: isize) -> isize { + populate +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..8968482 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,48 @@ +use proc_macro::TokenStream; +use std::env; +use std::fs::{create_dir_all, File}; +use std::io::Read; +use std::path::Path; + +use std::process::Command; + +#[proc_macro_attribute] +pub fn perl(attr: TokenStream, item: TokenStream) -> TokenStream { + let out_path = format!("/tmp/{}/outputs", env!("CARGO_PKG_NAME")); + if !Path::new(&out_path).exists() { + create_dir_all(Path::new(&out_path)).expect("Couldn't create temp directory"); + } + + let pl = attr.to_string(); + let body = item.to_string(); + + let filestub = format!("{:x}", md5::compute(format!("{}+{}", pl, body))); + + let header_pl = format!( + "$_ = @ARGV[0]; {}; open (FH, '>', '{}/{}'); print FH $_;", + pl, out_path, filestub + ); + + let output = Command::new("perl") + .args(["-e", &header_pl, &body]) + .output() + .expect("Failed to invoke perl"); + + if !output.stderr.is_empty() { + let err = String::from_utf8(output.stderr).expect("Couldn't decode UTF-8"); + panic!("stderr(perl): {}", err) + } else { + if !output.stdout.is_empty() { + let stdout = String::from_utf8(output.stdout).expect("Couldn't decode UTF-8"); + println!("stdout(perl): {}", stdout); + } + + let mut outfile = File::open(Path::new(&format!("{}/{}", out_path, filestub))) + .expect("Couldn't open output file"); + let mut tokens = String::new(); + outfile + .read_to_string(&mut tokens) + .expect("Couldn't read output file"); + tokens.parse().expect("Couldn't form token stream") + } +}