From 5cfe6d3e5c62d2293299795bf7f25eef8369bea1 Mon Sep 17 00:00:00 2001
From: Emmanuel Benoit <tseeker@nocternity.net>
Date: Mon, 9 Jan 2023 07:10:10 +0100
Subject: [PATCH] Interpreter - Set instance properties

---
 src/interpreter/classes.rs       |  4 ++++
 src/interpreter/interpretable.rs | 20 +++++++++++++++++++-
 2 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/interpreter/classes.rs b/src/interpreter/classes.rs
index e2569fd..489190b 100644
--- a/src/interpreter/classes.rs
+++ b/src/interpreter/classes.rs
@@ -79,6 +79,10 @@ impl Instance {
             )),
         }
     }
+
+    pub(super) fn set(&mut self, name: &Token, value: Value) {
+        self.fields.insert(name.lexeme.clone(), value);
+    }
 }
 
 impl Display for Instance {
diff --git a/src/interpreter/interpretable.rs b/src/interpreter/interpretable.rs
index 7e6bc81..0e3abe9 100644
--- a/src/interpreter/interpretable.rs
+++ b/src/interpreter/interpretable.rs
@@ -1,7 +1,7 @@
 use std::{cell::RefCell, rc::Rc};
 
 use crate::{
-    ast::{ClassDecl, ExprNode, FunDecl, GetExpr, ProgramNode, StmtNode},
+    ast::{ClassDecl, ExprNode, FunDecl, GetExpr, ProgramNode, SetExpr, StmtNode},
     errors::{ErrorKind, SloxError, SloxResult},
     resolver::ResolvedVariables,
     tokens::{Token, TokenType},
@@ -342,6 +342,7 @@ impl Interpretable for ExprNode {
                 Ok(Value::from(lambda).into())
             }
             ExprNode::Get(get_expr) => self.on_get_expression(es, get_expr),
+            ExprNode::Set(set_expr) => self.on_set_expression(es, set_expr),
         }
     }
 }
@@ -523,4 +524,21 @@ impl ExprNode {
             || error(&get_expr.name, "only instances have properties"),
         )
     }
+
+    /// Evaluate a set expression.
+    fn on_set_expression(
+        &self,
+        itpr_state: &mut InterpreterState,
+        set_expr: &SetExpr,
+    ) -> InterpreterResult {
+        let instance = set_expr.instance.interpret(itpr_state)?.result();
+        instance.with_instance_mut(
+            |instance| {
+                let value = set_expr.value.interpret(itpr_state)?.result();
+                instance.set(&set_expr.name, value.clone());
+                Ok(value.into())
+            },
+            || error(&set_expr.name, "only instances have properties"),
+        )
+    }
 }