Merge remote-tracking branch 'schungx/closures' into closures
This commit is contained in:
@@ -576,7 +576,7 @@ pub fn search_scope_only<'s, 'a>(
|
||||
if let Some(val) = this_ptr {
|
||||
return Ok(((*val).into(), KEYWORD_THIS, ScopeEntryType::Normal, *pos));
|
||||
} else {
|
||||
return Err(Box::new(EvalAltResult::ErrorUnboundedThis(*pos)));
|
||||
return Err(Box::new(EvalAltResult::ErrorUnboundThis(*pos)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -737,16 +737,16 @@ impl Engine {
|
||||
let args = &mut [target.as_mut(), &mut idx_val2, _new_val];
|
||||
|
||||
self.exec_fn_call(
|
||||
state, lib, FN_IDX_SET, true, 0, args, is_ref, true, false,
|
||||
state, lib, FN_IDX_SET, 0, args, is_ref, true, false, None,
|
||||
None, level,
|
||||
)
|
||||
.or_else(|err| match *err {
|
||||
// If there is no index setter, no need to set it back because the indexer is read-only
|
||||
EvalAltResult::ErrorFunctionNotFound(_, _) => {
|
||||
Ok(Default::default())
|
||||
}
|
||||
_ => Err(err),
|
||||
})?;
|
||||
.or_else(|err| match *err {
|
||||
// If there is no index setter, no need to set it back because the indexer is read-only
|
||||
EvalAltResult::ErrorFunctionNotFound(_, _) => {
|
||||
Ok(Default::default())
|
||||
}
|
||||
_ => Err(err),
|
||||
})?;
|
||||
}
|
||||
|
||||
// next step is custom index setter call in case of error
|
||||
@@ -754,7 +754,7 @@ impl Engine {
|
||||
let args = &mut [target.as_mut(), &mut idx_val2, _new_val];
|
||||
|
||||
self.exec_fn_call(
|
||||
state, lib, FN_IDX_SET, true, 0, args, is_ref, true, false,
|
||||
state, lib, FN_IDX_SET, 0, args, is_ref, true, false, None,
|
||||
None, level,
|
||||
)?;
|
||||
}
|
||||
@@ -776,7 +776,7 @@ impl Engine {
|
||||
match rhs {
|
||||
// xxx.fn_name(arg_expr_list)
|
||||
Expr::FnCall(x) if x.1.is_none() => {
|
||||
let ((name, native, pos), _, hash, _, def_val) = x.as_ref();
|
||||
let ((name, native, _, pos), _, hash, _, def_val) = x.as_ref();
|
||||
self.make_method_call(
|
||||
state, lib, name, *hash, target, idx_val, *def_val, *native, false,
|
||||
level,
|
||||
@@ -810,7 +810,7 @@ impl Engine {
|
||||
let ((_, _, setter), pos) = x.as_ref();
|
||||
let mut args = [target.as_mut(), _new_val.as_mut().unwrap()];
|
||||
self.exec_fn_call(
|
||||
state, lib, setter, true, 0, &mut args, is_ref, true, false, None,
|
||||
state, lib, setter, 0, &mut args, is_ref, true, false, None, None,
|
||||
level,
|
||||
)
|
||||
.map(|(v, _)| (v, true))
|
||||
@@ -821,7 +821,7 @@ impl Engine {
|
||||
let ((_, getter, _), pos) = x.as_ref();
|
||||
let mut args = [target.as_mut()];
|
||||
self.exec_fn_call(
|
||||
state, lib, getter, true, 0, &mut args, is_ref, true, false, None,
|
||||
state, lib, getter, 0, &mut args, is_ref, true, false, None, None,
|
||||
level,
|
||||
)
|
||||
.map(|(v, _)| (v, false))
|
||||
@@ -839,7 +839,7 @@ impl Engine {
|
||||
}
|
||||
// {xxx:map}.fn_name(arg_expr_list)[expr] | {xxx:map}.fn_name(arg_expr_list).expr
|
||||
Expr::FnCall(x) if x.1.is_none() => {
|
||||
let ((name, native, pos), _, hash, _, def_val) = x.as_ref();
|
||||
let ((name, native, _, pos), _, hash, _, def_val) = x.as_ref();
|
||||
let (val, _) = self
|
||||
.make_method_call(
|
||||
state, lib, name, *hash, target, idx_val, *def_val,
|
||||
@@ -872,7 +872,7 @@ impl Engine {
|
||||
let args = &mut arg_values[..1];
|
||||
let (mut val, updated) = self
|
||||
.exec_fn_call(
|
||||
state, lib, getter, true, 0, args, is_ref, true, false,
|
||||
state, lib, getter, 0, args, is_ref, true, false, None,
|
||||
None, level,
|
||||
)
|
||||
.map_err(|err| err.new_position(*pos))?;
|
||||
@@ -891,8 +891,8 @@ impl Engine {
|
||||
// Re-use args because the first &mut parameter will not be consumed
|
||||
arg_values[1] = val;
|
||||
self.exec_fn_call(
|
||||
state, lib, setter, true, 0, arg_values, is_ref, true,
|
||||
false, None, level,
|
||||
state, lib, setter, 0, arg_values, is_ref, true, false,
|
||||
None, None, level,
|
||||
)
|
||||
.or_else(
|
||||
|err| match *err {
|
||||
@@ -909,7 +909,7 @@ impl Engine {
|
||||
}
|
||||
// xxx.fn_name(arg_expr_list)[expr] | xxx.fn_name(arg_expr_list).expr
|
||||
Expr::FnCall(x) if x.1.is_none() => {
|
||||
let ((name, native, pos), _, hash, _, def_val) = x.as_ref();
|
||||
let ((name, native, _, pos), _, hash, _, def_val) = x.as_ref();
|
||||
let (mut val, _) = self
|
||||
.make_method_call(
|
||||
state, lib, name, *hash, target, idx_val, *def_val,
|
||||
@@ -1148,7 +1148,7 @@ impl Engine {
|
||||
.read_lock::<ImmutableString>()
|
||||
.ok_or_else(|| EvalAltResult::ErrorStringIndexExpr(idx_pos))?;
|
||||
|
||||
map.get_mut(index.as_str())
|
||||
map.get_mut(&*index)
|
||||
.map(Target::from)
|
||||
.unwrap_or_else(|| Target::from(()))
|
||||
})
|
||||
@@ -1181,7 +1181,7 @@ impl Engine {
|
||||
let type_name = val.type_name();
|
||||
let args = &mut [val, &mut _idx];
|
||||
self.exec_fn_call(
|
||||
state, _lib, FN_IDX_GET, true, 0, args, is_ref, true, false, None, _level,
|
||||
state, _lib, FN_IDX_GET, 0, args, is_ref, true, false, None, None, _level,
|
||||
)
|
||||
.map(|(v, _)| v.into())
|
||||
.map_err(|err| match *err {
|
||||
@@ -1222,26 +1222,23 @@ impl Engine {
|
||||
#[cfg(not(feature = "no_index"))]
|
||||
Dynamic(Union::Array(mut rhs_value)) => {
|
||||
let op = "==";
|
||||
let mut scope = Scope::new();
|
||||
|
||||
// Call the `==` operator to compare each value
|
||||
for value in rhs_value.iter_mut() {
|
||||
let def_value = Some(false);
|
||||
let args = &mut [&mut lhs_value.clone(), value];
|
||||
|
||||
let hashes = (
|
||||
// Qualifiers (none) + function name + number of arguments + argument `TypeId`'s.
|
||||
calc_fn_hash(empty(), op, args.len(), args.iter().map(|a| a.type_id())),
|
||||
0,
|
||||
);
|
||||
// Qualifiers (none) + function name + number of arguments + argument `TypeId`'s.
|
||||
let hash =
|
||||
calc_fn_hash(empty(), op, args.len(), args.iter().map(|a| a.type_id()));
|
||||
|
||||
let (r, _) = self
|
||||
.call_fn_raw(
|
||||
&mut scope, mods, state, lib, op, hashes, args, false, false, false,
|
||||
def_value, level,
|
||||
)
|
||||
.map_err(|err| err.new_position(rhs.position()))?;
|
||||
if r.as_bool().unwrap_or(false) {
|
||||
if self
|
||||
.call_native_fn(state, lib, op, hash, args, false, false, def_value)
|
||||
.map_err(|err| err.new_position(rhs.position()))?
|
||||
.0
|
||||
.as_bool()
|
||||
.unwrap_or(false)
|
||||
{
|
||||
return Ok(true.into());
|
||||
}
|
||||
}
|
||||
@@ -1251,10 +1248,8 @@ impl Engine {
|
||||
#[cfg(not(feature = "no_object"))]
|
||||
Dynamic(Union::Map(rhs_value)) => match lhs_value {
|
||||
// Only allows String or char
|
||||
Dynamic(Union::Str(s)) => Ok(rhs_value.contains_key(s.as_str()).into()),
|
||||
Dynamic(Union::Char(c)) => {
|
||||
Ok(rhs_value.contains_key(c.to_string().as_str()).into())
|
||||
}
|
||||
Dynamic(Union::Str(s)) => Ok(rhs_value.contains_key(&s).into()),
|
||||
Dynamic(Union::Char(c)) => Ok(rhs_value.contains_key(&c.to_string()).into()),
|
||||
_ => Err(Box::new(EvalAltResult::ErrorInExpr(lhs.position()))),
|
||||
},
|
||||
Dynamic(Union::Str(rhs_value)) => match lhs_value {
|
||||
@@ -1294,7 +1289,7 @@ impl Engine {
|
||||
if let Some(val) = this_ptr {
|
||||
Ok(val.clone())
|
||||
} else {
|
||||
Err(Box::new(EvalAltResult::ErrorUnboundedThis((x.0).1)))
|
||||
Err(Box::new(EvalAltResult::ErrorUnboundThis((x.0).1)))
|
||||
}
|
||||
}
|
||||
Expr::Variable(_) => {
|
||||
@@ -1355,14 +1350,14 @@ impl Engine {
|
||||
} else if run_builtin_op_assignment(op, lhs_ptr, &rhs_val)?.is_none() {
|
||||
// Not built in, map to `var = var op rhs`
|
||||
let op = &op[..op.len() - 1]; // extract operator without =
|
||||
let hash = calc_fn_hash(empty(), op, 2, empty());
|
||||
|
||||
// Clone the LHS value
|
||||
let args = &mut [&mut lhs_ptr.clone(), &mut rhs_val];
|
||||
|
||||
// Run function
|
||||
let (value, _) = self
|
||||
.exec_fn_call(
|
||||
state, lib, op, true, hash, args, false, false, false, None,
|
||||
level,
|
||||
state, lib, op, 0, args, false, false, false, None, None, level,
|
||||
)
|
||||
.map_err(|err| err.new_position(*op_pos))?;
|
||||
if lhs_ptr.is_shared() {
|
||||
@@ -1390,13 +1385,12 @@ impl Engine {
|
||||
} else {
|
||||
// Op-assignment - always map to `lhs = lhs op rhs`
|
||||
let op = &op[..op.len() - 1]; // extract operator without =
|
||||
let hash = calc_fn_hash(empty(), op, 2, empty());
|
||||
let args = &mut [
|
||||
&mut self.eval_expr(scope, mods, state, lib, this_ptr, lhs_expr, level)?,
|
||||
&mut rhs_val,
|
||||
];
|
||||
self.exec_fn_call(
|
||||
state, lib, op, true, hash, args, false, false, false, None, level,
|
||||
state, lib, op, 0, args, false, false, false, None, None, level,
|
||||
)
|
||||
.map(|(v, _)| v)
|
||||
.map_err(|err| err.new_position(*op_pos))?
|
||||
@@ -1466,20 +1460,20 @@ impl Engine {
|
||||
|
||||
// Normal function call
|
||||
Expr::FnCall(x) if x.1.is_none() => {
|
||||
let ((name, native, pos), _, hash, args_expr, def_val) = x.as_ref();
|
||||
let ((name, native, capture, pos), _, hash, args_expr, def_val) = x.as_ref();
|
||||
self.make_function_call(
|
||||
scope, mods, state, lib, this_ptr, name, args_expr, *def_val, *hash, *native,
|
||||
false, level,
|
||||
false, *capture, level,
|
||||
)
|
||||
.map_err(|err| err.new_position(*pos))
|
||||
}
|
||||
|
||||
// Module-qualified function call
|
||||
Expr::FnCall(x) if x.1.is_some() => {
|
||||
let ((name, _, pos), modules, hash, args_expr, def_val) = x.as_ref();
|
||||
let ((name, _, capture, pos), modules, hash, args_expr, def_val) = x.as_ref();
|
||||
self.make_qualified_function_call(
|
||||
scope, mods, state, lib, this_ptr, modules, name, args_expr, *def_val, *hash,
|
||||
level,
|
||||
*capture, level,
|
||||
)
|
||||
.map_err(|err| err.new_position(*pos))
|
||||
}
|
||||
|
Reference in New Issue
Block a user