diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/lib.rs | 47 |
1 files changed, 27 insertions, 20 deletions
@@ -1,10 +1,26 @@ use log::{Level, error, info}; use wasm_bindgen::prelude::*; +use web_sys::js_sys; pub mod forth; pub mod robo; -use web_sys::js_sys; +enum Error { + NoVM, +} +impl From<Error> for String { + fn from(err: Error) -> Self { + match err { + Error::NoVM => "no vm".to_string().into(), + } + } +} + +impl From<forth::vm::RuntimeError> for String { + fn from(err: forth::vm::RuntimeError) -> Self { + format!("runtime error: {}", err) + } +} fn tr_op(op: &forth::vm::OpCode) -> String { use forth::vm::OpCode::*; @@ -85,20 +101,16 @@ impl ExportedVM { } pub fn tick(&mut self) -> Result<bool, String> { - let Some(vm) = &mut self.vm else { - return Err("no vm".to_string()); - }; - vm.tick().map_err(|err| format!("runtime error: {err:?}")) + let vm = (&mut self.vm).as_mut().ok_or(Error::NoVM)?; + Ok(vm.tick()?) } pub fn run(&mut self) -> Result<usize, String> { - let Some(vm) = &mut self.vm else { - return Err("no vm".to_string()); - }; + let vm = (&mut self.vm).as_mut().ok_or(Error::NoVM)?; vm.ip.word = 0; vm.ip.offset = 0; - vm.run().map_err(|err| format!("runtime error: {err:?}")) + Ok(vm.run()?) } pub fn reset_ip(&mut self) { @@ -109,16 +121,8 @@ impl ExportedVM { vm.ip.offset = 0; } - pub fn out(&mut self) -> Vec<String> { - let Some(vm) = &mut self.vm else { return vec![] }; - let mut res = vec![]; - std::mem::swap(&mut res, &mut vm.out); - res - } - - pub fn trans(&mut self) -> js_sys::Object { - let Some(vm) = &self.vm else { return js_sys::Object::new() }; - + pub fn trans(&mut self) -> Result<js_sys::Object, String> { + let vm = (&mut self.vm).as_mut().ok_or(Error::NoVM)?; let res = js_sys::Map::new(); // wordlist @@ -167,12 +171,15 @@ impl ExportedVM { map_set(&res, "callstack", js_sys::Array::from_iter(cs)); let vars = js_sys::Map::new(); + let mut out = vec![]; + std::mem::swap(&mut out, &mut vm.out); + map_set(&vars, "out", out); map_set::<isize>(&vars, "heading", vm.heading.into()); map_set::<isize>(&vars, "speed", vm.speed.into()); map_set::<isize>(&vars, "doppler", vm.doppler.into()); map_set(&res, "vars", js_sys::Object::from_entries(&vars).expect("can't make object from vars map")); - js_sys::Object::from_entries(&res).expect("can't make object from results map") + Ok(js_sys::Object::from_entries(&res).expect("can't make object from results map")) } } |
