Simplified function registration to not require explicit coercion step. Simplified eval to take &str instead of String

This commit is contained in:
jonathandturner
2016-03-16 18:07:08 -04:00
parent 6950219251
commit 254f4b081c
9 changed files with 143 additions and 116 deletions

View File

@@ -3,12 +3,15 @@ use std::boxed::Box;
use engine::{EvalAltResult, Engine, FnType};
pub trait FnRegister {
fn register(self, engine: &mut Engine, name: &str);
pub trait FnRegister<A, RetVal, Args> {
fn register_fn(&mut self, name: &str, f: A);
}
impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone, X: Any+Clone, Y: Any+Clone, Z: Any+Clone> FnRegister for fn(&mut T, U, V, W, X, Y)->Z {
fn register(self, engine: &mut Engine, name: &str) {
impl<'a, A, T, U, V, W, X, Y, Z> FnRegister<A, Z, (&'a mut T, U, V, W, X, Y)> for Engine
where A: 'static+Fn(&mut T, U, V, W, X, Y) -> Z, T: Clone+Any, U: Clone+Any, V: Clone+Any, W: Clone+Any,
X: Clone+Any, Y: Clone+Any, Z: Clone+Any
{
fn register_fn(&mut self, name: &str, fun: A) {
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>, &mut Box<Any>, &mut Box<Any>, &mut Box<Any>,
&mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
@@ -24,20 +27,23 @@ impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone, X: Any+Clone, Y: An
let inside6 = (*arg6).downcast_mut() as Option<&mut Y>;
match (inside1, inside2, inside3, inside4, inside5, inside6) {
(Some(b), Some(c), Some(d), Some(e), Some(f), Some(g)) => Ok(Box::new(self(b, c.clone(), d.clone(),
(Some(b), Some(c), Some(d), Some(e), Some(f), Some(g)) => Ok(Box::new(fun(b, c.clone(), d.clone(),
e.clone(), f.clone(), g.clone())) as Box<Any>),
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
}
}
);
let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
let ent = self.fns.entry(name.to_string()).or_insert(Vec::new());
(*ent).push(FnType::ExternalFn6(wrapped));
}
}
impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone, X: Any+Clone, Y: Any+Clone, Z: Any+Clone> FnRegister for fn(T, U, V, W, X, Y)->Z {
fn register(self, engine: &mut Engine, name: &str) {
impl<'a, A, T, U, V, W, X, Y, Z> FnRegister<A, Z, (&'a T, U, V, W, X, Y)> for Engine
where A: 'static+Fn(T, U, V, W, X, Y) -> Z, T: Clone+Any, U: Clone+Any, V: Clone+Any, W: Clone+Any,
X: Clone+Any, Y: Clone+Any, Z: Clone+Any
{
fn register_fn(&mut self, name: &str, fun: A) {
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>, &mut Box<Any>, &mut Box<Any>, &mut Box<Any>,
&mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
@@ -53,20 +59,22 @@ impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone, X: Any+Clone, Y: An
let inside6 = (*arg6).downcast_mut() as Option<&mut Y>;
match (inside1, inside2, inside3, inside4, inside5, inside6) {
(Some(b), Some(c), Some(d), Some(e), Some(f), Some(g)) => Ok(Box::new(self(b.clone(), c.clone(), d.clone(),
(Some(b), Some(c), Some(d), Some(e), Some(f), Some(g)) => Ok(Box::new(fun(b.clone(), c.clone(), d.clone(),
e.clone(), f.clone(), g.clone())) as Box<Any>),
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
}
}
);
let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
let ent = self.fns.entry(name.to_string()).or_insert(Vec::new());
(*ent).push(FnType::ExternalFn6(wrapped));
}
}
impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone, X: Any+Clone, Y: Any+Clone> FnRegister for fn(&mut T, U, V, W, X)->Y {
fn register(self, engine: &mut Engine, name: &str) {
impl<'a, A, T, U, V, W, X, Y> FnRegister<A, Y, (&'a mut T, U, V, W, X)> for Engine
where A: 'static+Fn(&mut T, U, V, W, X) -> Y, T: Clone+Any, U: Clone+Any, V: Clone+Any, W: Clone+Any, X: Clone+Any, Y: Clone+Any
{
fn register_fn(&mut self, name: &str, fun: A) {
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>, &mut Box<Any>, &mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
Box::new(
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>, arg3: &mut Box<Any>, arg4: &mut Box<Any>,
@@ -79,20 +87,22 @@ impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone, X: Any+Clone, Y: An
let inside5 = (*arg5).downcast_mut() as Option<&mut X>;
match (inside1, inside2, inside3, inside4, inside5) {
(Some(b), Some(c), Some(d), Some(e), Some(f)) => Ok(Box::new(self(b, c.clone(), d.clone(),
(Some(b), Some(c), Some(d), Some(e), Some(f)) => Ok(Box::new(fun(b, c.clone(), d.clone(),
e.clone(), f.clone())) as Box<Any>),
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
}
}
);
let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
let ent = self.fns.entry(name.to_string()).or_insert(Vec::new());
(*ent).push(FnType::ExternalFn5(wrapped));
}
}
impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone, X: Any+Clone, Y: Any+Clone> FnRegister for fn(T, U, V, W, X)->Y {
fn register(self, engine: &mut Engine, name: &str) {
impl<'a, A, T, U, V, W, X, Y> FnRegister<A, Y, (&'a T, U, V, W, X)> for Engine
where A: 'static+Fn(T, U, V, W, X) -> Y, T: Clone+Any, U: Clone+Any, V: Clone+Any, W: Clone+Any, X: Clone+Any, Y: Clone+Any
{
fn register_fn(&mut self, name: &str, fun: A) {
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>, &mut Box<Any>, &mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
Box::new(
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>, arg3: &mut Box<Any>, arg4: &mut Box<Any>,
@@ -105,20 +115,22 @@ impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone, X: Any+Clone, Y: An
let inside5 = (*arg5).downcast_mut() as Option<&mut X>;
match (inside1, inside2, inside3, inside4, inside5) {
(Some(b), Some(c), Some(d), Some(e), Some(f)) => Ok(Box::new(self(b.clone(), c.clone(), d.clone(),
(Some(b), Some(c), Some(d), Some(e), Some(f)) => Ok(Box::new(fun(b.clone(), c.clone(), d.clone(),
e.clone(), f.clone())) as Box<Any>),
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
}
}
);
let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
let ent = self.fns.entry(name.to_string()).or_insert(Vec::new());
(*ent).push(FnType::ExternalFn5(wrapped));
}
}
impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone, X: Any+Clone> FnRegister for fn(&mut T, U, V, W)->X {
fn register(self, engine: &mut Engine, name: &str) {
impl<'a, A, T, U, V, W, X> FnRegister<A, X, (&'a mut T, U, V, W)> for Engine
where A: 'static+Fn(&mut T, U, V, W) -> X, T: Clone+Any, U: Clone+Any, V: Clone+Any, W: Clone+Any, X: Clone+Any
{
fn register_fn(&mut self, name: &str, fun: A) {
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>, &mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
Box::new(
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>, arg3: &mut Box<Any>, arg4: &mut Box<Any>| {
@@ -128,19 +140,21 @@ impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone, X: Any+Clone> FnReg
let inside4 = (*arg4).downcast_mut() as Option<&mut W>;
match (inside1, inside2, inside3, inside4) {
(Some(b), Some(c), Some(d), Some(e)) => Ok(Box::new(self(b, c.clone(), d.clone(), e.clone())) as Box<Any>),
(Some(b), Some(c), Some(d), Some(e)) => Ok(Box::new(fun(b, c.clone(), d.clone(), e.clone())) as Box<Any>),
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
}
}
);
let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
let ent = self.fns.entry(name.to_string()).or_insert(Vec::new());
(*ent).push(FnType::ExternalFn4(wrapped));
}
}
impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone, X: Any+Clone> FnRegister for fn(T, U, V, W)->X {
fn register(self, engine: &mut Engine, name: &str) {
impl<'a, A, T, U, V, W, X> FnRegister<A, X, (&'a T, U, V, W)> for Engine
where A: 'static+Fn(T, U, V, W) -> X, T: Clone+Any, U: Clone+Any, V: Clone+Any, W: Clone+Any, X: Clone+Any
{
fn register_fn(&mut self, name: &str, fun: A) {
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>, &mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
Box::new(
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>, arg3: &mut Box<Any>, arg4: &mut Box<Any>| {
@@ -150,19 +164,21 @@ impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone, X: Any+Clone> FnReg
let inside4 = (*arg4).downcast_mut() as Option<&mut W>;
match (inside1, inside2, inside3, inside4) {
(Some(b), Some(c), Some(d), Some(e)) => Ok(Box::new(self(b.clone(), c.clone(), d.clone(), e.clone())) as Box<Any>),
(Some(b), Some(c), Some(d), Some(e)) => Ok(Box::new(fun(b.clone(), c.clone(), d.clone(), e.clone())) as Box<Any>),
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
}
}
);
let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
let ent = self.fns.entry(name.to_string()).or_insert(Vec::new());
(*ent).push(FnType::ExternalFn4(wrapped));
}
}
impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone> FnRegister for fn(&mut T, U, V)->W {
fn register(self, engine: &mut Engine, name: &str) {
impl<'a, A, T, U, V, W> FnRegister<A, W, (&'a mut T, U, V)> for Engine
where A: 'static+Fn(&mut T, U, V) -> W, T: Clone+Any, U: Clone+Any, V: Clone+Any, W: Clone+Any
{
fn register_fn(&mut self, name: &str, fun: A) {
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
Box::new(
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>, arg3: &mut Box<Any>| {
@@ -171,19 +187,21 @@ impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone> FnRegister for fn(&
let inside3 = (*arg3).downcast_mut() as Option<&mut V>;
match (inside1, inside2, inside3) {
(Some(b), Some(c), Some(d)) => Ok(Box::new(self(b, c.clone(), d.clone())) as Box<Any>),
(Some(b), Some(c), Some(d)) => Ok(Box::new(fun(b, c.clone(), d.clone())) as Box<Any>),
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
}
}
);
let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
let ent = self.fns.entry(name.to_string()).or_insert(Vec::new());
(*ent).push(FnType::ExternalFn3(wrapped));
}
}
impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone> FnRegister for fn(T, U, V)->W {
fn register(self, engine: &mut Engine, name: &str) {
impl<'a, A, T, U, V, W> FnRegister<A, W, (&'a T, U, V)> for Engine
where A: 'static+Fn(T, U, V) -> W, T: Clone+Any, U: Clone+Any, V: Clone+Any, W: Clone+Any
{
fn register_fn(&mut self, name: &str, fun: A) {
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
Box::new(
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>, arg3: &mut Box<Any>| {
@@ -192,19 +210,21 @@ impl<T: Any+Clone, U: Any+Clone, V: Any+Clone, W: Any+Clone> FnRegister for fn(T
let inside3 = (*arg3).downcast_mut() as Option<&mut V>;
match (inside1, inside2, inside3) {
(Some(b), Some(c), Some(d)) => Ok(Box::new(self(b.clone(), c.clone(), d.clone())) as Box<Any>),
(Some(b), Some(c), Some(d)) => Ok(Box::new(fun(b.clone(), c.clone(), d.clone())) as Box<Any>),
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
}
}
);
let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
let ent = self.fns.entry(name.to_string()).or_insert(Vec::new());
(*ent).push(FnType::ExternalFn3(wrapped));
}
}
impl<T: Any+Clone, U: Any+Clone, V: Any+Clone> FnRegister for fn(&mut T, U)->V {
fn register(self, engine: &mut Engine, name: &str) {
impl<'a, A, T, U, V> FnRegister<A, V, (&'a mut T, U)> for Engine
where A: 'static+Fn(&mut T, U) -> V, T: Clone+Any, U: Clone+Any, V: Clone+Any
{
fn register_fn(&mut self, name: &str, fun: A) {
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
Box::new(
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>| {
@@ -212,19 +232,21 @@ impl<T: Any+Clone, U: Any+Clone, V: Any+Clone> FnRegister for fn(&mut T, U)->V {
let inside2 = (*arg2).downcast_mut() as Option<&mut U>;
match (inside1, inside2) {
(Some(b), Some(c)) => Ok(Box::new(self(b, c.clone())) as Box<Any>),
(Some(b), Some(c)) => Ok(Box::new(fun(b, c.clone())) as Box<Any>),
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
}
}
);
let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
let ent = self.fns.entry(name.to_string()).or_insert(Vec::new());
(*ent).push(FnType::ExternalFn2(wrapped));
}
}
impl<T: Any+Clone, U: Any+Clone, V: Any+Clone> FnRegister for fn(T, U)->V {
fn register(self, engine: &mut Engine, name: &str) {
impl<'a, A, T, U, V> FnRegister<A, V, (&'a T, U)> for Engine
where A: 'static+Fn(T, U) -> V, T: Clone+Any, U: Clone+Any, V: Clone+Any
{
fn register_fn(&mut self, name: &str, fun: A) {
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
Box::new(
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>| {
@@ -232,62 +254,69 @@ impl<T: Any+Clone, U: Any+Clone, V: Any+Clone> FnRegister for fn(T, U)->V {
let inside2 = (*arg2).downcast_mut() as Option<&mut U>;
match (inside1, inside2) {
(Some(b), Some(c)) => Ok(Box::new(self(b.clone(), c.clone())) as Box<Any>),
(Some(b), Some(c)) => Ok(Box::new(fun(b.clone(), c.clone())) as Box<Any>),
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
}
}
);
let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
let ent = self.fns.entry(name.to_string()).or_insert(Vec::new());
(*ent).push(FnType::ExternalFn2(wrapped));
}
}
impl<T: Any+Clone, U: Any+Clone> FnRegister for fn(&mut T)->U {
fn register(self, engine: &mut Engine, name: &str) {
impl<'a, A, T, U> FnRegister<A, U, (&'a mut T)> for Engine
where A: 'static+Fn(&mut T) -> U, T: Clone+Any, U: Clone+Any
{
fn register_fn(&mut self, name: &str, fun: A) {
let wrapped : Box<Fn(&mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
Box::new(
move |arg: &mut Box<Any>| {
let inside = (*arg).downcast_mut() as Option<&mut T>;
match inside {
Some(b) => Ok(Box::new(self(b)) as Box<Any>),
Some(b) => Ok(Box::new(fun(b)) as Box<Any>),
None => Err(EvalAltResult::ErrorFunctionArgMismatch)
}
}
);
let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
let ent = self.fns.entry(name.to_string()).or_insert(Vec::new());
(*ent).push(FnType::ExternalFn1(wrapped));
}
}
impl<T: Any+Clone, U: Any+Clone> FnRegister for fn(T)->U {
fn register(self, engine: &mut Engine, name: &str) {
impl<'a, A, T, U> FnRegister<A, U, (&'a T)> for Engine
where A: 'static+Fn(T) -> U, T: Clone+Any, U: Clone+Any
{
fn register_fn(&mut self, name: &str, fun: A) {
let wrapped : Box<Fn(&mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
Box::new(
move |arg: &mut Box<Any>| {
let inside = (*arg).downcast_mut() as Option<&mut T>;
match inside {
Some(b) => Ok(Box::new(self(b.clone())) as Box<Any>),
Some(b) => Ok(Box::new(fun(b.clone())) as Box<Any>),
None => Err(EvalAltResult::ErrorFunctionArgMismatch)
}
}
);
let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
let ent = self.fns.entry(name.to_string()).or_insert(Vec::new());
(*ent).push(FnType::ExternalFn1(wrapped));
}
}
impl<T: Any+Clone> FnRegister for fn()->T {
fn register(self, engine: &mut Engine, name: &str) {
impl<A, T> FnRegister<A, T, ()> for Engine
where A: 'static+Fn() -> T, T: Clone+Any
{
fn register_fn(&mut self, name: &str, fun: A) {
let wrapped : Box<Fn()->Result<Box<Any>, EvalAltResult>> =
Box::new(
move || { Ok(Box::new(self()) as Box<Any>) }
move || { Ok(Box::new(fun()) as Box<Any>) }
);
let ent = engine.fns.entry(name.to_string()).or_insert(Vec::new());
let ent = self.fns.entry(name.to_string()).or_insert(Vec::new());
(*ent).push(FnType::ExternalFn0(wrapped));
}
}