diff --git a/examples/function_decl3.rhai b/examples/function_decl3.rhai new file mode 100644 index 00000000..b23846f4 --- /dev/null +++ b/examples/function_decl3.rhai @@ -0,0 +1,5 @@ +fn f(a, b, c, d, e, f) { + a - b * c - d * e - f +} + +print(f(100, 5, 2, 9, 6, 32)) diff --git a/src/engine.rs b/src/engine.rs index 63788160..4e907f06 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -43,52 +43,20 @@ impl fmt::Display for EvalError { } } -fn add(x: T, y: T) -> ::Output { - x + y + +pub enum Arity6 { + ExternalFn(Box, &mut Box, &mut Box, &mut Box, &mut Box, &mut Box)->Result, EvalError>>), + InternalFn(FnDef) } -fn sub(x: T, y: T) -> ::Output { - x - y +pub enum Arity5 { + ExternalFn(Box, &mut Box, &mut Box, &mut Box, &mut Box)->Result, EvalError>>), + InternalFn(FnDef) } -fn mul(x: T, y: T) -> ::Output { - x * y -} - -fn div(x: T, y: T) -> ::Output { - x / y -} - -fn lt(x: T, y: T) -> bool { - x < y -} - -fn lte(x: T, y: T) -> bool { - x <= y -} - -fn gt(x: T, y: T) -> bool { - x > y -} - -fn gte(x: T, y: T) -> bool { - x >= y -} - -fn eq(x: T, y: T) -> bool { - x == y -} - -fn ne(x: T, y: T) -> bool { - x != y -} - -fn and(x: bool, y: bool) -> bool { - x && y -} - -fn or(x: bool, y: bool) -> bool { - x || y +pub enum Arity4 { + ExternalFn(Box, &mut Box, &mut Box, &mut Box)->Result, EvalError>>), + InternalFn(FnDef) } pub enum Arity3 { @@ -112,6 +80,9 @@ pub enum Arity0 { } pub struct Engine { + pub fns_arity_6: HashMap>, + pub fns_arity_5: HashMap>, + pub fns_arity_4: HashMap>, pub fns_arity_3: HashMap>, pub fns_arity_2: HashMap>, pub fns_arity_1: HashMap>, @@ -242,6 +213,130 @@ impl Engine { } } + pub fn call_fn_4_arg(&self, name: &str, arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box) -> + Result, EvalError> { + + match self.fns_arity_4.get(name) { + Some(vf) => { + for arr_f in vf { + match arr_f { + & Arity4::ExternalFn(ref f) => { + let invoke = f(arg1, arg2, arg3, arg4); + match invoke { + Ok(v) => return Ok(v), + _ => () + } + } + & Arity4::InternalFn(ref f) => { + let mut new_scope: Scope = Vec::new(); + let result1 = self.call_fn_1_arg("clone", arg1); + let result2 = self.call_fn_1_arg("clone", arg2); + let result3 = self.call_fn_1_arg("clone", arg3); + let result4 = self.call_fn_1_arg("clone", arg3); + match (result1, result2, result3, result4) { + (Ok(r1), Ok(r2), Ok(r3), Ok(r4)) => { + new_scope.push((f.params[0].clone(), r1)); + new_scope.push((f.params[1].clone(), r2)); + new_scope.push((f.params[2].clone(), r3)); + new_scope.push((f.params[3].clone(), r4)); + }, + _ => return Err(EvalError::FunctionArgMismatch) + } + return self.eval_stmt(&mut new_scope, &*f.body); + } + } + }; + Err(EvalError::FunctionArgMismatch) + } + None => Err(EvalError::FunctionNotFound) + } + } + + pub fn call_fn_5_arg(&self, name: &str, arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, + arg4: &mut Box, arg5: &mut Box) -> Result, EvalError> { + + match self.fns_arity_5.get(name) { + Some(vf) => { + for arr_f in vf { + match arr_f { + & Arity5::ExternalFn(ref f) => { + let invoke = f(arg1, arg2, arg3, arg4, arg5); + match invoke { + Ok(v) => return Ok(v), + _ => () + } + } + & Arity5::InternalFn(ref f) => { + let mut new_scope: Scope = Vec::new(); + let result1 = self.call_fn_1_arg("clone", arg1); + let result2 = self.call_fn_1_arg("clone", arg2); + let result3 = self.call_fn_1_arg("clone", arg3); + let result4 = self.call_fn_1_arg("clone", arg4); + let result5 = self.call_fn_1_arg("clone", arg5); + match (result1, result2, result3, result4, result5) { + (Ok(r1), Ok(r2), Ok(r3), Ok(r4), Ok(r5)) => { + new_scope.push((f.params[0].clone(), r1)); + new_scope.push((f.params[1].clone(), r2)); + new_scope.push((f.params[2].clone(), r3)); + new_scope.push((f.params[3].clone(), r4)); + new_scope.push((f.params[4].clone(), r5)); + }, + _ => return Err(EvalError::FunctionArgMismatch) + } + return self.eval_stmt(&mut new_scope, &*f.body); + } + } + }; + Err(EvalError::FunctionArgMismatch) + } + None => Err(EvalError::FunctionNotFound) + } + } + + pub fn call_fn_6_arg(&self, name: &str, arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, + arg4: &mut Box, arg5: &mut Box, arg6: &mut Box) -> Result, EvalError> { + + match self.fns_arity_6.get(name) { + Some(vf) => { + for arr_f in vf { + match arr_f { + & Arity6::ExternalFn(ref f) => { + let invoke = f(arg1, arg2, arg3, arg4, arg5, arg6); + match invoke { + Ok(v) => return Ok(v), + _ => () + } + } + & Arity6::InternalFn(ref f) => { + let mut new_scope: Scope = Vec::new(); + let result1 = self.call_fn_1_arg("clone", arg1); + let result2 = self.call_fn_1_arg("clone", arg2); + let result3 = self.call_fn_1_arg("clone", arg3); + let result4 = self.call_fn_1_arg("clone", arg4); + let result5 = self.call_fn_1_arg("clone", arg5); + let result6 = self.call_fn_1_arg("clone", arg6); + + match (result1, result2, result3, result4, result5, result6) { + (Ok(r1), Ok(r2), Ok(r3), Ok(r4), Ok(r5), Ok(r6)) => { + new_scope.push((f.params[0].clone(), r1)); + new_scope.push((f.params[1].clone(), r2)); + new_scope.push((f.params[2].clone(), r3)); + new_scope.push((f.params[3].clone(), r4)); + new_scope.push((f.params[4].clone(), r5)); + new_scope.push((f.params[5].clone(), r6)); + }, + _ => return Err(EvalError::FunctionArgMismatch) + } + return self.eval_stmt(&mut new_scope, &*f.body); + } + } + }; + Err(EvalError::FunctionArgMismatch) + } + None => Err(EvalError::FunctionNotFound) + } + } + fn register_type(&mut self) { fn clone_helper(t:T)->T { t.clone() }; @@ -295,10 +390,37 @@ impl Engine { else if args.len() == 3 { let mut arg1 = try!(self.eval_expr(scope, &args[0])); let mut arg2 = try!(self.eval_expr(scope, &args[1])); - let mut arg3 = try!(self.eval_expr(scope, &args[1])); + let mut arg3 = try!(self.eval_expr(scope, &args[2])); self.call_fn_3_arg(&fn_name, &mut arg1, &mut arg2, &mut arg3) } + else if args.len() == 4 { + let mut arg1 = try!(self.eval_expr(scope, &args[0])); + let mut arg2 = try!(self.eval_expr(scope, &args[1])); + let mut arg3 = try!(self.eval_expr(scope, &args[2])); + let mut arg4 = try!(self.eval_expr(scope, &args[3])); + + self.call_fn_4_arg(&fn_name, &mut arg1, &mut arg2, &mut arg3, &mut arg4) + } + else if args.len() == 5 { + let mut arg1 = try!(self.eval_expr(scope, &args[0])); + let mut arg2 = try!(self.eval_expr(scope, &args[1])); + let mut arg3 = try!(self.eval_expr(scope, &args[2])); + let mut arg4 = try!(self.eval_expr(scope, &args[3])); + let mut arg5 = try!(self.eval_expr(scope, &args[4])); + + self.call_fn_5_arg(&fn_name, &mut arg1, &mut arg2, &mut arg3, &mut arg4, &mut arg5) + } + else if args.len() == 6 { + let mut arg1 = try!(self.eval_expr(scope, &args[0])); + let mut arg2 = try!(self.eval_expr(scope, &args[1])); + let mut arg3 = try!(self.eval_expr(scope, &args[2])); + let mut arg4 = try!(self.eval_expr(scope, &args[3])); + let mut arg5 = try!(self.eval_expr(scope, &args[4])); + let mut arg6 = try!(self.eval_expr(scope, &args[5])); + + self.call_fn_6_arg(&fn_name, &mut arg1, &mut arg2, &mut arg3, &mut arg4, &mut arg5, &mut arg6) + } else { Err(EvalError::FunctionCallNotSupported) } @@ -333,6 +455,45 @@ impl Engine { } Err(EvalError::VariableNotFound) } + else if args.len() == 3 { + let mut arg1 = try!(self.eval_expr(scope, &args[0])); + let mut arg2 = try!(self.eval_expr(scope, &args[1])); + let mut arg3 = try!(self.eval_expr(scope, &args[2])); + + for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() { + if *target == *name { + return self.call_fn_4_arg(&fn_name, val, &mut arg1, &mut arg2, &mut arg3); + } + } + Err(EvalError::VariableNotFound) + } + else if args.len() == 4 { + let mut arg1 = try!(self.eval_expr(scope, &args[0])); + let mut arg2 = try!(self.eval_expr(scope, &args[1])); + let mut arg3 = try!(self.eval_expr(scope, &args[2])); + let mut arg4 = try!(self.eval_expr(scope, &args[3])); + + for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() { + if *target == *name { + return self.call_fn_5_arg(&fn_name, val, &mut arg1, &mut arg2, &mut arg3, &mut arg4); + } + } + Err(EvalError::VariableNotFound) + } + else if args.len() == 5 { + let mut arg1 = try!(self.eval_expr(scope, &args[0])); + let mut arg2 = try!(self.eval_expr(scope, &args[1])); + let mut arg3 = try!(self.eval_expr(scope, &args[2])); + let mut arg4 = try!(self.eval_expr(scope, &args[3])); + let mut arg5 = try!(self.eval_expr(scope, &args[4])); + + for &mut (ref name, ref mut val) in &mut scope.iter_mut().rev() { + if *target == *name { + return self.call_fn_6_arg(&fn_name, val, &mut arg1, &mut arg2, &mut arg3, &mut arg4, &mut arg5); + } + } + Err(EvalError::VariableNotFound) + } else { Err(EvalError::FunctionCallNotSupported) } @@ -422,8 +583,6 @@ impl Engine { let mut peekables = tokens.peekable(); let tree = parse(&mut peekables); - println!("parse: {:?}", tree); - match tree { Ok((ref os, ref fns)) => { let mut x: Result, EvalError> = Ok(Box::new(())); @@ -454,6 +613,24 @@ impl Engine { let ent = self.fns_arity_3.entry(name).or_insert(Vec::new()); (*ent).push(Arity3::InternalFn(local_f)); }, + 4 => { + let name = f.name.clone(); + let local_f = f.clone(); + let ent = self.fns_arity_4.entry(name).or_insert(Vec::new()); + (*ent).push(Arity4::InternalFn(local_f)); + }, + 5 => { + let name = f.name.clone(); + let local_f = f.clone(); + let ent = self.fns_arity_5.entry(name).or_insert(Vec::new()); + (*ent).push(Arity5::InternalFn(local_f)); + }, + 6 => { + let name = f.name.clone(); + let local_f = f.clone(); + let ent = self.fns_arity_6.entry(name).or_insert(Vec::new()); + (*ent).push(Arity6::InternalFn(local_f)); + }, _ => return Err(EvalError::FunctionArityNotSupported) } } @@ -494,6 +671,19 @@ impl Engine { ) } + fn add(x: T, y: T) -> ::Output { x + y } + fn sub(x: T, y: T) -> ::Output { x - y } + fn mul(x: T, y: T) -> ::Output { x * y } + fn div(x: T, y: T) -> ::Output { x / y } + fn lt(x: T, y: T) -> bool { x < y } + fn lte(x: T, y: T) -> bool { x <= y } + fn gt(x: T, y: T) -> bool { x > y } + fn gte(x: T, y: T) -> bool { x >= y } + fn eq(x: T, y: T) -> bool { x == y } + fn ne(x: T, y: T) -> bool { x != y } + fn and(x: bool, y: bool) -> bool { x && y } + fn or(x: bool, y: bool) -> bool { x || y } + reg_op!(engine, "+", add, i32, i64, u32, u64, f32, f64); reg_op!(engine, "-", sub, i32, i64, u32, u64, f32, f64); reg_op!(engine, "*", mul, i32, i64, u32, u64, f32, f64); @@ -515,7 +705,10 @@ impl Engine { fns_arity_0: HashMap::new(), fns_arity_1: HashMap::new(), fns_arity_2: HashMap::new(), - fns_arity_3: HashMap::new() + fns_arity_3: HashMap::new(), + fns_arity_4: HashMap::new(), + fns_arity_5: HashMap::new(), + fns_arity_6: HashMap::new() }; Engine::register_default_lib(&mut engine); @@ -676,6 +869,18 @@ fn test_internal_fn() { } } +#[test] +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::() { + assert_eq!(*result, 112); + } + else { + assert!(false); + } +} + #[test] fn test_string() { let mut engine = Engine::new(); diff --git a/src/fn_register.rs b/src/fn_register.rs index a66ae5ec..b6321b3b 100644 --- a/src/fn_register.rs +++ b/src/fn_register.rs @@ -1,20 +1,174 @@ use std::any::Any; use std::boxed::Box; -use engine::{EvalError, Engine, Arity0, Arity1, Arity2, Arity3}; +use engine::{EvalError, Engine, Arity0, Arity1, Arity2, Arity3, Arity4, Arity5, Arity6}; pub trait FnRegister { fn register(self, engine: &mut Engine, name: &str); } +impl FnRegister for fn(&mut T, U, V, W, X, Y)->Z { + fn register(self, engine: &mut Engine, name: &str) { + let wrapped : Box, &mut Box, &mut Box, &mut Box, &mut Box, + &mut Box)->Result, EvalError>> = + + Box::new( + move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box, + arg5: &mut Box, arg6: &mut Box| { + + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + let inside4 = (*arg4).downcast_mut() as Option<&mut W>; + let inside5 = (*arg5).downcast_mut() as Option<&mut X>; + 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(), + e.clone(), f.clone(), g.clone())) as Box), + _ => Err(EvalError::FunctionArgMismatch) + } + } + ); + + let ent = engine.fns_arity_6.entry(name.to_string()).or_insert(Vec::new()); + (*ent).push(Arity6::ExternalFn(wrapped)); + } +} + +impl FnRegister for fn(T, U, V, W, X, Y)->Z { + fn register(self, engine: &mut Engine, name: &str) { + let wrapped : Box, &mut Box, &mut Box, &mut Box, &mut Box, + &mut Box)->Result, EvalError>> = + + Box::new( + move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box, + arg5: &mut Box, arg6: &mut Box| { + + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + let inside4 = (*arg4).downcast_mut() as Option<&mut W>; + let inside5 = (*arg5).downcast_mut() as Option<&mut X>; + 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(), + e.clone(), f.clone(), g.clone())) as Box), + _ => Err(EvalError::FunctionArgMismatch) + } + } + ); + + let ent = engine.fns_arity_6.entry(name.to_string()).or_insert(Vec::new()); + (*ent).push(Arity6::ExternalFn(wrapped)); + } +} + +impl FnRegister for fn(&mut T, U, V, W, X)->Y { + fn register(self, engine: &mut Engine, name: &str) { + let wrapped : Box, &mut Box, &mut Box, &mut Box, &mut Box)->Result, EvalError>> = + Box::new( + move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box, + arg5: &mut Box| { + + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + let inside4 = (*arg4).downcast_mut() as Option<&mut W>; + 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(), + e.clone(), f.clone())) as Box), + _ => Err(EvalError::FunctionArgMismatch) + } + } + ); + + let ent = engine.fns_arity_5.entry(name.to_string()).or_insert(Vec::new()); + (*ent).push(Arity5::ExternalFn(wrapped)); + } +} + +impl FnRegister for fn(T, U, V, W, X)->Y { + fn register(self, engine: &mut Engine, name: &str) { + let wrapped : Box, &mut Box, &mut Box, &mut Box, &mut Box)->Result, EvalError>> = + Box::new( + move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box, + arg5: &mut Box| { + + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + let inside4 = (*arg4).downcast_mut() as Option<&mut W>; + 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(), + e.clone(), f.clone())) as Box), + _ => Err(EvalError::FunctionArgMismatch) + } + } + ); + + let ent = engine.fns_arity_5.entry(name.to_string()).or_insert(Vec::new()); + (*ent).push(Arity5::ExternalFn(wrapped)); + } +} + +impl FnRegister for fn(&mut T, U, V, W)->X { + fn register(self, engine: &mut Engine, name: &str) { + let wrapped : Box, &mut Box, &mut Box, &mut Box)->Result, EvalError>> = + Box::new( + move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + 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), + _ => Err(EvalError::FunctionArgMismatch) + } + } + ); + + let ent = engine.fns_arity_4.entry(name.to_string()).or_insert(Vec::new()); + (*ent).push(Arity4::ExternalFn(wrapped)); + } +} + +impl FnRegister for fn(T, U, V, W)->X { + fn register(self, engine: &mut Engine, name: &str) { + let wrapped : Box, &mut Box, &mut Box, &mut Box)->Result, EvalError>> = + Box::new( + move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box, arg4: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + let inside3 = (*arg3).downcast_mut() as Option<&mut V>; + 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), + _ => Err(EvalError::FunctionArgMismatch) + } + } + ); + + let ent = engine.fns_arity_4.entry(name.to_string()).or_insert(Vec::new()); + (*ent).push(Arity4::ExternalFn(wrapped)); + } +} + impl FnRegister for fn(&mut T, U, V)->W { fn register(self, engine: &mut Engine, name: &str) { let wrapped : Box, &mut Box, &mut Box)->Result, EvalError>> = Box::new( - move |x: &mut Box, y: &mut Box, z: &mut Box| { - let inside1 = (*x).downcast_mut() as Option<&mut T>; - let inside2 = (*y).downcast_mut() as Option<&mut U>; - let inside3 = (*z).downcast_mut() as Option<&mut V>; + move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + 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), @@ -32,10 +186,10 @@ impl FnRegister for fn(T fn register(self, engine: &mut Engine, name: &str) { let wrapped : Box, &mut Box, &mut Box)->Result, EvalError>> = Box::new( - move |x: &mut Box, y: &mut Box, z: &mut Box| { - let inside1 = (*x).downcast_mut() as Option<&mut T>; - let inside2 = (*y).downcast_mut() as Option<&mut U>; - let inside3 = (*z).downcast_mut() as Option<&mut V>; + move |arg1: &mut Box, arg2: &mut Box, arg3: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + let inside2 = (*arg2).downcast_mut() as Option<&mut U>; + 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), @@ -53,9 +207,9 @@ impl FnRegister for fn(&mut T, U)->V { fn register(self, engine: &mut Engine, name: &str) { let wrapped : Box, &mut Box)->Result, EvalError>> = Box::new( - move |x: &mut Box, y: &mut Box| { - let inside1 = (*x).downcast_mut() as Option<&mut T>; - let inside2 = (*y).downcast_mut() as Option<&mut U>; + move |arg1: &mut Box, arg2: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + 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), @@ -73,9 +227,9 @@ impl FnRegister for fn(T, U)->V { fn register(self, engine: &mut Engine, name: &str) { let wrapped : Box, &mut Box)->Result, EvalError>> = Box::new( - move |x: &mut Box, y: &mut Box| { - let inside1 = (*x).downcast_mut() as Option<&mut T>; - let inside2 = (*y).downcast_mut() as Option<&mut U>; + move |arg1: &mut Box, arg2: &mut Box| { + let inside1 = (*arg1).downcast_mut() as Option<&mut T>; + 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), @@ -93,8 +247,8 @@ impl FnRegister for fn(&mut T)->U { fn register(self, engine: &mut Engine, name: &str) { let wrapped : Box)->Result, EvalError>> = Box::new( - move |x: &mut Box| { - let inside = (*x).downcast_mut() as Option<&mut T>; + move |arg: &mut Box| { + let inside = (*arg).downcast_mut() as Option<&mut T>; match inside { Some(b) => Ok(Box::new(self(b)) as Box), @@ -112,8 +266,8 @@ impl FnRegister for fn(T)->U { fn register(self, engine: &mut Engine, name: &str) { let wrapped : Box)->Result, EvalError>> = Box::new( - move |x: &mut Box| { - let inside = (*x).downcast_mut() as Option<&mut T>; + 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), None => Err(EvalError::FunctionArgMismatch) diff --git a/src/main.rs b/src/main.rs index 80fa76af..559d42d4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,7 +19,6 @@ mod parser; // * Maintaining state // * Overloading // * How it works -// * Arity to 10? // * Vectors // * Errors with positions? // * Remove empty box values?