Skip to content

Commit

Permalink
refactor(command): streamline process execution and improve error han…
Browse files Browse the repository at this point in the history
…dling
  • Loading branch information
garritfra committed Dec 10, 2024
1 parent f3a9ff3 commit e8708b1
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 70 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

- Fixed parsing of binary operations in inline function expressions ([#109](https://github.com/antimony-lang/antimony/pull/109))

**Maintenance**

- Refactored command execution for better error handling and code organization

## v0.8.0 (2024-04-05)

**Features**
Expand Down
141 changes: 71 additions & 70 deletions src/command/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,84 +16,85 @@
use crate::command::build;
use crate::generator::Target;
use std::fs::OpenOptions;
use std::io::Read;
use std::io::Write;
use std::path::PathBuf;
use std::process::Command;
use std::process::Stdio;
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};

pub fn run(target: Target, in_file: PathBuf) -> Result<(), String> {
let mut buf = Box::<Vec<u8>>::default();
build::build_to_buffer(&target, &in_file, &mut buf)?;
type Result<T> = std::result::Result<T, String>;

match target {
Target::JS => {
let process = Command::new("node")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.map_err(|e| format!("Could not spawn Node.js process: {}", e))?;
fn run_command(cmd: &mut Command) -> Result<()> {
cmd.spawn()
.map_err(|e| format!("Failed to spawn process: {}", e))?
.wait()
.map_err(|e| format!("Failed to wait for process: {}", e))
.map(|_| ())
}

fn run_node(buf: &[u8]) -> Result<()> {
let process = Command::new("node")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.map_err(|e| format!("Could not spawn Node.js process: {}", e))?;

// Write to stdin
process
.stdin
.ok_or("Failed to open stdin")?
.write_all(buf)
.map_err(|e| format!("Could not write to Node.js process: {}", e))?;

process
.stdin
.unwrap()
.write_all(&buf)
.map_err(|e| format!("Could not write to Node.js process: {}", e))?;
// Read from stdout
let mut output = Vec::new();
process
.stdout
.ok_or("Failed to open stdout")?
.read_to_end(&mut output)
.map_err(|e| format!("Could not read from child process: {}", e))?;

let mut s = Vec::new();
process
.stdout
.unwrap()
.read_to_end(&mut s)
.map_err(|e| format!("Could not read from child process: {}", e))?;
std::io::stdout()
.write_all(&s)
.map_err(|e| format!("Could not write to stdout: {}", e))?;
}
Target::Qbe => {
let dir_path = "./"; // TODO: Use this for changind build directory
let filename = in_file.file_stem().unwrap().to_str().unwrap();
let ssa_path = format!("{dir_path}{}.ssa", filename);
let asm_path = format!("{dir_path}{}.s", filename);
let exe_path = format!("{dir_path}{}.exe", filename);
// Write to stdout
std::io::stdout()
.write_all(&output)
.map_err(|e| format!("Could not write to stdout: {}", e))
}

fn run_qbe(buf: Vec<u8>, in_file: &Path) -> Result<()> {
let dir_path = "./"; // TODO: Use this for changing build directory
let filename = in_file
.file_stem()
.and_then(|s| s.to_str())
.ok_or("Invalid filename")?;

let mut ssa_file = OpenOptions::new()
.read(true)
.write(true)
.create(true)
.truncate(true)
.open(&ssa_path)
.unwrap();
let buff = *buf;
ssa_file.write_all(&buff).unwrap();
// Create paths without array destructuring
let ssa_path = format!("{dir_path}{}.ssa", filename);
let asm_path = format!("{dir_path}{}.s", filename);
let exe_path = format!("{dir_path}{}.exe", filename);

// TODO: Simplify!
// Write SSA file
OpenOptions::new()
.read(true)
.write(true)
.create(true)
.truncate(true)
.open(&ssa_path)
.map_err(|e| format!("Failed to open SSA file: {}", e))?
.write_all(&buf)
.map_err(|e| format!("Failed to write SSA file: {}", e))?;

// SSA to ASM
Command::new("qbe")
.arg(&ssa_path)
.arg("-o")
.arg(&asm_path)
.spawn()
.unwrap()
.wait()
.unwrap();
// Compile and run
run_command(Command::new("qbe").arg(&ssa_path).arg("-o").arg(&asm_path))?;
run_command(Command::new("gcc").arg(&asm_path).arg("-o").arg(&exe_path))?;
run_command(&mut Command::new(&exe_path))
}

// ASM to EXE
Command::new("gcc")
.arg(&asm_path)
.arg("-o")
.arg(&exe_path)
.spawn()
.unwrap()
.wait()
.unwrap();
pub fn run(target: Target, in_file: PathBuf) -> Result<()> {
let mut buf = Box::<Vec<u8>>::default();
build::build_to_buffer(&target, &in_file, &mut buf)?;

// Run the EXE
Command::new(exe_path).spawn().unwrap().wait().unwrap();
}
_ => todo!(),
match target {
Target::JS => run_node(&buf),
Target::Qbe => run_qbe(*buf, &in_file),
_ => Err("Unsupported target".to_string()),
}
Ok(())
}

0 comments on commit e8708b1

Please sign in to comment.