Interpreter - Initialize methods when creating classes

This commit is contained in:
Emmanuel BENOîT 2023-01-09 07:32:29 +01:00
parent 392aaa630d
commit e371217df0
2 changed files with 21 additions and 5 deletions

View file

@ -5,12 +5,13 @@ use crate::{
tokens::Token, tokens::Token,
}; };
use super::{Callable, InterpreterState, Value}; use super::{functions::Function, Callable, InterpreterState, Value};
/// A Lox class. /// A Lox class.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Class { pub struct Class {
name: String, name: String,
methods: HashMap<String, Function>,
} }
/// Classes are mostly used through references. /// Classes are mostly used through references.
@ -29,8 +30,8 @@ pub struct Instance {
impl Class { impl Class {
/// Create a new class, specifying its name. /// Create a new class, specifying its name.
pub fn new(name: String) -> Self { pub fn new(name: String, methods: HashMap<String, Function>) -> Self {
Self { name } Self { name, methods }
} }
} }

View file

@ -1,4 +1,4 @@
use std::{cell::RefCell, rc::Rc}; use std::{cell::RefCell, collections::HashMap, rc::Rc};
use crate::{ use crate::{
ast::{ClassDecl, ExprNode, FunDecl, GetExpr, ProgramNode, SetExpr, StmtNode}, ast::{ClassDecl, ExprNode, FunDecl, GetExpr, ProgramNode, SetExpr, StmtNode},
@ -197,7 +197,22 @@ impl StmtNode {
/// Handle a class declaration /// Handle a class declaration
fn on_class_decl(&self, es: &mut InterpreterState, decl: &ClassDecl) -> InterpreterResult { fn on_class_decl(&self, es: &mut InterpreterState, decl: &ClassDecl) -> InterpreterResult {
es.environment.borrow_mut().define(&decl.name, None)?; 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 es.environment
.borrow_mut() .borrow_mut()
.assign(&decl.name, class.into())?; .assign(&decl.name, class.into())?;