diff --git a/src/lib/shell/flow_control.rs b/src/lib/shell/flow_control.rs index c8179b1fa789c0ba32daab8a8f0f0f1320ac0f5f..6164189585658354b04c67766be06c1907d7c15e 100644 --- a/src/lib/shell/flow_control.rs +++ b/src/lib/shell/flow_control.rs @@ -190,14 +190,8 @@ impl Function { values.push((type_.clone(), value)); } - let mut index = None; - for (i, scope) in shell.variables.scopes.iter().enumerate().rev() { - if scope.contains_key(&name) { - index = Some(i); - break; - } - } - let index = index.expect("execute called with invalid function"); + let index = shell.variables.index_scope_for_var(&name) + .expect("execute called with invalid function"); // Pop off all scopes since function temporarily let temporary: Vec<_> = shell.variables.pop_scopes(index).collect(); diff --git a/src/lib/shell/variables/mod.rs b/src/lib/shell/variables/mod.rs index dd70a9f1980e9a8ebf35aefa3ef2f90d651918dd..35e9d1dc33770e69b6206d04ea4947daf85f11d9 100644 --- a/src/lib/shell/variables/mod.rs +++ b/src/lib/shell/variables/mod.rs @@ -36,7 +36,7 @@ pub enum VariableType { #[derive(Clone, Debug)] pub struct Variables { flags: u8, - pub scopes: Vec<FnvHashMap<Identifier, VariableType>>, + scopes: Vec<FnvHashMap<Identifier, VariableType>>, current: usize, } @@ -133,6 +133,42 @@ impl Variables { let amount = self.scopes.len() - self.current - 1; self.scopes.iter_mut().rev().skip(amount) } + pub fn index_scope_for_var(&self, name: &str) -> Option<usize> { + let amount = self.scopes.len() - self.current - 1; + for (i, scope) in self.scopes.iter().enumerate().rev().skip(amount) { + if scope.contains_key(name) { + return Some(i); + } + } + None + } + pub fn shadow(&mut self, name: SmallString, value: VariableType) -> Option<VariableType> { + self.scopes.get_mut(self.current).unwrap().insert(name, value) + } + pub fn lookup_any(&self, name: &str) -> Option<&VariableType> { + for scope in self.scopes() { + if let val @ Some(_) = scope.get(name) { + return val; + } + } + None + } + pub fn lookup_any_mut(&mut self, name: &str) -> Option<&mut VariableType> { + for scope in self.scopes_mut() { + if let val @ Some(_) = scope.get_mut(name) { + return val; + } + } + None + } + pub fn remove_any(&mut self, name: &str) -> Option<VariableType> { + for scope in self.scopes_mut() { + if let val @ Some(_) = scope.remove(name) { + return val; + } + } + None + } #[allow(dead_code)] pub(crate) fn is_hashmap_reference(key: &str) -> Option<(Identifier, Key)> { @@ -228,34 +264,6 @@ impl Variables { c.is_alphanumeric() || c == '_' || c == '?' || c == '.' } - pub fn shadow(&mut self, name: SmallString, value: VariableType) -> Option<VariableType> { - self.scopes.get_mut(self.current).unwrap().insert(name, value) - } - pub fn lookup_any(&self, name: &str) -> Option<&VariableType> { - for scope in self.scopes() { - if let val @ Some(_) = scope.get(name) { - return val; - } - } - None - } - pub fn lookup_any_mut(&mut self, name: &str) -> Option<&mut VariableType> { - for scope in self.scopes_mut() { - if let val @ Some(_) = scope.get_mut(name) { - return val; - } - } - None - } - pub fn remove_any(&mut self, name: &str) -> Option<VariableType> { - for scope in self.scopes_mut() { - if let val @ Some(_) = scope.remove(name) { - return val; - } - } - None - } - pub fn variables(&self) -> impl Iterator<Item = (&SmallString, &Value)> { self.scopes() .map(|map| {