2024-02-27 05:18:43 +00:00
|
|
|
use clap::{ColorChoice, Parser};
|
|
|
|
use talc_lang::{compiler::compile, value::function::disasm_recursive, Vm};
|
|
|
|
use std::{path::PathBuf, process::ExitCode, rc::Rc};
|
|
|
|
|
|
|
|
mod repl;
|
|
|
|
mod helper;
|
2024-02-21 16:04:18 +00:00
|
|
|
|
2024-02-23 19:54:34 +00:00
|
|
|
#[derive(Parser, Debug)]
|
|
|
|
#[command(version, about, long_about = None)]
|
|
|
|
struct Args {
|
2024-02-27 05:18:43 +00:00
|
|
|
/// file to run
|
|
|
|
file: Option<PathBuf>,
|
2024-02-23 19:54:34 +00:00
|
|
|
|
2024-02-27 05:18:43 +00:00
|
|
|
/// start the repl
|
|
|
|
#[arg(short, long)]
|
|
|
|
repl: bool,
|
2024-02-23 19:54:34 +00:00
|
|
|
|
2024-02-27 05:18:43 +00:00
|
|
|
/// show disassembled bytecode
|
|
|
|
#[arg(short, long)]
|
|
|
|
disasm: bool,
|
2024-02-23 19:54:34 +00:00
|
|
|
|
2024-03-08 00:38:57 +00:00
|
|
|
/// show disassembled bytecode
|
|
|
|
#[arg(short='H', long)]
|
|
|
|
histfile: Option<PathBuf>,
|
|
|
|
|
2024-02-27 05:18:43 +00:00
|
|
|
/// enable or disable color
|
|
|
|
#[arg(short, long, default_value="auto")]
|
|
|
|
color: ColorChoice,
|
2024-02-23 19:54:34 +00:00
|
|
|
}
|
|
|
|
|
2024-02-27 05:18:43 +00:00
|
|
|
fn exec(src: String, args: &Args) -> ExitCode {
|
2024-02-23 19:54:34 +00:00
|
|
|
let parser = talc_lang::Parser::new();
|
2024-02-21 16:04:18 +00:00
|
|
|
let mut vm = Vm::new(256);
|
2024-02-27 05:18:43 +00:00
|
|
|
talc_std::load_all(&mut vm);
|
|
|
|
|
|
|
|
let ex = match parser.parse(&src) {
|
|
|
|
Ok(ex) => ex,
|
|
|
|
Err(e) => {
|
|
|
|
eprintln!("Error: {e}");
|
|
|
|
return ExitCode::FAILURE
|
|
|
|
},
|
|
|
|
};
|
|
|
|
|
|
|
|
let func = Rc::new(compile(&ex));
|
|
|
|
|
|
|
|
if args.disasm {
|
|
|
|
if let Err(e) = disasm_recursive(&func, &mut std::io::stderr()) {
|
|
|
|
eprintln!("Error: {e}");
|
|
|
|
return ExitCode::FAILURE
|
2024-02-21 16:04:18 +00:00
|
|
|
}
|
|
|
|
}
|
2024-02-27 05:18:43 +00:00
|
|
|
|
|
|
|
if let Err(e) = vm.run_function(func.clone(), vec![func.into()]) {
|
|
|
|
eprintln!("{e}");
|
|
|
|
ExitCode::FAILURE
|
|
|
|
} else {
|
|
|
|
ExitCode::SUCCESS
|
|
|
|
}
|
2024-02-23 19:54:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fn main() -> ExitCode {
|
2024-02-27 05:18:43 +00:00
|
|
|
let args = Args::parse();
|
2024-02-23 19:54:34 +00:00
|
|
|
|
2024-02-27 05:18:43 +00:00
|
|
|
if args.repl || args.file.is_none() {
|
|
|
|
return repl::repl(&args)
|
|
|
|
}
|
2024-02-22 19:27:35 +00:00
|
|
|
|
2024-02-27 05:18:43 +00:00
|
|
|
match std::fs::read_to_string(args.file.as_ref().unwrap()) {
|
|
|
|
Ok(s) => exec(s, &args),
|
|
|
|
Err(e) => {
|
|
|
|
eprintln!("Error: {e}");
|
|
|
|
ExitCode::FAILURE
|
|
|
|
}
|
|
|
|
}
|
2024-02-21 16:04:18 +00:00
|
|
|
}
|