use lightning_sys::{Jit, JitWord, Reg, NULL};
const JIT_R0: Reg = Reg::R(0);
const JIT_R1: Reg = Reg::R(1);
#[allow(clippy::print_literal)]
fn main() {
let mut j = Jit::new();
let mut js = j.new_state();
let fact = js.forward();
js.prolog();
let inp = js.arg();
js.getarg(JIT_R0, &inp);
js.prepare();
js.pushargi(1);
js.pushargr(JIT_R0);
let call = js.finishi(NULL);
js.patch_at(&call, &fact);
js.retval(JIT_R0);
js.retr(JIT_R0);
js.epilog();
js.link(&fact);
js.prolog();
js.frame(16);
let fact_entry = js.label();
let ac = js.arg();
let inp = js.arg();
js.getarg(JIT_R0, &ac);
js.getarg(JIT_R1, &inp);
let fact_out = js.blei(JIT_R1, 1);
js.mulr(JIT_R0, JIT_R0, JIT_R1);
js.putargr(JIT_R0, &ac);
js.subi(JIT_R1, JIT_R1, 1);
js.putargr(JIT_R1, &inp);
let jump = js.jmpi();
js.patch_at(&jump, &fact_entry);
js.patch(&fact_out);
js.retr(JIT_R0);
let factorial = unsafe{ js.emit::<extern fn(JitWord) -> JitWord>() };
js.clear();
let arg = std::env::args().nth(1).map(|x| x.parse().unwrap_or(0)).unwrap_or(5);
println!("factorial({}) = {}", arg, factorial(arg));
}