Interpreter - Fixed class declaration handling
This commit is contained in:
parent
71a58c12a2
commit
fb7f2f16fa
1 changed files with 22 additions and 15 deletions
|
@ -2,8 +2,8 @@ use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{
|
ast::{
|
||||||
ClassDecl, ClassMemberDecl, ExprNode, FunDecl, GetExpr, ProgramNode, SetExpr, StmtNode,
|
ClassDecl, ClassMemberDecl, ClassMemberKind, ExprNode, FunDecl, GetExpr, ProgramNode,
|
||||||
VariableExpr,
|
SetExpr, StmtNode, VariableExpr,
|
||||||
},
|
},
|
||||||
errors::{ErrorKind, SloxError, SloxResult},
|
errors::{ErrorKind, SloxError, SloxResult},
|
||||||
resolver::ResolvedVariables,
|
resolver::ResolvedVariables,
|
||||||
|
@ -197,25 +197,26 @@ impl StmtNode {
|
||||||
Ok(InterpreterFlowControl::default())
|
Ok(InterpreterFlowControl::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extract methods from a class declaration
|
/// Extract members from a class declaration, generating a map of
|
||||||
fn extract_methods<F>(
|
/// functions.
|
||||||
|
fn extract_members<F>(
|
||||||
&self,
|
&self,
|
||||||
es: &mut InterpreterState,
|
es: &mut InterpreterState,
|
||||||
decl: &ClassDecl,
|
decl: &ClassDecl,
|
||||||
filter: F,
|
filter: F,
|
||||||
) -> HashMap<String, Function>
|
) -> HashMap<String, Function>
|
||||||
where
|
where
|
||||||
F: FnMut(&ClassMemberDecl) -> Option<&FunDecl>,
|
F: FnMut(&ClassMemberDecl) -> Option<(&FunDecl, &[Token])>,
|
||||||
{
|
{
|
||||||
decl.members
|
decl.members
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(filter)
|
.filter_map(filter)
|
||||||
.map(|fdecl| {
|
.map(|(fdecl, params)| {
|
||||||
(
|
(
|
||||||
fdecl.name.lexeme.clone(),
|
fdecl.name.lexeme.clone(),
|
||||||
Function::new(
|
Function::new(
|
||||||
Some(&fdecl.name),
|
Some(&fdecl.name),
|
||||||
&fdecl.params,
|
¶ms,
|
||||||
&fdecl.body,
|
&fdecl.body,
|
||||||
es.environment.clone(),
|
es.environment.clone(),
|
||||||
fdecl.name.lexeme == "init",
|
fdecl.name.lexeme == "init",
|
||||||
|
@ -228,12 +229,18 @@ 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 methods = self.extract_methods(es, decl, |member| match member {
|
let methods =
|
||||||
ClassMemberDecl::Method(method) => Some(method),
|
self.extract_members(es, decl, |member| match (&member.kind, member.is_static) {
|
||||||
|
(ClassMemberKind::Method, false) => {
|
||||||
|
Some((&member.fun_decl, &member.fun_decl.params))
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
let static_methods = self.extract_methods(es, decl, |member| match member {
|
let static_methods =
|
||||||
ClassMemberDecl::StaticMethod(method) => Some(method),
|
self.extract_members(es, decl, |member| match (&member.kind, member.is_static) {
|
||||||
|
(ClassMemberKind::Method, true) => {
|
||||||
|
Some((&member.fun_decl, &member.fun_decl.params))
|
||||||
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
});
|
});
|
||||||
let class = Class::new(decl.name.lexeme.clone(), methods, static_methods);
|
let class = Class::new(decl.name.lexeme.clone(), methods, static_methods);
|
||||||
|
|
Loading…
Reference in a new issue