use anyhow::Result; use clap::{Parser, Subcommand}; use hence::assembler::ToCode; 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(short, long, action)] optimize: 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)?; println!("{:#?}", tokens); Ok(()) } Commands::Parse { src } => { let source = fs::read_to_string(src)?; let tokens = lexer::lex(&source)?; let body = parser::parse(tokens)?; println!("{:#?}", body); Ok(()) } Commands::Compile { src, out, optimize, dump, } => { let source = fs::read_to_string(&src)?; let tokens = lexer::lex(&source)?; let ast = parser::parse(tokens)?; let ast = compiler::compile(ast, optimize.unwrap_or(true))?; let assembly = format!("{}\n", ast.to_code()); if dump { print!("{}", assembly); } if let Some(x) = out { fs::write(x, &assembly)?; } Ok(()) } } }