hence/henceforth/src/main.rs

81 lines
2.0 KiB
Rust

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<String>,
#[clap(short, long, action)]
optimize: Option<bool>,
#[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(())
}
}
}