Enable call in function-call style.
This commit is contained in:
@@ -944,7 +944,7 @@ impl Engine {
|
||||
}
|
||||
|
||||
// Has a system function an override?
|
||||
fn has_override(&self, lib: &Module, (hash_fn, hash_script): (u64, u64)) -> bool {
|
||||
fn has_override(&self, lib: &Module, hash_fn: u64, hash_script: u64) -> bool {
|
||||
// NOTE: We skip script functions for global_module and packages, and native functions for lib
|
||||
|
||||
// First check script-defined functions
|
||||
@@ -986,13 +986,15 @@ impl Engine {
|
||||
|
||||
match fn_name {
|
||||
// type_of
|
||||
KEYWORD_TYPE_OF if args.len() == 1 && !self.has_override(lib, hashes) => Ok((
|
||||
self.map_type_name(args[0].type_name()).to_string().into(),
|
||||
false,
|
||||
)),
|
||||
KEYWORD_TYPE_OF if args.len() == 1 && !self.has_override(lib, hashes.0, hashes.1) => {
|
||||
Ok((
|
||||
self.map_type_name(args[0].type_name()).to_string().into(),
|
||||
false,
|
||||
))
|
||||
}
|
||||
|
||||
// Fn
|
||||
KEYWORD_FN_PTR if args.len() == 1 && !self.has_override(lib, hashes) => {
|
||||
KEYWORD_FN_PTR if args.len() == 1 && !self.has_override(lib, hashes.0, hashes.1) => {
|
||||
Err(Box::new(EvalAltResult::ErrorRuntime(
|
||||
"'Fn' should not be called in method style. Try Fn(...);".into(),
|
||||
Position::none(),
|
||||
@@ -1000,7 +1002,7 @@ impl Engine {
|
||||
}
|
||||
|
||||
// eval - reaching this point it must be a method-style call
|
||||
KEYWORD_EVAL if args.len() == 1 && !self.has_override(lib, hashes) => {
|
||||
KEYWORD_EVAL if args.len() == 1 && !self.has_override(lib, hashes.0, hashes.1) => {
|
||||
Err(Box::new(EvalAltResult::ErrorRuntime(
|
||||
"'eval' should not be called in method style. Try eval(...);".into(),
|
||||
Position::none(),
|
||||
@@ -1926,7 +1928,7 @@ impl Engine {
|
||||
let hash_fn =
|
||||
calc_fn_hash(empty(), name, 1, once(TypeId::of::<ImmutableString>()));
|
||||
|
||||
if !self.has_override(lib, (hash_fn, *hash)) {
|
||||
if !self.has_override(lib, hash_fn, *hash) {
|
||||
// Fn - only in function call style
|
||||
let expr = args_expr.get(0);
|
||||
let arg_value =
|
||||
@@ -1952,7 +1954,7 @@ impl Engine {
|
||||
let hash_fn =
|
||||
calc_fn_hash(empty(), name, 1, once(TypeId::of::<ImmutableString>()));
|
||||
|
||||
if !self.has_override(lib, (hash_fn, *hash)) {
|
||||
if !self.has_override(lib, hash_fn, *hash) {
|
||||
// eval - only in function call style
|
||||
let prev_len = scope.len();
|
||||
let expr = args_expr.get(0);
|
||||
@@ -1972,6 +1974,36 @@ impl Engine {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle call() - Redirect function call
|
||||
let redirected;
|
||||
let mut name = name.as_ref();
|
||||
let mut args_expr = args_expr.as_ref();
|
||||
let mut hash = *hash;
|
||||
|
||||
if name == KEYWORD_FN_PTR_CALL
|
||||
&& args_expr.len() >= 1
|
||||
&& !self.has_override(lib, 0, hash)
|
||||
{
|
||||
let expr = args_expr.get(0).unwrap();
|
||||
let fn_ptr = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?;
|
||||
|
||||
if fn_ptr.is::<FnPtr>() {
|
||||
// Redirect function name
|
||||
redirected = Some(fn_ptr.cast::<FnPtr>().take_fn_name());
|
||||
name = redirected.as_ref().unwrap();
|
||||
// Skip the first argument
|
||||
args_expr = &args_expr.as_ref()[1..];
|
||||
// Recalculate hash
|
||||
hash = calc_fn_hash(empty(), name, args_expr.len(), empty());
|
||||
} else {
|
||||
return Err(Box::new(EvalAltResult::ErrorMismatchOutputType(
|
||||
self.map_type_name(type_name::<FnPtr>()).into(),
|
||||
fn_ptr.type_name().into(),
|
||||
expr.position(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
// Normal function call - except for Fn and eval (handled above)
|
||||
let mut arg_values: StaticVec<Dynamic>;
|
||||
let mut args: StaticVec<_>;
|
||||
@@ -1983,7 +2015,7 @@ impl Engine {
|
||||
} else {
|
||||
// See if the first argument is a variable, if so, convert to method-call style
|
||||
// in order to leverage potential &mut first argument and avoid cloning the value
|
||||
match args_expr.get(0) {
|
||||
match args_expr.get(0).unwrap() {
|
||||
// func(x, ...) -> x.func(...)
|
||||
lhs @ Expr::Variable(_) => {
|
||||
arg_values = args_expr
|
||||
@@ -2020,7 +2052,7 @@ impl Engine {
|
||||
|
||||
let args = args.as_mut();
|
||||
self.exec_fn_call(
|
||||
state, lib, name, *native, *hash, args, is_ref, false, def_val, level,
|
||||
state, lib, name, *native, hash, args, is_ref, false, def_val, level,
|
||||
)
|
||||
.map(|(v, _)| v)
|
||||
.map_err(|err| err.new_position(*pos))
|
||||
|
Reference in New Issue
Block a user