use clap::{Parser, Subcommand};
use std::env;
use std::fs;
use std::path::PathBuf;
use woxi::interpret;
#[derive(Parser)]
#[command(author, version, about, long_about = None)]
struct Cli {
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Eval {
expression: String,
},
Run {
#[arg(value_name = "FILE")]
file: PathBuf,
},
#[command(external_subcommand)]
Script(Vec<String>), }
fn without_shebang(src: &str) -> String {
if src.starts_with("#!") {
src.lines().skip(1).collect::<Vec<_>>().join("\n")
} else {
src.to_owned()
}
}
fn main() {
let cli = Cli::parse();
match cli.command {
Commands::Eval { expression } => match interpret(&expression) {
Ok(result) => println!("{result}"),
Err(e) => eprintln!("Error: {}", e),
},
Commands::Run { file } => {
let absolute_path = if file.is_absolute() {
file.clone()
} else {
env::current_dir()
.unwrap_or_else(|_| PathBuf::from("."))
.join(&file)
};
match fs::read_to_string(&absolute_path) {
Ok(content) => {
let code = without_shebang(&content);
match interpret(&code) {
Ok(_result) => {
}
Err(e) => eprintln!("Error interpreting file: {}", e),
}
}
Err(e) => eprintln!("Error reading file: {}", e),
}
}
Commands::Script(args) => {
if args.is_empty() {
eprintln!("Error: no script file supplied");
return;
}
let file = PathBuf::from(&args[0]);
let absolute_path = if file.is_absolute() {
file.clone()
} else {
env::current_dir()
.unwrap_or_else(|_| PathBuf::from("."))
.join(&file)
};
match fs::read_to_string(&absolute_path) {
Ok(content) => {
let code = without_shebang(&content);
match interpret(&code) {
Ok(_result) => { }
Err(e) => eprintln!("Error interpreting file: {}", e),
}
}
Err(e) => eprintln!("Error reading file: {}", e),
}
}
}
}