rhai/src/eval/eval_context.rs

197 lines
6.2 KiB
Rust
Raw Normal View History

2022-01-07 11:43:47 +08:00
//! Evaluation context.
2022-04-16 16:36:53 +08:00
use super::{Caches, GlobalRuntimeState};
2022-11-19 18:57:15 +08:00
use crate::{Dynamic, Engine, Scope};
2022-01-07 11:43:47 +08:00
#[cfg(feature = "no_std")]
use std::prelude::v1::*;
/// Context of a script evaluation process.
2022-08-19 13:21:47 +08:00
#[derive(Debug)]
2022-07-05 22:59:03 +08:00
#[allow(dead_code)]
pub struct EvalContext<'a, 's, 'ps, 'g, 'c, 't> {
2022-01-07 11:43:47 +08:00
/// The current [`Engine`].
2022-05-17 16:21:17 +08:00
engine: &'a Engine,
2022-01-07 11:43:47 +08:00
/// The current [`GlobalRuntimeState`].
global: &'g mut GlobalRuntimeState,
2022-04-16 23:32:14 +08:00
/// The current [caches][Caches], if available.
2022-11-08 15:01:40 +08:00
caches: &'c mut Caches,
2022-11-10 14:25:48 +08:00
/// The current [`Scope`].
scope: &'s mut Scope<'ps>,
2022-01-07 11:43:47 +08:00
/// The current bound `this` pointer, if any.
this_ptr: &'t mut Dynamic,
2022-01-07 11:43:47 +08:00
}
impl<'a, 's, 'ps, 'g, 'c, 't> EvalContext<'a, 's, 'ps, 'g, 'c, 't> {
2022-05-17 16:21:17 +08:00
/// Create a new [`EvalContext`].
#[inline(always)]
#[must_use]
pub fn new(
engine: &'a Engine,
global: &'g mut GlobalRuntimeState,
2022-11-08 15:01:40 +08:00
caches: &'c mut Caches,
2022-11-04 21:47:09 +08:00
scope: &'s mut Scope<'ps>,
this_ptr: &'t mut Dynamic,
2022-05-17 16:21:17 +08:00
) -> Self {
Self {
engine,
global,
caches,
2022-11-10 14:25:48 +08:00
scope,
2022-05-17 16:21:17 +08:00
this_ptr,
}
}
2022-01-07 11:43:47 +08:00
/// The current [`Engine`].
#[inline(always)]
#[must_use]
2022-05-17 16:21:17 +08:00
pub const fn engine(&self) -> &'a Engine {
2022-01-07 11:43:47 +08:00
self.engine
}
/// The current source.
#[inline(always)]
#[must_use]
pub fn source(&self) -> Option<&str> {
2022-10-29 14:12:18 +08:00
self.global.source()
2022-01-07 11:43:47 +08:00
}
/// The current [`Scope`].
#[inline(always)]
#[must_use]
2022-04-16 23:32:14 +08:00
pub const fn scope(&self) -> &Scope<'ps> {
2022-01-07 11:43:47 +08:00
self.scope
}
2022-01-24 17:04:40 +08:00
/// Get a mutable reference to the current [`Scope`].
2022-01-07 11:43:47 +08:00
#[inline(always)]
#[must_use]
pub fn scope_mut(&mut self) -> &mut Scope<'ps> {
self.scope
2022-01-07 11:43:47 +08:00
}
2022-01-26 22:14:53 +08:00
/// Get an iterator over the current set of modules imported via `import` statements,
/// in reverse order (i.e. modules imported last come first).
2022-01-07 11:43:47 +08:00
#[cfg(not(feature = "no_module"))]
#[inline(always)]
2022-11-19 18:57:15 +08:00
pub fn iter_imports(&self) -> impl Iterator<Item = (&str, &crate::Module)> {
self.global.iter_imports()
2022-01-07 11:43:47 +08:00
}
2022-05-02 00:03:45 +08:00
/// Custom state kept in a [`Dynamic`].
#[inline(always)]
#[must_use]
pub const fn tag(&self) -> &Dynamic {
&self.global.tag
}
/// Mutable reference to the custom state kept in a [`Dynamic`].
#[inline(always)]
#[must_use]
pub fn tag_mut(&mut self) -> &mut Dynamic {
&mut self.global.tag
}
2022-01-07 11:43:47 +08:00
/// _(internals)_ The current [`GlobalRuntimeState`].
/// Exported under the `internals` feature only.
#[cfg(feature = "internals")]
#[inline(always)]
#[must_use]
pub const fn global_runtime_state(&self) -> &GlobalRuntimeState {
self.global
}
2022-01-24 17:04:40 +08:00
/// _(internals)_ Get a mutable reference to the current [`GlobalRuntimeState`].
/// Exported under the `internals` feature only.
#[cfg(feature = "internals")]
#[inline(always)]
#[must_use]
pub fn global_runtime_state_mut(&mut self) -> &mut GlobalRuntimeState {
self.global
2022-01-24 17:04:40 +08:00
}
2022-01-07 11:43:47 +08:00
/// Get an iterator over the namespaces containing definition of all script-defined functions.
2022-11-10 14:25:48 +08:00
///
/// Not available under `no_function`.
#[cfg(not(feature = "no_function"))]
2022-01-07 11:43:47 +08:00
#[inline]
2022-11-19 18:57:15 +08:00
pub fn iter_namespaces(&self) -> impl Iterator<Item = &crate::Module> {
self.global.lib.iter().map(AsRef::as_ref)
2022-01-07 11:43:47 +08:00
}
/// _(internals)_ The current set of namespaces containing definitions of all script-defined functions.
/// Exported under the `internals` feature only.
2022-11-10 14:25:48 +08:00
///
/// Not available under `no_function`.
#[cfg(not(feature = "no_function"))]
2022-01-07 11:43:47 +08:00
#[cfg(feature = "internals")]
#[inline(always)]
#[must_use]
2022-11-10 12:16:23 +08:00
pub fn namespaces(&self) -> &[crate::SharedModule] {
2022-11-10 11:49:10 +08:00
&self.global.lib
2022-01-07 11:43:47 +08:00
}
/// The current bound `this` pointer, if any.
#[inline]
2022-01-07 11:43:47 +08:00
#[must_use]
pub fn this_ptr(&self) -> Option<&Dynamic> {
if self.this_ptr.is_null() {
None
} else {
Some(self.this_ptr)
}
2022-01-07 11:43:47 +08:00
}
/// Mutable reference to the current bound `this` pointer, if any.
#[inline]
2022-01-07 11:43:47 +08:00
#[must_use]
pub fn this_ptr_mut(&mut self) -> Option<&mut Dynamic> {
if self.this_ptr.is_null() {
None
} else {
Some(self.this_ptr)
}
2022-01-07 11:43:47 +08:00
}
/// The current nesting level of function calls.
#[inline(always)]
#[must_use]
pub const fn call_level(&self) -> usize {
2022-11-08 21:28:20 +08:00
self.global.level
2022-01-07 11:43:47 +08:00
}
2022-05-17 16:21:17 +08:00
2022-07-05 22:59:03 +08:00
/// Evaluate an [expression tree][crate::Expression] within this [evaluation context][`EvalContext`].
2022-05-17 16:21:17 +08:00
///
/// # WARNING - Low Level API
///
/// This function is very low level. It evaluates an expression from an [`AST`][crate::AST].
2022-07-05 22:59:03 +08:00
#[cfg(not(feature = "no_custom_syntax"))]
2022-05-17 16:21:17 +08:00
#[inline(always)]
2022-07-05 22:59:03 +08:00
pub fn eval_expression_tree(&mut self, expr: &crate::Expression) -> crate::RhaiResult {
2022-07-06 12:56:15 +08:00
#[allow(deprecated)]
self.eval_expression_tree_raw(expr, true)
}
/// Evaluate an [expression tree][crate::Expression] within this [evaluation context][`EvalContext`].
///
/// The following option is available:
///
/// * whether to rewind the [`Scope`] after evaluation if the expression is a [`StmtBlock`][crate::ast::StmtBlock]
///
/// # WARNING - Unstable API
///
/// This API is volatile and may change in the future.
///
/// # WARNING - Low Level API
///
/// This function is _extremely_ low level. It evaluates an expression from an [`AST`][crate::AST].
#[cfg(not(feature = "no_custom_syntax"))]
#[deprecated = "This API is NOT deprecated, but it is considered volatile and may change in the future."]
#[inline]
pub fn eval_expression_tree_raw(
&mut self,
expr: &crate::Expression,
rewind_scope: bool,
) -> crate::RhaiResult {
let expr: &crate::ast::Expr = expr;
match expr {
2022-07-06 13:13:21 +08:00
crate::ast::Expr::Stmt(statements) => self.engine.eval_stmt_block(
2022-07-06 12:56:15 +08:00
self.global,
2022-11-08 15:01:40 +08:00
self.caches,
2022-11-04 21:47:09 +08:00
self.scope,
2022-07-06 12:56:15 +08:00
self.this_ptr,
2022-07-20 21:16:35 +09:00
statements,
2022-07-06 12:56:15 +08:00
rewind_scope,
),
2022-11-10 11:49:10 +08:00
_ => self
.engine
.eval_expr(self.global, self.caches, self.scope, self.this_ptr, expr),
2022-07-06 12:56:15 +08:00
}
2022-05-17 16:21:17 +08:00
}
2022-01-07 11:43:47 +08:00
}