Classes - Refactored super handling

This commit is contained in:
Emmanuel BENOîT 2023-01-17 07:13:09 +01:00
parent f29902b210
commit b01ae10d09

View file

@ -48,9 +48,9 @@ pub struct Instance {
/// Helper type used to refer to instances. /// Helper type used to refer to instances.
pub type InstanceRef = Rc<RefCell<Instance>>; pub type InstanceRef = Rc<RefCell<Instance>>;
/* -------------------- * /* --------------- *
* Class implementation * * Various helpers *
* -------------------- */ * --------------- */
lazy_static! { lazy_static! {
static ref INIT_METHOD_KEY: ClassMemberKey = static ref INIT_METHOD_KEY: ClassMemberKey =
@ -63,6 +63,46 @@ fn bind_method(method: &Function, this_value: Value) -> Function {
bm bm
} }
fn get_super<T>(
on_ref: &T,
is_static: bool,
itpr_state: &mut InterpreterState,
super_expr: &SuperExpr,
distance: usize,
) -> SloxResult<Value>
where
T: Clone + Into<Value>,
{
let mb_key = (
ClassMemberKind::Method,
is_static,
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, on_ref.clone().into());
Ok(Value::from(bound_method))
}) {
method
} else {
Err(SloxError::with_token(
ErrorKind::Runtime,
&super_expr.method,
"undefined property".to_owned(),
))
}
}
/* -------------------- *
* Class implementation *
* -------------------- */
impl Class { impl Class {
/// Create a new class, specifying its name. /// Create a new class, specifying its name.
pub fn new( pub fn new(
@ -192,30 +232,7 @@ impl PropertyCarrier for ClassRef {
super_expr: &SuperExpr, super_expr: &SuperExpr,
distance: usize, distance: usize,
) -> SloxResult<Value> { ) -> SloxResult<Value> {
let mb_key = ( get_super(self, true, itpr_state, super_expr, distance)
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(),
))
}
} }
} }
@ -300,29 +317,6 @@ impl PropertyCarrier for InstanceRef {
super_expr: &SuperExpr, super_expr: &SuperExpr,
distance: usize, distance: usize,
) -> SloxResult<Value> { ) -> SloxResult<Value> {
let mb_key = ( get_super(self, false, itpr_state, super_expr, distance)
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(),
))
}
} }
} }