use clap::{ColorChoice, Parser}; use std::{path::PathBuf, process::ExitCode, rc::Rc}; use talc_lang::{ compiler::compile, parser, symbol::Symbol, value::function::disasm_recursive, Vm, }; mod helper; mod repl; #[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(name: Symbol, src: &str, args: &Args) -> ExitCode { 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, Some(name))); 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) } let file = args.file.as_ref().unwrap(); match std::fs::read_to_string(file) { Ok(s) => exec(Symbol::get(file.as_os_str()), &s, &args), Err(e) => { eprintln!("Error: {e}"); ExitCode::FAILURE } } }