Change modules to namespace.
This commit is contained in:
parent
ecfdfa8a97
commit
958762079e
@ -209,7 +209,7 @@ Bug fixes
|
|||||||
---------
|
---------
|
||||||
|
|
||||||
* Fixes bug that prevents calling functions in closures.
|
* Fixes bug that prevents calling functions in closures.
|
||||||
* Fixes bug that erroneously consumes the first argument to a module-qualified function call.
|
* Fixes bug that erroneously consumes the first argument to a namespace-qualified function call.
|
||||||
|
|
||||||
New features
|
New features
|
||||||
------------
|
------------
|
||||||
@ -299,7 +299,7 @@ New features
|
|||||||
* The boolean `^` (XOR) operator is added.
|
* The boolean `^` (XOR) operator is added.
|
||||||
* `FnPtr` is exposed as the function pointer type.
|
* `FnPtr` is exposed as the function pointer type.
|
||||||
* `rhai::module_resolvers::ModuleResolversCollection` added to try a list of module resolvers.
|
* `rhai::module_resolvers::ModuleResolversCollection` added to try a list of module resolvers.
|
||||||
* It is now possible to mutate the first argument of a module-qualified function call when the argument is a simple variable (but not a module constant).
|
* It is now possible to mutate the first argument of a namespace-qualified function call when the argument is a simple variable (but not a module constant).
|
||||||
* Many configuration/setting API's now returns `&mut Self` so that the calls can be chained.
|
* Many configuration/setting API's now returns `&mut Self` so that the calls can be chained.
|
||||||
* `String` parameters in functions are supported (but inefficiently).
|
* `String` parameters in functions are supported (but inefficiently).
|
||||||
|
|
||||||
|
@ -15,10 +15,10 @@ allow combining all functions in one [`AST`] into another, forming a new, unifie
|
|||||||
|
|
||||||
In general, there are two types of _namespaces_ where functions are looked up:
|
In general, there are two types of _namespaces_ where functions are looked up:
|
||||||
|
|
||||||
| Namespace | Source | Lookup method | Sub-modules? | Variables? |
|
| Namespace | Source | Lookup method | Sub-modules? | Variables? |
|
||||||
| --------- | ------------------------------------------------------------------------------------- | ------------------------------ | :----------: | :--------: |
|
| --------- | ------------------------------------------------------------------------------------- | --------------------------------- | :----------: | :--------: |
|
||||||
| Global | 1) `Engine::register_XXX` API<br/>2) [`AST`] being evaluated<br/>3) [packages] loaded | simple function name | ignored | ignored |
|
| Global | 1) `Engine::register_XXX` API<br/>2) [`AST`] being evaluated<br/>3) [packages] loaded | simple function name | ignored | ignored |
|
||||||
| Module | [`Module`] | module-qualified function name | yes | yes |
|
| Module | [`Module`] | namespace-qualified function name | yes | yes |
|
||||||
|
|
||||||
|
|
||||||
Global Namespace
|
Global Namespace
|
||||||
|
@ -69,9 +69,9 @@ resolver.insert("question", module);
|
|||||||
let mut engine = Engine::new();
|
let mut engine = Engine::new();
|
||||||
engine.set_module_resolver(Some(resolver));
|
engine.set_module_resolver(Some(resolver));
|
||||||
|
|
||||||
// Use module-qualified variables
|
// Use namespace-qualified variables
|
||||||
engine.eval::<i64>(r#"import "question" as q; q::answer + 1"#)? == 42;
|
engine.eval::<i64>(r#"import "question" as q; q::answer + 1"#)? == 42;
|
||||||
|
|
||||||
// Call module-qualified functions
|
// Call namespace-qualified functions
|
||||||
engine.eval::<i64>(r#"import "question" as q; q::inc(q::answer)"#)? == 42;
|
engine.eval::<i64>(r#"import "question" as q; q::inc(q::answer)"#)? == 42;
|
||||||
```
|
```
|
||||||
|
16
src/ast.rs
16
src/ast.rs
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use crate::dynamic::{Dynamic, Union};
|
use crate::dynamic::{Dynamic, Union};
|
||||||
use crate::fn_native::{FnPtr, Shared};
|
use crate::fn_native::{FnPtr, Shared};
|
||||||
use crate::module::{Module, ModuleRef};
|
use crate::module::{Module, NamespaceRef};
|
||||||
use crate::syntax::FnCustomSyntaxEval;
|
use crate::syntax::FnCustomSyntaxEval;
|
||||||
use crate::token::{Position, Token, NO_POS};
|
use crate::token::{Position, Token, NO_POS};
|
||||||
use crate::utils::ImmutableString;
|
use crate::utils::ImmutableString;
|
||||||
@ -778,7 +778,7 @@ impl Stmt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// _[INTERNALS]_ A type wrapping a custom syntax definition.
|
/// _[INTERNALS]_ A custom syntax definition.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
///
|
///
|
||||||
/// ## WARNING
|
/// ## WARNING
|
||||||
@ -823,7 +823,7 @@ impl CustomExpr {
|
|||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
///
|
///
|
||||||
/// This type is mainly used to provide a standard `Hash` implementation
|
/// This type is mainly used to provide a standard `Hash` implementation
|
||||||
/// to floating-point numbers, allowing `Expr` to derive `Hash` automatically.
|
/// for floating-point numbers, allowing `Expr` to derive `Hash`.
|
||||||
///
|
///
|
||||||
/// ## WARNING
|
/// ## WARNING
|
||||||
///
|
///
|
||||||
@ -856,7 +856,7 @@ impl From<INT> for FloatWrapper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A binary expression structure.
|
/// _[INTERNALS]_ A binary expression.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
///
|
///
|
||||||
/// ## WARNING
|
/// ## WARNING
|
||||||
@ -877,7 +877,7 @@ pub struct BinaryExpr {
|
|||||||
///
|
///
|
||||||
/// This type is volatile and may change.
|
/// This type is volatile and may change.
|
||||||
#[derive(Debug, Clone, Hash, Default)]
|
#[derive(Debug, Clone, Hash, Default)]
|
||||||
pub struct FnCallInfo {
|
pub struct FnCallExpr {
|
||||||
/// Pre-calculated hash for a script-defined function of the same name and number of parameters.
|
/// Pre-calculated hash for a script-defined function of the same name and number of parameters.
|
||||||
pub hash: u64,
|
pub hash: u64,
|
||||||
/// Call native functions only? Set to `true` to skip searching for script-defined function overrides
|
/// Call native functions only? Set to `true` to skip searching for script-defined function overrides
|
||||||
@ -889,7 +889,7 @@ pub struct FnCallInfo {
|
|||||||
/// Type is `bool` in order for `FnCallInfo` to be `Hash`
|
/// Type is `bool` in order for `FnCallInfo` to be `Hash`
|
||||||
pub def_value: Option<bool>,
|
pub def_value: Option<bool>,
|
||||||
/// Namespace of the function, if any. Boxed because it occurs rarely.
|
/// Namespace of the function, if any. Boxed because it occurs rarely.
|
||||||
pub namespace: Option<Box<ModuleRef>>,
|
pub namespace: Option<Box<NamespaceRef>>,
|
||||||
/// Function name.
|
/// Function name.
|
||||||
/// Use `Cow<'static, str>` because a lot of operators (e.g. `==`, `>=`) are implemented as function calls
|
/// Use `Cow<'static, str>` because a lot of operators (e.g. `==`, `>=`) are implemented as function calls
|
||||||
/// and the function names are predictable, so no need to allocate a new `String`.
|
/// and the function names are predictable, so no need to allocate a new `String`.
|
||||||
@ -918,7 +918,7 @@ pub enum Expr {
|
|||||||
/// FnPtr constant.
|
/// FnPtr constant.
|
||||||
FnPointer(Box<IdentX>),
|
FnPointer(Box<IdentX>),
|
||||||
/// Variable access - (optional index, optional modules, hash, variable name)
|
/// Variable access - (optional index, optional modules, hash, variable name)
|
||||||
Variable(Box<(Option<NonZeroUsize>, Option<Box<ModuleRef>>, u64, Ident)>),
|
Variable(Box<(Option<NonZeroUsize>, Option<Box<NamespaceRef>>, u64, Ident)>),
|
||||||
/// Property access - (getter, setter), prop
|
/// Property access - (getter, setter), prop
|
||||||
Property(Box<((String, String), IdentX)>),
|
Property(Box<((String, String), IdentX)>),
|
||||||
/// { stmt }
|
/// { stmt }
|
||||||
@ -926,7 +926,7 @@ pub enum Expr {
|
|||||||
/// Wrapped expression - should not be optimized away.
|
/// Wrapped expression - should not be optimized away.
|
||||||
Expr(Box<Expr>),
|
Expr(Box<Expr>),
|
||||||
/// func(expr, ... )
|
/// func(expr, ... )
|
||||||
FnCall(Box<FnCallInfo>, Position),
|
FnCall(Box<FnCallExpr>, Position),
|
||||||
/// lhs.rhs
|
/// lhs.rhs
|
||||||
Dot(Box<BinaryExpr>, Position),
|
Dot(Box<BinaryExpr>, Position),
|
||||||
/// expr[expr]
|
/// expr[expr]
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
//! Main module defining the script evaluation `Engine`.
|
//! Main module defining the script evaluation `Engine`.
|
||||||
|
|
||||||
use crate::ast::{BinaryExpr, Expr, FnCallInfo, Ident, IdentX, ReturnType, Stmt};
|
use crate::ast::{BinaryExpr, Expr, FnCallExpr, Ident, IdentX, ReturnType, Stmt};
|
||||||
use crate::dynamic::{map_std_type_name, Dynamic, Union, Variant};
|
use crate::dynamic::{map_std_type_name, Dynamic, Union, Variant};
|
||||||
use crate::fn_call::run_builtin_op_assignment;
|
use crate::fn_call::run_builtin_op_assignment;
|
||||||
use crate::fn_native::{Callback, FnPtr, OnVarCallback, Shared};
|
use crate::fn_native::{Callback, FnPtr, OnVarCallback, Shared};
|
||||||
use crate::module::{Module, ModuleRef};
|
use crate::module::{Module, NamespaceRef};
|
||||||
use crate::optimize::OptimizationLevel;
|
use crate::optimize::OptimizationLevel;
|
||||||
use crate::packages::{Package, PackagesCollection, StandardPackage};
|
use crate::packages::{Package, PackagesCollection, StandardPackage};
|
||||||
use crate::r#unsafe::unsafe_cast_var_name_to_lifetime;
|
use crate::r#unsafe::unsafe_cast_var_name_to_lifetime;
|
||||||
@ -593,7 +593,7 @@ pub struct Engine {
|
|||||||
|
|
||||||
/// Max limits.
|
/// Max limits.
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
pub(crate) limits_set: Limits,
|
pub(crate) limits: Limits,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Engine {
|
impl fmt::Debug for Engine {
|
||||||
@ -636,6 +636,7 @@ pub fn is_anonymous_fn(fn_name: &str) -> bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Print/debug to stdout
|
/// Print/debug to stdout
|
||||||
|
#[inline(always)]
|
||||||
fn default_print(_s: &str) {
|
fn default_print(_s: &str) {
|
||||||
#[cfg(not(feature = "no_std"))]
|
#[cfg(not(feature = "no_std"))]
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
@ -647,15 +648,15 @@ fn default_print(_s: &str) {
|
|||||||
pub fn search_imports(
|
pub fn search_imports(
|
||||||
mods: &Imports,
|
mods: &Imports,
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
modules: &ModuleRef,
|
namespace: &NamespaceRef,
|
||||||
) -> Result<Shared<Module>, Box<EvalAltResult>> {
|
) -> Result<Shared<Module>, Box<EvalAltResult>> {
|
||||||
let Ident { name: root, pos } = &modules[0];
|
let Ident { name: root, pos } = &namespace[0];
|
||||||
|
|
||||||
// Qualified - check if the root module is directly indexed
|
// Qualified - check if the root module is directly indexed
|
||||||
let index = if state.always_search {
|
let index = if state.always_search {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
modules.index().map_or(0, NonZeroUsize::get)
|
namespace.index().map_or(0, NonZeroUsize::get)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(if index > 0 {
|
Ok(if index > 0 {
|
||||||
@ -670,7 +671,7 @@ pub fn search_imports(
|
|||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
/// Create a new `Engine`
|
/// Create a new `Engine`
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
// Create the new scripting Engine
|
// Create the new scripting Engine
|
||||||
let mut engine = Self {
|
let mut engine = Self {
|
||||||
@ -710,7 +711,7 @@ impl Engine {
|
|||||||
},
|
},
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
limits_set: Limits {
|
limits: Limits {
|
||||||
max_call_stack_depth: MAX_CALL_STACK_DEPTH,
|
max_call_stack_depth: MAX_CALL_STACK_DEPTH,
|
||||||
max_expr_depth: MAX_EXPR_DEPTH,
|
max_expr_depth: MAX_EXPR_DEPTH,
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
@ -733,7 +734,7 @@ impl Engine {
|
|||||||
|
|
||||||
/// Create a new `Engine` with minimal built-in functions.
|
/// Create a new `Engine` with minimal built-in functions.
|
||||||
/// Use the `load_package` method to load additional packages of functions.
|
/// Use the `load_package` method to load additional packages of functions.
|
||||||
#[inline(always)]
|
#[inline]
|
||||||
pub fn new_raw() -> Self {
|
pub fn new_raw() -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: Default::default(),
|
id: Default::default(),
|
||||||
@ -762,7 +763,7 @@ impl Engine {
|
|||||||
},
|
},
|
||||||
|
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
limits_set: Limits {
|
limits: Limits {
|
||||||
max_call_stack_depth: MAX_CALL_STACK_DEPTH,
|
max_call_stack_depth: MAX_CALL_STACK_DEPTH,
|
||||||
max_expr_depth: MAX_EXPR_DEPTH,
|
max_expr_depth: MAX_EXPR_DEPTH,
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
@ -780,7 +781,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Search for a variable within the scope or within imports,
|
/// Search for a variable within the scope or within imports,
|
||||||
/// depending on whether the variable name is qualified.
|
/// depending on whether the variable name is namespace-qualified.
|
||||||
pub(crate) fn search_namespace<'s, 'a>(
|
pub(crate) fn search_namespace<'s, 'a>(
|
||||||
&self,
|
&self,
|
||||||
scope: &'s mut Scope,
|
scope: &'s mut Scope,
|
||||||
@ -1000,7 +1001,7 @@ impl Engine {
|
|||||||
match rhs {
|
match rhs {
|
||||||
// xxx.fn_name(arg_expr_list)
|
// xxx.fn_name(arg_expr_list)
|
||||||
Expr::FnCall(x, pos) if x.namespace.is_none() => {
|
Expr::FnCall(x, pos) if x.namespace.is_none() => {
|
||||||
let FnCallInfo {
|
let FnCallExpr {
|
||||||
name,
|
name,
|
||||||
native_only: native,
|
native_only: native,
|
||||||
hash,
|
hash,
|
||||||
@ -1073,7 +1074,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
// {xxx:map}.fn_name(arg_expr_list)[expr] | {xxx:map}.fn_name(arg_expr_list).expr
|
// {xxx:map}.fn_name(arg_expr_list)[expr] | {xxx:map}.fn_name(arg_expr_list).expr
|
||||||
Expr::FnCall(x, pos) if x.namespace.is_none() => {
|
Expr::FnCall(x, pos) if x.namespace.is_none() => {
|
||||||
let FnCallInfo {
|
let FnCallExpr {
|
||||||
name,
|
name,
|
||||||
native_only: native,
|
native_only: native,
|
||||||
hash,
|
hash,
|
||||||
@ -1157,7 +1158,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
// xxx.fn_name(arg_expr_list)[expr] | xxx.fn_name(arg_expr_list).expr
|
// xxx.fn_name(arg_expr_list)[expr] | xxx.fn_name(arg_expr_list).expr
|
||||||
Expr::FnCall(f, pos) if f.namespace.is_none() => {
|
Expr::FnCall(f, pos) if f.namespace.is_none() => {
|
||||||
let FnCallInfo {
|
let FnCallExpr {
|
||||||
name,
|
name,
|
||||||
native_only: native,
|
native_only: native,
|
||||||
hash,
|
hash,
|
||||||
@ -1209,14 +1210,7 @@ impl Engine {
|
|||||||
level: usize,
|
level: usize,
|
||||||
new_val: Option<(Dynamic, Position)>,
|
new_val: Option<(Dynamic, Position)>,
|
||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
let (
|
let (BinaryExpr { lhs, rhs }, chain_type, op_pos) = match expr {
|
||||||
BinaryExpr {
|
|
||||||
lhs: dot_lhs,
|
|
||||||
rhs: dot_rhs,
|
|
||||||
},
|
|
||||||
chain_type,
|
|
||||||
op_pos,
|
|
||||||
) = match expr {
|
|
||||||
Expr::Index(x, pos) => (x.as_ref(), ChainType::Index, *pos),
|
Expr::Index(x, pos) => (x.as_ref(), ChainType::Index, *pos),
|
||||||
Expr::Dot(x, pos) => (x.as_ref(), ChainType::Dot, *pos),
|
Expr::Dot(x, pos) => (x.as_ref(), ChainType::Dot, *pos),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@ -1230,14 +1224,14 @@ impl Engine {
|
|||||||
state,
|
state,
|
||||||
lib,
|
lib,
|
||||||
this_ptr,
|
this_ptr,
|
||||||
dot_rhs,
|
rhs,
|
||||||
chain_type,
|
chain_type,
|
||||||
&mut idx_values,
|
&mut idx_values,
|
||||||
0,
|
0,
|
||||||
level,
|
level,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
match dot_lhs {
|
match lhs {
|
||||||
// id.??? or id[???]
|
// id.??? or id[???]
|
||||||
Expr::Variable(x) => {
|
Expr::Variable(x) => {
|
||||||
let Ident {
|
let Ident {
|
||||||
@ -1249,7 +1243,7 @@ impl Engine {
|
|||||||
.map_err(|err| err.fill_position(*var_pos))?;
|
.map_err(|err| err.fill_position(*var_pos))?;
|
||||||
|
|
||||||
let (target, _, typ, pos) =
|
let (target, _, typ, pos) =
|
||||||
self.search_namespace(scope, mods, state, lib, this_ptr, dot_lhs)?;
|
self.search_namespace(scope, mods, state, lib, this_ptr, lhs)?;
|
||||||
|
|
||||||
// Constants cannot be modified
|
// Constants cannot be modified
|
||||||
match typ {
|
match typ {
|
||||||
@ -1262,7 +1256,7 @@ impl Engine {
|
|||||||
|
|
||||||
let obj_ptr = &mut target.into();
|
let obj_ptr = &mut target.into();
|
||||||
self.eval_dot_index_chain_helper(
|
self.eval_dot_index_chain_helper(
|
||||||
mods, state, lib, &mut None, obj_ptr, dot_rhs, idx_values, chain_type, level,
|
mods, state, lib, &mut None, obj_ptr, rhs, idx_values, chain_type, level,
|
||||||
new_val,
|
new_val,
|
||||||
)
|
)
|
||||||
.map(|(v, _)| v)
|
.map(|(v, _)| v)
|
||||||
@ -1275,7 +1269,7 @@ impl Engine {
|
|||||||
let val = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?;
|
let val = self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?;
|
||||||
let obj_ptr = &mut val.into();
|
let obj_ptr = &mut val.into();
|
||||||
self.eval_dot_index_chain_helper(
|
self.eval_dot_index_chain_helper(
|
||||||
mods, state, lib, this_ptr, obj_ptr, dot_rhs, idx_values, chain_type, level,
|
mods, state, lib, this_ptr, obj_ptr, rhs, idx_values, chain_type, level,
|
||||||
new_val,
|
new_val,
|
||||||
)
|
)
|
||||||
.map(|(v, _)| v)
|
.map(|(v, _)| v)
|
||||||
@ -1605,7 +1599,7 @@ impl Engine {
|
|||||||
|
|
||||||
// Normal function call
|
// Normal function call
|
||||||
Expr::FnCall(x, pos) if x.namespace.is_none() => {
|
Expr::FnCall(x, pos) if x.namespace.is_none() => {
|
||||||
let FnCallInfo {
|
let FnCallExpr {
|
||||||
name,
|
name,
|
||||||
native_only: native,
|
native_only: native,
|
||||||
capture: cap_scope,
|
capture: cap_scope,
|
||||||
@ -1622,9 +1616,9 @@ impl Engine {
|
|||||||
.map_err(|err| err.fill_position(*pos))
|
.map_err(|err| err.fill_position(*pos))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Module-qualified function call
|
// Namespace-qualified function call
|
||||||
Expr::FnCall(x, pos) if x.namespace.is_some() => {
|
Expr::FnCall(x, pos) if x.namespace.is_some() => {
|
||||||
let FnCallInfo {
|
let FnCallExpr {
|
||||||
name,
|
name,
|
||||||
namespace,
|
namespace,
|
||||||
hash,
|
hash,
|
||||||
@ -1632,9 +1626,9 @@ impl Engine {
|
|||||||
def_value,
|
def_value,
|
||||||
..
|
..
|
||||||
} = x.as_ref();
|
} = x.as_ref();
|
||||||
let modules = namespace.as_ref().map(|v| v.as_ref());
|
let namespace = namespace.as_ref().map(|v| v.as_ref());
|
||||||
self.make_qualified_function_call(
|
self.make_qualified_function_call(
|
||||||
scope, mods, state, lib, this_ptr, modules, name, args, *def_value, *hash,
|
scope, mods, state, lib, this_ptr, namespace, name, args, *def_value, *hash,
|
||||||
level,
|
level,
|
||||||
)
|
)
|
||||||
.map_err(|err| err.fill_position(*pos))
|
.map_err(|err| err.fill_position(*pos))
|
||||||
|
@ -1156,10 +1156,9 @@ impl Engine {
|
|||||||
) -> Result<AST, ParseError> {
|
) -> Result<AST, ParseError> {
|
||||||
let scripts = [script];
|
let scripts = [script];
|
||||||
let stream = self.lex(&scripts, None);
|
let stream = self.lex(&scripts, None);
|
||||||
{
|
|
||||||
let mut peekable = stream.peekable();
|
let mut peekable = stream.peekable();
|
||||||
self.parse_global_expr(&mut peekable, scope, self.optimization_level)
|
self.parse_global_expr(&mut peekable, scope, self.optimization_level)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluate a script file.
|
/// Evaluate a script file.
|
||||||
|
@ -53,7 +53,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_max_call_levels(&mut self, levels: usize) -> &mut Self {
|
pub fn set_max_call_levels(&mut self, levels: usize) -> &mut Self {
|
||||||
self.limits_set.max_call_stack_depth = levels;
|
self.limits.max_call_stack_depth = levels;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn max_call_levels(&self) -> usize {
|
pub fn max_call_levels(&self) -> usize {
|
||||||
self.limits_set.max_call_stack_depth
|
self.limits.max_call_stack_depth
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the maximum number of operations allowed for a script to run to avoid
|
/// Set the maximum number of operations allowed for a script to run to avoid
|
||||||
@ -69,7 +69,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_max_operations(&mut self, operations: u64) -> &mut Self {
|
pub fn set_max_operations(&mut self, operations: u64) -> &mut Self {
|
||||||
self.limits_set.max_operations = if operations == u64::MAX {
|
self.limits.max_operations = if operations == u64::MAX {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
operations
|
operations
|
||||||
@ -81,7 +81,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn max_operations(&self) -> u64 {
|
pub fn max_operations(&self) -> u64 {
|
||||||
self.limits_set.max_operations
|
self.limits.max_operations
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the maximum number of imported modules allowed for a script.
|
/// Set the maximum number of imported modules allowed for a script.
|
||||||
@ -89,7 +89,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_max_modules(&mut self, modules: usize) -> &mut Self {
|
pub fn set_max_modules(&mut self, modules: usize) -> &mut Self {
|
||||||
self.limits_set.max_modules = modules;
|
self.limits.max_modules = modules;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn max_modules(&self) -> usize {
|
pub fn max_modules(&self) -> usize {
|
||||||
self.limits_set.max_modules
|
self.limits.max_modules
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the depth limits for expressions (0 for unlimited).
|
/// Set the depth limits for expressions (0 for unlimited).
|
||||||
@ -109,14 +109,14 @@ impl Engine {
|
|||||||
max_expr_depth: usize,
|
max_expr_depth: usize,
|
||||||
#[cfg(not(feature = "no_function"))] max_function_expr_depth: usize,
|
#[cfg(not(feature = "no_function"))] max_function_expr_depth: usize,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.limits_set.max_expr_depth = if max_expr_depth == usize::MAX {
|
self.limits.max_expr_depth = if max_expr_depth == usize::MAX {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
max_expr_depth
|
max_expr_depth
|
||||||
};
|
};
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
{
|
{
|
||||||
self.limits_set.max_function_expr_depth = if max_function_expr_depth == usize::MAX {
|
self.limits.max_function_expr_depth = if max_function_expr_depth == usize::MAX {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
max_function_expr_depth
|
max_function_expr_depth
|
||||||
@ -129,7 +129,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn max_expr_depth(&self) -> usize {
|
pub fn max_expr_depth(&self) -> usize {
|
||||||
self.limits_set.max_expr_depth
|
self.limits.max_expr_depth
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The depth limit for expressions in functions (0 for unlimited).
|
/// The depth limit for expressions in functions (0 for unlimited).
|
||||||
@ -137,14 +137,14 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn max_function_expr_depth(&self) -> usize {
|
pub fn max_function_expr_depth(&self) -> usize {
|
||||||
self.limits_set.max_function_expr_depth
|
self.limits.max_function_expr_depth
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the maximum length of strings (0 for unlimited).
|
/// Set the maximum length of strings (0 for unlimited).
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_max_string_size(&mut self, max_size: usize) -> &mut Self {
|
pub fn set_max_string_size(&mut self, max_size: usize) -> &mut Self {
|
||||||
self.limits_set.max_string_size = if max_size == usize::MAX { 0 } else { max_size };
|
self.limits.max_string_size = if max_size == usize::MAX { 0 } else { max_size };
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn max_string_size(&self) -> usize {
|
pub fn max_string_size(&self) -> usize {
|
||||||
self.limits_set.max_string_size
|
self.limits.max_string_size
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the maximum length of arrays (0 for unlimited).
|
/// Set the maximum length of arrays (0 for unlimited).
|
||||||
@ -160,7 +160,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_max_array_size(&mut self, max_size: usize) -> &mut Self {
|
pub fn set_max_array_size(&mut self, max_size: usize) -> &mut Self {
|
||||||
self.limits_set.max_array_size = if max_size == usize::MAX { 0 } else { max_size };
|
self.limits.max_array_size = if max_size == usize::MAX { 0 } else { max_size };
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +169,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_index"))]
|
#[cfg(not(feature = "no_index"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn max_array_size(&self) -> usize {
|
pub fn max_array_size(&self) -> usize {
|
||||||
self.limits_set.max_array_size
|
self.limits.max_array_size
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the maximum length of object maps (0 for unlimited).
|
/// Set the maximum length of object maps (0 for unlimited).
|
||||||
@ -177,7 +177,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn set_max_map_size(&mut self, max_size: usize) -> &mut Self {
|
pub fn set_max_map_size(&mut self, max_size: usize) -> &mut Self {
|
||||||
self.limits_set.max_map_size = if max_size == usize::MAX { 0 } else { max_size };
|
self.limits.max_map_size = if max_size == usize::MAX { 0 } else { max_size };
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,7 +186,7 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn max_map_size(&self) -> usize {
|
pub fn max_map_size(&self) -> usize {
|
||||||
self.limits_set.max_map_size
|
self.limits.max_map_size
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the module resolution service used by the `Engine`.
|
/// Set the module resolution service used by the `Engine`.
|
||||||
|
@ -8,7 +8,7 @@ use crate::engine::{
|
|||||||
KEYWORD_PRINT, KEYWORD_TYPE_OF,
|
KEYWORD_PRINT, KEYWORD_TYPE_OF,
|
||||||
};
|
};
|
||||||
use crate::fn_native::{FnCallArgs, FnPtr};
|
use crate::fn_native::{FnCallArgs, FnPtr};
|
||||||
use crate::module::{Module, ModuleRef};
|
use crate::module::{Module, NamespaceRef};
|
||||||
use crate::optimize::OptimizationLevel;
|
use crate::optimize::OptimizationLevel;
|
||||||
use crate::parse_error::ParseErrorType;
|
use crate::parse_error::ParseErrorType;
|
||||||
use crate::result::EvalAltResult;
|
use crate::result::EvalAltResult;
|
||||||
@ -432,13 +432,13 @@ impl Engine {
|
|||||||
pub(crate) fn has_override_by_name_and_arguments(
|
pub(crate) fn has_override_by_name_and_arguments(
|
||||||
&self,
|
&self,
|
||||||
lib: &[&Module],
|
lib: &[&Module],
|
||||||
name: &str,
|
fn_name: &str,
|
||||||
arg_types: impl AsRef<[TypeId]>,
|
arg_types: impl AsRef<[TypeId]>,
|
||||||
pub_only: bool,
|
pub_only: bool,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let arg_types = arg_types.as_ref();
|
let arg_types = arg_types.as_ref();
|
||||||
let hash_fn = calc_native_fn_hash(empty(), name, arg_types.iter().cloned());
|
let hash_fn = calc_native_fn_hash(empty(), fn_name, arg_types.iter().cloned());
|
||||||
let hash_script = calc_script_fn_hash(empty(), name, arg_types.len());
|
let hash_script = calc_script_fn_hash(empty(), fn_name, arg_types.len());
|
||||||
|
|
||||||
self.has_override(lib, hash_fn, hash_script, pub_only)
|
self.has_override(lib, hash_fn, hash_script, pub_only)
|
||||||
}
|
}
|
||||||
@ -694,7 +694,7 @@ impl Engine {
|
|||||||
mods: &mut Imports,
|
mods: &mut Imports,
|
||||||
state: &mut State,
|
state: &mut State,
|
||||||
lib: &[&Module],
|
lib: &[&Module],
|
||||||
name: &str,
|
fn_name: &str,
|
||||||
hash_script: u64,
|
hash_script: u64,
|
||||||
target: &mut Target,
|
target: &mut Target,
|
||||||
mut call_args: StaticVec<Dynamic>,
|
mut call_args: StaticVec<Dynamic>,
|
||||||
@ -707,9 +707,9 @@ impl Engine {
|
|||||||
|
|
||||||
// Get a reference to the mutation target Dynamic
|
// Get a reference to the mutation target Dynamic
|
||||||
let obj = target.as_mut();
|
let obj = target.as_mut();
|
||||||
let mut _fn_name = name;
|
let mut fn_name = fn_name;
|
||||||
|
|
||||||
let (result, updated) = if _fn_name == KEYWORD_FN_PTR_CALL && obj.is::<FnPtr>() {
|
let (result, updated) = if fn_name == KEYWORD_FN_PTR_CALL && obj.is::<FnPtr>() {
|
||||||
// FnPtr call
|
// FnPtr call
|
||||||
let fn_ptr = obj.read_lock::<FnPtr>().unwrap();
|
let fn_ptr = obj.read_lock::<FnPtr>().unwrap();
|
||||||
// Redirect function name
|
// Redirect function name
|
||||||
@ -733,7 +733,7 @@ impl Engine {
|
|||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
mods, state, lib, fn_name, hash, args, false, false, pub_only, None, def_val, level,
|
mods, state, lib, fn_name, hash, args, false, false, pub_only, None, def_val, level,
|
||||||
)
|
)
|
||||||
} else if _fn_name == KEYWORD_FN_PTR_CALL
|
} else if fn_name == KEYWORD_FN_PTR_CALL
|
||||||
&& call_args.len() > 0
|
&& call_args.len() > 0
|
||||||
&& call_args[0].is::<FnPtr>()
|
&& call_args[0].is::<FnPtr>()
|
||||||
{
|
{
|
||||||
@ -760,7 +760,7 @@ impl Engine {
|
|||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
mods, state, lib, fn_name, hash, args, is_ref, true, pub_only, None, def_val, level,
|
mods, state, lib, fn_name, hash, args, is_ref, true, pub_only, None, def_val, level,
|
||||||
)
|
)
|
||||||
} else if _fn_name == KEYWORD_FN_PTR_CURRY && obj.is::<FnPtr>() {
|
} else if fn_name == KEYWORD_FN_PTR_CURRY && obj.is::<FnPtr>() {
|
||||||
// Curry call
|
// Curry call
|
||||||
let fn_ptr = obj.read_lock::<FnPtr>().unwrap();
|
let fn_ptr = obj.read_lock::<FnPtr>().unwrap();
|
||||||
Ok((
|
Ok((
|
||||||
@ -779,7 +779,7 @@ impl Engine {
|
|||||||
} else if {
|
} else if {
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
{
|
{
|
||||||
_fn_name == KEYWORD_IS_SHARED && call_args.is_empty()
|
fn_name == KEYWORD_IS_SHARED && call_args.is_empty()
|
||||||
}
|
}
|
||||||
#[cfg(feature = "no_closure")]
|
#[cfg(feature = "no_closure")]
|
||||||
false
|
false
|
||||||
@ -793,11 +793,11 @@ impl Engine {
|
|||||||
// Check if it is a map method call in OOP style
|
// Check if it is a map method call in OOP style
|
||||||
#[cfg(not(feature = "no_object"))]
|
#[cfg(not(feature = "no_object"))]
|
||||||
if let Some(map) = obj.read_lock::<Map>() {
|
if let Some(map) = obj.read_lock::<Map>() {
|
||||||
if let Some(val) = map.get(_fn_name) {
|
if let Some(val) = map.get(fn_name) {
|
||||||
if let Some(fn_ptr) = val.read_lock::<FnPtr>() {
|
if let Some(fn_ptr) = val.read_lock::<FnPtr>() {
|
||||||
// Remap the function name
|
// Remap the function name
|
||||||
_redirected = fn_ptr.get_fn_name().clone();
|
_redirected = fn_ptr.get_fn_name().clone();
|
||||||
_fn_name = &_redirected;
|
fn_name = &_redirected;
|
||||||
// Add curried arguments
|
// Add curried arguments
|
||||||
fn_ptr
|
fn_ptr
|
||||||
.curry()
|
.curry()
|
||||||
@ -809,7 +809,7 @@ impl Engine {
|
|||||||
hash = if native {
|
hash = if native {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
calc_script_fn_hash(empty(), _fn_name, call_args.len())
|
calc_script_fn_hash(empty(), fn_name, call_args.len())
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -826,8 +826,7 @@ impl Engine {
|
|||||||
let args = arg_values.as_mut();
|
let args = arg_values.as_mut();
|
||||||
|
|
||||||
self.exec_fn_call(
|
self.exec_fn_call(
|
||||||
mods, state, lib, _fn_name, hash, args, is_ref, true, pub_only, None, def_val,
|
mods, state, lib, fn_name, hash, args, is_ref, true, pub_only, None, def_val, level,
|
||||||
level,
|
|
||||||
)
|
)
|
||||||
}?;
|
}?;
|
||||||
|
|
||||||
@ -848,7 +847,7 @@ impl Engine {
|
|||||||
state: &mut State,
|
state: &mut State,
|
||||||
lib: &[&Module],
|
lib: &[&Module],
|
||||||
this_ptr: &mut Option<&mut Dynamic>,
|
this_ptr: &mut Option<&mut Dynamic>,
|
||||||
name: &str,
|
fn_name: &str,
|
||||||
args_expr: impl AsRef<[Expr]>,
|
args_expr: impl AsRef<[Expr]>,
|
||||||
def_val: Option<Dynamic>,
|
def_val: Option<Dynamic>,
|
||||||
mut hash_script: u64,
|
mut hash_script: u64,
|
||||||
@ -860,8 +859,9 @@ impl Engine {
|
|||||||
let args_expr = args_expr.as_ref();
|
let args_expr = args_expr.as_ref();
|
||||||
|
|
||||||
// Handle Fn()
|
// Handle Fn()
|
||||||
if name == KEYWORD_FN_PTR && args_expr.len() == 1 {
|
if fn_name == KEYWORD_FN_PTR && args_expr.len() == 1 {
|
||||||
let hash_fn = calc_native_fn_hash(empty(), name, once(TypeId::of::<ImmutableString>()));
|
let hash_fn =
|
||||||
|
calc_native_fn_hash(empty(), fn_name, once(TypeId::of::<ImmutableString>()));
|
||||||
|
|
||||||
if !self.has_override(lib, hash_fn, hash_script, pub_only) {
|
if !self.has_override(lib, hash_fn, hash_script, pub_only) {
|
||||||
// Fn - only in function call style
|
// Fn - only in function call style
|
||||||
@ -878,7 +878,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle curry()
|
// Handle curry()
|
||||||
if name == KEYWORD_FN_PTR_CURRY && args_expr.len() > 1 {
|
if fn_name == KEYWORD_FN_PTR_CURRY && args_expr.len() > 1 {
|
||||||
let fn_ptr = self.eval_expr(scope, mods, state, lib, this_ptr, &args_expr[0], level)?;
|
let fn_ptr = self.eval_expr(scope, mods, state, lib, this_ptr, &args_expr[0], level)?;
|
||||||
|
|
||||||
if !fn_ptr.is::<FnPtr>() {
|
if !fn_ptr.is::<FnPtr>() {
|
||||||
@ -905,7 +905,7 @@ impl Engine {
|
|||||||
|
|
||||||
// Handle is_shared()
|
// Handle is_shared()
|
||||||
#[cfg(not(feature = "no_closure"))]
|
#[cfg(not(feature = "no_closure"))]
|
||||||
if name == KEYWORD_IS_SHARED && args_expr.len() == 1 {
|
if fn_name == KEYWORD_IS_SHARED && args_expr.len() == 1 {
|
||||||
let value = self.eval_expr(scope, mods, state, lib, this_ptr, &args_expr[0], level)?;
|
let value = self.eval_expr(scope, mods, state, lib, this_ptr, &args_expr[0], level)?;
|
||||||
|
|
||||||
return Ok(value.is_shared().into());
|
return Ok(value.is_shared().into());
|
||||||
@ -915,7 +915,7 @@ impl Engine {
|
|||||||
let redirected;
|
let redirected;
|
||||||
let mut args_expr = args_expr.as_ref();
|
let mut args_expr = args_expr.as_ref();
|
||||||
let mut curry = StaticVec::new();
|
let mut curry = StaticVec::new();
|
||||||
let mut name = name;
|
let mut name = fn_name;
|
||||||
|
|
||||||
if name == KEYWORD_FN_PTR_CALL
|
if name == KEYWORD_FN_PTR_CALL
|
||||||
&& args_expr.len() >= 1
|
&& args_expr.len() >= 1
|
||||||
@ -1078,7 +1078,7 @@ impl Engine {
|
|||||||
.map(|(v, _)| v)
|
.map(|(v, _)| v)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call a module-qualified function in normal function-call style.
|
/// Call a namespace-qualified function in normal function-call style.
|
||||||
/// Position in `EvalAltResult` is `None` and must be set afterwards.
|
/// Position in `EvalAltResult` is `None` and must be set afterwards.
|
||||||
pub(crate) fn make_qualified_function_call(
|
pub(crate) fn make_qualified_function_call(
|
||||||
&self,
|
&self,
|
||||||
@ -1087,8 +1087,8 @@ impl Engine {
|
|||||||
state: &mut State,
|
state: &mut State,
|
||||||
lib: &[&Module],
|
lib: &[&Module],
|
||||||
this_ptr: &mut Option<&mut Dynamic>,
|
this_ptr: &mut Option<&mut Dynamic>,
|
||||||
modules: Option<&ModuleRef>,
|
namespace: Option<&NamespaceRef>,
|
||||||
name: &str,
|
fn_name: &str,
|
||||||
args_expr: impl AsRef<[Expr]>,
|
args_expr: impl AsRef<[Expr]>,
|
||||||
def_val: Option<bool>,
|
def_val: Option<bool>,
|
||||||
hash_script: u64,
|
hash_script: u64,
|
||||||
@ -1096,7 +1096,7 @@ impl Engine {
|
|||||||
) -> Result<Dynamic, Box<EvalAltResult>> {
|
) -> Result<Dynamic, Box<EvalAltResult>> {
|
||||||
let args_expr = args_expr.as_ref();
|
let args_expr = args_expr.as_ref();
|
||||||
|
|
||||||
let modules = modules.as_ref().unwrap();
|
let namespace = namespace.as_ref().unwrap();
|
||||||
let mut arg_values: StaticVec<_>;
|
let mut arg_values: StaticVec<_>;
|
||||||
let mut first_arg_value = None;
|
let mut first_arg_value = None;
|
||||||
let mut args: StaticVec<_>;
|
let mut args: StaticVec<_>;
|
||||||
@ -1105,7 +1105,7 @@ impl Engine {
|
|||||||
// No arguments
|
// No arguments
|
||||||
args = Default::default();
|
args = Default::default();
|
||||||
} else {
|
} else {
|
||||||
// See if the first argument is a variable (not module-qualified).
|
// See if the first argument is a variable (not namespace-qualified).
|
||||||
// If so, convert to method-call style in order to leverage potential
|
// If so, convert to method-call style in order to leverage potential
|
||||||
// &mut first argument and avoid cloning the value
|
// &mut first argument and avoid cloning the value
|
||||||
if args_expr[0].get_variable_access(true).is_some() {
|
if args_expr[0].get_variable_access(true).is_some() {
|
||||||
@ -1151,7 +1151,7 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let module = search_imports(mods, state, modules)?;
|
let module = search_imports(mods, state, namespace)?;
|
||||||
|
|
||||||
// First search in script-defined functions (can override built-in)
|
// First search in script-defined functions (can override built-in)
|
||||||
let func = match module.get_qualified_fn(hash_script) {
|
let func = match module.get_qualified_fn(hash_script) {
|
||||||
@ -1159,7 +1159,7 @@ impl Engine {
|
|||||||
None => {
|
None => {
|
||||||
self.inc_operations(state)?;
|
self.inc_operations(state)?;
|
||||||
|
|
||||||
// Qualified Rust functions are indexed in two steps:
|
// Namespace-qualified Rust functions are indexed in two steps:
|
||||||
// 1) Calculate a hash in a similar manner to script-defined functions,
|
// 1) Calculate a hash in a similar manner to script-defined functions,
|
||||||
// i.e. qualifiers + function name + number of arguments.
|
// i.e. qualifiers + function name + number of arguments.
|
||||||
// 2) Calculate a second hash with no qualifiers, empty function name,
|
// 2) Calculate a second hash with no qualifiers, empty function name,
|
||||||
@ -1210,8 +1210,8 @@ impl Engine {
|
|||||||
None => EvalAltResult::ErrorFunctionNotFound(
|
None => EvalAltResult::ErrorFunctionNotFound(
|
||||||
format!(
|
format!(
|
||||||
"{}{} ({})",
|
"{}{} ({})",
|
||||||
modules,
|
namespace,
|
||||||
name,
|
fn_name,
|
||||||
args.iter()
|
args.iter()
|
||||||
.map(|a| if a.is::<ImmutableString>() {
|
.map(|a| if a.is::<ImmutableString>() {
|
||||||
"&str | ImmutableString | String"
|
"&str | ImmutableString | String"
|
||||||
|
10
src/lib.rs
10
src/lib.rs
@ -83,19 +83,20 @@ mod token;
|
|||||||
mod r#unsafe;
|
mod r#unsafe;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
/// The system integer type.
|
/// The system integer type. It is defined as `i64`.
|
||||||
///
|
///
|
||||||
/// If the `only_i32` feature is enabled, this will be `i32` instead.
|
/// If the `only_i32` feature is enabled, this will be `i32` instead.
|
||||||
#[cfg(not(feature = "only_i32"))]
|
#[cfg(not(feature = "only_i32"))]
|
||||||
pub type INT = i64;
|
pub type INT = i64;
|
||||||
|
|
||||||
/// The system integer type.
|
/// The system integer type.
|
||||||
|
/// It is defined as `i32` since the `only_i32` feature is used.
|
||||||
///
|
///
|
||||||
/// If the `only_i32` feature is not enabled, this will be `i64` instead.
|
/// If the `only_i32` feature is not enabled, this will be `i64` instead.
|
||||||
#[cfg(feature = "only_i32")]
|
#[cfg(feature = "only_i32")]
|
||||||
pub type INT = i32;
|
pub type INT = i32;
|
||||||
|
|
||||||
/// The system floating-point type.
|
/// The system floating-point type. It is defined as `f64`.
|
||||||
///
|
///
|
||||||
/// Not available under the `no_float` feature.
|
/// Not available under the `no_float` feature.
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
@ -103,6 +104,7 @@ pub type INT = i32;
|
|||||||
pub type FLOAT = f64;
|
pub type FLOAT = f64;
|
||||||
|
|
||||||
/// The system floating-point type.
|
/// The system floating-point type.
|
||||||
|
/// It is defined as `f32` since the `f32_float` feature is used.
|
||||||
///
|
///
|
||||||
/// Not available under the `no_float` feature.
|
/// Not available under the `no_float` feature.
|
||||||
#[cfg(not(feature = "no_float"))]
|
#[cfg(not(feature = "no_float"))]
|
||||||
@ -168,7 +170,7 @@ pub use token::{get_next_token, parse_string_literal, InputStream, Token, Tokeni
|
|||||||
#[cfg(feature = "internals")]
|
#[cfg(feature = "internals")]
|
||||||
#[deprecated(note = "this type is volatile and may change")]
|
#[deprecated(note = "this type is volatile and may change")]
|
||||||
pub use ast::{
|
pub use ast::{
|
||||||
BinaryExpr, CustomExpr, Expr, FloatWrapper, FnCallInfo, Ident, IdentX, ReturnType, ScriptFnDef,
|
BinaryExpr, CustomExpr, Expr, FloatWrapper, FnCallExpr, Ident, IdentX, ReturnType, ScriptFnDef,
|
||||||
Stmt,
|
Stmt,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -178,7 +180,7 @@ pub use engine::{Imports, Limits, State as EvalState};
|
|||||||
|
|
||||||
#[cfg(feature = "internals")]
|
#[cfg(feature = "internals")]
|
||||||
#[deprecated(note = "this type is volatile and may change")]
|
#[deprecated(note = "this type is volatile and may change")]
|
||||||
pub use module::ModuleRef;
|
pub use module::NamespaceRef;
|
||||||
|
|
||||||
/// _[INTERNALS]_ Alias to [`smallvec::SmallVec<[T; 4]>`](https://crates.io/crates/smallvec),
|
/// _[INTERNALS]_ Alias to [`smallvec::SmallVec<[T; 4]>`](https://crates.io/crates/smallvec),
|
||||||
/// which is a specialized `Vec` backed by a small, fixed-size array when there are <= 4 items stored.
|
/// which is a specialized `Vec` backed by a small, fixed-size array when there are <= 4 items stored.
|
||||||
|
@ -55,8 +55,8 @@ pub struct FuncInfo {
|
|||||||
pub types: Option<StaticVec<TypeId>>,
|
pub types: Option<StaticVec<TypeId>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An imported module, which may contain variables, sub-modules,
|
/// A module which may contain variables, sub-modules, external Rust functions,
|
||||||
/// external Rust functions, and script-defined functions.
|
/// and/or script-defined functions.
|
||||||
///
|
///
|
||||||
/// Not available under the `no_module` feature.
|
/// Not available under the `no_module` feature.
|
||||||
#[derive(Default, Clone)]
|
#[derive(Default, Clone)]
|
||||||
@ -253,7 +253,7 @@ impl Module {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a reference to a modules-qualified variable.
|
/// Get a reference to a namespace-qualified variable.
|
||||||
/// Name and Position in `EvalAltResult` are None and must be set afterwards.
|
/// Name and Position in `EvalAltResult` are None and must be set afterwards.
|
||||||
///
|
///
|
||||||
/// The `u64` hash is calculated by the function `crate::calc_native_fn_hash`.
|
/// The `u64` hash is calculated by the function `crate::calc_native_fn_hash`.
|
||||||
@ -1105,7 +1105,7 @@ impl Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a modules-qualified function.
|
/// Get a namespace-qualified function.
|
||||||
/// Name and Position in `EvalAltResult` are None and must be set afterwards.
|
/// Name and Position in `EvalAltResult` are None and must be set afterwards.
|
||||||
///
|
///
|
||||||
/// The `u64` hash is calculated by the function `crate::calc_native_fn_hash` and must match
|
/// The `u64` hash is calculated by the function `crate::calc_native_fn_hash` and must match
|
||||||
@ -1435,7 +1435,7 @@ impl Module {
|
|||||||
if let Some(param_types) = types {
|
if let Some(param_types) = types {
|
||||||
assert_eq!(*params, param_types.len());
|
assert_eq!(*params, param_types.len());
|
||||||
|
|
||||||
// Qualified Rust functions are indexed in two steps:
|
// Namespace-qualified Rust functions are indexed in two steps:
|
||||||
// 1) Calculate a hash in a similar manner to script-defined functions,
|
// 1) Calculate a hash in a similar manner to script-defined functions,
|
||||||
// i.e. qualifiers + function name + number of arguments.
|
// i.e. qualifiers + function name + number of arguments.
|
||||||
let hash_qualified_script =
|
let hash_qualified_script =
|
||||||
@ -1516,21 +1516,21 @@ impl Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// _[INTERNALS]_ A chain of module names to qualify a variable or function call.
|
/// _[INTERNALS]_ A chain of module names to namespace-qualify a variable or function call.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
///
|
///
|
||||||
/// A `u64` hash key is cached for quick search purposes.
|
/// A `u64` hash key is cached for quick search purposes.
|
||||||
///
|
///
|
||||||
/// A `StaticVec` is used because most module-level access contains only one level,
|
/// A `StaticVec` is used because most namespace-qualified access contains only one level,
|
||||||
/// and it is wasteful to always allocate a `Vec` with one element.
|
/// and it is wasteful to always allocate a `Vec` with one element.
|
||||||
///
|
///
|
||||||
/// ## WARNING
|
/// ## WARNING
|
||||||
///
|
///
|
||||||
/// This type is volatile and may change.
|
/// This type is volatile and may change.
|
||||||
#[derive(Clone, Eq, PartialEq, Default, Hash)]
|
#[derive(Clone, Eq, PartialEq, Default, Hash)]
|
||||||
pub struct ModuleRef(StaticVec<Ident>, Option<NonZeroUsize>);
|
pub struct NamespaceRef(StaticVec<Ident>, Option<NonZeroUsize>);
|
||||||
|
|
||||||
impl fmt::Debug for ModuleRef {
|
impl fmt::Debug for NamespaceRef {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
fmt::Debug::fmt(&self.0, f)?;
|
fmt::Debug::fmt(&self.0, f)?;
|
||||||
|
|
||||||
@ -1542,7 +1542,7 @@ impl fmt::Debug for ModuleRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deref for ModuleRef {
|
impl Deref for NamespaceRef {
|
||||||
type Target = StaticVec<Ident>;
|
type Target = StaticVec<Ident>;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
@ -1550,13 +1550,13 @@ impl Deref for ModuleRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DerefMut for ModuleRef {
|
impl DerefMut for NamespaceRef {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.0
|
&mut self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ModuleRef {
|
impl fmt::Display for NamespaceRef {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
for Ident { name, .. } in self.0.iter() {
|
for Ident { name, .. } in self.0.iter() {
|
||||||
write!(f, "{}{}", name, Token::DoubleColon.syntax())?;
|
write!(f, "{}{}", name, Token::DoubleColon.syntax())?;
|
||||||
@ -1565,7 +1565,7 @@ impl fmt::Display for ModuleRef {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<StaticVec<Ident>> for ModuleRef {
|
impl From<StaticVec<Ident>> for NamespaceRef {
|
||||||
fn from(modules: StaticVec<Ident>) -> Self {
|
fn from(modules: StaticVec<Ident>) -> Self {
|
||||||
Self(modules, None)
|
Self(modules, None)
|
||||||
}
|
}
|
||||||
@ -1596,7 +1596,7 @@ impl<M: Into<Module>> AddAssign<M> for Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleRef {
|
impl NamespaceRef {
|
||||||
pub(crate) fn index(&self) -> Option<NonZeroUsize> {
|
pub(crate) fn index(&self) -> Option<NonZeroUsize> {
|
||||||
self.1
|
self.1
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Module implementing the AST optimizer.
|
//! Module implementing the AST optimizer.
|
||||||
|
|
||||||
use crate::ast::{BinaryExpr, CustomExpr, Expr, FnCallInfo, ScriptFnDef, Stmt, AST};
|
use crate::ast::{BinaryExpr, CustomExpr, Expr, FnCallExpr, ScriptFnDef, Stmt, AST};
|
||||||
use crate::dynamic::Dynamic;
|
use crate::dynamic::Dynamic;
|
||||||
use crate::engine::{
|
use crate::engine::{
|
||||||
Engine, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_IS_DEF_FN, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT,
|
Engine, KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_IS_DEF_FN, KEYWORD_IS_DEF_VAR, KEYWORD_PRINT,
|
||||||
@ -644,7 +644,7 @@ fn optimize_expr(expr: Expr, state: &mut State) -> Expr {
|
|||||||
&& x.args.iter().all(Expr::is_constant) // all arguments are constants
|
&& x.args.iter().all(Expr::is_constant) // all arguments are constants
|
||||||
&& !is_valid_identifier(x.name.chars()) // cannot be scripted
|
&& !is_valid_identifier(x.name.chars()) // cannot be scripted
|
||||||
=> {
|
=> {
|
||||||
let FnCallInfo { name, args, .. } = x.as_mut();
|
let FnCallExpr { name, args, .. } = x.as_mut();
|
||||||
|
|
||||||
let arg_values: StaticVec<_> = args.iter().map(|e| e.get_constant_value().unwrap()).collect();
|
let arg_values: StaticVec<_> = args.iter().map(|e| e.get_constant_value().unwrap()).collect();
|
||||||
let arg_types: StaticVec<_> = arg_values.iter().map(Dynamic::type_id).collect();
|
let arg_types: StaticVec<_> = arg_values.iter().map(Dynamic::type_id).collect();
|
||||||
@ -670,7 +670,7 @@ fn optimize_expr(expr: Expr, state: &mut State) -> Expr {
|
|||||||
&& state.optimization_level == OptimizationLevel::Full // full optimizations
|
&& state.optimization_level == OptimizationLevel::Full // full optimizations
|
||||||
&& x.args.iter().all(Expr::is_constant) // all arguments are constants
|
&& x.args.iter().all(Expr::is_constant) // all arguments are constants
|
||||||
=> {
|
=> {
|
||||||
let FnCallInfo { name, args, def_value, .. } = x.as_mut();
|
let FnCallExpr { name, args, def_value, .. } = x.as_mut();
|
||||||
|
|
||||||
// First search for script-defined functions (can override built-in)
|
// First search for script-defined functions (can override built-in)
|
||||||
#[cfg(not(feature = "no_function"))]
|
#[cfg(not(feature = "no_function"))]
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
//! Main module defining the lexer and parser.
|
//! Main module defining the lexer and parser.
|
||||||
|
|
||||||
use crate::ast::{
|
use crate::ast::{
|
||||||
BinaryExpr, CustomExpr, Expr, FnCallInfo, Ident, IdentX, ReturnType, ScriptFnDef, Stmt, AST,
|
BinaryExpr, CustomExpr, Expr, FnCallExpr, Ident, IdentX, ReturnType, ScriptFnDef, Stmt, AST,
|
||||||
};
|
};
|
||||||
use crate::dynamic::{Dynamic, Union};
|
use crate::dynamic::{Dynamic, Union};
|
||||||
use crate::engine::{Engine, KEYWORD_THIS, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT};
|
use crate::engine::{Engine, KEYWORD_THIS, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT};
|
||||||
use crate::module::ModuleRef;
|
use crate::module::NamespaceRef;
|
||||||
use crate::optimize::{optimize_into_ast, OptimizationLevel};
|
use crate::optimize::{optimize_into_ast, OptimizationLevel};
|
||||||
use crate::parse_error::{LexError, ParseError, ParseErrorType};
|
use crate::parse_error::{LexError, ParseError, ParseErrorType};
|
||||||
use crate::scope::{EntryType as ScopeEntryType, Scope};
|
use crate::scope::{EntryType as ScopeEntryType, Scope};
|
||||||
@ -270,7 +270,7 @@ fn parse_fn_call(
|
|||||||
lib: &mut FunctionsLib,
|
lib: &mut FunctionsLib,
|
||||||
id: String,
|
id: String,
|
||||||
capture: bool,
|
capture: bool,
|
||||||
mut namespace: Option<Box<ModuleRef>>,
|
mut namespace: Option<Box<NamespaceRef>>,
|
||||||
settings: ParseSettings,
|
settings: ParseSettings,
|
||||||
) -> Result<Expr, ParseError> {
|
) -> Result<Expr, ParseError> {
|
||||||
let (token, token_pos) = input.peek().unwrap();
|
let (token, token_pos) = input.peek().unwrap();
|
||||||
@ -313,7 +313,7 @@ fn parse_fn_call(
|
|||||||
};
|
};
|
||||||
|
|
||||||
return Ok(Expr::FnCall(
|
return Ok(Expr::FnCall(
|
||||||
Box::new(FnCallInfo {
|
Box::new(FnCallExpr {
|
||||||
name: id.into(),
|
name: id.into(),
|
||||||
capture,
|
capture,
|
||||||
namespace,
|
namespace,
|
||||||
@ -360,7 +360,7 @@ fn parse_fn_call(
|
|||||||
};
|
};
|
||||||
|
|
||||||
return Ok(Expr::FnCall(
|
return Ok(Expr::FnCall(
|
||||||
Box::new(FnCallInfo {
|
Box::new(FnCallExpr {
|
||||||
name: id.into(),
|
name: id.into(),
|
||||||
capture,
|
capture,
|
||||||
namespace,
|
namespace,
|
||||||
@ -907,7 +907,7 @@ fn parse_primary(
|
|||||||
if let Some(ref mut modules) = modules {
|
if let Some(ref mut modules) = modules {
|
||||||
modules.push(var_name_def);
|
modules.push(var_name_def);
|
||||||
} else {
|
} else {
|
||||||
let mut m: ModuleRef = Default::default();
|
let mut m: NamespaceRef = Default::default();
|
||||||
m.push(var_name_def);
|
m.push(var_name_def);
|
||||||
modules = Some(Box::new(m));
|
modules = Some(Box::new(m));
|
||||||
}
|
}
|
||||||
@ -934,16 +934,16 @@ fn parse_primary(
|
|||||||
}
|
}
|
||||||
|
|
||||||
match &mut root_expr {
|
match &mut root_expr {
|
||||||
// Cache the hash key for module-qualified variables
|
// Cache the hash key for namespace-qualified variables
|
||||||
Expr::Variable(x) if x.1.is_some() => {
|
Expr::Variable(x) if x.1.is_some() => {
|
||||||
let (_, modules, hash, Ident { name, .. }) = x.as_mut();
|
let (_, modules, hash, Ident { name, .. }) = x.as_mut();
|
||||||
let modules = modules.as_mut().unwrap();
|
let namespace = modules.as_mut().unwrap();
|
||||||
|
|
||||||
// Qualifiers + variable name
|
// Qualifiers + variable name
|
||||||
*hash = calc_script_fn_hash(modules.iter().map(|v| v.name.as_str()), name, 0);
|
*hash = calc_script_fn_hash(namespace.iter().map(|v| v.name.as_str()), name, 0);
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
modules.set_index(state.find_module(&modules[0].name));
|
namespace.set_index(state.find_module(&namespace[0].name));
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
@ -1001,7 +1001,7 @@ fn parse_unary(
|
|||||||
args.push(expr);
|
args.push(expr);
|
||||||
|
|
||||||
Ok(Expr::FnCall(
|
Ok(Expr::FnCall(
|
||||||
Box::new(FnCallInfo {
|
Box::new(FnCallExpr {
|
||||||
name: op.into(),
|
name: op.into(),
|
||||||
native_only: true,
|
native_only: true,
|
||||||
namespace: None,
|
namespace: None,
|
||||||
@ -1030,7 +1030,7 @@ fn parse_unary(
|
|||||||
let hash = calc_script_fn_hash(empty(), op, 1);
|
let hash = calc_script_fn_hash(empty(), op, 1);
|
||||||
|
|
||||||
Ok(Expr::FnCall(
|
Ok(Expr::FnCall(
|
||||||
Box::new(FnCallInfo {
|
Box::new(FnCallExpr {
|
||||||
name: op.into(),
|
name: op.into(),
|
||||||
native_only: true,
|
native_only: true,
|
||||||
hash,
|
hash,
|
||||||
@ -1490,7 +1490,7 @@ fn parse_binary_op(
|
|||||||
let op = op_token.syntax();
|
let op = op_token.syntax();
|
||||||
let hash = calc_script_fn_hash(empty(), &op, 2);
|
let hash = calc_script_fn_hash(empty(), &op, 2);
|
||||||
|
|
||||||
let op_base = FnCallInfo {
|
let op_base = FnCallExpr {
|
||||||
name: op,
|
name: op,
|
||||||
native_only: true,
|
native_only: true,
|
||||||
capture: false,
|
capture: false,
|
||||||
@ -1513,7 +1513,7 @@ fn parse_binary_op(
|
|||||||
| Token::Ampersand
|
| Token::Ampersand
|
||||||
| Token::Pipe
|
| Token::Pipe
|
||||||
| Token::XOr => Expr::FnCall(
|
| Token::XOr => Expr::FnCall(
|
||||||
Box::new(FnCallInfo {
|
Box::new(FnCallExpr {
|
||||||
hash,
|
hash,
|
||||||
args,
|
args,
|
||||||
..op_base
|
..op_base
|
||||||
@ -1523,7 +1523,7 @@ fn parse_binary_op(
|
|||||||
|
|
||||||
// '!=' defaults to true when passed invalid operands
|
// '!=' defaults to true when passed invalid operands
|
||||||
Token::NotEqualsTo => Expr::FnCall(
|
Token::NotEqualsTo => Expr::FnCall(
|
||||||
Box::new(FnCallInfo {
|
Box::new(FnCallExpr {
|
||||||
hash,
|
hash,
|
||||||
args,
|
args,
|
||||||
def_value: Some(true),
|
def_value: Some(true),
|
||||||
@ -1538,7 +1538,7 @@ fn parse_binary_op(
|
|||||||
| Token::LessThanEqualsTo
|
| Token::LessThanEqualsTo
|
||||||
| Token::GreaterThan
|
| Token::GreaterThan
|
||||||
| Token::GreaterThanEqualsTo => Expr::FnCall(
|
| Token::GreaterThanEqualsTo => Expr::FnCall(
|
||||||
Box::new(FnCallInfo {
|
Box::new(FnCallExpr {
|
||||||
hash,
|
hash,
|
||||||
args,
|
args,
|
||||||
def_value: cmp_def,
|
def_value: cmp_def,
|
||||||
@ -1585,7 +1585,7 @@ fn parse_binary_op(
|
|||||||
Token::Custom(s) if state.engine.custom_keywords.contains_key(&s) => {
|
Token::Custom(s) if state.engine.custom_keywords.contains_key(&s) => {
|
||||||
// Accept non-native functions for custom operators
|
// Accept non-native functions for custom operators
|
||||||
Expr::FnCall(
|
Expr::FnCall(
|
||||||
Box::new(FnCallInfo {
|
Box::new(FnCallExpr {
|
||||||
hash,
|
hash,
|
||||||
args,
|
args,
|
||||||
native_only: false,
|
native_only: false,
|
||||||
@ -2518,7 +2518,7 @@ fn make_curry_from_externals(fn_expr: Expr, externals: StaticVec<Ident>, pos: Po
|
|||||||
let hash = calc_script_fn_hash(empty(), KEYWORD_FN_PTR_CURRY, num_externals + 1);
|
let hash = calc_script_fn_hash(empty(), KEYWORD_FN_PTR_CURRY, num_externals + 1);
|
||||||
|
|
||||||
let expr = Expr::FnCall(
|
let expr = Expr::FnCall(
|
||||||
Box::new(FnCallInfo {
|
Box::new(FnCallExpr {
|
||||||
name: KEYWORD_FN_PTR_CURRY.into(),
|
name: KEYWORD_FN_PTR_CURRY.into(),
|
||||||
hash,
|
hash,
|
||||||
args,
|
args,
|
||||||
|
@ -1735,7 +1735,7 @@ impl Engine {
|
|||||||
engine: self,
|
engine: self,
|
||||||
state: TokenizeState {
|
state: TokenizeState {
|
||||||
#[cfg(not(feature = "unchecked"))]
|
#[cfg(not(feature = "unchecked"))]
|
||||||
max_string_size: self.limits_set.max_string_size,
|
max_string_size: self.limits.max_string_size,
|
||||||
#[cfg(feature = "unchecked")]
|
#[cfg(feature = "unchecked")]
|
||||||
max_string_size: 0,
|
max_string_size: 0,
|
||||||
non_unary: false,
|
non_unary: false,
|
||||||
|
@ -55,7 +55,7 @@ impl BuildHasher for StraightHasherBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// _[INTERNALS]_ Calculate a `u64` hash key from a module-qualified function name and parameter types.
|
/// _[INTERNALS]_ Calculate a `u64` hash key from a namespace-qualified function name and parameter types.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
///
|
///
|
||||||
/// Module names are passed in via `&str` references from an iterator.
|
/// Module names are passed in via `&str` references from an iterator.
|
||||||
@ -73,8 +73,8 @@ pub fn calc_native_fn_hash<'a>(
|
|||||||
calc_fn_hash(modules, fn_name, None, params)
|
calc_fn_hash(modules, fn_name, None, params)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// _[INTERNALS]_ Calculate a `u64` hash key from a module-qualified function name and the number of parameters,
|
/// _[INTERNALS]_ Calculate a `u64` hash key from a namespace-qualified function name
|
||||||
/// but no parameter types.
|
/// and the number of parameters, but no parameter types.
|
||||||
/// Exported under the `internals` feature only.
|
/// Exported under the `internals` feature only.
|
||||||
///
|
///
|
||||||
/// Module names are passed in via `&str` references from an iterator.
|
/// Module names are passed in via `&str` references from an iterator.
|
||||||
@ -92,7 +92,7 @@ pub fn calc_script_fn_hash<'a>(
|
|||||||
calc_fn_hash(modules, fn_name, Some(num), empty())
|
calc_fn_hash(modules, fn_name, Some(num), empty())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate a `u64` hash key from a module-qualified function name and parameter types.
|
/// Calculate a `u64` hash key from a namespace-qualified function name and parameter types.
|
||||||
///
|
///
|
||||||
/// Module names are passed in via `&str` references from an iterator.
|
/// Module names are passed in via `&str` references from an iterator.
|
||||||
/// Parameter types are passed in via `TypeId` values from an iterator.
|
/// Parameter types are passed in via `TypeId` values from an iterator.
|
||||||
|
Loading…
Reference in New Issue
Block a user