Minor tweaks, fix bug

This commit is contained in:
torkleyy 2017-12-20 14:35:44 +01:00
parent f09545921f
commit a0fb5036f6
4 changed files with 35 additions and 38 deletions

View File

@ -1,5 +1,5 @@
extern crate rhai; extern crate rhai;
use rhai::{Engine, FnRegister}; use rhai::{Any, Engine, EvalAltResult, RegisterFn};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
struct TestStruct { struct TestStruct {
@ -16,14 +16,27 @@ impl TestStruct {
} }
} }
fn print_ty_name(test: Vec<&mut Box<Any>>) -> Result<Box<Any>, EvalAltResult> {
println!("Ty name: {:?}", (*test[0]).as_ref().type_name());
Ok(Box::new(()))
}
fn main() { fn main() {
let mut engine = Engine::new(); let mut engine = Engine::new();
engine.register_type::<TestStruct>(); engine.register_type::<TestStruct>();
print_ty_name(vec![&mut (Box::new(TestStruct::new()) as Box<Any>)]).unwrap();
engine.register_fn("update", TestStruct::update); engine.register_fn("update", TestStruct::update);
engine.register_fn("new_ts", TestStruct::new); engine.register_fn("new_ts", TestStruct::new);
engine.register_fn_raw("ty_name".to_owned(), None, Box::new(print_ty_name));
println!(
"{:?}",
engine.eval::<TestStruct>("let x = new_ts(); x.update(); x")
);
println!( println!(
"{:?}", "{:?}",
engine.eval::<TestStruct>("let x = [new_ts()]; x[0].update(); x[0]") engine.eval::<TestStruct>("let x = [new_ts()]; x[0].update(); x[0]")

View File

@ -2,8 +2,6 @@ extern crate rhai;
use rhai::{Any, Engine, RegisterFn}; use rhai::{Any, Engine, RegisterFn};
fn add(x: i64, y: i64) -> i64 { fn add(x: i64, y: i64) -> i64 {
println!("Adding: {}", x + y);
x + y x + y
} }
@ -11,17 +9,7 @@ fn main() {
let mut engine = Engine::new(); let mut engine = Engine::new();
engine.register_fn("add", add); engine.register_fn("add", add);
engine if let Ok(result) = engine.eval::<i64>("add(40, 2)") {
.call_fn_raw( println!("Answer: {}", result); // prints 42
"add".to_owned(), }
vec![
&mut (Box::new(3i64) as Box<Any>),
&mut (Box::new(5i64) as Box<Any>),
],
)
.expect("FAIL");
//if let Ok(result) = engine.eval::<i64>("add(40, 2)") {
// println!("Answer: {}", result); // prints 42
//}
} }

View File

@ -122,28 +122,27 @@ impl Engine {
args: Vec<&mut Box<Any>>, args: Vec<&mut Box<Any>>,
) -> Result<Box<Any>, EvalAltResult> { ) -> Result<Box<Any>, EvalAltResult> {
let spec = FnSpec { let spec = FnSpec {
ident, ident: ident.clone(),
args: Some( args: Some(
args.iter() args.iter()
.map(|a| <Any as Any>::type_id(a.as_ref())) .map(|a| <Any as Any>::type_id(a.as_ref()))
.collect(), .collect(),
), ),
}; };
let spec1 = FnSpec { ident, args: None };
self.fns self.fns
.get(&spec) .get(&spec)
.or_else(|| self.fns.get(&spec1))
.ok_or(EvalAltResult::ErrorFunctionNotFound) .ok_or(EvalAltResult::ErrorFunctionNotFound)
.and_then(move |f| match *f { .and_then(move |f| match *f {
FnIntExt::Ext(ref f) => f(args), FnIntExt::Ext(ref f) => f(args),
FnIntExt::Int(_) => unimplemented!(), FnIntExt::Int(_) => unreachable!(),
}) })
} }
pub fn register_fn_raw(&mut self, ident: String, args: Vec<TypeId>, f: Box<FnAny>) { pub fn register_fn_raw(&mut self, ident: String, args: Option<Vec<TypeId>>, f: Box<FnAny>) {
let spec = FnSpec { let spec = FnSpec { ident, args };
ident,
args: Some(args),
};
self.fns.insert(spec, FnIntExt::Ext(f)); self.fns.insert(spec, FnIntExt::Ext(f));
} }
@ -152,6 +151,7 @@ impl Engine {
/// your type must implement Clone. /// your type must implement Clone.
pub fn register_type<T: Any>(&mut self) { pub fn register_type<T: Any>(&mut self) {
// currently a no-op, exists for future extensibility // currently a no-op, exists for future extensibility
println!("Registering {:?}", TypeId::of::<T>());
} }
/// Register a get function for a member of a registered type /// Register a get function for a member of a registered type
@ -216,7 +216,7 @@ impl Engine {
((*val).downcast_mut() as Option<&mut Vec<Box<Any>>>) ((*val).downcast_mut() as Option<&mut Vec<Box<Any>>>)
.and_then(|arr| idx.downcast_ref::<i64>().map(|idx| (arr, *idx as usize))) .and_then(|arr| idx.downcast_ref::<i64>().map(|idx| (arr, *idx as usize)))
.map(|(arr, idx)| arr[idx].box_clone()) .map(|(arr, idx)| arr[idx].clone())
.ok_or(EvalAltResult::ErrorIndexMismatch) .ok_or(EvalAltResult::ErrorIndexMismatch)
} }
Expr::Dot(ref inner_lhs, ref inner_rhs) => match **inner_lhs { Expr::Dot(ref inner_lhs, ref inner_rhs) => match **inner_lhs {
@ -243,7 +243,7 @@ impl Engine {
.iter_mut() .iter_mut()
.rev() .rev()
.find(|&&mut (ref name, _)| *id == *name) .find(|&&mut (ref name, _)| *id == *name)
.map(|&mut (_, ref mut val)| val.as_ref().box_clone()) .map(|&mut (_, ref mut val)| val.clone())
.ok_or_else(|| EvalAltResult::ErrorVariableNotFound(id.clone())) .ok_or_else(|| EvalAltResult::ErrorVariableNotFound(id.clone()))
.and_then(|mut target| self.get_dot_val_helper(scope, &mut target, dot_rhs)) .and_then(|mut target| self.get_dot_val_helper(scope, &mut target, dot_rhs))
@ -283,7 +283,7 @@ impl Engine {
.and_then(|arr| { .and_then(|arr| {
idx_boxed idx_boxed
.downcast_ref::<i64>() .downcast_ref::<i64>()
.map(|idx| arr[*idx as usize].box_clone()) .map(|idx| arr[*idx as usize].clone())
}) })
.ok_or(EvalAltResult::ErrorIndexMismatch) .ok_or(EvalAltResult::ErrorIndexMismatch)
}) })
@ -455,7 +455,7 @@ impl Engine {
Expr::Identifier(ref id) => { Expr::Identifier(ref id) => {
for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() { for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() {
if *id == *name { if *id == *name {
return Ok(val.box_clone()); return Ok(val.clone());
} }
} }
Err(EvalAltResult::ErrorVariableNotFound(id.clone())) Err(EvalAltResult::ErrorVariableNotFound(id.clone()))
@ -469,7 +469,7 @@ impl Engine {
if let Some(arr_typed) = if let Some(arr_typed) =
(*val).downcast_mut() as Option<&mut Vec<Box<Any>>> (*val).downcast_mut() as Option<&mut Vec<Box<Any>>>
{ {
return Ok(arr_typed[*i as usize].box_clone()); return Ok(arr_typed[*i as usize].clone());
} else { } else {
return Err(EvalAltResult::ErrorIndexMismatch); return Err(EvalAltResult::ErrorIndexMismatch);
} }
@ -688,9 +688,6 @@ impl Engine {
let mut x: Result<Box<Any>, EvalAltResult> = Ok(Box::new(())); let mut x: Result<Box<Any>, EvalAltResult> = Ok(Box::new(()));
for f in fns { for f in fns {
if f.params.len() > 6 {
return Err(EvalAltResult::ErrorFunctionArityNotSupported);
}
let name = f.name.clone(); let name = f.name.clone();
let local_f = f.clone(); let local_f = f.clone();
@ -709,12 +706,11 @@ impl Engine {
} }
} }
match x { let x = x?;
Ok(v) => match v.downcast::<T>() {
match x.downcast::<T>() {
Ok(out) => Ok(*out), Ok(out) => Ok(*out),
Err(_) => Err(EvalAltResult::ErrorMismatchOutputType), Err(_) => Err(EvalAltResult::ErrorMismatchOutputType),
},
Err(e) => Err(e),
} }
} }
Err(_) => Err(EvalAltResult::ErrorFunctionArgMismatch), Err(_) => Err(EvalAltResult::ErrorFunctionArgMismatch),

View File

@ -45,7 +45,7 @@ macro_rules! def_register {
// potentially clone the value, otherwise pass the reference. // potentially clone the value, otherwise pass the reference.
Ok(Box::new(f($(($clone)($par)),*)) as Box<Any>) Ok(Box::new(f($(($clone)($par)),*)) as Box<Any>)
}; };
self.register_fn_raw(name.to_owned(), vec![$(TypeId::of::<$par>()),*], Box::new(fun)); self.register_fn_raw(name.to_owned(), Some(vec![$(TypeId::of::<$par>()),*]), Box::new(fun));
} }
} }