From b01ae10d09ffdf9781fa264cb51ddc70d244127f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= Date: Tue, 17 Jan 2023 07:13:09 +0100 Subject: [PATCH] Classes - Refactored super handling --- src/interpreter/classes.rs | 96 ++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 51 deletions(-) diff --git a/src/interpreter/classes.rs b/src/interpreter/classes.rs index 593573b..ccfc295 100644 --- a/src/interpreter/classes.rs +++ b/src/interpreter/classes.rs @@ -48,9 +48,9 @@ pub struct Instance { /// Helper type used to refer to instances. pub type InstanceRef = Rc>; -/* -------------------- * - * Class implementation * - * -------------------- */ +/* --------------- * + * Various helpers * + * --------------- */ lazy_static! { static ref INIT_METHOD_KEY: ClassMemberKey = @@ -63,6 +63,46 @@ fn bind_method(method: &Function, this_value: Value) -> Function { bm } +fn get_super( + on_ref: &T, + is_static: bool, + itpr_state: &mut InterpreterState, + super_expr: &SuperExpr, + distance: usize, +) -> SloxResult +where + T: Clone + Into, +{ + 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 { /// Create a new class, specifying its name. pub fn new( @@ -192,30 +232,7 @@ impl PropertyCarrier for ClassRef { super_expr: &SuperExpr, distance: usize, ) -> SloxResult { - 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(), - )) - } + get_super(self, true, itpr_state, super_expr, distance) } } @@ -300,29 +317,6 @@ impl PropertyCarrier for InstanceRef { super_expr: &SuperExpr, distance: usize, ) -> SloxResult { - 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(), - )) - } + get_super(self, false, itpr_state, super_expr, distance) } }