From c64cc5e0fb1c9d215974b1c6ab5d105d6e1b3657 Mon Sep 17 00:00:00 2001 From: RudideC Date: Mon, 6 May 2024 20:56:37 +0200 Subject: [PATCH] Overhauled flag system and added compilation Usage: wyst --flags Flags: (none) -> shows transpiled code -r / --rust -> shows transpiled code and turns it into a rust file -c / --compile -> shows transpiled code, creates a temp.rs file, compiles to an exe and deletes the temp.rs file --- src/compile.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 42 +++++++++++++++++++++++++++++++++----- 2 files changed, 92 insertions(+), 5 deletions(-) create mode 100644 src/compile.rs diff --git a/src/compile.rs b/src/compile.rs new file mode 100644 index 0000000..610fcbd --- /dev/null +++ b/src/compile.rs @@ -0,0 +1,55 @@ +use std::fs; +use std::path::Path; +use std::process::Command; +use std::io::{Error, ErrorKind}; + +pub fn write_to_rust_file(transpiled_code: &str, file_name: &str) -> Result<(), Error> { + // Determine the file extension based on the provided file_name + let mut output_file = String::from(file_name); + if let Some(extension) = Path::new(file_name).extension() { + if let Some(ext_str) = extension.to_str() { + // Replace the existing extension with ".rs" if it's not already ".rs" + if ext_str != "rs" { + output_file.push_str(".rs"); + } + } + } else { + // If no extension is provided, append ".rs" to the file_name + output_file.push_str(".rs"); + } + + // Write the transpiled_code to the determined output file + fs::write(&output_file, transpiled_code)?; + + Ok(()) +} + +pub fn compile_to_executable(rust_file: &str, output_exe: &str) -> Result<(), Error> { + let output = Command::new("rustc") + .arg(rust_file) + .arg("-o") + .arg(output_exe) + .output()?; + + // Check if compilation was successful + if output.status.success() { + println!("Compilation successful!"); + } else { + if let Some(code) = output.status.code() { + eprintln!("Compilation failed with error code: {}", code); + } + if !output.stdout.is_empty() { + eprintln!("Compiler output:\n{}", String::from_utf8_lossy(&output.stdout)); + } + if !output.stderr.is_empty() { + eprintln!("Compiler errors:\n{}", String::from_utf8_lossy(&output.stderr)); + } + // Compilation failed, delete the temporary Rust file + if let Err(err) = fs::remove_file(rust_file) { + eprintln!("Failed to delete temporary Rust file: {}", err); + } + return Err(Error::new(ErrorKind::Other, "Compilation failed")); + } + + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 01642a4..4642ce4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,15 +1,21 @@ mod transpiler; mod parser; mod lexer; +mod compile; use std::fs; use clap::Parser; - -//Arguments for Wyst (short and long version) +// Arguments for Wyst (short and long version) #[derive(Parser)] struct Args { + #[clap()] + file: std::path::PathBuf, + #[clap(short, long)] - file: String, + rust: Option, + + #[clap(short, long)] + compile: Option, } fn main() { @@ -18,5 +24,31 @@ fn main() { .expect("Error reading file"); let transpiled_code = transpiler::transpile(file_content, 0); - println!("{}", transpiled_code); -} \ No newline at end of file + + match args.rust { + Some(ref rust_file_name) => { + // Write transpiled code to Rust file + compile::write_to_rust_file(&transpiled_code, rust_file_name) + .expect("Error writing to Rust file"); + println!("Transpiled code written to {}", rust_file_name); + } + None => { + // No Rust file specified, print transpiled code + println!("{}", transpiled_code); + } + } + + match args.compile { + Some(ref exe_name) => { + // Compile transpiled Rust code into executable + compile::write_to_rust_file(&transpiled_code, "temp.rs") + .expect("Error writing to temporary Rust file"); + compile::compile_to_executable("temp.rs", exe_name) + .expect("Error compiling to executable"); + fs::remove_file("temp.rs") + .expect("Error removing temporary Rust file"); + println!("Compiled executable: {}", exe_name); + } + None => {} + } +}