From e371217df07b743027e3e139ab74931790de060f Mon Sep 17 00:00:00 2001
From: Emmanuel Benoit <tseeker@nocternity.net>
Date: Mon, 9 Jan 2023 07:32:29 +0100
Subject: [PATCH] Interpreter - Initialize methods when creating classes

---
 src/interpreter/classes.rs       |  7 ++++---
 src/interpreter/interpretable.rs | 19 +++++++++++++++++--
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/src/interpreter/classes.rs b/src/interpreter/classes.rs
index 489190b..5aa9110 100644
--- a/src/interpreter/classes.rs
+++ b/src/interpreter/classes.rs
@@ -5,12 +5,13 @@ use crate::{
     tokens::Token,
 };
 
-use super::{Callable, InterpreterState, Value};
+use super::{functions::Function, Callable, InterpreterState, Value};
 
 /// A Lox class.
 #[derive(Debug, Clone)]
 pub struct Class {
     name: String,
+    methods: HashMap<String, Function>,
 }
 
 /// Classes are mostly used through references.
@@ -29,8 +30,8 @@ pub struct Instance {
 
 impl Class {
     /// Create a new class, specifying its name.
-    pub fn new(name: String) -> Self {
-        Self { name }
+    pub fn new(name: String, methods: HashMap<String, Function>) -> Self {
+        Self { name, methods }
     }
 }
 
diff --git a/src/interpreter/interpretable.rs b/src/interpreter/interpretable.rs
index 0e3abe9..14660f2 100644
--- a/src/interpreter/interpretable.rs
+++ b/src/interpreter/interpretable.rs
@@ -1,4 +1,4 @@
-use std::{cell::RefCell, rc::Rc};
+use std::{cell::RefCell, collections::HashMap, rc::Rc};
 
 use crate::{
     ast::{ClassDecl, ExprNode, FunDecl, GetExpr, ProgramNode, SetExpr, StmtNode},
@@ -197,7 +197,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());
+        let methods = decl
+            .methods
+            .iter()
+            .map(|method| {
+                (
+                    method.name.lexeme.clone(),
+                    Function::new(
+                        Some(&method.name),
+                        &method.params,
+                        &method.body,
+                        es.environment.clone(),
+                    ),
+                )
+            })
+            .collect::<HashMap<String, Function>>();
+        let class = Class::new(decl.name.lexeme.clone(), methods);
         es.environment
             .borrow_mut()
             .assign(&decl.name, class.into())?;