diff --git a/src/interpreter/host.rs b/src/interpreter/host.rs index 39a635b..05248b1 100644 --- a/src/interpreter/host.rs +++ b/src/interpreter/host.rs @@ -41,6 +41,25 @@ impl HostModuleBuilder { } } + pub fn with_func0< + Cl: Fn(&mut St) -> Result, Error> + 'static, + Ret: AsReturnVal + 'static, + F: Into>, + >( + &mut self, + name: &str, + f: F, + ) { + let func_type = Func0::::derive_func_type(); + let host_func = Arc::new(f.into()) as Arc; + + self.items.push(HostItem::Func { + name: name.to_owned(), + func_type, + host_func, + }); + } + pub fn with_func1< Cl: Fn(&mut St, P1) -> Result, Error> + 'static, Ret: AsReturnVal + 'static, @@ -61,6 +80,27 @@ impl HostModuleBuilder { }); } + pub fn with_func2< + Cl: Fn(&mut St, P1, P2) -> Result, Error> + 'static, + Ret: AsReturnVal + 'static, + P1: FromArg + 'static, + P2: FromArg + 'static, + F: Into>, + >( + &mut self, + name: &str, + f: F, + ) { + let func_type = Func2::::derive_func_type(); + let host_func = Arc::new(f.into()) as Arc; + + self.items.push(HostItem::Func { + name: name.to_owned(), + func_type, + host_func, + }); + } + pub fn with_global(&mut self, name: &str, global_type: GlobalType, init_val: RuntimeValue) { self.items.push(HostItem::Global { name: name.to_owned(), @@ -178,6 +218,47 @@ impl AsReturnVal for () { } } +pub struct Func0 Result, Error>, St, Ret: AsReturnVal> { + closure: Cl, + _marker: PhantomData<(St, Ret)>, +} + +impl< + St: 'static, + Ret: AsReturnVal, + Cl: Fn(&mut St) -> Result, Error>, +> AnyFunc for Func0 { + fn call_as_any( + &self, + state: &mut Any, + args: &[RuntimeValue], + ) -> Result, Error> { + let state = state.downcast_mut::().unwrap(); + let result = (self.closure)(state); + result.map(|r| r.and_then(|r| r.as_return_val())) + } +} + +impl Result, Error>> From + for Func0 { + fn from(cl: Cl) -> Self { + Func0 { + closure: cl, + _marker: PhantomData, + } + } +} + +impl< + St: 'static, + Ret: AsReturnVal, + Cl: Fn(&mut St) -> Result, Error>, +> Func0 { + fn derive_func_type() -> FunctionType { + FunctionType::new(vec![], Ret::value_type()) + } +} + pub struct Func1 Result, Error>, St, Ret: AsReturnVal, P1: FromArg> { closure: Cl, _marker: PhantomData<(St, Ret, P1)>, @@ -221,3 +302,50 @@ impl< FunctionType::new(vec![P1::value_type()], Ret::value_type()) } } + +pub struct Func2 Result, Error>, St, Ret: AsReturnVal, P1: FromArg, P2: FromArg> { + closure: Cl, + _marker: PhantomData<(St, Ret, P1, P2)>, +} + +impl< + St: 'static, + Ret: AsReturnVal, + P1: FromArg, + P2: FromArg, + Cl: Fn(&mut St, P1, P2) -> Result, Error>, +> AnyFunc for Func2 { + fn call_as_any( + &self, + state: &mut Any, + args: &[RuntimeValue], + ) -> Result, Error> { + let state = state.downcast_mut::().unwrap(); + let p1 = P1::from_arg(&args[0]); + let p2 = P2::from_arg(&args[1]); + let result = (self.closure)(state, p1, p2); + result.map(|r| r.and_then(|r| r.as_return_val())) + } +} + +impl Result, Error>> From + for Func2 { + fn from(cl: Cl) -> Self { + Func2 { + closure: cl, + _marker: PhantomData, + } + } +} + +impl< + St: 'static, + Ret: AsReturnVal, + P1: FromArg, + P2: FromArg, + Cl: Fn(&mut St, P1, P2) -> Result, Error>, +> Func2 { + fn derive_func_type() -> FunctionType { + FunctionType::new(vec![P1::value_type(), P2::value_type()], Ret::value_type()) + } +}