diff --git a/RELEASES.md b/RELEASES.md index aec6810f..ac4ddd40 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -8,6 +8,7 @@ Bug fixes --------- * Constants are no longer propagated by the optimizer if shadowed by a non-constant variable. +* Constants passed as the `this` parameter to Rhai functions now throws an error if assigned to. Version 0.19.7 diff --git a/src/ast.rs b/src/ast.rs index 14156b88..140a7cd8 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -1,6 +1,6 @@ //! Module defining the AST (abstract syntax tree). -use crate::dynamic::{AccessType, Union}; +use crate::dynamic::{AccessMode, Union}; use crate::fn_native::shared_make_mut; use crate::module::NamespaceRef; use crate::stdlib::{ @@ -942,7 +942,7 @@ impl Expr { Self::StringConstant(x, _) => x.clone().into(), Self::FnPointer(x, _) => Dynamic(Union::FnPtr( Box::new(FnPtr::new_unchecked(x.clone(), Default::default())), - AccessType::Constant, + AccessMode::ReadOnly, )), Self::BoolConstant(x, _) => (*x).into(), Self::Unit(_) => ().into(), @@ -954,7 +954,7 @@ impl Expr { x.len(), )); arr.extend(x.iter().map(|v| v.get_constant_value().unwrap())); - Dynamic(Union::Array(Box::new(arr), AccessType::Constant)) + Dynamic(Union::Array(Box::new(arr), AccessMode::ReadOnly)) } #[cfg(not(feature = "no_object"))] @@ -967,7 +967,7 @@ impl Expr { x.iter() .map(|(k, v)| (k.name.clone(), v.get_constant_value().unwrap())), ); - Dynamic(Union::Map(Box::new(map), AccessType::Constant)) + Dynamic(Union::Map(Box::new(map), AccessMode::ReadOnly)) } _ => return None, diff --git a/src/dynamic.rs b/src/dynamic.rs index 750c07c6..e5880ea5 100644 --- a/src/dynamic.rs +++ b/src/dynamic.rs @@ -116,21 +116,21 @@ impl dyn Variant { } } -/// Type of an entry in the Scope. +/// Modes of access. #[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)] -pub enum AccessType { - /// Normal value. - Normal, - /// Immutable constant value. - Constant, +pub enum AccessMode { + /// Mutable. + ReadWrite, + /// Immutable. + ReadOnly, } -impl AccessType { - /// Is the access type [`Constant`]? - pub fn is_constant(self) -> bool { +impl AccessMode { + /// Is the access type [`ReadOnly`]? + pub fn is_read_only(self) -> bool { match self { - Self::Normal => false, - Self::Constant => true, + Self::ReadWrite => false, + Self::ReadOnly => true, } } } @@ -142,25 +142,25 @@ pub struct Dynamic(pub(crate) Union); /// /// Most variants are boxed to reduce the size. pub enum Union { - Unit((), AccessType), - Bool(bool, AccessType), - Str(ImmutableString, AccessType), - Char(char, AccessType), - Int(INT, AccessType), + Unit((), AccessMode), + Bool(bool, AccessMode), + Str(ImmutableString, AccessMode), + Char(char, AccessMode), + Int(INT, AccessMode), #[cfg(not(feature = "no_float"))] - Float(FLOAT, AccessType), + Float(FLOAT, AccessMode), #[cfg(not(feature = "no_index"))] - Array(Box, AccessType), + Array(Box, AccessMode), #[cfg(not(feature = "no_object"))] - Map(Box, AccessType), - FnPtr(Box, AccessType), + Map(Box, AccessMode), + FnPtr(Box, AccessMode), #[cfg(not(feature = "no_std"))] - TimeStamp(Box, AccessType), + TimeStamp(Box, AccessMode), - Variant(Box>, AccessType), + Variant(Box>, AccessMode), #[cfg(not(feature = "no_closure"))] - Shared(crate::Shared>, AccessType), + Shared(crate::Shared>, AccessMode), } /// Underlying [`Variant`] read guard for [`Dynamic`]. @@ -506,27 +506,27 @@ impl Clone for Dynamic { /// The cloned copy is marked [`AccessType::Normal`] even if the original is constant. fn clone(&self) -> Self { match self.0 { - Union::Unit(value, _) => Self(Union::Unit(value, AccessType::Normal)), - Union::Bool(value, _) => Self(Union::Bool(value, AccessType::Normal)), - Union::Str(ref value, _) => Self(Union::Str(value.clone(), AccessType::Normal)), - Union::Char(value, _) => Self(Union::Char(value, AccessType::Normal)), - Union::Int(value, _) => Self(Union::Int(value, AccessType::Normal)), + Union::Unit(value, _) => Self(Union::Unit(value, AccessMode::ReadWrite)), + Union::Bool(value, _) => Self(Union::Bool(value, AccessMode::ReadWrite)), + Union::Str(ref value, _) => Self(Union::Str(value.clone(), AccessMode::ReadWrite)), + Union::Char(value, _) => Self(Union::Char(value, AccessMode::ReadWrite)), + Union::Int(value, _) => Self(Union::Int(value, AccessMode::ReadWrite)), #[cfg(not(feature = "no_float"))] - Union::Float(value, _) => Self(Union::Float(value, AccessType::Normal)), + Union::Float(value, _) => Self(Union::Float(value, AccessMode::ReadWrite)), #[cfg(not(feature = "no_index"))] - Union::Array(ref value, _) => Self(Union::Array(value.clone(), AccessType::Normal)), + Union::Array(ref value, _) => Self(Union::Array(value.clone(), AccessMode::ReadWrite)), #[cfg(not(feature = "no_object"))] - Union::Map(ref value, _) => Self(Union::Map(value.clone(), AccessType::Normal)), - Union::FnPtr(ref value, _) => Self(Union::FnPtr(value.clone(), AccessType::Normal)), + Union::Map(ref value, _) => Self(Union::Map(value.clone(), AccessMode::ReadWrite)), + Union::FnPtr(ref value, _) => Self(Union::FnPtr(value.clone(), AccessMode::ReadWrite)), #[cfg(not(feature = "no_std"))] Union::TimeStamp(ref value, _) => { - Self(Union::TimeStamp(value.clone(), AccessType::Normal)) + Self(Union::TimeStamp(value.clone(), AccessMode::ReadWrite)) } Union::Variant(ref value, _) => (***value).clone_into_dynamic(), #[cfg(not(feature = "no_closure"))] - Union::Shared(ref cell, _) => Self(Union::Shared(cell.clone(), AccessType::Normal)), + Union::Shared(ref cell, _) => Self(Union::Shared(cell.clone(), AccessMode::ReadWrite)), } } } @@ -540,29 +540,29 @@ impl Default for Dynamic { impl Dynamic { /// A [`Dynamic`] containing a `()`. - pub const UNIT: Dynamic = Self(Union::Unit((), AccessType::Normal)); + pub const UNIT: Dynamic = Self(Union::Unit((), AccessMode::ReadWrite)); /// A [`Dynamic`] containing a `true`. - pub const TRUE: Dynamic = Self(Union::Bool(true, AccessType::Normal)); + pub const TRUE: Dynamic = Self(Union::Bool(true, AccessMode::ReadWrite)); /// A [`Dynamic`] containing a [`false`]. - pub const FALSE: Dynamic = Self(Union::Bool(false, AccessType::Normal)); + pub const FALSE: Dynamic = Self(Union::Bool(false, AccessMode::ReadWrite)); /// A [`Dynamic`] containing the integer zero. - pub const ZERO: Dynamic = Self(Union::Int(0, AccessType::Normal)); + pub const ZERO: Dynamic = Self(Union::Int(0, AccessMode::ReadWrite)); /// A [`Dynamic`] containing the integer one. - pub const ONE: Dynamic = Self(Union::Int(1, AccessType::Normal)); + pub const ONE: Dynamic = Self(Union::Int(1, AccessMode::ReadWrite)); /// A [`Dynamic`] containing the integer negative one. - pub const NEGATIVE_ONE: Dynamic = Self(Union::Int(-1, AccessType::Normal)); + pub const NEGATIVE_ONE: Dynamic = Self(Union::Int(-1, AccessMode::ReadWrite)); /// A [`Dynamic`] containing the floating-point zero. #[cfg(not(feature = "no_float"))] - pub const FLOAT_ZERO: Dynamic = Self(Union::Float(0.0, AccessType::Normal)); + pub const FLOAT_ZERO: Dynamic = Self(Union::Float(0.0, AccessMode::ReadWrite)); /// A [`Dynamic`] containing the floating-point one. #[cfg(not(feature = "no_float"))] - pub const FLOAT_ONE: Dynamic = Self(Union::Float(1.0, AccessType::Normal)); + pub const FLOAT_ONE: Dynamic = Self(Union::Float(1.0, AccessMode::ReadWrite)); /// A [`Dynamic`] containing the floating-point negative one. #[cfg(not(feature = "no_float"))] - pub const FLOAT_NEGATIVE_ONE: Dynamic = Self(Union::Float(-1.0, AccessType::Normal)); + pub const FLOAT_NEGATIVE_ONE: Dynamic = Self(Union::Float(-1.0, AccessMode::ReadWrite)); - /// Get the [`AccessType`] for this [`Dynamic`]. - pub(crate) fn access_type(&self) -> AccessType { + /// Get the [`AccessMode`] for this [`Dynamic`]. + pub(crate) fn access_mode(&self) -> AccessMode { match self.0 { Union::Unit(_, access) | Union::Bool(_, access) @@ -584,8 +584,8 @@ impl Dynamic { Union::Shared(_, access) => access, } } - /// Set the [`AccessType`] for this [`Dynamic`]. - pub(crate) fn set_access_type(&mut self, typ: AccessType) { + /// Set the [`AccessMode`] for this [`Dynamic`]. + pub(crate) fn set_access_mode(&mut self, typ: AccessMode) { match &mut self.0 { Union::Unit(_, access) | Union::Bool(_, access) @@ -615,7 +615,7 @@ impl Dynamic { /// if its value is going to be modified. This safe-guards constant values from being modified /// from within Rust functions. pub fn is_read_only(&self) -> bool { - self.access_type().is_constant() + self.access_mode().is_read_only() } /// Create a [`Dynamic`] from any type. A [`Dynamic`] value is simply returned as is. /// @@ -733,7 +733,7 @@ impl Dynamic { } } - Self(Union::Variant(Box::new(boxed), AccessType::Normal)) + Self(Union::Variant(Box::new(boxed), AccessMode::ReadWrite)) } /// Turn the [`Dynamic`] value into a shared [`Dynamic`] value backed by an [`Rc`][std::rc::Rc]`<`[`RefCell`][std::cell::RefCell]`<`[`Dynamic`]`>>` /// or [`Arc`][std::sync::Arc]`<`[`RwLock`][std::sync::RwLock]`<`[`Dynamic`]`>>` depending on the `sync` feature. @@ -750,7 +750,7 @@ impl Dynamic { /// Panics under the `no_closure` feature. #[inline(always)] pub fn into_shared(self) -> Self { - let _access = self.access_type(); + let _access = self.access_mode(); #[cfg(not(feature = "no_closure"))] return match self.0 { @@ -1338,38 +1338,38 @@ impl Dynamic { impl From<()> for Dynamic { #[inline(always)] fn from(value: ()) -> Self { - Self(Union::Unit(value, AccessType::Normal)) + Self(Union::Unit(value, AccessMode::ReadWrite)) } } impl From for Dynamic { #[inline(always)] fn from(value: bool) -> Self { - Self(Union::Bool(value, AccessType::Normal)) + Self(Union::Bool(value, AccessMode::ReadWrite)) } } impl From for Dynamic { #[inline(always)] fn from(value: INT) -> Self { - Self(Union::Int(value, AccessType::Normal)) + Self(Union::Int(value, AccessMode::ReadWrite)) } } #[cfg(not(feature = "no_float"))] impl From for Dynamic { #[inline(always)] fn from(value: FLOAT) -> Self { - Self(Union::Float(value, AccessType::Normal)) + Self(Union::Float(value, AccessMode::ReadWrite)) } } impl From for Dynamic { #[inline(always)] fn from(value: char) -> Self { - Self(Union::Char(value, AccessType::Normal)) + Self(Union::Char(value, AccessMode::ReadWrite)) } } impl> From for Dynamic { #[inline(always)] fn from(value: S) -> Self { - Self(Union::Str(value.into(), AccessType::Normal)) + Self(Union::Str(value.into(), AccessMode::ReadWrite)) } } #[cfg(not(feature = "no_index"))] @@ -1378,7 +1378,7 @@ impl From> for Dynamic { fn from(value: crate::stdlib::vec::Vec) -> Self { Self(Union::Array( Box::new(value.into_iter().map(Dynamic::from).collect()), - AccessType::Normal, + AccessMode::ReadWrite, )) } } @@ -1388,7 +1388,7 @@ impl From<&[T]> for Dynamic { fn from(value: &[T]) -> Self { Self(Union::Array( Box::new(value.iter().cloned().map(Dynamic::from).collect()), - AccessType::Normal, + AccessMode::ReadWrite, )) } } @@ -1405,26 +1405,26 @@ impl, T: Variant + Clone> From for Dynamic { #[inline(always)] fn from(value: FnPtr) -> Self { - Self(Union::FnPtr(Box::new(value), AccessType::Normal)) + Self(Union::FnPtr(Box::new(value), AccessMode::ReadWrite)) } } impl From> for Dynamic { #[inline(always)] fn from(value: Box) -> Self { - Self(Union::FnPtr(value, AccessType::Normal)) + Self(Union::FnPtr(value, AccessMode::ReadWrite)) } } #[cfg(not(feature = "no_std"))] impl From for Dynamic { #[inline(always)] fn from(value: Instant) -> Self { - Self(Union::TimeStamp(Box::new(value), AccessType::Normal)) + Self(Union::TimeStamp(Box::new(value), AccessMode::ReadWrite)) } } diff --git a/src/engine.rs b/src/engine.rs index 7fcb0dbd..e42d06ac 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -1,7 +1,7 @@ //! Main module defining the script evaluation [`Engine`]. use crate::ast::{Expr, FnCallExpr, Ident, IdentX, ReturnType, Stmt}; -use crate::dynamic::{map_std_type_name, AccessType, Union, Variant}; +use crate::dynamic::{map_std_type_name, AccessMode, Union, Variant}; use crate::fn_call::run_builtin_op_assignment; use crate::fn_native::{CallableFunction, Callback, IteratorFn, OnVarCallback}; use crate::module::NamespaceRef; @@ -850,7 +850,7 @@ impl Engine { // Module variables are constant let mut target = target.clone(); - target.set_access_type(AccessType::Constant); + target.set_access_mode(AccessMode::ReadOnly); Ok((target.into(), name, *pos)) } // Normal variable access @@ -905,7 +905,7 @@ impl Engine { if let Some(mut result) = resolve_var(name, index, &context).map_err(|err| err.fill_position(*pos))? { - result.set_access_type(AccessType::Constant); + result.set_access_mode(AccessMode::ReadOnly); return Ok((result.into(), name, *pos)); } } @@ -1732,7 +1732,7 @@ impl Engine { for item in x.as_ref() { arr.push(self.eval_expr(scope, mods, state, lib, this_ptr, item, level)?); } - Ok(Dynamic(Union::Array(Box::new(arr), AccessType::Normal))) + Ok(Dynamic(Union::Array(Box::new(arr), AccessMode::ReadWrite))) } #[cfg(not(feature = "no_object"))] @@ -1745,7 +1745,7 @@ impl Engine { self.eval_expr(scope, mods, state, lib, this_ptr, expr, level)?, ); } - Ok(Dynamic(Union::Map(Box::new(map), AccessType::Normal))) + Ok(Dynamic(Union::Map(Box::new(map), AccessMode::ReadWrite))) } // Normal function call @@ -2289,8 +2289,8 @@ impl Engine { // Let/const statement Stmt::Let(var_def, expr, export, _) | Stmt::Const(var_def, expr, export, _) => { let entry_type = match stmt { - Stmt::Let(_, _, _, _) => AccessType::Normal, - Stmt::Const(_, _, _, _) => AccessType::Constant, + Stmt::Let(_, _, _, _) => AccessMode::ReadWrite, + Stmt::Const(_, _, _, _) => AccessMode::ReadOnly, _ => unreachable!(), }; @@ -2384,7 +2384,7 @@ impl Engine { #[cfg(not(feature = "no_closure"))] Stmt::Share(x) => { match scope.get_index(&x.name) { - Some((index, AccessType::Normal)) => { + Some((index, AccessMode::ReadWrite)) => { let val = scope.get_mut(index); if !val.is_shared() { diff --git a/src/optimize.rs b/src/optimize.rs index 77a60e46..f04dda40 100644 --- a/src/optimize.rs +++ b/src/optimize.rs @@ -1,7 +1,7 @@ //! Module implementing the [`AST`] optimizer. use crate::ast::{Expr, ScriptFnDef, Stmt}; -use crate::dynamic::AccessType; +use crate::dynamic::AccessMode; use crate::engine::{KEYWORD_DEBUG, KEYWORD_EVAL, KEYWORD_PRINT, KEYWORD_TYPE_OF}; use crate::fn_call::run_builtin_binary_op; use crate::parser::map_dynamic_to_expr; @@ -59,7 +59,7 @@ struct State<'a> { /// Has the [`AST`] been changed during this pass? changed: bool, /// Collection of constants to use for eager function evaluations. - variables: Vec<(String, AccessType, Expr)>, + variables: Vec<(String, AccessMode, Expr)>, /// An [`Engine`] instance for eager function evaluation. engine: &'a Engine, /// [Module] containing script-defined functions. @@ -102,7 +102,7 @@ impl<'a> State<'a> { } /// Add a new constant to the list. #[inline(always)] - pub fn push_var(&mut self, name: &str, access: AccessType, value: Expr) { + pub fn push_var(&mut self, name: &str, access: AccessMode, value: Expr) { self.variables.push((name.into(), access, value)) } /// Look up a constant from the list. @@ -110,7 +110,7 @@ impl<'a> State<'a> { pub fn find_constant(&self, name: &str) -> Option<&Expr> { for (n, access, expr) in self.variables.iter().rev() { if n == name { - return if access.is_constant() { + return if access.is_read_only() { Some(expr) } else { None @@ -163,14 +163,18 @@ fn optimize_stmt_block( statements.iter_mut().for_each(|stmt| match stmt { // Add constant literals into the state Stmt::Const(var_def, Some(expr), _, _) if expr.is_constant() => { - state.push_var(&var_def.name, AccessType::Constant, mem::take(expr)); + state.push_var(&var_def.name, AccessMode::ReadOnly, mem::take(expr)); } Stmt::Const(var_def, None, _, _) => { - state.push_var(&var_def.name, AccessType::Constant, Expr::Unit(var_def.pos)); + state.push_var(&var_def.name, AccessMode::ReadOnly, Expr::Unit(var_def.pos)); } // Add variables into the state Stmt::Let(var_def, _, _, _) => { - state.push_var(&var_def.name, AccessType::Normal, Expr::Unit(var_def.pos)); + state.push_var( + &var_def.name, + AccessMode::ReadWrite, + Expr::Unit(var_def.pos), + ); } // Optimize the statement _ => optimize_stmt(stmt, state, preserve_result), @@ -749,11 +753,11 @@ fn optimize_top_level( // Add constants and variables from the scope scope.iter().for_each(|(name, constant, value)| { if !constant { - state.push_var(name, AccessType::Normal, Expr::Unit(Position::NONE)); + state.push_var(name, AccessMode::ReadWrite, Expr::Unit(Position::NONE)); } else if let Some(val) = map_dynamic_to_expr(value, Position::NONE) { - state.push_var(name, AccessType::Constant, val); + state.push_var(name, AccessMode::ReadOnly, val); } else { - state.push_var(name, AccessType::Constant, Expr::Unit(Position::NONE)); + state.push_var(name, AccessMode::ReadOnly, Expr::Unit(Position::NONE)); } }); @@ -774,7 +778,7 @@ fn optimize_top_level( optimize_expr(value_expr, &mut state); if value_expr.is_constant() { - state.push_var(&var_def.name, AccessType::Constant, value_expr.clone()); + state.push_var(&var_def.name, AccessMode::ReadOnly, value_expr.clone()); } // Keep it in the global scope @@ -784,10 +788,14 @@ fn optimize_top_level( } } Stmt::Const(var_def, None, _, _) => { - state.push_var(&var_def.name, AccessType::Constant, Expr::Unit(var_def.pos)); + state.push_var(&var_def.name, AccessMode::ReadOnly, Expr::Unit(var_def.pos)); } Stmt::Let(var_def, _, _, _) => { - state.push_var(&var_def.name, AccessType::Normal, Expr::Unit(var_def.pos)); + state.push_var( + &var_def.name, + AccessMode::ReadWrite, + Expr::Unit(var_def.pos), + ); } _ => { // Keep all variable declarations at this level diff --git a/src/parser.rs b/src/parser.rs index 956e197b..34c4f848 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -3,7 +3,7 @@ use crate::ast::{ BinaryExpr, CustomExpr, Expr, FnCallExpr, Ident, IdentX, ReturnType, ScriptFnDef, Stmt, }; -use crate::dynamic::{AccessType, Union}; +use crate::dynamic::{AccessMode, Union}; use crate::engine::{KEYWORD_THIS, MARKER_BLOCK, MARKER_EXPR, MARKER_IDENT}; use crate::module::NamespaceRef; use crate::optimize::optimize_into_ast; @@ -48,7 +48,7 @@ struct ParseState<'e> { /// Interned strings. strings: HashMap, /// Encapsulates a local stack with variable names to simulate an actual runtime scope. - stack: Vec<(ImmutableString, AccessType)>, + stack: Vec<(ImmutableString, AccessMode)>, /// Size of the local variables stack upon entry of the current block scope. entry_stack_len: usize, /// Tracks a list of external variables (variables that are not explicitly declared in the scope). @@ -1290,11 +1290,11 @@ fn make_assignment_stmt<'a>( }, ) = x.as_ref(); match state.stack[(state.stack.len() - index.unwrap().get())].1 { - AccessType::Normal => { + AccessMode::ReadWrite => { Ok(Stmt::Assignment(Box::new((lhs, fn_name.into(), rhs)), pos)) } // Constant values cannot be assigned to - AccessType::Constant => { + AccessMode::ReadOnly => { Err(PERR::AssignmentToConstant(name.to_string()).into_err(*name_pos)) } } @@ -1317,11 +1317,11 @@ fn make_assignment_stmt<'a>( }, ) = x.as_ref(); match state.stack[(state.stack.len() - index.unwrap().get())].1 { - AccessType::Normal => { + AccessMode::ReadWrite => { Ok(Stmt::Assignment(Box::new((lhs, fn_name.into(), rhs)), pos)) } // Constant values cannot be assigned to - AccessType::Constant => { + AccessMode::ReadOnly => { Err(PERR::AssignmentToConstant(name.to_string()).into_err(*name_pos)) } } @@ -1810,7 +1810,7 @@ fn parse_custom_syntax( // Variable searches stop at the first empty variable name. state.stack.resize( state.stack.len() + delta as usize, - ("".into(), AccessType::Normal), + ("".into(), AccessMode::ReadWrite), ); } delta if delta < 0 && state.stack.len() <= delta.abs() as usize => state.stack.clear(), @@ -2109,7 +2109,7 @@ fn parse_for( let loop_var = state.get_interned_string(name.clone()); let prev_stack_len = state.stack.len(); - state.stack.push((loop_var, AccessType::Normal)); + state.stack.push((loop_var, AccessMode::ReadWrite)); settings.is_breakable = true; let body = parse_block(input, state, lib, settings.level_up())?; @@ -2124,7 +2124,7 @@ fn parse_let( input: &mut TokenStream, state: &mut ParseState, lib: &mut FunctionsLib, - var_type: AccessType, + var_type: AccessMode, export: bool, mut settings: ParseSettings, ) -> Result { @@ -2155,16 +2155,16 @@ fn parse_let( match var_type { // let name = expr - AccessType::Normal => { + AccessMode::ReadWrite => { let var_name = state.get_interned_string(name.clone()); - state.stack.push((var_name, AccessType::Normal)); + state.stack.push((var_name, AccessMode::ReadWrite)); let var_def = Ident::new(name, pos); Ok(Stmt::Let(Box::new(var_def), init_expr, export, token_pos)) } // const name = { expr:constant } - AccessType::Constant => { + AccessMode::ReadOnly => { let var_name = state.get_interned_string(name.clone()); - state.stack.push((var_name, AccessType::Constant)); + state.stack.push((var_name, AccessMode::ReadOnly)); let var_def = Ident::new(name, pos); Ok(Stmt::Const(Box::new(var_def), init_expr, export, token_pos)) } @@ -2231,13 +2231,13 @@ fn parse_export( match input.peek().unwrap() { (Token::Let, pos) => { let pos = *pos; - let mut stmt = parse_let(input, state, lib, AccessType::Normal, true, settings)?; + let mut stmt = parse_let(input, state, lib, AccessMode::ReadWrite, true, settings)?; stmt.set_position(pos); return Ok(stmt); } (Token::Const, pos) => { let pos = *pos; - let mut stmt = parse_let(input, state, lib, AccessType::Constant, true, settings)?; + let mut stmt = parse_let(input, state, lib, AccessMode::ReadOnly, true, settings)?; stmt.set_position(pos); return Ok(stmt); } @@ -2392,7 +2392,7 @@ fn parse_stmt( lib: &mut FunctionsLib, mut settings: ParseSettings, ) -> Result, ParseError> { - use AccessType::{Constant, Normal}; + use AccessMode::{ReadOnly, ReadWrite}; let (token, token_pos) = match input.peek().unwrap() { (Token::EOF, pos) => return Ok(Some(Stmt::Noop(*pos))), @@ -2520,9 +2520,9 @@ fn parse_stmt( Token::Try => parse_try_catch(input, state, lib, settings.level_up()).map(Some), - Token::Let => parse_let(input, state, lib, Normal, false, settings.level_up()).map(Some), + Token::Let => parse_let(input, state, lib, ReadWrite, false, settings.level_up()).map(Some), Token::Const => { - parse_let(input, state, lib, Constant, false, settings.level_up()).map(Some) + parse_let(input, state, lib, ReadOnly, false, settings.level_up()).map(Some) } #[cfg(not(feature = "no_module"))] @@ -2636,7 +2636,7 @@ fn parse_fn( return Err(PERR::FnDuplicatedParam(name, s).into_err(pos)); } let s = state.get_interned_string(s); - state.stack.push((s.clone(), AccessType::Normal)); + state.stack.push((s.clone(), AccessMode::ReadWrite)); params.push((s, pos)) } (Token::LexError(err), pos) => return Err(err.into_err(pos)), @@ -2769,7 +2769,7 @@ fn parse_anon_fn( return Err(PERR::FnDuplicatedParam("".to_string(), s).into_err(pos)); } let s = state.get_interned_string(s); - state.stack.push((s.clone(), AccessType::Normal)); + state.stack.push((s.clone(), AccessMode::ReadWrite)); params.push((s, pos)) } (Token::LexError(err), pos) => return Err(err.into_err(pos)), diff --git a/src/scope.rs b/src/scope.rs index 42216538..93b4ba7d 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -1,6 +1,6 @@ //! Module that defines the [`Scope`] type representing a function call-stack scope. -use crate::dynamic::{AccessType, Variant}; +use crate::dynamic::{AccessMode, Variant}; use crate::stdlib::{borrow::Cow, boxed::Box, iter, string::String, vec::Vec}; use crate::{Dynamic, StaticVec}; @@ -156,7 +156,7 @@ impl<'a> Scope<'a> { name: impl Into>, value: impl Variant + Clone, ) -> &mut Self { - self.push_dynamic_value(name, AccessType::Normal, Dynamic::from(value)) + self.push_dynamic_value(name, AccessMode::ReadWrite, Dynamic::from(value)) } /// Add (push) a new [`Dynamic`] entry to the [`Scope`]. /// @@ -172,7 +172,7 @@ impl<'a> Scope<'a> { /// ``` #[inline(always)] pub fn push_dynamic(&mut self, name: impl Into>, value: Dynamic) -> &mut Self { - self.push_dynamic_value(name, value.access_type(), value) + self.push_dynamic_value(name, value.access_mode(), value) } /// Add (push) a new constant to the [`Scope`]. /// @@ -195,7 +195,7 @@ impl<'a> Scope<'a> { name: impl Into>, value: impl Variant + Clone, ) -> &mut Self { - self.push_dynamic_value(name, AccessType::Constant, Dynamic::from(value)) + self.push_dynamic_value(name, AccessMode::ReadOnly, Dynamic::from(value)) } /// Add (push) a new constant with a [`Dynamic`] value to the Scope. /// @@ -218,18 +218,18 @@ impl<'a> Scope<'a> { name: impl Into>, value: Dynamic, ) -> &mut Self { - self.push_dynamic_value(name, AccessType::Constant, value) + self.push_dynamic_value(name, AccessMode::ReadOnly, value) } /// Add (push) a new entry with a [`Dynamic`] value to the [`Scope`]. #[inline] pub(crate) fn push_dynamic_value( &mut self, name: impl Into>, - access: AccessType, + access: AccessMode, mut value: Dynamic, ) -> &mut Self { self.names.push((name.into(), Box::new(Default::default()))); - value.set_access_type(access); + value.set_access_mode(access); self.values.push(value.into()); self } @@ -287,14 +287,14 @@ impl<'a> Scope<'a> { } /// Find an entry in the [`Scope`], starting from the last. #[inline(always)] - pub(crate) fn get_index(&self, name: &str) -> Option<(usize, AccessType)> { + pub(crate) fn get_index(&self, name: &str) -> Option<(usize, AccessMode)> { self.names .iter() .enumerate() .rev() // Always search a Scope in reverse order .find_map(|(index, (key, _))| { if name == key.as_ref() { - Some((index, self.values[index].access_type())) + Some((index, self.values[index].access_mode())) } else { None } @@ -349,8 +349,8 @@ impl<'a> Scope<'a> { None => { self.push(name, value); } - Some((_, AccessType::Constant)) => panic!("variable {} is constant", name), - Some((index, AccessType::Normal)) => { + Some((_, AccessMode::ReadOnly)) => panic!("variable {} is constant", name), + Some((index, AccessMode::ReadWrite)) => { *self.values.get_mut(index).unwrap() = Dynamic::from(value); } }