feat: add class methods

This commit is contained in:
2026-02-06 21:47:50 +01:00
parent e070492f69
commit c6f1e05f07
5 changed files with 24 additions and 5 deletions

View File

@@ -10,4 +10,7 @@ class Breakfast {
print(Breakfast)
let bf = Breakfast()
print(bf)
print(bf)
bf.cook()
bf.serve("Bob")

View File

@@ -1,7 +1,8 @@
from __future__ import annotations
from typing import TYPE_CHECKING, Any
from typing import TYPE_CHECKING, Any, Optional
from src.core.function import PebbleFunction
from src.interpreter.error import PebbleRuntimeError
from src.token import Token
@@ -21,6 +22,9 @@ class PebbleInstance:
try:
return self.fields[name.lexeme]
except KeyError:
method: Optional[PebbleFunction] = self.klass.find_method(name.lexeme)
if method is not None:
return method
raise PebbleRuntimeError(name, f"Undefined property '{name.lexeme}'.")
def set(self, name: Token, value: Any) -> None:

View File

@@ -1,8 +1,9 @@
from __future__ import annotations
from typing import Any, TYPE_CHECKING
from typing import Any, TYPE_CHECKING, Optional
from src.core.callable import PebbleCallable
from src.core.function import PebbleFunction
from src.core.instance import PebbleInstance
if TYPE_CHECKING:
@@ -10,8 +11,9 @@ if TYPE_CHECKING:
class PebbleClass(PebbleCallable):
def __init__(self, name: str):
def __init__(self, name: str, methods: dict[str, PebbleFunction]):
self.name: str = name
self.methods: dict[str, PebbleFunction] = methods
def __str__(self):
return self.name
@@ -22,3 +24,6 @@ class PebbleClass(PebbleCallable):
def call(self, interpreter: Interpreter, arguments: list[Any]) -> Any:
instance: PebbleInstance = PebbleInstance(self)
return instance
def find_method(self, name: str) -> Optional[PebbleFunction]:
return self.methods.get(name)

View File

@@ -174,7 +174,11 @@ class Interpreter(Expr.Visitor[Any], Stmt.Visitor[None]):
def visit_class_stmt(self, stmt: ClassStmt) -> None:
self.env.define(stmt.name.lexeme, None)
klass: PebbleClass = PebbleClass(stmt.name.lexeme)
methods: dict[str, PebbleFunction] = {}
for method in stmt.methods:
func: PebbleFunction = PebbleFunction(method, self.env)
methods[method.name.lexeme] = func
klass: PebbleClass = PebbleClass(stmt.name.lexeme, methods)
self.env.assign(stmt.name, klass)
def visit_expression_stmt(self, stmt: ExpressionStmt) -> None:

View File

@@ -17,6 +17,7 @@ if TYPE_CHECKING:
class FunctionType(Enum):
NONE = auto()
FUNCTION = auto()
METHOD = auto()
class LoopType(Enum):
@@ -116,6 +117,8 @@ class Resolver(Expr.Visitor[None], Stmt.Visitor[None]):
def visit_class_stmt(self, stmt: ClassStmt) -> None:
self.declare(stmt.name)
for method in stmt.methods:
self.resolve_function(method, FunctionType.METHOD)
self.define(stmt.name)
def visit_expression_stmt(self, stmt: ExpressionStmt) -> None: