diff --git a/Cargo.toml b/Cargo.toml index 7218676a..82cb29f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "rhai" -version = "0.1.0" +version = "0.2.0" authors = ["Jonathan Turner"] description = "Embedded scripting for Rust" homepage = "https://github.com/jonathandturner/rhai" @@ -11,4 +11,4 @@ include = [ "**/*.rs", "scripts/*.rhai", "Cargo.toml" -] \ No newline at end of file +] diff --git a/examples/custom_types_and_methods.rs b/examples/custom_types_and_methods.rs index 94641009..0fce4043 100644 --- a/examples/custom_types_and_methods.rs +++ b/examples/custom_types_and_methods.rs @@ -21,10 +21,10 @@ fn main() { engine.register_type::(); - &(TestStruct::update as fn(&mut TestStruct)->()).register(&mut engine, "update"); - &(TestStruct::new as fn()->TestStruct).register(&mut engine, "new_ts"); + engine.register_fn("update", TestStruct::update); + engine.register_fn("new_ts", TestStruct::new); - if let Ok(result) = engine.eval("var x = new_ts(); x.update(); x".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("var x = new_ts(); x.update(); x").unwrap().downcast::() { println!("result: {}", result.x); // prints 1001 } } \ No newline at end of file diff --git a/examples/hello.rs b/examples/hello.rs index d90f198a..029fd925 100644 --- a/examples/hello.rs +++ b/examples/hello.rs @@ -4,7 +4,7 @@ use rhai::Engine; fn main() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval("40 + 2".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("40 + 2").unwrap().downcast::() { println!("Answer: {}", *result); // prints 42 } } \ No newline at end of file diff --git a/examples/reuse_scope.rs b/examples/reuse_scope.rs index 7635a4f9..748ee0c6 100644 --- a/examples/reuse_scope.rs +++ b/examples/reuse_scope.rs @@ -5,9 +5,9 @@ fn main() { let mut engine = Engine::new(); let mut scope: Scope = Vec::new(); - if let Ok(_) = engine.eval_with_scope(&mut scope, "var x = 4 + 5".to_string()) { } else { assert!(false); } + if let Ok(_) = engine.eval_with_scope(&mut scope, "var x = 4 + 5") { } else { assert!(false); } - if let Ok(result) = engine.eval_with_scope(&mut scope, "x".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval_with_scope(&mut scope, "x").unwrap().downcast::() { println!("result: {}", result); } } diff --git a/examples/rhai_runner.rs b/examples/rhai_runner.rs index cb69e804..80b1afd9 100644 --- a/examples/rhai_runner.rs +++ b/examples/rhai_runner.rs @@ -14,20 +14,20 @@ fn main() { for fname in env::args().skip(1) { let mut engine = Engine::new(); - &(showit as fn(x: &mut i32)->()).register(&mut engine, "print"); - &(showit as fn(x: &mut i64)->()).register(&mut engine, "print"); - &(showit as fn(x: &mut u32)->()).register(&mut engine, "print"); - &(showit as fn(x: &mut u64)->()).register(&mut engine, "print"); - &(showit as fn(x: &mut f32)->()).register(&mut engine, "print"); - &(showit as fn(x: &mut f64)->()).register(&mut engine, "print"); - &(showit as fn(x: &mut bool)->()).register(&mut engine, "print"); - &(showit as fn(x: &mut String)->()).register(&mut engine, "print"); + engine.register_fn("print", showit as fn(x: &mut i32)->()); + engine.register_fn("print", showit as fn(x: &mut i64)->()); + engine.register_fn("print", showit as fn(x: &mut u32)->()); + engine.register_fn("print", showit as fn(x: &mut u64)->()); + engine.register_fn("print", showit as fn(x: &mut f32)->()); + engine.register_fn("print", showit as fn(x: &mut f64)->()); + engine.register_fn("print", showit as fn(x: &mut bool)->()); + engine.register_fn("print", showit as fn(x: &mut String)->()); if let Ok(mut f) = File::open(fname.clone()) { let mut contents = String::new(); if let Ok(_) = f.read_to_string(&mut contents) { - match engine.eval(contents) { + match engine.eval(&contents) { Ok(_) => (), Err(e) => {println!("Error: {:?}", e)} } diff --git a/examples/simple_fn.rs b/examples/simple_fn.rs index bc8badb7..f8b56418 100644 --- a/examples/simple_fn.rs +++ b/examples/simple_fn.rs @@ -8,9 +8,9 @@ fn add(x: i32, y: i32) -> i32 { fn main() { let mut engine = Engine::new(); - &(add as fn(x: i32, y: i32)->i32).register(&mut engine, "add"); + engine.register_fn("add", add); - if let Ok(result) = engine.eval("add(40, 2)".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("add(40, 2)").unwrap().downcast::() { println!("Answer: {}", *result); // prints 42 } } diff --git a/src/engine.rs b/src/engine.rs index b976e06a..9e5c7a65 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -320,7 +320,7 @@ impl Engine { pub fn register_type(&mut self) { fn clone_helper(t:T)->T { t.clone() }; - &(clone_helper as fn(T)->T).register(self, "clone"); + self.register_fn("clone", clone_helper as fn(T)->T); } fn get_dot_val_helper(&self, scope: &mut Scope, this_ptr: &mut Box, dot_rhs: &Expr) -> Result, EvalAltResult> { @@ -693,14 +693,14 @@ impl Engine { } } - pub fn eval(&mut self, input: String) -> Result, EvalAltResult> { + pub fn eval(&mut self, input: &str) -> Result, EvalAltResult> { let mut scope: Scope = Vec::new(); self.eval_with_scope(&mut scope, input) } - pub fn eval_with_scope(&mut self, scope: &mut Scope, input: String) -> Result, EvalAltResult> { - let tokens = lex(&input); + pub fn eval_with_scope(&mut self, scope: &mut Scope, input: &str) -> Result, EvalAltResult> { + let tokens = lex(input); let mut peekables = tokens.peekable(); let tree = parse(&mut peekables); @@ -742,15 +742,15 @@ impl Engine { macro_rules! reg_op { ($engine:expr, $x:expr, $op:expr, $( $y:ty ),*) => ( $( - ($op as fn(x: $y, y: $y)->$y).register($engine, $x); + $engine.register_fn($x, ($op as fn(x: $y, y: $y)->$y)); )* ) } - + macro_rules! reg_cmp { ($engine:expr, $x:expr, $op:expr, $( $y:ty ),*) => ( $( - ($op as fn(x: $y, y: $y)->bool).register($engine, $x); + $engine.register_fn($x, ($op as fn(x: $y, y: $y)->bool)); )* ) } @@ -800,7 +800,7 @@ impl Engine { fn test_number_literal() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval("65".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("65").unwrap().downcast::() { assert_eq!(*result, 65); } else { @@ -812,14 +812,14 @@ fn test_number_literal() { fn test_ops() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval("60 + 5".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("60 + 5").unwrap().downcast::() { assert_eq!(*result, 65); } else { assert!(false); } - if let Ok(result) = engine.eval("(1 + 2) * (6 - 4) / 2".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("(1 + 2) * (6 - 4) / 2").unwrap().downcast::() { assert_eq!(*result, 3); } else { @@ -831,7 +831,7 @@ fn test_ops() { fn test_bool_op1() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval("true && (false || true)".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("true && (false || true)").unwrap().downcast::() { assert_eq!(*result, true); } else { @@ -843,7 +843,7 @@ fn test_bool_op1() { fn test_bool_op2() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval("false && (false || true)".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("false && (false || true)").unwrap().downcast::() { assert_eq!(*result, false); } else { @@ -855,7 +855,7 @@ fn test_bool_op2() { fn test_op_prec() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval("var x = 0; if x == 10 || true { x = 1} x".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("var x = 0; if x == 10 || true { x = 1} x").unwrap().downcast::() { assert_eq!(*result, 1); } else { @@ -867,21 +867,21 @@ fn test_op_prec() { fn test_if() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval("if true { 55 }".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("if true { 55 }").unwrap().downcast::() { assert_eq!(*result, 55); } else { assert!(false); } - if let Ok(result) = engine.eval("if false { 55 } else { 44 }".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("if false { 55 } else { 44 }").unwrap().downcast::() { assert_eq!(*result, 44); } else { assert!(false); } - if let Ok(result) = engine.eval("if true { 55 } else { 44 }".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("if true { 55 } else { 44 }").unwrap().downcast::() { assert_eq!(*result, 55); } else { @@ -893,7 +893,7 @@ fn test_if() { fn test_while() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval("var x = 0; while x < 10 { x = x + 1; if x > 5 { break } } x".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("var x = 0; while x < 10 { x = x + 1; if x > 5 { break } } x").unwrap().downcast::() { assert_eq!(*result, 6); } else { @@ -906,27 +906,27 @@ fn test_var_scope() { let mut engine = Engine::new(); let mut scope: Scope = Vec::new(); - if let Ok(_) = engine.eval_with_scope(&mut scope, "var x = 4 + 5".to_string()) { } else { assert!(false); } + if let Ok(_) = engine.eval_with_scope(&mut scope, "var x = 4 + 5") { } else { assert!(false); } - if let Ok(result) = engine.eval_with_scope(&mut scope, "x".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval_with_scope(&mut scope, "x").unwrap().downcast::() { assert_eq!(*result, 9); } else { assert!(false); } - if let Ok(_) = engine.eval_with_scope(&mut scope, "x = x + 1; x = x + 2;".to_string()) { } else { assert!(false); } + if let Ok(_) = engine.eval_with_scope(&mut scope, "x = x + 1; x = x + 2;") { } else { assert!(false); } - if let Ok(result) = engine.eval_with_scope(&mut scope, "x".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval_with_scope(&mut scope, "x").unwrap().downcast::() { assert_eq!(*result, 12); } else { assert!(false); } - if let Ok(_) = engine.eval_with_scope(&mut scope, "{var x = 3}".to_string()) { } else { assert!(false); } + if let Ok(_) = engine.eval_with_scope(&mut scope, "{var x = 3}") { } else { assert!(false); } - if let Ok(result) = engine.eval_with_scope(&mut scope, "x".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval_with_scope(&mut scope, "x").unwrap().downcast::() { assert_eq!(*result, 12); } else { @@ -955,10 +955,10 @@ fn test_method_call() { engine.register_type::(); - &(TestStruct::update as fn(&mut TestStruct)->()).register(&mut engine, "update"); - &(TestStruct::new as fn()->TestStruct).register(&mut engine, "new_ts"); + engine.register_fn("update", TestStruct::update); + engine.register_fn("new_ts", TestStruct::new); - if let Ok(result) = engine.eval("var x = new_ts(); x.update(); x".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("var x = new_ts(); x.update(); x").unwrap().downcast::() { assert_eq!(result.x, 1001); } else { @@ -992,11 +992,11 @@ fn test_get_set() { engine.register_type::(); - &(TestStruct::get_x as fn(&mut TestStruct)->i32).register(&mut engine, "get$x"); - &(TestStruct::set_x as fn(&mut TestStruct, i32)->()).register(&mut engine, "set$x"); - &(TestStruct::new as fn()->TestStruct).register(&mut engine, "new_ts"); + engine.register_fn("get$x", TestStruct::get_x); + engine.register_fn("set$x", TestStruct::set_x); + engine.register_fn("new_ts", TestStruct::new); - if let Ok(result) = engine.eval("var a = new_ts(); a.x = 500; a.x".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("var a = new_ts(); a.x = 500; a.x").unwrap().downcast::() { assert_eq!(*result, 500); } else { @@ -1050,15 +1050,13 @@ fn test_big_get_set() { engine.register_type::(); engine.register_type::(); - &(TestChild::get_x as fn(&mut TestChild)->i32).register(&mut engine, "get$x"); - &(TestChild::set_x as fn(&mut TestChild, i32)->()).register(&mut engine, "set$x"); + engine.register_fn("get$x", TestChild::get_x); + engine.register_fn("set$x", TestChild::set_x); + engine.register_fn("get$child", TestParent::get_child); + engine.register_fn("set$child", TestParent::set_child); + engine.register_fn("new_tp", TestParent::new); - &(TestParent::get_child as fn(&mut TestParent)->TestChild).register(&mut engine, "get$child"); - &(TestParent::set_child as fn(&mut TestParent, TestChild)->()).register(&mut engine, "set$child"); - - &(TestParent::new as fn()->TestParent).register(&mut engine, "new_tp"); - - if let Ok(result) = engine.eval("var a = new_tp(); a.child.x = 500; a.child.x".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("var a = new_tp(); a.child.x = 500; a.child.x").unwrap().downcast::() { assert_eq!(*result, 500); } else { @@ -1070,14 +1068,14 @@ fn test_big_get_set() { fn test_internal_fn() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval("fn addme(a, b) { a+b } addme(3, 4)".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("fn addme(a, b) { a+b } addme(3, 4)").unwrap().downcast::() { assert_eq!(*result, 7); } else { assert!(false); } - if let Ok(result) = engine.eval("fn bob() { return 4; 5 } bob()".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("fn bob() { return 4; 5 } bob()").unwrap().downcast::() { assert_eq!(*result, 4); } else { @@ -1089,7 +1087,7 @@ fn test_internal_fn() { fn test_big_internal_fn() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval("fn mathme(a, b, c, d, e, f) { a - b * c + d * e - f } mathme(100, 5, 2, 9, 6, 32)".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("fn mathme(a, b, c, d, e, f) { a - b * c + d * e - f } mathme(100, 5, 2, 9, 6, 32)").unwrap().downcast::() { assert_eq!(*result, 112); } else { @@ -1101,7 +1099,7 @@ fn test_big_internal_fn() { fn test_string() { let mut engine = Engine::new(); - if let Ok(result) = engine.eval("\"Test string: \\u2764\"".to_string()).unwrap().downcast::() { + if let Ok(result) = engine.eval("\"Test string: \\u2764\"").unwrap().downcast::() { assert_eq!(*result, "Test string: ❤"); } else { diff --git a/src/fn_register.rs b/src/fn_register.rs index 1aeee4a1..eb1f2b47 100644 --- a/src/fn_register.rs +++ b/src/fn_register.rs @@ -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 { + fn register_fn(&mut self, name: &str, f: A); } -impl 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 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, &mut Box, &mut Box, &mut Box, &mut Box, &mut Box)->Result, EvalAltResult>> = @@ -24,20 +27,23 @@ impl; 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), _ => 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 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 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, &mut Box, &mut Box, &mut Box, &mut Box, &mut Box)->Result, EvalAltResult>> = @@ -53,20 +59,22 @@ impl; 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), _ => 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 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 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, &mut Box, &mut Box, &mut Box, &mut Box)->Result, EvalAltResult>> = Box::new( move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box, @@ -79,20 +87,22 @@ impl; 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), _ => 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 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 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, &mut Box, &mut Box, &mut Box, &mut Box)->Result, EvalAltResult>> = Box::new( move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box, @@ -105,20 +115,22 @@ impl; 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), _ => 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 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 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, &mut Box, &mut Box, &mut Box)->Result, EvalAltResult>> = Box::new( move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box| { @@ -128,19 +140,21 @@ impl 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), + (Some(b), Some(c), Some(d), Some(e)) => Ok(Box::new(fun(b, c.clone(), d.clone(), e.clone())) as Box), _ => 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 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 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, &mut Box, &mut Box, &mut Box)->Result, EvalAltResult>> = Box::new( move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box| { @@ -150,19 +164,21 @@ impl 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), + (Some(b), Some(c), Some(d), Some(e)) => Ok(Box::new(fun(b.clone(), c.clone(), d.clone(), e.clone())) as Box), _ => 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 FnRegister for fn(&mut T, U, V)->W { - fn register(self, engine: &mut Engine, name: &str) { +impl<'a, A, T, U, V, W> FnRegister 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, &mut Box, &mut Box)->Result, EvalAltResult>> = Box::new( move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box| { @@ -171,19 +187,21 @@ impl 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), + (Some(b), Some(c), Some(d)) => Ok(Box::new(fun(b, c.clone(), d.clone())) as Box), _ => 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 FnRegister for fn(T, U, V)->W { - fn register(self, engine: &mut Engine, name: &str) { +impl<'a, A, T, U, V, W> FnRegister 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, &mut Box, &mut Box)->Result, EvalAltResult>> = Box::new( move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box| { @@ -192,19 +210,21 @@ impl 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), + (Some(b), Some(c), Some(d)) => Ok(Box::new(fun(b.clone(), c.clone(), d.clone())) as Box), _ => 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 FnRegister for fn(&mut T, U)->V { - fn register(self, engine: &mut Engine, name: &str) { +impl<'a, A, T, U, V> FnRegister 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, &mut Box)->Result, EvalAltResult>> = Box::new( move |arg1: &mut Box, arg2: &mut Box| { @@ -212,19 +232,21 @@ impl 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), + (Some(b), Some(c)) => Ok(Box::new(fun(b, c.clone())) as Box), _ => 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 FnRegister for fn(T, U)->V { - fn register(self, engine: &mut Engine, name: &str) { +impl<'a, A, T, U, V> FnRegister 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, &mut Box)->Result, EvalAltResult>> = Box::new( move |arg1: &mut Box, arg2: &mut Box| { @@ -232,62 +254,69 @@ impl 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), + (Some(b), Some(c)) => Ok(Box::new(fun(b.clone(), c.clone())) as Box), _ => 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 FnRegister for fn(&mut T)->U { - fn register(self, engine: &mut Engine, name: &str) { +impl<'a, A, T, U> FnRegister 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)->Result, EvalAltResult>> = Box::new( move |arg: &mut Box| { let inside = (*arg).downcast_mut() as Option<&mut T>; match inside { - Some(b) => Ok(Box::new(self(b)) as Box), + Some(b) => Ok(Box::new(fun(b)) as Box), 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 FnRegister for fn(T)->U { - fn register(self, engine: &mut Engine, name: &str) { + +impl<'a, A, T, U> FnRegister 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)->Result, EvalAltResult>> = Box::new( move |arg: &mut Box| { let inside = (*arg).downcast_mut() as Option<&mut T>; match inside { - Some(b) => Ok(Box::new(self(b.clone())) as Box), + Some(b) => Ok(Box::new(fun(b.clone())) as Box), 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 FnRegister for fn()->T { - fn register(self, engine: &mut Engine, name: &str) { +impl FnRegister for Engine + where A: 'static+Fn() -> T, T: Clone+Any +{ + fn register_fn(&mut self, name: &str, fun: A) { let wrapped : BoxResult, EvalAltResult>> = Box::new( - move || { Ok(Box::new(self()) as Box) } + move || { Ok(Box::new(fun()) as Box) } ); - 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)); } } diff --git a/src/parser.rs b/src/parser.rs index 19d43b55..82eb2e42 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -322,7 +322,7 @@ impl<'a> Iterator for TokenIterator<'a> { } } -pub fn lex<'a>(input: &'a String) -> TokenIterator<'a> { +pub fn lex<'a>(input: &'a str) -> TokenIterator<'a> { TokenIterator { char_stream: input.chars().peekable() } }