Use &mut Any instead of &mut Box<Any>

This commit is contained in:
torkleyy 2017-12-20 21:52:26 +01:00
parent 348a680980
commit 71ebd0d4d1
3 changed files with 25 additions and 23 deletions

View File

@ -117,7 +117,7 @@ pub enum FnIntExt {
Int(FnDef), Int(FnDef),
} }
pub type FnAny = Fn(Vec<&mut Box<Any>>) -> Result<Box<Any>, EvalAltResult>; pub type FnAny = Fn(Vec<&mut Any>) -> Result<Box<Any>, EvalAltResult>;
/// A type containing information about current scope. /// A type containing information about current scope.
/// Useful for keeping state between `Engine` runs /// Useful for keeping state between `Engine` runs
@ -141,19 +141,19 @@ impl Engine {
pub fn call_fn_raw( pub fn call_fn_raw(
&self, &self,
ident: String, ident: String,
args: Vec<&mut Box<Any>>, args: Vec<&mut Any>,
) -> Result<Box<Any>, EvalAltResult> { ) -> Result<Box<Any>, EvalAltResult> {
println!( println!(
"Trying to call function {:?} with args {:?}", "Trying to call function {:?} with args {:?}",
ident, ident,
args.iter().map(|x| (***x).type_id()).collect::<Vec<_>>() args.iter().map(|x| (&**x).type_id()).collect::<Vec<_>>()
); );
let spec = FnSpec { let spec = FnSpec {
ident: ident.clone(), ident: ident.clone(),
args: Some( args: Some(
args.iter() args.iter()
.map(|a| <Any as Any>::type_id(a.as_ref())) .map(|a| <Any as Any>::type_id(&**a))
.collect(), .collect(),
), ),
}; };
@ -171,7 +171,7 @@ impl Engine {
f.params f.params
.iter() .iter()
.cloned() .cloned()
.zip(args.iter().map(|x| (&**x).clone())), .zip(args.iter().map(|x| (&**x).box_clone())),
); );
match self.eval_stmt(&mut scope, &*f.body) { match self.eval_stmt(&mut scope, &*f.body) {
@ -231,17 +231,17 @@ impl Engine {
fn get_dot_val_helper( fn get_dot_val_helper(
&self, &self,
scope: &mut Scope, scope: &mut Scope,
this_ptr: &mut Box<Any>, this_ptr: &mut Any,
dot_rhs: &Expr, dot_rhs: &Expr,
) -> Result<Box<Any>, EvalAltResult> { ) -> Result<Box<Any>, EvalAltResult> {
use std::iter::once; use std::iter::once;
match *dot_rhs { match *dot_rhs {
Expr::FnCall(ref fn_name, ref args) => { Expr::FnCall(ref fn_name, ref args) => {
let mut args: Vec<_> = args.iter() let mut args: Vec<Box<Any>> = args.iter()
.map(|arg| self.eval_expr(scope, arg)) .map(|arg| self.eval_expr(scope, arg))
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()?;
let args = once(this_ptr).chain(args.iter_mut()).collect(); let args = once(this_ptr).chain(args.iter_mut().map(|b| b.as_mut())).collect();
self.call_fn_raw(fn_name.to_owned(), args) self.call_fn_raw(fn_name.to_owned(), args)
} }
@ -265,7 +265,7 @@ impl Engine {
Expr::Identifier(ref id) => { Expr::Identifier(ref id) => {
let get_fn_name = "get$".to_string() + id; let get_fn_name = "get$".to_string() + id;
self.call_fn_raw(get_fn_name, vec![this_ptr]) self.call_fn_raw(get_fn_name, vec![this_ptr])
.and_then(|mut v| self.get_dot_val_helper(scope, &mut v, inner_rhs)) .and_then(|mut v| self.get_dot_val_helper(scope, v.as_mut(), inner_rhs))
} }
_ => Err(EvalAltResult::InternalErrorMalformedDotExpression), _ => Err(EvalAltResult::InternalErrorMalformedDotExpression),
}, },
@ -279,7 +279,7 @@ impl Engine {
map: F, map: F,
) -> Result<(usize, T), EvalAltResult> ) -> Result<(usize, T), EvalAltResult>
where where
F: FnOnce(&'a mut Box<Any>) -> Result<T, EvalAltResult>, F: FnOnce(&'a mut Any) -> Result<T, EvalAltResult>,
{ {
scope scope
.iter_mut() .iter_mut()
@ -287,7 +287,7 @@ impl Engine {
.rev() .rev()
.find(|&(_, &mut (ref name, _))| *id == *name) .find(|&(_, &mut (ref name, _))| *id == *name)
.ok_or_else(|| EvalAltResult::ErrorVariableNotFound(id.to_owned())) .ok_or_else(|| EvalAltResult::ErrorVariableNotFound(id.to_owned()))
.and_then(move |(idx, &mut (_, ref mut val))| map(val).map(|val| (idx, val))) .and_then(move |(idx, &mut (_, ref mut val))| map(val.as_mut()).map(|val| (idx, val)))
} }
fn array_value( fn array_value(
@ -317,8 +317,8 @@ impl Engine {
) -> Result<Box<Any>, EvalAltResult> { ) -> Result<Box<Any>, EvalAltResult> {
match *dot_lhs { match *dot_lhs {
Expr::Identifier(ref id) => { Expr::Identifier(ref id) => {
let (sc_idx, mut target) = Self::search_scope(scope, id, |x| Ok(x.clone()))?; let (sc_idx, mut target) = Self::search_scope(scope, id, |x| Ok(x.box_clone()))?;
let value = self.get_dot_val_helper(scope, &mut target, dot_rhs); let value = self.get_dot_val_helper(scope, target.as_mut(), dot_rhs);
// In case the expression mutated `target`, we need to reassign it because // In case the expression mutated `target`, we need to reassign it because
// of the above `clone`. // of the above `clone`.
@ -328,7 +328,7 @@ impl Engine {
} }
Expr::Index(ref id, ref idx_raw) => { Expr::Index(ref id, ref idx_raw) => {
let (sc_idx, idx, mut target) = self.array_value(scope, id, idx_raw)?; let (sc_idx, idx, mut target) = self.array_value(scope, id, idx_raw)?;
let value = self.get_dot_val_helper(scope, &mut target, dot_rhs); let value = self.get_dot_val_helper(scope, target.as_mut(), dot_rhs);
// In case the expression mutated `target`, we need to reassign it because // In case the expression mutated `target`, we need to reassign it because
// of the above `clone`. // of the above `clone`.
@ -342,27 +342,27 @@ impl Engine {
fn set_dot_val_helper( fn set_dot_val_helper(
&self, &self,
this_ptr: &mut Box<Any>, this_ptr: &mut Any,
dot_rhs: &Expr, dot_rhs: &Expr,
mut source_val: Box<Any>, mut source_val: Box<Any>,
) -> Result<Box<Any>, EvalAltResult> { ) -> Result<Box<Any>, EvalAltResult> {
match *dot_rhs { match *dot_rhs {
Expr::Identifier(ref id) => { Expr::Identifier(ref id) => {
let set_fn_name = "set$".to_string() + id; let set_fn_name = "set$".to_string() + id;
self.call_fn_raw(set_fn_name, vec![this_ptr, &mut source_val]) self.call_fn_raw(set_fn_name, vec![this_ptr, source_val.as_mut()])
} }
Expr::Dot(ref inner_lhs, ref inner_rhs) => match **inner_lhs { Expr::Dot(ref inner_lhs, ref inner_rhs) => match **inner_lhs {
Expr::Identifier(ref id) => { Expr::Identifier(ref id) => {
let get_fn_name = "get$".to_string() + id; let get_fn_name = "get$".to_string() + id;
self.call_fn_raw(get_fn_name, vec![this_ptr]) self.call_fn_raw(get_fn_name, vec![this_ptr])
.and_then(|mut v| { .and_then(|mut v| {
self.set_dot_val_helper(&mut v, inner_rhs, source_val) self.set_dot_val_helper(v.as_mut(), inner_rhs, source_val)
.map(|_| v) // Discard Ok return value .map(|_| v) // Discard Ok return value
}) })
.and_then(|mut v| { .and_then(|mut v| {
let set_fn_name = "set$".to_string() + id; let set_fn_name = "set$".to_string() + id;
self.call_fn_raw(set_fn_name, vec![this_ptr, &mut v]) self.call_fn_raw(set_fn_name, vec![this_ptr, v.as_mut()])
}) })
} }
_ => Err(EvalAltResult::InternalErrorMalformedDotExpression), _ => Err(EvalAltResult::InternalErrorMalformedDotExpression),
@ -380,8 +380,8 @@ impl Engine {
) -> Result<Box<Any>, EvalAltResult> { ) -> Result<Box<Any>, EvalAltResult> {
match *dot_lhs { match *dot_lhs {
Expr::Identifier(ref id) => { Expr::Identifier(ref id) => {
let (sc_idx, mut target) = Self::search_scope(scope, id, |x| Ok(x.clone()))?; let (sc_idx, mut target) = Self::search_scope(scope, id, |x| Ok(x.box_clone()))?;
let value = self.set_dot_val_helper(&mut target, dot_rhs, source_val); let value = self.set_dot_val_helper(target.as_mut(), dot_rhs, source_val);
// In case the expression mutated `target`, we need to reassign it because // In case the expression mutated `target`, we need to reassign it because
// of the above `clone`. // of the above `clone`.
@ -391,7 +391,7 @@ impl Engine {
} }
Expr::Index(ref id, ref idx_raw) => { Expr::Index(ref id, ref idx_raw) => {
let (sc_idx, idx, mut target) = self.array_value(scope, id, idx_raw)?; let (sc_idx, idx, mut target) = self.array_value(scope, id, idx_raw)?;
let value = self.set_dot_val_helper(&mut target, dot_rhs, source_val); let value = self.set_dot_val_helper(target.as_mut(), dot_rhs, source_val);
// In case the expression mutated `target`, we need to reassign it because // In case the expression mutated `target`, we need to reassign it because
// of the above `clone`. // of the above `clone`.
@ -477,8 +477,9 @@ impl Engine {
fn_name.to_owned(), fn_name.to_owned(),
args.iter() args.iter()
.map(|ex| self.eval_expr(scope, ex)) .map(|ex| self.eval_expr(scope, ex))
.collect::<Result<Vec<_>, _>>()? .collect::<Result<Vec<Box<Any>>, _>>()?
.iter_mut() .iter_mut()
.map(|b| b.as_mut())
.collect(), .collect(),
), ),
Expr::True => Ok(Box::new(true)), Expr::True => Ok(Box::new(true)),

View File

@ -27,7 +27,7 @@ macro_rules! def_register {
RET: Any, RET: Any,
{ {
fn register_fn(&mut self, name: &str, f: FN) { fn register_fn(&mut self, name: &str, f: FN) {
let fun = move |mut args: Vec<&mut Box<Any>>| { let fun = move |mut args: Vec<&mut Any>| {
// Check for length at the beginning to avoid // Check for length at the beginning to avoid
// per-element bound checks. // per-element bound checks.
if args.len() != count_args!($($par)*) { if args.len() != count_args!($($par)*) {

View File

@ -41,6 +41,7 @@
needless_pass_by_value, too_many_arguments)] needless_pass_by_value, too_many_arguments)]
mod any; mod any;
mod call;
mod engine; mod engine;
mod fn_register; mod fn_register;
mod parser; mod parser;