use std::path::PathBuf;
use clap::Parser;
use miette::{IntoDiagnostic, WrapErr};
use xqasm::assemble_source;
use xqvm::Program;
#[derive(Debug, Parser)]
pub(crate) struct Args {
#[arg(long)]
text: bool,
file: PathBuf,
}
pub(crate) fn run(args: &Args) -> miette::Result<()> {
let source = std::fs::read(&args.file)
.into_diagnostic()
.wrap_err_with(|| format!("failed to read '{}'", args.file.display()))?;
let program: Program = if args.text {
let text = String::from_utf8(source)
.into_diagnostic()
.wrap_err("assembly file is not valid UTF-8")?;
assemble_source(&text)
.map_err(|e| miette::miette!("{e}"))
.wrap_err("assembly failed")?
} else {
Program::decode(&source)
.into_diagnostic()
.wrap_err("failed to decode program")?
};
xqvm::verifier::verify(&program).map_err(|e| miette::miette!("{e}"))?;
let count = instruction_count(program.code());
println!(
"ok: {} ({} instruction{})",
args.file.display(),
count,
if count == 1 { "" } else { "s" },
);
Ok(())
}
fn instruction_count(buf: &[u8]) -> usize {
xqvm::InstructionStream::new(buf)
.filter_map(Result::ok)
.count()
}