feat: add class methods
This commit is contained in:
@@ -11,3 +11,6 @@ class Breakfast {
|
|||||||
print(Breakfast)
|
print(Breakfast)
|
||||||
let bf = Breakfast()
|
let bf = Breakfast()
|
||||||
print(bf)
|
print(bf)
|
||||||
|
|
||||||
|
bf.cook()
|
||||||
|
bf.serve("Bob")
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
from __future__ import annotations
|
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.interpreter.error import PebbleRuntimeError
|
||||||
from src.token import Token
|
from src.token import Token
|
||||||
|
|
||||||
@@ -21,6 +22,9 @@ class PebbleInstance:
|
|||||||
try:
|
try:
|
||||||
return self.fields[name.lexeme]
|
return self.fields[name.lexeme]
|
||||||
except KeyError:
|
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}'.")
|
raise PebbleRuntimeError(name, f"Undefined property '{name.lexeme}'.")
|
||||||
|
|
||||||
def set(self, name: Token, value: Any) -> None:
|
def set(self, name: Token, value: Any) -> None:
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
from __future__ import annotations
|
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.callable import PebbleCallable
|
||||||
|
from src.core.function import PebbleFunction
|
||||||
from src.core.instance import PebbleInstance
|
from src.core.instance import PebbleInstance
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -10,8 +11,9 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
|
|
||||||
class PebbleClass(PebbleCallable):
|
class PebbleClass(PebbleCallable):
|
||||||
def __init__(self, name: str):
|
def __init__(self, name: str, methods: dict[str, PebbleFunction]):
|
||||||
self.name: str = name
|
self.name: str = name
|
||||||
|
self.methods: dict[str, PebbleFunction] = methods
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
@@ -22,3 +24,6 @@ class PebbleClass(PebbleCallable):
|
|||||||
def call(self, interpreter: Interpreter, arguments: list[Any]) -> Any:
|
def call(self, interpreter: Interpreter, arguments: list[Any]) -> Any:
|
||||||
instance: PebbleInstance = PebbleInstance(self)
|
instance: PebbleInstance = PebbleInstance(self)
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
def find_method(self, name: str) -> Optional[PebbleFunction]:
|
||||||
|
return self.methods.get(name)
|
||||||
|
|||||||
@@ -174,7 +174,11 @@ class Interpreter(Expr.Visitor[Any], Stmt.Visitor[None]):
|
|||||||
|
|
||||||
def visit_class_stmt(self, stmt: ClassStmt) -> None:
|
def visit_class_stmt(self, stmt: ClassStmt) -> None:
|
||||||
self.env.define(stmt.name.lexeme, 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)
|
self.env.assign(stmt.name, klass)
|
||||||
|
|
||||||
def visit_expression_stmt(self, stmt: ExpressionStmt) -> None:
|
def visit_expression_stmt(self, stmt: ExpressionStmt) -> None:
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ if TYPE_CHECKING:
|
|||||||
class FunctionType(Enum):
|
class FunctionType(Enum):
|
||||||
NONE = auto()
|
NONE = auto()
|
||||||
FUNCTION = auto()
|
FUNCTION = auto()
|
||||||
|
METHOD = auto()
|
||||||
|
|
||||||
|
|
||||||
class LoopType(Enum):
|
class LoopType(Enum):
|
||||||
@@ -116,6 +117,8 @@ class Resolver(Expr.Visitor[None], Stmt.Visitor[None]):
|
|||||||
|
|
||||||
def visit_class_stmt(self, stmt: ClassStmt) -> None:
|
def visit_class_stmt(self, stmt: ClassStmt) -> None:
|
||||||
self.declare(stmt.name)
|
self.declare(stmt.name)
|
||||||
|
for method in stmt.methods:
|
||||||
|
self.resolve_function(method, FunctionType.METHOD)
|
||||||
self.define(stmt.name)
|
self.define(stmt.name)
|
||||||
|
|
||||||
def visit_expression_stmt(self, stmt: ExpressionStmt) -> None:
|
def visit_expression_stmt(self, stmt: ExpressionStmt) -> None:
|
||||||
|
|||||||
Reference in New Issue
Block a user