Allow shadowing of global.
This commit is contained in:
parent
9a8da93145
commit
eefdc09352
@ -1,9 +1,11 @@
|
||||
// This script defines a function with many parameters and calls it
|
||||
|
||||
const KEY = 38;
|
||||
|
||||
fn f(a, b, c, d, e, f) {
|
||||
a - b * c - d * e - f
|
||||
a - b * c - d * e - f + global::KEY
|
||||
}
|
||||
|
||||
print("f() call should be 4:");
|
||||
print("f() call should be 42:");
|
||||
|
||||
print(f(100, 5, 2, 9, 6, 32));
|
||||
|
@ -52,10 +52,7 @@ pub type Precedence = NonZeroU8;
|
||||
// the module name will live beyond the AST of the eval script text.
|
||||
// The best we can do is a shared reference.
|
||||
#[derive(Clone, Default)]
|
||||
pub struct Imports(
|
||||
smallvec::SmallVec<[Identifier; 8]>,
|
||||
smallvec::SmallVec<[Shared<Module>; 8]>,
|
||||
);
|
||||
pub struct Imports(StaticVec<Identifier>, StaticVec<Shared<Module>>);
|
||||
|
||||
impl Imports {
|
||||
/// Get the length of this stack of imported [modules][Module].
|
||||
@ -74,7 +71,7 @@ impl Imports {
|
||||
self.1.get(index).cloned()
|
||||
}
|
||||
/// Get the imported [modules][Module] at a particular index.
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
#[allow(dead_code)]
|
||||
#[inline(always)]
|
||||
pub(crate) fn get_mut(&mut self, index: usize) -> Option<&mut Shared<Module>> {
|
||||
self.1.get_mut(index)
|
||||
@ -907,6 +904,7 @@ impl Engine {
|
||||
disable_doc_comments: false,
|
||||
};
|
||||
|
||||
engine.global_namespace.set_internal(true);
|
||||
engine.register_global_module(StandardPackage::new().as_shared_module());
|
||||
|
||||
engine
|
||||
@ -917,7 +915,7 @@ impl Engine {
|
||||
/// Use [`register_global_module`][Engine::register_global_module] to add packages of functions.
|
||||
#[inline(always)]
|
||||
pub fn new_raw() -> Self {
|
||||
Self {
|
||||
let mut engine = Self {
|
||||
global_namespace: Default::default(),
|
||||
global_modules: Default::default(),
|
||||
global_sub_modules: Default::default(),
|
||||
@ -963,7 +961,11 @@ impl Engine {
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
#[cfg(feature = "metadata")]
|
||||
disable_doc_comments: false,
|
||||
}
|
||||
};
|
||||
|
||||
engine.global_namespace.set_internal(true);
|
||||
|
||||
engine
|
||||
}
|
||||
|
||||
/// Search for a module within an imports stack.
|
||||
@ -2516,19 +2518,28 @@ impl Engine {
|
||||
|
||||
let (var_name, _alias): (Cow<'_, str>, _) = if state.is_global() {
|
||||
#[cfg(not(feature = "no_function"))]
|
||||
if entry_type == AccessMode::ReadOnly {
|
||||
let index = if let Some(index) = mods.find(KEYWORD_GLOBAL) {
|
||||
index
|
||||
if entry_type == AccessMode::ReadOnly && lib.iter().any(|&m| !m.is_empty()) {
|
||||
let global = if let Some(index) = mods.find(KEYWORD_GLOBAL) {
|
||||
let global = mods.get_mut(index).unwrap();
|
||||
|
||||
if !global.is_internal() {
|
||||
None
|
||||
} else {
|
||||
Some(global)
|
||||
}
|
||||
} else {
|
||||
// Create automatic global module
|
||||
mods.push(crate::engine::KEYWORD_GLOBAL, Module::new());
|
||||
mods.len() - 1
|
||||
let mut global = Module::new();
|
||||
global.set_internal(true);
|
||||
mods.push(crate::engine::KEYWORD_GLOBAL, global);
|
||||
Some(mods.get_mut(mods.len() - 1).unwrap())
|
||||
};
|
||||
|
||||
let global = mods.get_mut(index).unwrap();
|
||||
let global = Shared::get_mut(global).unwrap();
|
||||
global.set_var(name.clone(), value.clone());
|
||||
global.build_index();
|
||||
if let Some(global) = global {
|
||||
let global = Shared::get_mut(global).unwrap();
|
||||
global.set_var(name.clone(), value.clone());
|
||||
global.build_index();
|
||||
}
|
||||
}
|
||||
|
||||
(
|
||||
|
@ -128,6 +128,8 @@ fn calc_native_fn_hash<'a>(
|
||||
pub struct Module {
|
||||
/// ID identifying the module.
|
||||
id: Option<Identifier>,
|
||||
/// Is this module internal?
|
||||
internal: bool,
|
||||
/// Sub-modules.
|
||||
modules: BTreeMap<Identifier, Shared<Module>>,
|
||||
/// [`Module`] variables.
|
||||
@ -156,6 +158,7 @@ impl Default for Module {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
id: None,
|
||||
internal: false,
|
||||
modules: Default::default(),
|
||||
variables: Default::default(),
|
||||
all_variables: Default::default(),
|
||||
@ -301,8 +304,45 @@ impl Module {
|
||||
/// assert_eq!(module.id(), Some("hello"));
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub fn set_id<S: Into<Identifier>>(&mut self, id: Option<S>) {
|
||||
pub fn set_id<S: Into<Identifier>>(&mut self, id: Option<S>) -> &mut Self {
|
||||
self.id = id.map(|s| s.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Is the [`Module`] internal?
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use rhai::Module;
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// assert!(!module.is_internal());
|
||||
/// module.set_internal(true);
|
||||
/// assert!(module.is_internal());
|
||||
/// ```
|
||||
#[allow(dead_code)]
|
||||
#[inline(always)]
|
||||
pub(crate) fn is_internal(&self) -> bool {
|
||||
self.internal
|
||||
}
|
||||
|
||||
/// Set the interal status of the [`Module`].
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use rhai::Module;
|
||||
///
|
||||
/// let mut module = Module::new();
|
||||
/// assert!(!module.is_internal());
|
||||
/// module.set_internal(true);
|
||||
/// assert!(module.is_internal());
|
||||
/// ```
|
||||
#[inline(always)]
|
||||
pub(crate) fn set_internal(&mut self, value: bool) -> &mut Self {
|
||||
self.internal = value;
|
||||
self
|
||||
}
|
||||
|
||||
/// Is the [`Module`] empty?
|
||||
|
Loading…
Reference in New Issue
Block a user