From 47c4136c25c8ce4755a4daa166cb53a0471fe34b Mon Sep 17 00:00:00 2001 From: Emmanuel Benoit Date: Wed, 11 Jan 2023 08:21:48 +0100 Subject: [PATCH] Interpreter - Refactored instance to avoid runtime borrom problems --- src/interpreter/classes.rs | 10 +++++----- src/interpreter/interpretable.rs | 2 +- src/interpreter/value.rs | 17 ----------------- 3 files changed, 6 insertions(+), 23 deletions(-) diff --git a/src/interpreter/classes.rs b/src/interpreter/classes.rs index 46c4bfc..d89facb 100644 --- a/src/interpreter/classes.rs +++ b/src/interpreter/classes.rs @@ -21,7 +21,7 @@ pub type ClassRef = Rc>; #[derive(Debug, Clone)] pub struct Instance { class: Rc>, - fields: HashMap, + fields: RefCell>, } /* -------------------- * @@ -76,12 +76,12 @@ impl Instance { fn new(class: ClassRef) -> Self { Self { class, - fields: HashMap::default(), + fields: RefCell::new(HashMap::default()), } } pub(super) fn get(&self, this_value: &Value, name: &Token) -> SloxResult { - if let Some(value) = self.fields.get(&name.lexeme) { + if let Some(value) = self.fields.borrow().get(&name.lexeme) { return Ok(value.clone()); } if let Some(method) = self.class.borrow().methods.get(&name.lexeme) { @@ -96,8 +96,8 @@ impl Instance { )) } - pub(super) fn set(&mut self, name: &Token, value: Value) { - self.fields.insert(name.lexeme.clone(), value); + pub(super) fn set(&self, name: &Token, value: Value) { + self.fields.borrow_mut().insert(name.lexeme.clone(), value); } fn bind_method(&self, method: &Function, this_value: &Value) -> Function { diff --git a/src/interpreter/interpretable.rs b/src/interpreter/interpretable.rs index 8b39932..adc500b 100644 --- a/src/interpreter/interpretable.rs +++ b/src/interpreter/interpretable.rs @@ -553,7 +553,7 @@ impl ExprNode { set_expr: &SetExpr, ) -> InterpreterResult { let instance = set_expr.instance.interpret(itpr_state)?.result(); - instance.with_instance_mut( + instance.with_instance( |instance| { let value = set_expr.value.interpret(itpr_state)?.result(); instance.set(&set_expr.name, value.clone()); diff --git a/src/interpreter/value.rs b/src/interpreter/value.rs index 7f1b8cd..285170a 100644 --- a/src/interpreter/value.rs +++ b/src/interpreter/value.rs @@ -75,23 +75,6 @@ impl Value { _ => ferr(), } } - - /// Run some code against a mutable instance value. If the value does - /// not contain an instance, an error function will be called instead. - pub fn with_instance_mut(&self, fok: Fok, ferr: Ferr) -> Rt - where - Fok: FnOnce(&mut Instance) -> Rt, - Ferr: FnOnce() -> Rt, - { - let mut obj = match self { - Value::Object(obj_ref) => obj_ref.borrow_mut(), - _ => return ferr(), - }; - match &mut *obj { - Object::Instance(inst) => fok(inst), - _ => ferr(), - } - } } impl PartialEq for Value {