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; #[derive(Parser, Debug)] #[command(version, about, long_about = None)] struct Args { /// file to run file: Option, /// start the repl #[arg(short, long)] repl: bool, /// show disassembled bytecode #[arg(short, long)] disasm: bool, /// show disassembled bytecode #[arg(short='H', long)] histfile: Option, /// enable or disable color #[arg(short, long, default_value="auto")] color: ColorChoice, } fn exec(src: &str, args: &Args) -> ExitCode { let parser = talc_lang::Parser::new(); let mut vm = Vm::new(256); 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 } } if let Err(e) = vm.run_function(func.clone(), vec![func.into()]) { eprintln!("{e}"); ExitCode::FAILURE } else { ExitCode::SUCCESS } } fn main() -> ExitCode { let args = Args::parse(); if args.repl || args.file.is_none() { return repl::repl(&args) } match std::fs::read_to_string(args.file.as_ref().unwrap()) { Ok(s) => exec(&s, &args), Err(e) => { eprintln!("Error: {e}"); ExitCode::FAILURE } } }