use kataan::parser::Parser;
use kataan::{Ctx, Interp, NanBox};
fn main() {
let mut interp = Interp::new();
interp.register_global_fn("hypot", 2, |cx: &mut Ctx, _this, args| {
let a = cx.to_number(args.first().copied().unwrap_or(cx.undefined()))?;
let b = cx.to_number(args.get(1).copied().unwrap_or(cx.undefined()))?;
Ok(cx.number((a * a + b * b).sqrt()))
});
interp.register_global_fn("parseHex", 1, |cx: &mut Ctx, _this, args| {
let s = cx.to_string(args.first().copied().unwrap_or(cx.undefined()))?;
match i64::from_str_radix(s.trim_start_matches("0x"), 16) {
Ok(n) => {
let obj = cx.new_object();
let dec = cx.number(n as f64);
cx.set(obj, "decimal", dec);
let hex = cx.string(&s);
cx.set(obj, "source", hex);
Ok(obj)
}
Err(_) => Err(cx.range_error(&format!("not hex: {s}"))),
}
});
interp.register_global_fn("times", 2, |cx: &mut Ctx, _this, args| {
let f = args.first().copied().unwrap_or(cx.undefined());
let n = cx.to_number(args.get(1).copied().unwrap_or(cx.undefined()))? as i64;
let mut acc: Vec<NanBox> = Vec::new();
for i in 0..n {
let idx = cx.number(i as f64);
acc.push(cx.call(f, cx.undefined(), &[idx])?);
}
Ok(cx.new_array(acc))
});
let src = r#"
var out = [];
out.push("hypot(3,4) = " + hypot(3, 4));
out.push("parseHex('0xff') = " + JSON.stringify(parseHex("0xff")));
try { parseHex("nope"); } catch (e) { out.push("threw: " + e.message); }
out.push("times(sq,5) = " + JSON.stringify(times(function (i) { return i * i; }, 5)));
out.join("\n");
"#;
let program = Parser::parse_program(src).expect("parse");
let value = interp.run(&program).expect("run");
println!("{}", interp.realm().to_display_string(value));
}