use anyhow::Result; use clap::{Parser, Subcommand}; use std::fs; use henceforth::*; #[derive(Debug, Parser)] #[clap(author, version, about, long_about = None)] struct Cli { #[clap(subcommand)] commands: Commands, } #[derive(Debug, Subcommand)] enum Commands { #[clap(about = "Lexes source code and outputs tokens")] Lex { #[clap(value_parser)] src: String, }, #[clap(about = "Parses source code and outputs AST")] Parse { #[clap(value_parser)] src: String, }, #[clap(about = "Compiles assembly from source code")] Compile { #[clap(value_parser)] src: String, #[clap(value_parser)] out: Option, #[clap(long, action)] dump: bool, }, } fn main() -> Result<()> { let args = Cli::parse(); match args.commands { Commands::Lex { src } => { let source = fs::read_to_string(src)?; let tokens = lexer::lex(source)?; dbg!(tokens); Ok(()) } Commands::Parse { src } => { let source = fs::read_to_string(src)?; let tokens = lexer::lex(source)?; let body = parser::parse(tokens)?; dbg!(body); Ok(()) } Commands::Compile { src, out, dump } => { let source = fs::read_to_string(&src)?; let tokens = lexer::lex(source)?; let ast = parser::parse(tokens)?; let assembly = compiler::compile(ast)?; if let Some(x) = out { fs::write(x, &assembly)?; } if dump { println!("{}", assembly); } Ok(()) } } } #[cfg(test)] mod tests {}