Classes - Superclass method accessor
This commit is contained in:
parent
772e8ad64f
commit
4e866165ea
1 changed files with 71 additions and 1 deletions
|
@ -3,7 +3,7 @@ use std::{cell::RefCell, collections::HashMap, fmt::Display, rc::Rc};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::ClassMemberKind,
|
ast::{ClassMemberKind, SuperExpr},
|
||||||
errors::{ErrorKind, SloxError, SloxResult},
|
errors::{ErrorKind, SloxError, SloxResult},
|
||||||
tokens::Token,
|
tokens::Token,
|
||||||
};
|
};
|
||||||
|
@ -15,6 +15,12 @@ use super::{functions::Function, Callable, InterpreterState, Value};
|
||||||
pub trait PropertyCarrier {
|
pub trait PropertyCarrier {
|
||||||
fn get(&self, itpr_state: &mut InterpreterState, name: &Token) -> SloxResult<Value>;
|
fn get(&self, itpr_state: &mut InterpreterState, name: &Token) -> SloxResult<Value>;
|
||||||
fn set(&self, itpr_state: &mut InterpreterState, name: &Token, value: Value);
|
fn set(&self, itpr_state: &mut InterpreterState, name: &Token, value: Value);
|
||||||
|
fn get_super(
|
||||||
|
&self,
|
||||||
|
itpr_state: &mut InterpreterState,
|
||||||
|
super_expr: &SuperExpr,
|
||||||
|
distance: usize,
|
||||||
|
) -> SloxResult<Value>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The key for the table of class members.
|
/// The key for the table of class members.
|
||||||
|
@ -179,6 +185,38 @@ impl PropertyCarrier for ClassRef {
|
||||||
// Set the property directly
|
// Set the property directly
|
||||||
class.fields.borrow_mut().insert(name.lexeme.clone(), value);
|
class.fields.borrow_mut().insert(name.lexeme.clone(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_super(
|
||||||
|
&self,
|
||||||
|
itpr_state: &mut InterpreterState,
|
||||||
|
super_expr: &SuperExpr,
|
||||||
|
distance: usize,
|
||||||
|
) -> SloxResult<Value> {
|
||||||
|
let mb_key = (
|
||||||
|
ClassMemberKind::Method,
|
||||||
|
true,
|
||||||
|
super_expr.method.lexeme.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let sc_value = itpr_state
|
||||||
|
.environment
|
||||||
|
.borrow()
|
||||||
|
.get_at(distance, &super_expr.keyword.token)?;
|
||||||
|
let class = sc_value.as_class_ref().expect("class reference expected");
|
||||||
|
|
||||||
|
if let Some(method) = with_class_member(&class, &mb_key, |method| {
|
||||||
|
let bound_method = bind_method(method, Value::from(self.clone()));
|
||||||
|
Ok(Value::from(bound_method))
|
||||||
|
}) {
|
||||||
|
method
|
||||||
|
} else {
|
||||||
|
Err(SloxError::with_token(
|
||||||
|
ErrorKind::Runtime,
|
||||||
|
&super_expr.method,
|
||||||
|
"undefined property".to_owned(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ----------------------- *
|
/* ----------------------- *
|
||||||
|
@ -255,4 +293,36 @@ impl PropertyCarrier for InstanceRef {
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.insert(name.lexeme.clone(), value);
|
.insert(name.lexeme.clone(), value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_super(
|
||||||
|
&self,
|
||||||
|
itpr_state: &mut InterpreterState,
|
||||||
|
super_expr: &SuperExpr,
|
||||||
|
distance: usize,
|
||||||
|
) -> SloxResult<Value> {
|
||||||
|
let mb_key = (
|
||||||
|
ClassMemberKind::Method,
|
||||||
|
false,
|
||||||
|
super_expr.method.lexeme.clone(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let sc_value = itpr_state
|
||||||
|
.environment
|
||||||
|
.borrow()
|
||||||
|
.get_at(distance, &super_expr.keyword.token)?;
|
||||||
|
let class = sc_value.as_class_ref().expect("class reference expected");
|
||||||
|
|
||||||
|
if let Some(method) = with_class_member(&class, &mb_key, |method| {
|
||||||
|
let bound_method = bind_method(method, Value::from(self.clone()));
|
||||||
|
Ok(Value::from(bound_method))
|
||||||
|
}) {
|
||||||
|
method
|
||||||
|
} else {
|
||||||
|
Err(SloxError::with_token(
|
||||||
|
ErrorKind::Runtime,
|
||||||
|
&super_expr.method,
|
||||||
|
"undefined property".to_owned(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue