Search for global variables in global modules.

This commit is contained in:
Stephen Chung 2022-03-27 21:49:34 +08:00
parent 2b10c33b81
commit 5caf20d26b
4 changed files with 25 additions and 9 deletions

View File

@ -32,6 +32,8 @@ Enhancements
* A function `sleep` is added to block the current thread by a specified number of seconds.
* `Scope::set_alias` is added to export a variable under a particular alias name.
* `starts_with` and `ends_with` are added for strings.
* Variables in modules registered via `register_global_module` can now be accessed in the global namespace.
* `Dynamic::into_read_only` is added to convert a `Dynamic` value into constant.
Version 1.5.0

View File

@ -165,11 +165,8 @@ impl Engine {
this_ptr,
level,
};
match resolve_var(
expr.get_variable_name(true).expect("`Expr::Variable`"),
index,
&context,
) {
let var_name = expr.get_variable_name(true).expect("`Expr::Variable`");
match resolve_var(var_name, index, &context) {
Ok(Some(mut result)) => {
result.set_access_mode(AccessMode::ReadOnly);
return Ok((result.into(), var_pos));
@ -184,10 +181,18 @@ impl Engine {
} else {
// Find the variable in the scope
let var_name = expr.get_variable_name(true).expect("`Expr::Variable`");
scope
.get_index(var_name)
.ok_or_else(|| ERR::ErrorVariableNotFound(var_name.to_string(), var_pos))?
.0
match scope.get_index(var_name) {
Some((index, _)) => index,
None => {
return match self.global_modules.iter().find_map(|m| m.get_var(var_name)) {
Some(val) => Ok((val.into(), var_pos)),
None => {
Err(ERR::ErrorVariableNotFound(var_name.to_string(), var_pos).into())
}
}
}
}
};
let val = scope.get_mut_by_index(index);

View File

@ -1051,6 +1051,13 @@ impl Dynamic {
}
self
}
/// Make this [`Dynamic`] read-only (i.e. a constant).
#[inline(always)]
pub fn into_read_only(self) -> Self {
let mut value = self;
value.set_access_mode(AccessMode::ReadOnly);
value
}
/// Is this [`Dynamic`] read-only?
///
/// Constant [`Dynamic`] values are read-only.

View File

@ -85,6 +85,8 @@ fn test_plugins_package() -> Result<(), Box<EvalAltResult>> {
reg_functions!(engine += greet::single(INT, bool, char));
assert_eq!(engine.eval::<INT>("MYSTIC_NUMBER")?, 42);
#[cfg(not(feature = "no_object"))]
{
assert_eq!(engine.eval::<INT>("let a = [1, 2, 3]; a.foo")?, 1);