1mod repl;
4
5use core::str;
6pub use repl::repl;
7use stak_compiler::compile_r7rs;
8use stak_device::ReadWriteDevice;
9use stak_file::{MemoryFileSystem, VoidFileSystem};
10use stak_macro::include_module;
11use stak_module::Module;
12use stak_process_context::{MemoryProcessContext, VoidProcessContext};
13use stak_r7rs::SmallPrimitiveSet;
14use stak_time::VoidClock;
15use stak_vm::Vm;
16use wasm_bindgen::prelude::*;
17
18#[wasm_bindgen]
20pub fn compile(source: &str) -> Result<Vec<u8>, JsError> {
21 let mut target = vec![];
22 compile_r7rs(source.as_bytes(), &mut target)?;
23 Ok(target)
24}
25
26#[wasm_bindgen]
28pub fn interpret(bytecode: &[u8], input: &[u8], heap_size: usize) -> Result<Vec<u8>, JsError> {
29 let mut output = vec![];
30 let mut error = vec![];
31
32 let mut vm = Vm::new(
33 vec![Default::default(); heap_size],
34 SmallPrimitiveSet::new(
35 ReadWriteDevice::new(input, &mut output, &mut error),
36 VoidFileSystem::new(),
37 VoidProcessContext::new(),
38 VoidClock::new(),
39 ),
40 )?;
41
42 vm.initialize(bytecode.iter().copied())?;
43 vm.run()?;
44
45 Ok(output)
46}
47
48#[wasm_bindgen]
50pub fn run(source: &str, input: &[u8], heap_size: usize) -> Result<Vec<u8>, JsError> {
51 const MAIN_FILE: &str = "main.scm";
52
53 let mut output = vec![];
54 let mut error = vec![];
55 let files = [(MAIN_FILE.as_bytes(), source.as_bytes())];
56 let mut file_entries = [Default::default(); 1];
57
58 let mut vm = Vm::new(
59 vec![Default::default(); heap_size],
60 SmallPrimitiveSet::new(
61 ReadWriteDevice::new(input, &mut output, &mut error),
62 MemoryFileSystem::new(&files, &mut file_entries),
63 MemoryProcessContext::new(&["scheme", MAIN_FILE], &[]),
64 VoidClock::new(),
65 ),
66 )?;
67
68 vm.initialize(
69 include_module!("run.scm", stak_module)
70 .bytecode()
71 .iter()
72 .copied(),
73 )?;
74 vm.run().map_err(|vm_error| match str::from_utf8(&error) {
75 Ok(error) if !error.is_empty() => JsError::new(error),
76 Ok(_) => JsError::from(vm_error),
77 Err(error) => JsError::from(error),
78 })?;
79
80 Ok(output)
81}