Remove RefCell in Scope.
This commit is contained in:
parent
ce121ed6af
commit
07c5abcc02
@ -13,7 +13,6 @@ use crate::token::Position;
|
|||||||
use crate::stdlib::{
|
use crate::stdlib::{
|
||||||
any::TypeId,
|
any::TypeId,
|
||||||
boxed::Box,
|
boxed::Box,
|
||||||
cell::RefCell,
|
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
format,
|
format,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
@ -80,8 +79,6 @@ const FUNCTIONS_COUNT: usize = 256;
|
|||||||
enum Target<'a> {
|
enum Target<'a> {
|
||||||
/// The target is a mutable reference to a `Dynamic` value somewhere.
|
/// The target is a mutable reference to a `Dynamic` value somewhere.
|
||||||
Ref(&'a mut Dynamic),
|
Ref(&'a mut Dynamic),
|
||||||
/// The target is a variable stored in the current `Scope`.
|
|
||||||
Scope(&'a RefCell<Dynamic>),
|
|
||||||
/// The target is a temporary `Dynamic` value (i.e. the mutation can cause no side effects).
|
/// The target is a temporary `Dynamic` value (i.e. the mutation can cause no side effects).
|
||||||
Value(Box<Dynamic>),
|
Value(Box<Dynamic>),
|
||||||
/// The target is a character inside a String.
|
/// The target is a character inside a String.
|
||||||
@ -93,7 +90,6 @@ impl Target<'_> {
|
|||||||
pub fn into_dynamic(self) -> Dynamic {
|
pub fn into_dynamic(self) -> Dynamic {
|
||||||
match self {
|
match self {
|
||||||
Target::Ref(r) => r.clone(),
|
Target::Ref(r) => r.clone(),
|
||||||
Target::Scope(r) => r.borrow().clone(),
|
|
||||||
Target::Value(v) => *v,
|
Target::Value(v) => *v,
|
||||||
Target::StringChar(s) => s.2,
|
Target::StringChar(s) => s.2,
|
||||||
}
|
}
|
||||||
@ -102,7 +98,6 @@ impl Target<'_> {
|
|||||||
/// Update the value of the `Target`.
|
/// Update the value of the `Target`.
|
||||||
pub fn set_value(&mut self, new_val: Dynamic, pos: Position) -> Result<(), Box<EvalAltResult>> {
|
pub fn set_value(&mut self, new_val: Dynamic, pos: Position) -> Result<(), Box<EvalAltResult>> {
|
||||||
match self {
|
match self {
|
||||||
Target::Scope(r) => *r.borrow_mut() = new_val,
|
|
||||||
Target::Ref(r) => **r = new_val,
|
Target::Ref(r) => **r = new_val,
|
||||||
Target::Value(_) => {
|
Target::Value(_) => {
|
||||||
return Err(Box::new(EvalAltResult::ErrorAssignmentToUnknownLHS(pos)))
|
return Err(Box::new(EvalAltResult::ErrorAssignmentToUnknownLHS(pos)))
|
||||||
@ -132,11 +127,6 @@ impl Target<'_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<&'a RefCell<Dynamic>> for Target<'a> {
|
|
||||||
fn from(value: &'a RefCell<Dynamic>) -> Self {
|
|
||||||
Self::Scope(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'a> From<&'a mut Dynamic> for Target<'a> {
|
impl<'a> From<&'a mut Dynamic> for Target<'a> {
|
||||||
fn from(value: &'a mut Dynamic) -> Self {
|
fn from(value: &'a mut Dynamic) -> Self {
|
||||||
Self::Ref(value)
|
Self::Ref(value)
|
||||||
@ -395,15 +385,15 @@ fn default_print(s: &str) {
|
|||||||
|
|
||||||
/// Search for a variable within the scope, returning its value and index inside the Scope
|
/// Search for a variable within the scope, returning its value and index inside the Scope
|
||||||
fn search_scope<'a>(
|
fn search_scope<'a>(
|
||||||
scope: &'a Scope,
|
scope: &'a mut Scope,
|
||||||
id: &str,
|
id: &str,
|
||||||
begin: Position,
|
begin: Position,
|
||||||
) -> Result<(&'a RefCell<Dynamic>, ScopeEntryType), Box<EvalAltResult>> {
|
) -> Result<(&'a mut Dynamic, ScopeEntryType), Box<EvalAltResult>> {
|
||||||
let (entry, _) = scope
|
let (ScopeSource { typ, index, .. }, _) = scope
|
||||||
.get(id)
|
.get(id)
|
||||||
.ok_or_else(|| Box::new(EvalAltResult::ErrorVariableNotFound(id.into(), begin)))?;
|
.ok_or_else(|| Box::new(EvalAltResult::ErrorVariableNotFound(id.into(), begin)))?;
|
||||||
|
|
||||||
Ok((&scope.get_ref(entry), entry.typ))
|
Ok((scope.get_mut(ScopeSource { name: id, typ, index }), typ))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Engine {
|
impl Engine {
|
||||||
@ -717,14 +707,8 @@ impl Engine {
|
|||||||
level: usize,
|
level: usize,
|
||||||
mut new_val: Option<Dynamic>,
|
mut new_val: Option<Dynamic>,
|
||||||
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
) -> Result<(Dynamic, bool), Box<EvalAltResult>> {
|
||||||
// Store a copy of the RefMut<Dynamic> from `borrow_mut` since it is a temporary value
|
|
||||||
let mut scope_base = match target {
|
|
||||||
Target::Scope(r) => Some(r.borrow_mut()),
|
|
||||||
Target::Ref(_) | Target::Value(_) | Target::StringChar(_) => None,
|
|
||||||
};
|
|
||||||
// Get a reference to the mutation target Dynamic
|
// Get a reference to the mutation target Dynamic
|
||||||
let obj = match target {
|
let obj = match target {
|
||||||
Target::Scope(_) => scope_base.as_mut().unwrap().deref_mut(),
|
|
||||||
Target::Ref(r) => r,
|
Target::Ref(r) => r,
|
||||||
Target::Value(ref mut r) => r.as_mut(),
|
Target::Value(ref mut r) => r.as_mut(),
|
||||||
Target::StringChar(ref mut x) => &mut x.2,
|
Target::StringChar(ref mut x) => &mut x.2,
|
||||||
@ -1157,7 +1141,7 @@ impl Engine {
|
|||||||
Expr::StringConstant(s, _) => Ok(s.to_string().into()),
|
Expr::StringConstant(s, _) => Ok(s.to_string().into()),
|
||||||
Expr::CharConstant(c, _) => Ok((*c).into()),
|
Expr::CharConstant(c, _) => Ok((*c).into()),
|
||||||
Expr::Variable(id, pos) => {
|
Expr::Variable(id, pos) => {
|
||||||
search_scope(scope, id, *pos).map(|(v, _)| v.borrow().clone())
|
search_scope(scope, id, *pos).map(|(v, _)| v.clone())
|
||||||
}
|
}
|
||||||
Expr::Property(_, _) => panic!("unexpected property."),
|
Expr::Property(_, _) => panic!("unexpected property."),
|
||||||
|
|
||||||
@ -1189,7 +1173,7 @@ impl Engine {
|
|||||||
)) => {
|
)) => {
|
||||||
// Avoid referencing scope which is used below as mut
|
// Avoid referencing scope which is used below as mut
|
||||||
let entry = ScopeSource { name, ..entry };
|
let entry = ScopeSource { name, ..entry };
|
||||||
*scope.get_ref(entry).borrow_mut() = rhs_val.clone();
|
*scope.get_mut(entry) = rhs_val.clone();
|
||||||
Ok(rhs_val)
|
Ok(rhs_val)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1440,7 +1424,7 @@ impl Engine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
for a in iter_fn(arr) {
|
for a in iter_fn(arr) {
|
||||||
*scope.get_ref(entry).borrow_mut() = a;
|
*scope.get_mut(entry) = a;
|
||||||
|
|
||||||
match self.eval_stmt(scope, fn_lib, body, level) {
|
match self.eval_stmt(scope, fn_lib, body, level) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
|
16
src/scope.rs
16
src/scope.rs
@ -4,7 +4,7 @@ use crate::any::{Dynamic, Variant};
|
|||||||
use crate::parser::{map_dynamic_to_expr, Expr};
|
use crate::parser::{map_dynamic_to_expr, Expr};
|
||||||
use crate::token::Position;
|
use crate::token::Position;
|
||||||
|
|
||||||
use crate::stdlib::{borrow::Cow, cell::RefCell, iter, vec::Vec};
|
use crate::stdlib::{borrow::Cow, iter, vec::Vec};
|
||||||
|
|
||||||
/// Type of an entry in the Scope.
|
/// Type of an entry in the Scope.
|
||||||
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)]
|
#[derive(Debug, Eq, PartialEq, Hash, Copy, Clone)]
|
||||||
@ -23,7 +23,7 @@ pub struct Entry<'a> {
|
|||||||
/// Type of the entry.
|
/// Type of the entry.
|
||||||
pub typ: EntryType,
|
pub typ: EntryType,
|
||||||
/// Current value of the entry.
|
/// Current value of the entry.
|
||||||
pub value: RefCell<Dynamic>,
|
pub value: Dynamic,
|
||||||
/// A constant expression if the initial value matches one of the recognized types.
|
/// A constant expression if the initial value matches one of the recognized types.
|
||||||
pub expr: Option<Expr>,
|
pub expr: Option<Expr>,
|
||||||
}
|
}
|
||||||
@ -313,7 +313,7 @@ impl<'a> Scope<'a> {
|
|||||||
index,
|
index,
|
||||||
typ: *typ,
|
typ: *typ,
|
||||||
},
|
},
|
||||||
value.borrow().clone(),
|
value.clone(),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -339,7 +339,7 @@ impl<'a> Scope<'a> {
|
|||||||
.iter()
|
.iter()
|
||||||
.rev()
|
.rev()
|
||||||
.find(|Entry { name: key, .. }| name == key)
|
.find(|Entry { name: key, .. }| name == key)
|
||||||
.and_then(|Entry { value, .. }| value.borrow().downcast_ref::<T>().cloned())
|
.and_then(|Entry { value, .. }| value.downcast_ref::<T>().cloned())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Update the value of the named entry.
|
/// Update the value of the named entry.
|
||||||
@ -379,14 +379,14 @@ impl<'a> Scope<'a> {
|
|||||||
..
|
..
|
||||||
},
|
},
|
||||||
_,
|
_,
|
||||||
)) => *self.0.get_mut(index).unwrap().value.borrow_mut() = Dynamic::from(value),
|
)) => self.0.get_mut(index).unwrap().value = Dynamic::from(value),
|
||||||
None => self.push(name, value),
|
None => self.push(name, value),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a mutable reference to an entry in the Scope.
|
/// Get a mutable reference to an entry in the Scope.
|
||||||
pub(crate) fn get_ref(&self, key: EntryRef) -> &RefCell<Dynamic> {
|
pub(crate) fn get_mut(&mut self, key: EntryRef) -> &mut Dynamic {
|
||||||
let entry = self.0.get(key.index).expect("invalid index in Scope");
|
let entry = self.0.get_mut(key.index).expect("invalid index in Scope");
|
||||||
assert_eq!(entry.typ, key.typ, "entry type not matched");
|
assert_eq!(entry.typ, key.typ, "entry type not matched");
|
||||||
|
|
||||||
// assert_ne!(
|
// assert_ne!(
|
||||||
@ -396,7 +396,7 @@ impl<'a> Scope<'a> {
|
|||||||
// );
|
// );
|
||||||
assert_eq!(entry.name, key.name, "incorrect key at Scope entry");
|
assert_eq!(entry.name, key.name, "incorrect key at Scope entry");
|
||||||
|
|
||||||
&entry.value
|
&mut entry.value
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get an iterator to entries in the Scope.
|
/// Get an iterator to entries in the Scope.
|
||||||
|
Loading…
Reference in New Issue
Block a user