Simplified function registration to not require explicit coercion step. Simplified eval to take &str instead of String
This commit is contained in:
parent
6950219251
commit
254f4b081c
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "rhai"
|
name = "rhai"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
authors = ["Jonathan Turner"]
|
authors = ["Jonathan Turner"]
|
||||||
description = "Embedded scripting for Rust"
|
description = "Embedded scripting for Rust"
|
||||||
homepage = "https://github.com/jonathandturner/rhai"
|
homepage = "https://github.com/jonathandturner/rhai"
|
||||||
@ -11,4 +11,4 @@ include = [
|
|||||||
"**/*.rs",
|
"**/*.rs",
|
||||||
"scripts/*.rhai",
|
"scripts/*.rhai",
|
||||||
"Cargo.toml"
|
"Cargo.toml"
|
||||||
]
|
]
|
||||||
|
@ -21,10 +21,10 @@ fn main() {
|
|||||||
|
|
||||||
engine.register_type::<TestStruct>();
|
engine.register_type::<TestStruct>();
|
||||||
|
|
||||||
&(TestStruct::update as fn(&mut TestStruct)->()).register(&mut engine, "update");
|
engine.register_fn("update", TestStruct::update);
|
||||||
&(TestStruct::new as fn()->TestStruct).register(&mut engine, "new_ts");
|
engine.register_fn("new_ts", TestStruct::new);
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("var x = new_ts(); x.update(); x".to_string()).unwrap().downcast::<TestStruct>() {
|
if let Ok(result) = engine.eval("var x = new_ts(); x.update(); x").unwrap().downcast::<TestStruct>() {
|
||||||
println!("result: {}", result.x); // prints 1001
|
println!("result: {}", result.x); // prints 1001
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,7 +4,7 @@ use rhai::Engine;
|
|||||||
fn main() {
|
fn main() {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("40 + 2".to_string()).unwrap().downcast::<i32>() {
|
if let Ok(result) = engine.eval("40 + 2").unwrap().downcast::<i32>() {
|
||||||
println!("Answer: {}", *result); // prints 42
|
println!("Answer: {}", *result); // prints 42
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,9 +5,9 @@ fn main() {
|
|||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
let mut scope: Scope = Vec::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::<i32>() {
|
if let Ok(result) = engine.eval_with_scope(&mut scope, "x").unwrap().downcast::<i32>() {
|
||||||
println!("result: {}", result);
|
println!("result: {}", result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,20 +14,20 @@ fn main() {
|
|||||||
for fname in env::args().skip(1) {
|
for fname in env::args().skip(1) {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
&(showit as fn(x: &mut i32)->()).register(&mut engine, "print");
|
engine.register_fn("print", showit as fn(x: &mut i32)->());
|
||||||
&(showit as fn(x: &mut i64)->()).register(&mut engine, "print");
|
engine.register_fn("print", showit as fn(x: &mut i64)->());
|
||||||
&(showit as fn(x: &mut u32)->()).register(&mut engine, "print");
|
engine.register_fn("print", showit as fn(x: &mut u32)->());
|
||||||
&(showit as fn(x: &mut u64)->()).register(&mut engine, "print");
|
engine.register_fn("print", showit as fn(x: &mut u64)->());
|
||||||
&(showit as fn(x: &mut f32)->()).register(&mut engine, "print");
|
engine.register_fn("print", showit as fn(x: &mut f32)->());
|
||||||
&(showit as fn(x: &mut f64)->()).register(&mut engine, "print");
|
engine.register_fn("print", showit as fn(x: &mut f64)->());
|
||||||
&(showit as fn(x: &mut bool)->()).register(&mut engine, "print");
|
engine.register_fn("print", showit as fn(x: &mut bool)->());
|
||||||
&(showit as fn(x: &mut String)->()).register(&mut engine, "print");
|
engine.register_fn("print", showit as fn(x: &mut String)->());
|
||||||
|
|
||||||
if let Ok(mut f) = File::open(fname.clone()) {
|
if let Ok(mut f) = File::open(fname.clone()) {
|
||||||
let mut contents = String::new();
|
let mut contents = String::new();
|
||||||
|
|
||||||
if let Ok(_) = f.read_to_string(&mut contents) {
|
if let Ok(_) = f.read_to_string(&mut contents) {
|
||||||
match engine.eval(contents) {
|
match engine.eval(&contents) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(e) => {println!("Error: {:?}", e)}
|
Err(e) => {println!("Error: {:?}", e)}
|
||||||
}
|
}
|
||||||
|
@ -8,9 +8,9 @@ fn add(x: i32, y: i32) -> i32 {
|
|||||||
fn main() {
|
fn main() {
|
||||||
let mut engine = Engine::new();
|
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::<i32>() {
|
if let Ok(result) = engine.eval("add(40, 2)").unwrap().downcast::<i32>() {
|
||||||
println!("Answer: {}", *result); // prints 42
|
println!("Answer: {}", *result); // prints 42
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,7 +320,7 @@ impl Engine {
|
|||||||
pub fn register_type<T: Clone+Any>(&mut self) {
|
pub fn register_type<T: Clone+Any>(&mut self) {
|
||||||
fn clone_helper<T: Clone>(t:T)->T { t.clone() };
|
fn clone_helper<T: Clone>(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<Any>, dot_rhs: &Expr) -> Result<Box<Any>, EvalAltResult> {
|
fn get_dot_val_helper(&self, scope: &mut Scope, this_ptr: &mut Box<Any>, dot_rhs: &Expr) -> Result<Box<Any>, EvalAltResult> {
|
||||||
@ -693,14 +693,14 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eval(&mut self, input: String) -> Result<Box<Any>, EvalAltResult> {
|
pub fn eval(&mut self, input: &str) -> Result<Box<Any>, EvalAltResult> {
|
||||||
let mut scope: Scope = Vec::new();
|
let mut scope: Scope = Vec::new();
|
||||||
|
|
||||||
self.eval_with_scope(&mut scope, input)
|
self.eval_with_scope(&mut scope, input)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eval_with_scope(&mut self, scope: &mut Scope, input: String) -> Result<Box<Any>, EvalAltResult> {
|
pub fn eval_with_scope(&mut self, scope: &mut Scope, input: &str) -> Result<Box<Any>, EvalAltResult> {
|
||||||
let tokens = lex(&input);
|
let tokens = lex(input);
|
||||||
|
|
||||||
let mut peekables = tokens.peekable();
|
let mut peekables = tokens.peekable();
|
||||||
let tree = parse(&mut peekables);
|
let tree = parse(&mut peekables);
|
||||||
@ -742,15 +742,15 @@ impl Engine {
|
|||||||
macro_rules! reg_op {
|
macro_rules! reg_op {
|
||||||
($engine:expr, $x:expr, $op:expr, $( $y:ty ),*) => (
|
($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 {
|
macro_rules! reg_cmp {
|
||||||
($engine:expr, $x:expr, $op:expr, $( $y:ty ),*) => (
|
($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() {
|
fn test_number_literal() {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("65".to_string()).unwrap().downcast::<i32>() {
|
if let Ok(result) = engine.eval("65").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 65);
|
assert_eq!(*result, 65);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -812,14 +812,14 @@ fn test_number_literal() {
|
|||||||
fn test_ops() {
|
fn test_ops() {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("60 + 5".to_string()).unwrap().downcast::<i32>() {
|
if let Ok(result) = engine.eval("60 + 5").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 65);
|
assert_eq!(*result, 65);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert!(false);
|
assert!(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("(1 + 2) * (6 - 4) / 2".to_string()).unwrap().downcast::<i32>() {
|
if let Ok(result) = engine.eval("(1 + 2) * (6 - 4) / 2").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 3);
|
assert_eq!(*result, 3);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -831,7 +831,7 @@ fn test_ops() {
|
|||||||
fn test_bool_op1() {
|
fn test_bool_op1() {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("true && (false || true)".to_string()).unwrap().downcast::<bool>() {
|
if let Ok(result) = engine.eval("true && (false || true)").unwrap().downcast::<bool>() {
|
||||||
assert_eq!(*result, true);
|
assert_eq!(*result, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -843,7 +843,7 @@ fn test_bool_op1() {
|
|||||||
fn test_bool_op2() {
|
fn test_bool_op2() {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("false && (false || true)".to_string()).unwrap().downcast::<bool>() {
|
if let Ok(result) = engine.eval("false && (false || true)").unwrap().downcast::<bool>() {
|
||||||
assert_eq!(*result, false);
|
assert_eq!(*result, false);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -855,7 +855,7 @@ fn test_bool_op2() {
|
|||||||
fn test_op_prec() {
|
fn test_op_prec() {
|
||||||
let mut engine = Engine::new();
|
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::<i32>() {
|
if let Ok(result) = engine.eval("var x = 0; if x == 10 || true { x = 1} x").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 1);
|
assert_eq!(*result, 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -867,21 +867,21 @@ fn test_op_prec() {
|
|||||||
fn test_if() {
|
fn test_if() {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("if true { 55 }".to_string()).unwrap().downcast::<i32>() {
|
if let Ok(result) = engine.eval("if true { 55 }").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 55);
|
assert_eq!(*result, 55);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert!(false);
|
assert!(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("if false { 55 } else { 44 }".to_string()).unwrap().downcast::<i32>() {
|
if let Ok(result) = engine.eval("if false { 55 } else { 44 }").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 44);
|
assert_eq!(*result, 44);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert!(false);
|
assert!(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("if true { 55 } else { 44 }".to_string()).unwrap().downcast::<i32>() {
|
if let Ok(result) = engine.eval("if true { 55 } else { 44 }").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 55);
|
assert_eq!(*result, 55);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -893,7 +893,7 @@ fn test_if() {
|
|||||||
fn test_while() {
|
fn test_while() {
|
||||||
let mut engine = Engine::new();
|
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::<i32>() {
|
if let Ok(result) = engine.eval("var x = 0; while x < 10 { x = x + 1; if x > 5 { break } } x").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 6);
|
assert_eq!(*result, 6);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -906,27 +906,27 @@ fn test_var_scope() {
|
|||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
let mut scope: Scope = Vec::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::<i32>() {
|
if let Ok(result) = engine.eval_with_scope(&mut scope, "x").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 9);
|
assert_eq!(*result, 9);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert!(false);
|
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::<i32>() {
|
if let Ok(result) = engine.eval_with_scope(&mut scope, "x").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 12);
|
assert_eq!(*result, 12);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert!(false);
|
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::<i32>() {
|
if let Ok(result) = engine.eval_with_scope(&mut scope, "x").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 12);
|
assert_eq!(*result, 12);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -955,10 +955,10 @@ fn test_method_call() {
|
|||||||
|
|
||||||
engine.register_type::<TestStruct>();
|
engine.register_type::<TestStruct>();
|
||||||
|
|
||||||
&(TestStruct::update as fn(&mut TestStruct)->()).register(&mut engine, "update");
|
engine.register_fn("update", TestStruct::update);
|
||||||
&(TestStruct::new as fn()->TestStruct).register(&mut engine, "new_ts");
|
engine.register_fn("new_ts", TestStruct::new);
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("var x = new_ts(); x.update(); x".to_string()).unwrap().downcast::<TestStruct>() {
|
if let Ok(result) = engine.eval("var x = new_ts(); x.update(); x").unwrap().downcast::<TestStruct>() {
|
||||||
assert_eq!(result.x, 1001);
|
assert_eq!(result.x, 1001);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -992,11 +992,11 @@ fn test_get_set() {
|
|||||||
|
|
||||||
engine.register_type::<TestStruct>();
|
engine.register_type::<TestStruct>();
|
||||||
|
|
||||||
&(TestStruct::get_x as fn(&mut TestStruct)->i32).register(&mut engine, "get$x");
|
engine.register_fn("get$x", TestStruct::get_x);
|
||||||
&(TestStruct::set_x as fn(&mut TestStruct, i32)->()).register(&mut engine, "set$x");
|
engine.register_fn("set$x", TestStruct::set_x);
|
||||||
&(TestStruct::new as fn()->TestStruct).register(&mut engine, "new_ts");
|
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::<i32>() {
|
if let Ok(result) = engine.eval("var a = new_ts(); a.x = 500; a.x").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 500);
|
assert_eq!(*result, 500);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1050,15 +1050,13 @@ fn test_big_get_set() {
|
|||||||
engine.register_type::<TestChild>();
|
engine.register_type::<TestChild>();
|
||||||
engine.register_type::<TestParent>();
|
engine.register_type::<TestParent>();
|
||||||
|
|
||||||
&(TestChild::get_x as fn(&mut TestChild)->i32).register(&mut engine, "get$x");
|
engine.register_fn("get$x", TestChild::get_x);
|
||||||
&(TestChild::set_x as fn(&mut TestChild, i32)->()).register(&mut engine, "set$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");
|
if let Ok(result) = engine.eval("var a = new_tp(); a.child.x = 500; a.child.x").unwrap().downcast::<i32>() {
|
||||||
&(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::<i32>() {
|
|
||||||
assert_eq!(*result, 500);
|
assert_eq!(*result, 500);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1070,14 +1068,14 @@ fn test_big_get_set() {
|
|||||||
fn test_internal_fn() {
|
fn test_internal_fn() {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("fn addme(a, b) { a+b } addme(3, 4)".to_string()).unwrap().downcast::<i32>() {
|
if let Ok(result) = engine.eval("fn addme(a, b) { a+b } addme(3, 4)").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 7);
|
assert_eq!(*result, 7);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert!(false);
|
assert!(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("fn bob() { return 4; 5 } bob()".to_string()).unwrap().downcast::<i32>() {
|
if let Ok(result) = engine.eval("fn bob() { return 4; 5 } bob()").unwrap().downcast::<i32>() {
|
||||||
assert_eq!(*result, 4);
|
assert_eq!(*result, 4);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1089,7 +1087,7 @@ fn test_internal_fn() {
|
|||||||
fn test_big_internal_fn() {
|
fn test_big_internal_fn() {
|
||||||
let mut engine = Engine::new();
|
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::<i32>() {
|
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::<i32>() {
|
||||||
assert_eq!(*result, 112);
|
assert_eq!(*result, 112);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1101,7 +1099,7 @@ fn test_big_internal_fn() {
|
|||||||
fn test_string() {
|
fn test_string() {
|
||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
|
|
||||||
if let Ok(result) = engine.eval("\"Test string: \\u2764\"".to_string()).unwrap().downcast::<String>() {
|
if let Ok(result) = engine.eval("\"Test string: \\u2764\"").unwrap().downcast::<String>() {
|
||||||
assert_eq!(*result, "Test string: ❤");
|
assert_eq!(*result, "Test string: ❤");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -3,12 +3,15 @@ use std::boxed::Box;
|
|||||||
|
|
||||||
use engine::{EvalAltResult, Engine, FnType};
|
use engine::{EvalAltResult, Engine, FnType};
|
||||||
|
|
||||||
pub trait FnRegister {
|
pub trait FnRegister<A, RetVal, Args> {
|
||||||
fn register(self, engine: &mut Engine, name: &str);
|
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 {
|
impl<'a, A, T, U, V, W, X, Y, Z> FnRegister<A, Z, (&'a mut T, U, V, W, X, Y)> for Engine
|
||||||
fn register(self, engine: &mut Engine, name: &str) {
|
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>,
|
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>> =
|
&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>;
|
let inside6 = (*arg6).downcast_mut() as Option<&mut Y>;
|
||||||
|
|
||||||
match (inside1, inside2, inside3, inside4, inside5, inside6) {
|
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>),
|
e.clone(), f.clone(), g.clone())) as Box<Any>),
|
||||||
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
|
_ => 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));
|
(*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 {
|
impl<'a, A, T, U, V, W, X, Y, Z> FnRegister<A, Z, (&'a T, U, V, W, X, Y)> for Engine
|
||||||
fn register(self, engine: &mut Engine, name: &str) {
|
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>,
|
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>> =
|
&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>;
|
let inside6 = (*arg6).downcast_mut() as Option<&mut Y>;
|
||||||
|
|
||||||
match (inside1, inside2, inside3, inside4, inside5, inside6) {
|
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>),
|
e.clone(), f.clone(), g.clone())) as Box<Any>),
|
||||||
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
|
_ => 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));
|
(*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 {
|
impl<'a, A, T, U, V, W, X, Y> FnRegister<A, Y, (&'a mut T, U, V, W, X)> for Engine
|
||||||
fn register(self, engine: &mut Engine, name: &str) {
|
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>> =
|
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(
|
Box::new(
|
||||||
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>, arg3: &mut Box<Any>, arg4: &mut Box<Any>,
|
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>;
|
let inside5 = (*arg5).downcast_mut() as Option<&mut X>;
|
||||||
|
|
||||||
match (inside1, inside2, inside3, inside4, inside5) {
|
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>),
|
e.clone(), f.clone())) as Box<Any>),
|
||||||
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
|
_ => 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));
|
(*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 {
|
impl<'a, A, T, U, V, W, X, Y> FnRegister<A, Y, (&'a T, U, V, W, X)> for Engine
|
||||||
fn register(self, engine: &mut Engine, name: &str) {
|
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>> =
|
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(
|
Box::new(
|
||||||
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>, arg3: &mut Box<Any>, arg4: &mut Box<Any>,
|
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>;
|
let inside5 = (*arg5).downcast_mut() as Option<&mut X>;
|
||||||
|
|
||||||
match (inside1, inside2, inside3, inside4, inside5) {
|
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>),
|
e.clone(), f.clone())) as Box<Any>),
|
||||||
_ => Err(EvalAltResult::ErrorFunctionArgMismatch)
|
_ => 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));
|
(*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 {
|
impl<'a, A, T, U, V, W, X> FnRegister<A, X, (&'a mut T, U, V, W)> for Engine
|
||||||
fn register(self, engine: &mut Engine, name: &str) {
|
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>> =
|
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>, &mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
|
||||||
Box::new(
|
Box::new(
|
||||||
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>, arg3: &mut Box<Any>, arg4: &mut Box<Any>| {
|
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>;
|
let inside4 = (*arg4).downcast_mut() as Option<&mut W>;
|
||||||
|
|
||||||
match (inside1, inside2, inside3, inside4) {
|
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)
|
_ => 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));
|
(*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 {
|
impl<'a, A, T, U, V, W, X> FnRegister<A, X, (&'a T, U, V, W)> for Engine
|
||||||
fn register(self, engine: &mut Engine, name: &str) {
|
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>> =
|
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>, &mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
|
||||||
Box::new(
|
Box::new(
|
||||||
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>, arg3: &mut Box<Any>, arg4: &mut Box<Any>| {
|
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>;
|
let inside4 = (*arg4).downcast_mut() as Option<&mut W>;
|
||||||
|
|
||||||
match (inside1, inside2, inside3, inside4) {
|
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)
|
_ => 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));
|
(*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 {
|
impl<'a, A, T, U, V, W> FnRegister<A, W, (&'a mut T, U, V)> for Engine
|
||||||
fn register(self, engine: &mut Engine, name: &str) {
|
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>> =
|
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
|
||||||
Box::new(
|
Box::new(
|
||||||
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>, arg3: &mut Box<Any>| {
|
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>;
|
let inside3 = (*arg3).downcast_mut() as Option<&mut V>;
|
||||||
|
|
||||||
match (inside1, inside2, inside3) {
|
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)
|
_ => 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));
|
(*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 {
|
impl<'a, A, T, U, V, W> FnRegister<A, W, (&'a T, U, V)> for Engine
|
||||||
fn register(self, engine: &mut Engine, name: &str) {
|
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>> =
|
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
|
||||||
Box::new(
|
Box::new(
|
||||||
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>, arg3: &mut Box<Any>| {
|
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>;
|
let inside3 = (*arg3).downcast_mut() as Option<&mut V>;
|
||||||
|
|
||||||
match (inside1, inside2, inside3) {
|
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)
|
_ => 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));
|
(*ent).push(FnType::ExternalFn3(wrapped));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Any+Clone, U: Any+Clone, V: Any+Clone> FnRegister for fn(&mut T, U)->V {
|
impl<'a, A, T, U, V> FnRegister<A, V, (&'a mut T, U)> for Engine
|
||||||
fn register(self, engine: &mut Engine, name: &str) {
|
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>> =
|
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
|
||||||
Box::new(
|
Box::new(
|
||||||
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>| {
|
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>;
|
let inside2 = (*arg2).downcast_mut() as Option<&mut U>;
|
||||||
|
|
||||||
match (inside1, inside2) {
|
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)
|
_ => 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));
|
(*ent).push(FnType::ExternalFn2(wrapped));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Any+Clone, U: Any+Clone, V: Any+Clone> FnRegister for fn(T, U)->V {
|
impl<'a, A, T, U, V> FnRegister<A, V, (&'a T, U)> for Engine
|
||||||
fn register(self, engine: &mut Engine, name: &str) {
|
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>> =
|
let wrapped : Box<Fn(&mut Box<Any>, &mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
|
||||||
Box::new(
|
Box::new(
|
||||||
move |arg1: &mut Box<Any>, arg2: &mut Box<Any>| {
|
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>;
|
let inside2 = (*arg2).downcast_mut() as Option<&mut U>;
|
||||||
|
|
||||||
match (inside1, inside2) {
|
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)
|
_ => 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));
|
(*ent).push(FnType::ExternalFn2(wrapped));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Any+Clone, U: Any+Clone> FnRegister for fn(&mut T)->U {
|
impl<'a, A, T, U> FnRegister<A, U, (&'a mut T)> for Engine
|
||||||
fn register(self, engine: &mut Engine, name: &str) {
|
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>> =
|
let wrapped : Box<Fn(&mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
|
||||||
Box::new(
|
Box::new(
|
||||||
move |arg: &mut Box<Any>| {
|
move |arg: &mut Box<Any>| {
|
||||||
let inside = (*arg).downcast_mut() as Option<&mut T>;
|
let inside = (*arg).downcast_mut() as Option<&mut T>;
|
||||||
|
|
||||||
match inside {
|
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)
|
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));
|
(*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>> =
|
let wrapped : Box<Fn(&mut Box<Any>)->Result<Box<Any>, EvalAltResult>> =
|
||||||
Box::new(
|
Box::new(
|
||||||
move |arg: &mut Box<Any>| {
|
move |arg: &mut Box<Any>| {
|
||||||
let inside = (*arg).downcast_mut() as Option<&mut T>;
|
let inside = (*arg).downcast_mut() as Option<&mut T>;
|
||||||
match inside {
|
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)
|
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));
|
(*ent).push(FnType::ExternalFn1(wrapped));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Any+Clone> FnRegister for fn()->T {
|
impl<A, T> FnRegister<A, T, ()> for Engine
|
||||||
fn register(self, engine: &mut Engine, name: &str) {
|
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>> =
|
let wrapped : Box<Fn()->Result<Box<Any>, EvalAltResult>> =
|
||||||
Box::new(
|
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));
|
(*ent).push(FnType::ExternalFn0(wrapped));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() }
|
TokenIterator { char_stream: input.chars().peekable() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user