Reduce size of Engine.
This commit is contained in:
parent
cefe3f1715
commit
2bf8e610a3
@ -12,7 +12,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
use std::{borrow::Borrow, ops::Deref};
|
use std::{borrow::Borrow, collections::BTreeMap, ops::Deref};
|
||||||
|
|
||||||
/// Collection of special markers for custom syntax definition.
|
/// Collection of special markers for custom syntax definition.
|
||||||
pub mod markers {
|
pub mod markers {
|
||||||
@ -257,19 +257,29 @@ impl Engine {
|
|||||||
// Standard or reserved keyword/symbol not in first position
|
// Standard or reserved keyword/symbol not in first position
|
||||||
_ if !segments.is_empty() && token.is_some() => {
|
_ if !segments.is_empty() && token.is_some() => {
|
||||||
// Make it a custom keyword/symbol if it is disabled or reserved
|
// Make it a custom keyword/symbol if it is disabled or reserved
|
||||||
if ((!self.disabled_symbols.is_empty() && self.disabled_symbols.contains(s))
|
if (self
|
||||||
|
.disabled_symbols
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.contains(s))
|
||||||
|| token.map_or(false, |v| v.is_reserved()))
|
|| token.map_or(false, |v| v.is_reserved()))
|
||||||
&& (self.custom_keywords.is_empty()
|
&& !self
|
||||||
|| !self.custom_keywords.contains_key(s))
|
.custom_keywords
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.contains_key(s))
|
||||||
{
|
{
|
||||||
self.custom_keywords.insert(s.into(), None);
|
self.custom_keywords
|
||||||
|
.get_or_insert_with(|| BTreeMap::new().into())
|
||||||
|
.insert(s.into(), None);
|
||||||
}
|
}
|
||||||
s.into()
|
s.into()
|
||||||
}
|
}
|
||||||
// Standard keyword in first position but not disabled
|
// Standard keyword in first position but not disabled
|
||||||
_ if segments.is_empty()
|
_ if segments.is_empty()
|
||||||
&& token.as_ref().map_or(false, Token::is_standard_keyword)
|
&& token.as_ref().map_or(false, Token::is_standard_keyword)
|
||||||
&& (self.disabled_symbols.is_empty() || !self.disabled_symbols.contains(s)) =>
|
&& !self
|
||||||
|
.disabled_symbols
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.contains(s)) =>
|
||||||
{
|
{
|
||||||
return Err(LexError::ImproperSymbol(
|
return Err(LexError::ImproperSymbol(
|
||||||
s.to_string(),
|
s.to_string(),
|
||||||
@ -283,12 +293,19 @@ impl Engine {
|
|||||||
// Identifier in first position
|
// Identifier in first position
|
||||||
_ if segments.is_empty() && is_valid_identifier(s) => {
|
_ if segments.is_empty() && is_valid_identifier(s) => {
|
||||||
// Make it a custom keyword/symbol if it is disabled or reserved
|
// Make it a custom keyword/symbol if it is disabled or reserved
|
||||||
if (!self.disabled_symbols.is_empty() && self.disabled_symbols.contains(s))
|
if self
|
||||||
|| token.map_or(false, |v| v.is_reserved())
|
.disabled_symbols
|
||||||
&& self.custom_keywords.is_empty()
|
.as_ref()
|
||||||
|| !self.custom_keywords.contains_key(s)
|
.map_or(false, |m| m.contains(s))
|
||||||
|
|| (token.map_or(false, |v| v.is_reserved())
|
||||||
|
&& !self
|
||||||
|
.custom_keywords
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.contains_key(s)))
|
||||||
{
|
{
|
||||||
self.custom_keywords.insert(s.into(), None);
|
self.custom_keywords
|
||||||
|
.get_or_insert_with(|| BTreeMap::new().into())
|
||||||
|
.insert(s.into(), None);
|
||||||
}
|
}
|
||||||
s.into()
|
s.into()
|
||||||
}
|
}
|
||||||
@ -373,14 +390,16 @@ impl Engine {
|
|||||||
scope_may_be_changed: bool,
|
scope_may_be_changed: bool,
|
||||||
func: impl Fn(&mut EvalContext, &[Expression], &Dynamic) -> RhaiResult + SendSync + 'static,
|
func: impl Fn(&mut EvalContext, &[Expression], &Dynamic) -> RhaiResult + SendSync + 'static,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.custom_syntax.insert(
|
self.custom_syntax
|
||||||
key.into(),
|
.get_or_insert_with(|| BTreeMap::new().into())
|
||||||
CustomSyntax {
|
.insert(
|
||||||
parse: Box::new(parse),
|
key.into(),
|
||||||
func: Box::new(func),
|
CustomSyntax {
|
||||||
scope_may_be_changed,
|
parse: Box::new(parse),
|
||||||
},
|
func: Box::new(func),
|
||||||
);
|
scope_may_be_changed,
|
||||||
|
},
|
||||||
|
);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -369,6 +369,7 @@ impl Definitions<'_> {
|
|||||||
.engine
|
.engine
|
||||||
.global_sub_modules
|
.global_sub_modules
|
||||||
.iter()
|
.iter()
|
||||||
|
.flat_map(|m| m.iter())
|
||||||
.map(move |(name, module)| {
|
.map(move |(name, module)| {
|
||||||
(
|
(
|
||||||
name.to_string(),
|
name.to_string(),
|
||||||
@ -445,13 +446,16 @@ impl Module {
|
|||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
if f.access != FnAccess::Private {
|
if f.access != FnAccess::Private {
|
||||||
#[cfg(not(feature = "no_custom_syntax"))]
|
|
||||||
let operator = def.engine.custom_keywords.contains_key(f.name.as_str())
|
|
||||||
|| (!f.name.contains('$') && !is_valid_function_name(f.name.as_str()));
|
|
||||||
|
|
||||||
#[cfg(feature = "no_custom_syntax")]
|
|
||||||
let operator = !f.name.contains('$') && !is_valid_function_name(&f.name);
|
let operator = !f.name.contains('$') && !is_valid_function_name(&f.name);
|
||||||
|
|
||||||
|
#[cfg(not(feature = "no_custom_syntax"))]
|
||||||
|
let operator = operator
|
||||||
|
|| def
|
||||||
|
.engine
|
||||||
|
.custom_keywords
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.contains_key(f.name.as_str()));
|
||||||
|
|
||||||
f.write_definition(writer, def, operator)?;
|
f.write_definition(writer, def, operator)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -360,7 +360,7 @@ impl Engine {
|
|||||||
+ SendSync
|
+ SendSync
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
self.debugger = Some((Box::new(init), Box::new(callback)));
|
self.debugger = Some(Box::new((Box::new(init), Box::new(callback))));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ pub mod definitions;
|
|||||||
|
|
||||||
use crate::{Dynamic, Engine, Identifier};
|
use crate::{Dynamic, Engine, Identifier};
|
||||||
|
|
||||||
|
use std::collections::BTreeSet;
|
||||||
#[cfg(feature = "no_std")]
|
#[cfg(feature = "no_std")]
|
||||||
use std::prelude::v1::*;
|
use std::prelude::v1::*;
|
||||||
|
|
||||||
@ -107,7 +108,9 @@ impl Engine {
|
|||||||
/// ```
|
/// ```
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn disable_symbol(&mut self, symbol: impl Into<Identifier>) -> &mut Self {
|
pub fn disable_symbol(&mut self, symbol: impl Into<Identifier>) -> &mut Self {
|
||||||
self.disabled_symbols.insert(symbol.into());
|
self.disabled_symbols
|
||||||
|
.get_or_insert_with(|| BTreeSet::new().into())
|
||||||
|
.insert(symbol.into());
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,18 +166,31 @@ impl Engine {
|
|||||||
// Active standard keywords cannot be made custom
|
// Active standard keywords cannot be made custom
|
||||||
// Disabled keywords are OK
|
// Disabled keywords are OK
|
||||||
Some(token) if token.is_standard_keyword() => {
|
Some(token) if token.is_standard_keyword() => {
|
||||||
if !self.disabled_symbols.contains(token.literal_syntax()) {
|
if !self
|
||||||
|
.disabled_symbols
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.contains(token.literal_syntax()))
|
||||||
|
{
|
||||||
return Err(format!("'{keyword}' is a reserved keyword"));
|
return Err(format!("'{keyword}' is a reserved keyword"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Active standard symbols cannot be made custom
|
// Active standard symbols cannot be made custom
|
||||||
Some(token) if token.is_standard_symbol() => {
|
Some(token) if token.is_standard_symbol() => {
|
||||||
if !self.disabled_symbols.contains(token.literal_syntax()) {
|
if !self
|
||||||
|
.disabled_symbols
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.contains(token.literal_syntax()))
|
||||||
|
{
|
||||||
return Err(format!("'{keyword}' is a reserved operator"));
|
return Err(format!("'{keyword}' is a reserved operator"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Active standard symbols cannot be made custom
|
// Active standard symbols cannot be made custom
|
||||||
Some(token) if !self.disabled_symbols.contains(token.literal_syntax()) => {
|
Some(token)
|
||||||
|
if !self
|
||||||
|
.disabled_symbols
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.contains(token.literal_syntax())) =>
|
||||||
|
{
|
||||||
return Err(format!("'{keyword}' is a reserved symbol"))
|
return Err(format!("'{keyword}' is a reserved symbol"))
|
||||||
}
|
}
|
||||||
// Disabled symbols are OK
|
// Disabled symbols are OK
|
||||||
@ -183,6 +199,7 @@ impl Engine {
|
|||||||
|
|
||||||
// Add to custom keywords
|
// Add to custom keywords
|
||||||
self.custom_keywords
|
self.custom_keywords
|
||||||
|
.get_or_insert_with(|| std::collections::BTreeMap::new().into())
|
||||||
.insert(keyword.into(), Some(precedence));
|
.insert(keyword.into(), Some(precedence));
|
||||||
|
|
||||||
Ok(self)
|
Ok(self)
|
||||||
|
@ -683,8 +683,10 @@ impl Engine {
|
|||||||
name: impl AsRef<str>,
|
name: impl AsRef<str>,
|
||||||
module: SharedModule,
|
module: SharedModule,
|
||||||
) -> &mut Self {
|
) -> &mut Self {
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
fn register_static_module_raw(
|
fn register_static_module_raw(
|
||||||
root: &mut std::collections::BTreeMap<Identifier, SharedModule>,
|
root: &mut BTreeMap<Identifier, SharedModule>,
|
||||||
name: &str,
|
name: &str,
|
||||||
module: SharedModule,
|
module: SharedModule,
|
||||||
) {
|
) {
|
||||||
@ -717,7 +719,12 @@ impl Engine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
register_static_module_raw(&mut self.global_sub_modules, name.as_ref(), module);
|
register_static_module_raw(
|
||||||
|
self.global_sub_modules
|
||||||
|
.get_or_insert_with(|| BTreeMap::new().into()),
|
||||||
|
name.as_ref(),
|
||||||
|
module,
|
||||||
|
);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
/// _(metadata)_ Generate a list of all registered functions.
|
/// _(metadata)_ Generate a list of all registered functions.
|
||||||
@ -737,7 +744,7 @@ impl Engine {
|
|||||||
signatures.extend(self.global_namespace().gen_fn_signatures());
|
signatures.extend(self.global_namespace().gen_fn_signatures());
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
for (name, m) in &self.global_sub_modules {
|
for (name, m) in self.global_sub_modules.iter().flat_map(|m| m.iter()) {
|
||||||
signatures.extend(m.gen_fn_signatures().map(|f| format!("{name}::{f}")));
|
signatures.extend(m.gen_fn_signatures().map(|f| format!("{name}::{f}")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,6 +205,7 @@ impl Engine {
|
|||||||
return self
|
return self
|
||||||
.global_sub_modules
|
.global_sub_modules
|
||||||
.iter()
|
.iter()
|
||||||
|
.flat_map(|m| m.iter())
|
||||||
.find_map(|(_, m)| m.get_custom_type(name));
|
.find_map(|(_, m)| m.get_custom_type(name));
|
||||||
#[cfg(feature = "no_module")]
|
#[cfg(feature = "no_module")]
|
||||||
return None;
|
return None;
|
||||||
@ -238,6 +239,7 @@ impl Engine {
|
|||||||
return self
|
return self
|
||||||
.global_sub_modules
|
.global_sub_modules
|
||||||
.iter()
|
.iter()
|
||||||
|
.flat_map(|m| m.iter())
|
||||||
.find_map(|(_, m)| m.get_custom_type(name));
|
.find_map(|(_, m)| m.get_custom_type(name));
|
||||||
#[cfg(feature = "no_module")]
|
#[cfg(feature = "no_module")]
|
||||||
return None;
|
return None;
|
||||||
|
@ -96,7 +96,8 @@ pub struct Engine {
|
|||||||
pub(crate) global_modules: StaticVec<SharedModule>,
|
pub(crate) global_modules: StaticVec<SharedModule>,
|
||||||
/// A collection of all sub-modules directly loaded into the Engine.
|
/// A collection of all sub-modules directly loaded into the Engine.
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
pub(crate) global_sub_modules: std::collections::BTreeMap<Identifier, SharedModule>,
|
pub(crate) global_sub_modules:
|
||||||
|
Option<Box<std::collections::BTreeMap<Identifier, SharedModule>>>,
|
||||||
|
|
||||||
/// A module resolution service.
|
/// A module resolution service.
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
@ -106,14 +107,16 @@ pub struct Engine {
|
|||||||
pub(crate) interned_strings: Locked<StringsInterner>,
|
pub(crate) interned_strings: Locked<StringsInterner>,
|
||||||
|
|
||||||
/// A set of symbols to disable.
|
/// A set of symbols to disable.
|
||||||
pub(crate) disabled_symbols: BTreeSet<Identifier>,
|
pub(crate) disabled_symbols: Option<Box<BTreeSet<Identifier>>>,
|
||||||
/// A map containing custom keywords and precedence to recognize.
|
/// A map containing custom keywords and precedence to recognize.
|
||||||
#[cfg(not(feature = "no_custom_syntax"))]
|
#[cfg(not(feature = "no_custom_syntax"))]
|
||||||
pub(crate) custom_keywords: std::collections::BTreeMap<Identifier, Option<Precedence>>,
|
pub(crate) custom_keywords:
|
||||||
|
Option<Box<std::collections::BTreeMap<Identifier, Option<Precedence>>>>,
|
||||||
/// Custom syntax.
|
/// Custom syntax.
|
||||||
#[cfg(not(feature = "no_custom_syntax"))]
|
#[cfg(not(feature = "no_custom_syntax"))]
|
||||||
pub(crate) custom_syntax:
|
pub(crate) custom_syntax: Option<
|
||||||
std::collections::BTreeMap<Identifier, crate::api::custom_syntax::CustomSyntax>,
|
Box<std::collections::BTreeMap<Identifier, crate::api::custom_syntax::CustomSyntax>>,
|
||||||
|
>,
|
||||||
/// Callback closure for filtering variable definition.
|
/// Callback closure for filtering variable definition.
|
||||||
pub(crate) def_var_filter: Option<Box<OnDefVarCallback>>,
|
pub(crate) def_var_filter: Option<Box<OnDefVarCallback>>,
|
||||||
/// Callback closure for resolving variable access.
|
/// Callback closure for resolving variable access.
|
||||||
@ -144,10 +147,12 @@ pub struct Engine {
|
|||||||
|
|
||||||
/// Callback closure for debugging.
|
/// Callback closure for debugging.
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
pub(crate) debugger: Option<(
|
pub(crate) debugger: Option<
|
||||||
Box<crate::eval::OnDebuggingInit>,
|
Box<(
|
||||||
Box<crate::eval::OnDebuggerCallback>,
|
Box<crate::eval::OnDebuggingInit>,
|
||||||
)>,
|
Box<crate::eval::OnDebuggerCallback>,
|
||||||
|
)>,
|
||||||
|
>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Engine {
|
impl fmt::Debug for Engine {
|
||||||
@ -168,7 +173,8 @@ impl fmt::Debug for Engine {
|
|||||||
"custom_syntax",
|
"custom_syntax",
|
||||||
&self
|
&self
|
||||||
.custom_syntax
|
.custom_syntax
|
||||||
.keys()
|
.iter()
|
||||||
|
.flat_map(|m| m.keys())
|
||||||
.map(crate::SmartString::as_str)
|
.map(crate::SmartString::as_str)
|
||||||
.collect::<String>(),
|
.collect::<String>(),
|
||||||
);
|
);
|
||||||
@ -264,17 +270,17 @@ impl Engine {
|
|||||||
global_modules: StaticVec::new_const(),
|
global_modules: StaticVec::new_const(),
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
global_sub_modules: std::collections::BTreeMap::new(),
|
global_sub_modules: None,
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
module_resolver: Box::new(crate::module::resolvers::DummyModuleResolver::new()),
|
module_resolver: Box::new(crate::module::resolvers::DummyModuleResolver::new()),
|
||||||
|
|
||||||
interned_strings: StringsInterner::new().into(),
|
interned_strings: StringsInterner::new().into(),
|
||||||
disabled_symbols: BTreeSet::new(),
|
disabled_symbols: None,
|
||||||
#[cfg(not(feature = "no_custom_syntax"))]
|
#[cfg(not(feature = "no_custom_syntax"))]
|
||||||
custom_keywords: std::collections::BTreeMap::new(),
|
custom_keywords: None,
|
||||||
#[cfg(not(feature = "no_custom_syntax"))]
|
#[cfg(not(feature = "no_custom_syntax"))]
|
||||||
custom_syntax: std::collections::BTreeMap::new(),
|
custom_syntax: None,
|
||||||
|
|
||||||
def_var_filter: None,
|
def_var_filter: None,
|
||||||
resolve_var: None,
|
resolve_var: None,
|
||||||
|
@ -512,7 +512,9 @@ impl Engine {
|
|||||||
let src = src.as_ref().map(|s| s.as_str());
|
let src = src.as_ref().map(|s| s.as_str());
|
||||||
let context = crate::EvalContext::new(self, global, caches, scope, this_ptr);
|
let context = crate::EvalContext::new(self, global, caches, scope, this_ptr);
|
||||||
|
|
||||||
if let Some((.., ref on_debugger)) = self.debugger {
|
if let Some(ref x) = self.debugger {
|
||||||
|
let (.., ref on_debugger) = **x;
|
||||||
|
|
||||||
let command = on_debugger(context, event, node, src, node.position())?;
|
let command = on_debugger(context, event, node, src, node.position())?;
|
||||||
|
|
||||||
match command {
|
match command {
|
||||||
|
@ -36,7 +36,12 @@ impl Engine {
|
|||||||
|
|
||||||
// Do a text-match search if the index doesn't work
|
// Do a text-match search if the index doesn't work
|
||||||
global.find_import(root).map_or_else(
|
global.find_import(root).map_or_else(
|
||||||
|| self.global_sub_modules.get(root).cloned(),
|
|| {
|
||||||
|
self.global_sub_modules
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|m| m.get(root))
|
||||||
|
.cloned()
|
||||||
|
},
|
||||||
|offset| global.get_shared_import(offset),
|
|offset| global.get_shared_import(offset),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -401,13 +406,17 @@ impl Engine {
|
|||||||
// The first token acts as the custom syntax's key
|
// The first token acts as the custom syntax's key
|
||||||
let key_token = custom.tokens.first().unwrap();
|
let key_token = custom.tokens.first().unwrap();
|
||||||
// The key should exist, unless the AST is compiled in a different Engine
|
// The key should exist, unless the AST is compiled in a different Engine
|
||||||
let custom_def = self.custom_syntax.get(key_token.as_str()).ok_or_else(|| {
|
let custom_def = self
|
||||||
Box::new(ERR::ErrorCustomSyntax(
|
.custom_syntax
|
||||||
format!("Invalid custom syntax prefix: {key_token}"),
|
.as_ref()
|
||||||
custom.tokens.iter().map(<_>::to_string).collect(),
|
.and_then(|m| m.get(key_token.as_str()))
|
||||||
*pos,
|
.ok_or_else(|| {
|
||||||
))
|
Box::new(ERR::ErrorCustomSyntax(
|
||||||
})?;
|
format!("Invalid custom syntax prefix: {key_token}"),
|
||||||
|
custom.tokens.iter().map(<_>::to_string).collect(),
|
||||||
|
*pos,
|
||||||
|
))
|
||||||
|
})?;
|
||||||
let mut context = EvalContext::new(self, global, caches, scope, this_ptr);
|
let mut context = EvalContext::new(self, global, caches, scope, this_ptr);
|
||||||
|
|
||||||
(custom_def.func)(&mut context, &expressions, &custom.state)
|
(custom_def.func)(&mut context, &expressions, &custom.state)
|
||||||
|
@ -111,8 +111,8 @@ impl GlobalRuntimeState {
|
|||||||
tag: engine.default_tag().clone(),
|
tag: engine.default_tag().clone(),
|
||||||
|
|
||||||
#[cfg(feature = "debugging")]
|
#[cfg(feature = "debugging")]
|
||||||
debugger: engine.debugger.as_ref().map(|(init, ..)| {
|
debugger: engine.debugger.as_ref().map(|x| {
|
||||||
crate::eval::Debugger::new(crate::eval::DebuggerStatus::Init, init(engine))
|
crate::eval::Debugger::new(crate::eval::DebuggerStatus::Init, (x.0)(engine))
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -502,7 +502,8 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
let func = func.or_else(|| global.get_iter(iter_type)).or_else(|| {
|
let func = func.or_else(|| global.get_iter(iter_type)).or_else(|| {
|
||||||
self.global_sub_modules
|
self.global_sub_modules
|
||||||
.values()
|
.iter()
|
||||||
|
.flat_map(|m| m.values())
|
||||||
.find_map(|m| m.get_qualified_iter(iter_type))
|
.find_map(|m| m.get_qualified_iter(iter_type))
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -212,7 +212,8 @@ impl Engine {
|
|||||||
} else {
|
} else {
|
||||||
func.or_else(|| _global.get_qualified_fn(hash)).or_else(|| {
|
func.or_else(|| _global.get_qualified_fn(hash)).or_else(|| {
|
||||||
self.global_sub_modules
|
self.global_sub_modules
|
||||||
.values()
|
.iter()
|
||||||
|
.flat_map(|m| m.values())
|
||||||
.find_map(|m| m.get_qualified_fn(hash).map(|f| (f, m.id_raw())))
|
.find_map(|m| m.get_qualified_fn(hash).map(|f| (f, m.id_raw())))
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
@ -252,7 +253,8 @@ impl Engine {
|
|||||||
|| _global.may_contain_dynamic_fn(hash_base)
|
|| _global.may_contain_dynamic_fn(hash_base)
|
||||||
|| self
|
|| self
|
||||||
.global_sub_modules
|
.global_sub_modules
|
||||||
.values()
|
.iter()
|
||||||
|
.flat_map(|m| m.values())
|
||||||
.any(|m| m.may_contain_dynamic_fn(hash_base));
|
.any(|m| m.may_contain_dynamic_fn(hash_base));
|
||||||
|
|
||||||
// Set maximum bitmask when there are dynamic versions of the function
|
// Set maximum bitmask when there are dynamic versions of the function
|
||||||
|
@ -236,7 +236,7 @@ impl Engine {
|
|||||||
// Then check imported modules
|
// Then check imported modules
|
||||||
global.contains_qualified_fn(hash_script)
|
global.contains_qualified_fn(hash_script)
|
||||||
// Then check sub-modules
|
// Then check sub-modules
|
||||||
|| self.global_sub_modules.values().any(|m| m.contains_qualified_fn(hash_script));
|
|| self.global_sub_modules.iter().flat_map(|m| m.values()).any(|m| m.contains_qualified_fn(hash_script));
|
||||||
|
|
||||||
if !result && !cache.filter.is_absent_and_set(hash_script) {
|
if !result && !cache.filter.is_absent_and_set(hash_script) {
|
||||||
// Do not cache "one-hit wonders"
|
// Do not cache "one-hit wonders"
|
||||||
|
@ -179,7 +179,8 @@ fn has_native_fn_override(
|
|||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
if engine
|
if engine
|
||||||
.global_sub_modules
|
.global_sub_modules
|
||||||
.values()
|
.iter()
|
||||||
|
.flat_map(|m| m.values())
|
||||||
.any(|m| m.contains_qualified_fn(hash))
|
.any(|m| m.contains_qualified_fn(hash))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -267,7 +267,8 @@ fn collect_fn_metadata(
|
|||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
ctx.engine()
|
ctx.engine()
|
||||||
.global_sub_modules
|
.global_sub_modules
|
||||||
.values()
|
.iter()
|
||||||
|
.flat_map(|m| m.values())
|
||||||
.flat_map(|m| m.iter_script_fn())
|
.flat_map(|m| m.iter_script_fn())
|
||||||
.filter(|(ns, a, n, p, f)| filter(*ns, *a, n, *p, f))
|
.filter(|(ns, a, n, p, f)| filter(*ns, *a, n, *p, f))
|
||||||
.for_each(|(.., f)| {
|
.for_each(|(.., f)| {
|
||||||
|
@ -600,7 +600,10 @@ impl Engine {
|
|||||||
&& index.is_none()
|
&& index.is_none()
|
||||||
&& !is_global
|
&& !is_global
|
||||||
&& !state.global_imports.iter().any(|m| m.as_str() == root)
|
&& !state.global_imports.iter().any(|m| m.as_str() == root)
|
||||||
&& !self.global_sub_modules.contains_key(root)
|
&& !self
|
||||||
|
.global_sub_modules
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.contains_key(root))
|
||||||
{
|
{
|
||||||
return Err(
|
return Err(
|
||||||
PERR::ModuleUndefined(root.into()).into_err(namespace.position())
|
PERR::ModuleUndefined(root.into()).into_err(namespace.position())
|
||||||
@ -668,7 +671,10 @@ impl Engine {
|
|||||||
&& index.is_none()
|
&& index.is_none()
|
||||||
&& !is_global
|
&& !is_global
|
||||||
&& !state.global_imports.iter().any(|m| m.as_str() == root)
|
&& !state.global_imports.iter().any(|m| m.as_str() == root)
|
||||||
&& !self.global_sub_modules.contains_key(root)
|
&& !self
|
||||||
|
.global_sub_modules
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.contains_key(root))
|
||||||
{
|
{
|
||||||
return Err(
|
return Err(
|
||||||
PERR::ModuleUndefined(root.into()).into_err(namespace.position())
|
PERR::ModuleUndefined(root.into()).into_err(namespace.position())
|
||||||
@ -1550,9 +1556,16 @@ impl Engine {
|
|||||||
// Custom syntax.
|
// Custom syntax.
|
||||||
#[cfg(not(feature = "no_custom_syntax"))]
|
#[cfg(not(feature = "no_custom_syntax"))]
|
||||||
Token::Custom(key) | Token::Reserved(key) | Token::Identifier(key)
|
Token::Custom(key) | Token::Reserved(key) | Token::Identifier(key)
|
||||||
if !self.custom_syntax.is_empty() && self.custom_syntax.contains_key(&**key) =>
|
if self
|
||||||
|
.custom_syntax
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.contains_key(&**key)) =>
|
||||||
{
|
{
|
||||||
let (key, syntax) = self.custom_syntax.get_key_value(&**key).unwrap();
|
let (key, syntax) = self
|
||||||
|
.custom_syntax
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|m| m.get_key_value(&**key))
|
||||||
|
.unwrap();
|
||||||
let (.., pos) = input.next().expect(NEVER_ENDS);
|
let (.., pos) = input.next().expect(NEVER_ENDS);
|
||||||
let settings2 = settings.level_up()?;
|
let settings2 = settings.level_up()?;
|
||||||
self.parse_custom_syntax(input, state, lib, settings2, key, syntax, pos)?
|
self.parse_custom_syntax(input, state, lib, settings2, key, syntax, pos)?
|
||||||
@ -1856,7 +1869,10 @@ impl Engine {
|
|||||||
&& index.is_none()
|
&& index.is_none()
|
||||||
&& !is_global
|
&& !is_global
|
||||||
&& !state.global_imports.iter().any(|m| m.as_str() == root)
|
&& !state.global_imports.iter().any(|m| m.as_str() == root)
|
||||||
&& !self.global_sub_modules.contains_key(root)
|
&& !self
|
||||||
|
.global_sub_modules
|
||||||
|
.as_ref()
|
||||||
|
.map_or(false, |m| m.contains_key(root))
|
||||||
{
|
{
|
||||||
return Err(
|
return Err(
|
||||||
PERR::ModuleUndefined(root.into()).into_err(namespace.position())
|
PERR::ModuleUndefined(root.into()).into_err(namespace.position())
|
||||||
@ -2297,7 +2313,8 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_custom_syntax"))]
|
#[cfg(not(feature = "no_custom_syntax"))]
|
||||||
Token::Custom(c) => self
|
Token::Custom(c) => self
|
||||||
.custom_keywords
|
.custom_keywords
|
||||||
.get(&**c)
|
.as_ref()
|
||||||
|
.and_then(|m| m.get(&**c))
|
||||||
.copied()
|
.copied()
|
||||||
.ok_or_else(|| PERR::Reserved(c.to_string()).into_err(*current_pos))?,
|
.ok_or_else(|| PERR::Reserved(c.to_string()).into_err(*current_pos))?,
|
||||||
Token::Reserved(c) if !is_valid_identifier(c) => {
|
Token::Reserved(c) if !is_valid_identifier(c) => {
|
||||||
@ -2322,7 +2339,8 @@ impl Engine {
|
|||||||
#[cfg(not(feature = "no_custom_syntax"))]
|
#[cfg(not(feature = "no_custom_syntax"))]
|
||||||
Token::Custom(c) => self
|
Token::Custom(c) => self
|
||||||
.custom_keywords
|
.custom_keywords
|
||||||
.get(&**c)
|
.as_ref()
|
||||||
|
.and_then(|m| m.get(&**c))
|
||||||
.copied()
|
.copied()
|
||||||
.ok_or_else(|| PERR::Reserved(c.to_string()).into_err(*next_pos))?,
|
.ok_or_else(|| PERR::Reserved(c.to_string()).into_err(*next_pos))?,
|
||||||
Token::Reserved(c) if !is_valid_identifier(c) => {
|
Token::Reserved(c) if !is_valid_identifier(c) => {
|
||||||
@ -2414,7 +2432,8 @@ impl Engine {
|
|||||||
Token::Custom(s)
|
Token::Custom(s)
|
||||||
if self
|
if self
|
||||||
.custom_keywords
|
.custom_keywords
|
||||||
.get(s.as_str())
|
.as_ref()
|
||||||
|
.and_then(|m| m.get(s.as_str()))
|
||||||
.map_or(false, Option::is_some) =>
|
.map_or(false, Option::is_some) =>
|
||||||
{
|
{
|
||||||
op_base.hashes = if is_valid_script_function {
|
op_base.hashes = if is_valid_script_function {
|
||||||
|
@ -170,7 +170,7 @@ pub fn gen_metadata_to_json(
|
|||||||
let mut global = ModuleMetadata::new();
|
let mut global = ModuleMetadata::new();
|
||||||
|
|
||||||
#[cfg(not(feature = "no_module"))]
|
#[cfg(not(feature = "no_module"))]
|
||||||
for (name, m) in &engine.global_sub_modules {
|
for (name, m) in engine.global_sub_modules.iter().flat_map(|m| m.iter()) {
|
||||||
global.modules.insert(name, m.as_ref().into());
|
global.modules.insert(name, m.as_ref().into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2435,7 +2435,7 @@ impl<'a> Iterator for TokenIterator<'a> {
|
|||||||
Some((Token::Reserved(s), pos)) => (match
|
Some((Token::Reserved(s), pos)) => (match
|
||||||
(s.as_str(),
|
(s.as_str(),
|
||||||
#[cfg(not(feature = "no_custom_syntax"))]
|
#[cfg(not(feature = "no_custom_syntax"))]
|
||||||
self.engine.custom_keywords.contains_key(&*s),
|
self.engine.custom_keywords.as_ref().map_or(false, |m| m.contains_key(&*s)),
|
||||||
#[cfg(feature = "no_custom_syntax")]
|
#[cfg(feature = "no_custom_syntax")]
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
@ -2472,7 +2472,7 @@ impl<'a> Iterator for TokenIterator<'a> {
|
|||||||
#[cfg(feature = "no_custom_syntax")]
|
#[cfg(feature = "no_custom_syntax")]
|
||||||
(.., true) => unreachable!("no custom operators"),
|
(.., true) => unreachable!("no custom operators"),
|
||||||
// Reserved keyword that is not custom and disabled.
|
// Reserved keyword that is not custom and disabled.
|
||||||
(token, false) if self.engine.disabled_symbols.contains(token) => {
|
(token, false) if self.engine.disabled_symbols.as_ref().map_or(false,|m| m.contains(token)) => {
|
||||||
let msg = format!("reserved {} '{token}' is disabled", if is_valid_identifier(token) { "keyword"} else {"symbol"});
|
let msg = format!("reserved {} '{token}' is disabled", if is_valid_identifier(token) { "keyword"} else {"symbol"});
|
||||||
Token::LexError(LERR::ImproperSymbol(s.to_string(), msg).into())
|
Token::LexError(LERR::ImproperSymbol(s.to_string(), msg).into())
|
||||||
},
|
},
|
||||||
@ -2481,13 +2481,13 @@ impl<'a> Iterator for TokenIterator<'a> {
|
|||||||
}, pos),
|
}, pos),
|
||||||
// Custom keyword
|
// Custom keyword
|
||||||
#[cfg(not(feature = "no_custom_syntax"))]
|
#[cfg(not(feature = "no_custom_syntax"))]
|
||||||
Some((Token::Identifier(s), pos)) if self.engine.custom_keywords.contains_key(&*s) => {
|
Some((Token::Identifier(s), pos)) if self.engine.custom_keywords.as_ref().map_or(false,|m| m.contains_key(&*s)) => {
|
||||||
(Token::Custom(s), pos)
|
(Token::Custom(s), pos)
|
||||||
}
|
}
|
||||||
// Custom keyword/symbol - must be disabled
|
// Custom keyword/symbol - must be disabled
|
||||||
#[cfg(not(feature = "no_custom_syntax"))]
|
#[cfg(not(feature = "no_custom_syntax"))]
|
||||||
Some((token, pos)) if token.is_literal() && self.engine.custom_keywords.contains_key(token.literal_syntax()) => {
|
Some((token, pos)) if token.is_literal() && self.engine.custom_keywords.as_ref().map_or(false,|m| m.contains_key(token.literal_syntax())) => {
|
||||||
if self.engine.disabled_symbols.contains(token.literal_syntax()) {
|
if self.engine.disabled_symbols.as_ref().map_or(false,|m| m.contains(token.literal_syntax())) {
|
||||||
// Disabled standard keyword/symbol
|
// Disabled standard keyword/symbol
|
||||||
(Token::Custom(Box::new(token.literal_syntax().into())), pos)
|
(Token::Custom(Box::new(token.literal_syntax().into())), pos)
|
||||||
} else {
|
} else {
|
||||||
@ -2496,7 +2496,7 @@ impl<'a> Iterator for TokenIterator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Disabled symbol
|
// Disabled symbol
|
||||||
Some((token, pos)) if token.is_literal() && self.engine.disabled_symbols.contains(token.literal_syntax()) => {
|
Some((token, pos)) if token.is_literal() && self.engine.disabled_symbols.as_ref().map_or(false,|m| m.contains(token.literal_syntax())) => {
|
||||||
(Token::Reserved(Box::new(token.literal_syntax().into())), pos)
|
(Token::Reserved(Box::new(token.literal_syntax().into())), pos)
|
||||||
}
|
}
|
||||||
// Normal symbol
|
// Normal symbol
|
||||||
|
Loading…
Reference in New Issue
Block a user