1use console_error_panic_hook;
2use console_log;
3use log;
4use std::io;
5use tokay::*;
6use wasm_bindgen::prelude::*;
7
8#[wasm_bindgen]
9pub fn enable_logging() {
10 console_error_panic_hook::set_once();
11 console_log::init_with_level(log::Level::Debug).expect("logger init failed");
12}
13
14#[wasm_bindgen]
15pub fn version() -> String {
16 env!("CARGO_PKG_VERSION").to_string()
17}
18
19#[wasm_bindgen]
20pub fn run(code: &str, input: &str, print_fn: Option<js_sys::Function>) -> Option<String> {
21 let code = code.to_string();
22 let mut input = Reader::new(None, Box::new(io::Cursor::new(input.to_string())));
23
24 let mut compiler = Compiler::new();
25 compiler.constant(
26 "print",
27 RefValue::from(tokay::value::DynBuiltin {
28 name: "print",
29 func: Box::new(move |context, args, _nargs| {
30 let mut output = if args.len() == 0 && context.is_some() {
31 let context = context.unwrap();
32
33 if let Some(mut capture) = context.get_capture(0) {
34 let value = capture.extract(context.thread.reader);
35 value.to_string()
36 }
37 else {
38 String::new()
39 }
40 } else {
41 let mut output = String::new();
42
43 for i in 0..args.len() {
44 if i > 0 {
45 output.push(' ');
46 }
47
48 output.push_str(&args[i].to_string());
49 }
50
51 output
52 };
53
54 output.push('\n');
55
56 let output = JsValue::from_str(&output);
57 match &print_fn {
58 Some(f) => {
59 let _ = f.call1(&JsValue::NULL, &output);
60 }
61 None => {
62 web_sys::console::log_1(&output);
63 }
64 }
65
66 Value::Void.into() }),
68 }),
69 );
70
71 match compiler.compile(Reader::new(None, Box::new(io::Cursor::new(code)))) {
72 Ok(None) => None,
73 Ok(Some(program)) => {
74 let mut thread = vm::Thread::new(&program, vec![&mut input]);
75 match thread.run() {
79 Ok(Some(value)) => Some(value.repr()),
80 Err(error) => Some(error.to_string()),
81 _ => None,
82 }
83
84 }
86 Err(errors) => Some(format!("{:?}", errors)),
87 }
88}