Overhauled flag system and added compilation

Usage: wyst <file.wst> --flags

Flags:
(none) -> shows transpiled code
-r / --rust <rust_file_name> -> shows transpiled code and turns it into a rust file
-c / --compile <exe_name> -> shows transpiled code, creates a temp.rs file, compiles to an exe and deletes the temp.rs file
This commit is contained in:
RudideC
2024-05-06 20:56:37 +02:00
parent 7f7faf67b5
commit c64cc5e0fb
2 changed files with 92 additions and 5 deletions
+55
View File
@@ -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(())
}
+36 -4
View File
@@ -1,15 +1,21 @@
mod transpiler; mod transpiler;
mod parser; mod parser;
mod lexer; mod lexer;
mod compile;
use std::fs; use std::fs;
use clap::Parser; use clap::Parser;
// Arguments for Wyst (short and long version)
//Arguments for Wyst (short and long version)
#[derive(Parser)] #[derive(Parser)]
struct Args { struct Args {
#[clap()]
file: std::path::PathBuf,
#[clap(short, long)] #[clap(short, long)]
file: String, rust: Option<String>,
#[clap(short, long)]
compile: Option<String>,
} }
fn main() { fn main() {
@@ -18,5 +24,31 @@ fn main() {
.expect("Error reading file"); .expect("Error reading file");
let transpiled_code = transpiler::transpile(file_content, 0); let transpiled_code = transpiler::transpile(file_content, 0);
println!("{}", transpiled_code);
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 => {}
}
} }