Complete built-in operators.
This commit is contained in:
@@ -392,13 +392,8 @@ impl Default for Engine {
|
||||
optimization_level: OptimizationLevel::None,
|
||||
|
||||
#[cfg(not(feature = "no_optimize"))]
|
||||
#[cfg(not(feature = "optimize_full"))]
|
||||
optimization_level: OptimizationLevel::Simple,
|
||||
|
||||
#[cfg(not(feature = "no_optimize"))]
|
||||
#[cfg(feature = "optimize_full")]
|
||||
optimization_level: OptimizationLevel::Full,
|
||||
|
||||
max_call_stack_depth: MAX_CALL_STACK_DEPTH,
|
||||
max_expr_depth: MAX_EXPR_DEPTH,
|
||||
max_function_expr_depth: MAX_FUNCTION_EXPR_DEPTH,
|
||||
@@ -406,10 +401,6 @@ impl Default for Engine {
|
||||
max_modules: u64::MAX,
|
||||
};
|
||||
|
||||
#[cfg(feature = "no_stdlib")]
|
||||
engine.load_package(CorePackage::new().get());
|
||||
|
||||
#[cfg(not(feature = "no_stdlib"))]
|
||||
engine.load_package(StandardPackage::new().get());
|
||||
|
||||
engine
|
||||
@@ -534,13 +525,8 @@ impl Engine {
|
||||
optimization_level: OptimizationLevel::None,
|
||||
|
||||
#[cfg(not(feature = "no_optimize"))]
|
||||
#[cfg(not(feature = "optimize_full"))]
|
||||
optimization_level: OptimizationLevel::Simple,
|
||||
|
||||
#[cfg(not(feature = "no_optimize"))]
|
||||
#[cfg(feature = "optimize_full")]
|
||||
optimization_level: OptimizationLevel::Full,
|
||||
|
||||
max_call_stack_depth: MAX_CALL_STACK_DEPTH,
|
||||
max_expr_depth: MAX_EXPR_DEPTH,
|
||||
max_function_expr_depth: MAX_FUNCTION_EXPR_DEPTH,
|
||||
@@ -635,13 +621,15 @@ impl Engine {
|
||||
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
||||
self.inc_operations(state, pos)?;
|
||||
|
||||
let native_only = hashes.1 == 0;
|
||||
|
||||
// Check for stack overflow
|
||||
if level > self.max_call_stack_depth {
|
||||
return Err(Box::new(EvalAltResult::ErrorStackOverflow(pos)));
|
||||
}
|
||||
|
||||
// First search in script-defined functions (can override built-in)
|
||||
if hashes.1 > 0 {
|
||||
if !native_only {
|
||||
if let Some(fn_def) = state.get_function(hashes.1) {
|
||||
let (result, state2) =
|
||||
self.call_script_fn(scope, *state, fn_name, fn_def, args, pos, level)?;
|
||||
@@ -710,8 +698,8 @@ impl Engine {
|
||||
}
|
||||
|
||||
// If it is a 2-operand operator, see if it is built in
|
||||
if args.len() == 2 && args[0].type_id() == args[1].type_id() {
|
||||
match run_builtin_op(fn_name, args[0], args[1])? {
|
||||
if native_only && args.len() == 2 && args[0].type_id() == args[1].type_id() {
|
||||
match run_builtin_binary_op(fn_name, args[0], args[1])? {
|
||||
Some(v) => return Ok((v, false)),
|
||||
None => (),
|
||||
}
|
||||
@@ -1949,8 +1937,8 @@ impl Engine {
|
||||
}
|
||||
}
|
||||
|
||||
/// Build in certain common operator implementations to avoid the cost of searching through the functions space.
|
||||
fn run_builtin_op(
|
||||
/// Build in common binary operator implementations to avoid the cost of calling a registered function.
|
||||
fn run_builtin_binary_op(
|
||||
op: &str,
|
||||
x: &Dynamic,
|
||||
y: &Dynamic,
|
||||
|
@@ -710,8 +710,7 @@ fn parse_call_expr<'a>(
|
||||
input: &mut Peekable<TokenIterator<'a>>,
|
||||
state: &mut ParseState,
|
||||
id: String,
|
||||
#[cfg(not(feature = "no_module"))] mut modules: Option<Box<ModuleRef>>,
|
||||
#[cfg(feature = "no_module")] modules: Option<ModuleRef>,
|
||||
mut modules: Option<Box<ModuleRef>>,
|
||||
begin: Position,
|
||||
level: usize,
|
||||
allow_stmt_expr: bool,
|
||||
@@ -753,12 +752,13 @@ fn parse_call_expr<'a>(
|
||||
let qualifiers = modules.iter().map(|(m, _)| m.as_str());
|
||||
calc_fn_hash(qualifiers, &id, 0, empty())
|
||||
} else {
|
||||
// Qualifiers (none) + function name + no parameters.
|
||||
calc_fn_hash(empty(), &id, 0, empty())
|
||||
}
|
||||
};
|
||||
// Qualifiers (none) + function name + no parameters.
|
||||
#[cfg(feature = "no_module")]
|
||||
let hash_fn_def = calc_fn_hash(empty(), &id, empty());
|
||||
let hash_fn_def = calc_fn_hash(empty(), &id, 0, empty());
|
||||
|
||||
return Ok(Expr::FnCall(Box::new((
|
||||
(id.into(), false, begin),
|
||||
@@ -794,12 +794,13 @@ fn parse_call_expr<'a>(
|
||||
let qualifiers = modules.iter().map(|(m, _)| m.as_str());
|
||||
calc_fn_hash(qualifiers, &id, args.len(), empty())
|
||||
} else {
|
||||
// Qualifiers (none) + function name + number of arguments.
|
||||
calc_fn_hash(empty(), &id, args.len(), empty())
|
||||
}
|
||||
};
|
||||
// Qualifiers (none) + function name + dummy parameter types (one for each parameter).
|
||||
// Qualifiers (none) + function name + number of arguments.
|
||||
#[cfg(feature = "no_module")]
|
||||
let hash_fn_def = calc_fn_hash(empty(), &id, args_iter);
|
||||
let hash_fn_def = calc_fn_hash(empty(), &id, args.len(), empty());
|
||||
|
||||
return Ok(Expr::FnCall(Box::new((
|
||||
(id.into(), false, begin),
|
||||
|
Reference in New Issue
Block a user