tokay_wasm/
lib.rs

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() // need to push a void with high severity
67            }),
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            //thread.debug = compiler.debug;
76            //thread.globals = globals;
77
78            match thread.run() {
79                Ok(Some(value)) => Some(value.repr()),
80                Err(error) => Some(error.to_string()),
81                _ => None,
82            }
83
84            //globals = thread.globals;
85        }
86        Err(errors) => Some(format!("{:?}", errors)),
87    }
88}