From 9307fde4b384ae3cd90888fbb17b820cc8cd46ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Emmanuel=20Beno=C3=AEt?= <tseeker@nocternity.net>
Date: Sun, 15 Jan 2023 18:18:56 +0100
Subject: [PATCH] Interpreter - Obtain and set a class' superclass

---
 src/interpreter/interpretable.rs | 27 +++++++++++++++++++++++----
 1 file changed, 23 insertions(+), 4 deletions(-)

diff --git a/src/interpreter/interpretable.rs b/src/interpreter/interpretable.rs
index 934a9f3..0a11f98 100644
--- a/src/interpreter/interpretable.rs
+++ b/src/interpreter/interpretable.rs
@@ -225,7 +225,22 @@ impl StmtNode {
     /// Handle a class declaration
     fn on_class_decl(&self, es: &mut InterpreterState, decl: &ClassDecl) -> InterpreterResult {
         es.environment.borrow_mut().define(&decl.name, None)?;
-        let class = Class::new(decl.name.lexeme.clone(), extract_members(es, decl));
+        let superclass = match &decl.superclass {
+            None => None,
+            Some(superclass) => {
+                let sc_value = superclass.interpret(es)?.result();
+                if let Some(sc_ref) = sc_value.as_class_ref() {
+                    Some(sc_ref)
+                } else {
+                    return error(&superclass.token, "superclass must be a class");
+                }
+            }
+        };
+        let class = Class::new(
+            decl.name.lexeme.clone(),
+            superclass,
+            extract_members(es, decl),
+        );
         es.environment
             .borrow_mut()
             .assign(&decl.name, class.into())?;
@@ -362,9 +377,7 @@ impl Interpretable for ExprNode {
             ExprNode::Unary { operator, right } => self.on_unary(es, operator, right),
             ExprNode::Grouping { expression } => expression.interpret(es),
             ExprNode::Litteral { value } => self.on_litteral(value),
-            ExprNode::Variable(var_expr) | ExprNode::This(var_expr) => {
-                Ok(es.lookup_var(var_expr)?.into())
-            }
+            ExprNode::Variable(var_expr) | ExprNode::This(var_expr) => var_expr.interpret(es),
             ExprNode::Call {
                 callee,
                 right_paren,
@@ -380,6 +393,12 @@ impl Interpretable for ExprNode {
     }
 }
 
+impl Interpretable for VariableExpr {
+    fn interpret(&self, es: &mut InterpreterState) -> InterpreterResult {
+        Ok(es.lookup_var(self)?.into())
+    }
+}
+
 impl ExprNode {
     /// Evaluate a logical operator.
     fn on_logic(