// trait_upcasting - https://github.com/rust-lang/rust/issues/65991 // stabilization in progress #![feature(trait_upcasting)] mod ast; mod builtins; mod compiler; mod disassemble; mod obj; mod parser; mod token; mod vm; use std::fmt; use std::fs::File; use std::io::prelude::*; use std::path::PathBuf; use clap::Parser as ClapParser; use thiserror::Error; #[derive(ClapParser, Debug)] #[command(version, about, long_about = None)] struct Args { #[arg(short, long, help = "Dump program disassembly and exit")] disassemble: bool, #[arg(help = "The path of the file to run")] path: PathBuf, } #[derive(Debug, Error)] struct ProgramError(String); impl fmt::Display for ProgramError { fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result { write!(fmt, "{}", self.0) } } fn main() -> Result<(), Box> { let args = Args::parse(); let mut file = File::open(&args.path)?; let mut contents = String::new(); file.read_to_string(&mut contents)?; let mut parser = parser::Parser::new(contents, &args.path)?; let ast = parser.parse_all()?; if parser.was_error() { return Err(ProgramError("error occurred, exiting".to_string()).into()); } // initialize type system obj::init_types(); // compile let (chunk, constants, globals) = compiler::Compiler::default().compile(&ast)?; if args.disassemble { disassemble::disassemble(&chunk, &constants, &globals); return Ok(()); } // run let mut vm = vm::Vm::new(chunk.into(), constants, globals); vm.run(); Ok(()) }