From d3a97dc86b1e8e738939021b197d560b37575104 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Mon, 27 Apr 2020 22:49:09 +0800 Subject: [PATCH] Remove EntryRef from Scope. --- src/engine.rs | 40 ++++++++++------------------------------ src/scope.rs | 35 ++++++++--------------------------- 2 files changed, 18 insertions(+), 57 deletions(-) diff --git a/src/engine.rs b/src/engine.rs index 8023a6a8..4fd38ab6 100644 --- a/src/engine.rs +++ b/src/engine.rs @@ -7,7 +7,7 @@ use crate::optimize::OptimizationLevel; use crate::packages::{CorePackage, Package, PackageLibrary, StandardPackage}; use crate::parser::{Expr, FnDef, ReturnType, Stmt}; use crate::result::EvalAltResult; -use crate::scope::{EntryRef as ScopeSource, EntryType as ScopeEntryType, Scope}; +use crate::scope::{EntryType as ScopeEntryType, Scope}; use crate::token::Position; use crate::stdlib::{ @@ -439,11 +439,11 @@ fn search_scope<'a>( name: &str, begin: Position, ) -> Result<(&'a mut Dynamic, ScopeEntryType), Box> { - let ScopeSource { typ, index, .. } = scope + let (index, typ) = scope .get(name) .ok_or_else(|| Box::new(EvalAltResult::ErrorVariableNotFound(name.into(), begin)))?; - Ok((scope.get_mut(ScopeSource { name, typ, index }), typ)) + Ok((scope.get_mut(index), typ)) } impl Engine { @@ -517,9 +517,6 @@ impl Engine { return Err(Box::new(EvalAltResult::ErrorStackOverflow(pos))); } - #[cfg(feature = "no_function")] - const fn_lib: &FunctionsLib = None; - // First search in script-defined functions (can override built-in) if let Some(fn_def) = fn_lib.get_function(fn_name, args.len()) { return self.call_fn_from_lib(scope, fn_lib, fn_def, args, pos, level); @@ -1152,27 +1149,15 @@ impl Engine { ))) } - Some( - entry - @ - ScopeSource { - typ: ScopeEntryType::Normal, - .. - }, - ) => { + Some((index, ScopeEntryType::Normal)) => { // Avoid referencing scope which is used below as mut - let entry = ScopeSource { name, ..entry }; - *scope.get_mut(entry) = rhs_val.clone(); + *scope.get_mut(index) = rhs_val.clone(); Ok(rhs_val) } - Some(ScopeSource { - typ: ScopeEntryType::Constant, - .. - }) => Err(Box::new(EvalAltResult::ErrorAssignmentToConstant( - name.to_string(), - *op_pos, - ))), + Some((_, ScopeEntryType::Constant)) => Err(Box::new( + EvalAltResult::ErrorAssignmentToConstant(name.to_string(), *op_pos), + )), }, // idx_lhs[idx_expr] = rhs @@ -1402,15 +1387,10 @@ impl Engine { }) { // Add the loop variable scope.push(name.clone(), ()); - - let entry = ScopeSource { - name, - index: scope.len() - 1, - typ: ScopeEntryType::Normal, - }; + let index = scope.len() - 1; for a in iter_fn(arr) { - *scope.get_mut(entry) = a; + *scope.get_mut(index) = a; match self.eval_stmt(scope, fn_lib, body, level) { Ok(_) => (), diff --git a/src/scope.rs b/src/scope.rs index de57e8c2..2f6ca0c2 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -28,14 +28,6 @@ pub struct Entry<'a> { pub expr: Option>, } -/// Information about a particular entry in the Scope. -#[derive(Debug, Hash, Copy, Clone)] -pub(crate) struct EntryRef<'a> { - pub name: &'a str, - pub index: usize, - pub typ: EntryType, -} - /// A type containing information about the current scope. /// Useful for keeping state between `Engine` evaluation runs. /// @@ -291,18 +283,14 @@ impl<'a> Scope<'a> { } /// Find an entry in the Scope, starting from the last. - pub(crate) fn get(&self, name: &str) -> Option { + pub(crate) fn get(&self, name: &str) -> Option<(usize, EntryType)> { self.0 .iter() .enumerate() .rev() // Always search a Scope in reverse order .find_map(|(index, Entry { name: key, typ, .. })| { if name == key { - Some(EntryRef { - name: key, - index, - typ: *typ, - }) + Some((index, *typ)) } else { None } @@ -352,30 +340,23 @@ impl<'a> Scope<'a> { /// ``` pub fn set_value(&mut self, name: &'a str, value: T) { match self.get(name) { - Some(EntryRef { - typ: EntryType::Constant, - .. - }) => panic!("variable {} is constant", name), - Some(EntryRef { - index, - typ: EntryType::Normal, - .. - }) => self.0.get_mut(index).unwrap().value = Dynamic::from(value), + Some((_, EntryType::Constant)) => panic!("variable {} is constant", name), + Some((index, EntryType::Normal)) => { + self.0.get_mut(index).unwrap().value = Dynamic::from(value) + } None => self.push(name, value), } } /// Get a mutable reference to an entry in the Scope. - pub(crate) fn get_mut(&mut self, key: EntryRef) -> &mut Dynamic { - let entry = self.0.get_mut(key.index).expect("invalid index in Scope"); - assert_eq!(entry.typ, key.typ, "entry type not matched"); + pub(crate) fn get_mut(&mut self, index: usize) -> &mut Dynamic { + let entry = self.0.get_mut(index).expect("invalid index in Scope"); // assert_ne!( // entry.typ, // EntryType::Constant, // "get mut of constant entry" // ); - assert_eq!(entry.name, key.name, "incorrect key at Scope entry"); &mut entry.value }