Interpreter - Refactored instance to avoid runtime borrom problems
This commit is contained in:
parent
c4f0f0f721
commit
47c4136c25
3 changed files with 6 additions and 23 deletions
|
@ -21,7 +21,7 @@ pub type ClassRef = Rc<RefCell<Class>>;
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Instance {
|
pub struct Instance {
|
||||||
class: Rc<RefCell<Class>>,
|
class: Rc<RefCell<Class>>,
|
||||||
fields: HashMap<String, Value>,
|
fields: RefCell<HashMap<String, Value>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------- *
|
/* -------------------- *
|
||||||
|
@ -76,12 +76,12 @@ impl Instance {
|
||||||
fn new(class: ClassRef) -> Self {
|
fn new(class: ClassRef) -> Self {
|
||||||
Self {
|
Self {
|
||||||
class,
|
class,
|
||||||
fields: HashMap::default(),
|
fields: RefCell::new(HashMap::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn get(&self, this_value: &Value, name: &Token) -> SloxResult<Value> {
|
pub(super) fn get(&self, this_value: &Value, name: &Token) -> SloxResult<Value> {
|
||||||
if let Some(value) = self.fields.get(&name.lexeme) {
|
if let Some(value) = self.fields.borrow().get(&name.lexeme) {
|
||||||
return Ok(value.clone());
|
return Ok(value.clone());
|
||||||
}
|
}
|
||||||
if let Some(method) = self.class.borrow().methods.get(&name.lexeme) {
|
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) {
|
pub(super) fn set(&self, name: &Token, value: Value) {
|
||||||
self.fields.insert(name.lexeme.clone(), value);
|
self.fields.borrow_mut().insert(name.lexeme.clone(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_method(&self, method: &Function, this_value: &Value) -> Function {
|
fn bind_method(&self, method: &Function, this_value: &Value) -> Function {
|
||||||
|
|
|
@ -553,7 +553,7 @@ impl ExprNode {
|
||||||
set_expr: &SetExpr,
|
set_expr: &SetExpr,
|
||||||
) -> InterpreterResult {
|
) -> InterpreterResult {
|
||||||
let instance = set_expr.instance.interpret(itpr_state)?.result();
|
let instance = set_expr.instance.interpret(itpr_state)?.result();
|
||||||
instance.with_instance_mut(
|
instance.with_instance(
|
||||||
|instance| {
|
|instance| {
|
||||||
let value = set_expr.value.interpret(itpr_state)?.result();
|
let value = set_expr.value.interpret(itpr_state)?.result();
|
||||||
instance.set(&set_expr.name, value.clone());
|
instance.set(&set_expr.name, value.clone());
|
||||||
|
|
|
@ -75,23 +75,6 @@ impl Value {
|
||||||
_ => ferr(),
|
_ => 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<Fok, Ferr, Rt>(&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 {
|
impl PartialEq for Value {
|
||||||
|
|
Loading…
Reference in a new issue