More documentation on chained assignment.

This commit is contained in:
Stephen Chung 2020-03-14 14:57:59 +08:00
parent 360fab7760
commit 504fd56f1f
4 changed files with 19 additions and 7 deletions

View File

@ -5,8 +5,7 @@ const MAX_NUMBER_TO_CHECK = 10000; // 1229 primes
let prime_mask = []; let prime_mask = [];
prime_mask.pad(MAX_NUMBER_TO_CHECK, true); prime_mask.pad(MAX_NUMBER_TO_CHECK, true);
prime_mask[0] = false; prime_mask[0] = prime_mask[1] = false;
prime_mask[1] = false;
let total_primes_found = 0; let total_primes_found = 0;

View File

@ -80,7 +80,7 @@ pub use error::{ParseError, ParseErrorType};
pub use fn_register::{RegisterDynamicFn, RegisterFn, RegisterResultFn}; pub use fn_register::{RegisterDynamicFn, RegisterFn, RegisterResultFn};
pub use parser::{Position, AST, FLOAT, INT}; pub use parser::{Position, AST, FLOAT, INT};
pub use result::EvalAltResult; pub use result::EvalAltResult;
pub use scope::Scope; pub use scope::{Scope, ScopeEntry, VariableType};
#[cfg(not(feature = "no_index"))] #[cfg(not(feature = "no_index"))]
pub use engine::Array; pub use engine::Array;

View File

@ -153,12 +153,12 @@ impl AST {
/// Optimize the AST with constants defined in an external Scope. /// Optimize the AST with constants defined in an external Scope.
/// ///
/// Although optimization is performed by default during compilation, sometimes it is necessary to /// Although optimization is performed by default during compilation, sometimes it is necessary to
/// "re"-optimize an AST. For example, when working with constants that are passed in via an /// _re_-optimize an AST. For example, when working with constants that are passed in via an
/// external scope, it will be more efficient to optimize the AST once again to take advantage /// external scope, it will be more efficient to optimize the AST once again to take advantage
/// of the new constants. /// of the new constants.
/// ///
/// With this method, it is no longer necessary to regenerate a large script with hard-coded /// With this method, it is no longer necessary to regenerate a large script with hard-coded
/// constant values. The script AST can be compiled once and stored. During actually evaluation, /// constant values. The script AST can be compiled just once. During actual evaluation,
/// constants are passed into the Engine via an external scope (i.e. with `scope.push_constant(...)`). /// constants are passed into the Engine via an external scope (i.e. with `scope.push_constant(...)`).
/// Then, the AST is cloned and the copy re-optimized before running. /// Then, the AST is cloned and the copy re-optimized before running.
pub fn optimize(self, scope: &Scope) -> Self { pub fn optimize(self, scope: &Scope) -> Self {

View File

@ -8,21 +8,29 @@ use crate::parser::FLOAT;
use std::borrow::Cow; use std::borrow::Cow;
/// Type of a variable in the Scope.
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)]
pub enum VariableType { pub enum VariableType {
/// Normal variable.
Normal, Normal,
/// Immutable constant value.
Constant, Constant,
} }
/// An entry in the Scope.
pub struct ScopeEntry<'a> { pub struct ScopeEntry<'a> {
/// Name of the variable.
pub name: Cow<'a, str>, pub name: Cow<'a, str>,
/// Type of the variable.
pub var_type: VariableType, pub var_type: VariableType,
/// Current value of the variable.
pub value: Dynamic, pub value: Dynamic,
/// A constant expression if the initial value matches one of the recognized types.
pub expr: Option<Expr>, pub expr: Option<Expr>,
} }
/// A type containing information about current scope. /// A type containing information about the current scope.
/// Useful for keeping state between `Engine` runs. /// Useful for keeping state between `Engine` evaluation runs.
/// ///
/// # Example /// # Example
/// ///
@ -76,6 +84,11 @@ impl<'a> Scope<'a> {
} }
/// Add (push) a new constant to the Scope. /// Add (push) a new constant to the Scope.
///
/// Constants are immutable and cannot be assigned to. Their values never change.
/// Constants propagation is a technique used to optimize an AST.
/// However, in order to be used for optimization, constants must be in one of the recognized types:
/// `INT` (default to `i64`, `i32` if `only_i32`), `f64`, `String`, `char` and `bool`.
pub fn push_constant<K: Into<Cow<'a, str>>, T: Any>(&mut self, name: K, value: T) { pub fn push_constant<K: Into<Cow<'a, str>>, T: Any>(&mut self, name: K, value: T) {
let value = value.into_dynamic(); let value = value.into_dynamic();