-
Notifications
You must be signed in to change notification settings - Fork 0
/
LoxFunction.py
50 lines (39 loc) · 1.5 KB
/
LoxFunction.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
from typing import List, Any
from enum import Enum, auto
import LoxCallable
import Stmt
import Environment
import Interpreter
class FunctionType(Enum):
NONE = auto()
FUNCTION = auto()
INITIALIZER = auto()
METHOD = auto()
class LoxFunction(LoxCallable.LoxCallable):
declaration : Stmt.Function
closure : Environment.Environment
is_initializer : bool
def __init__(self, declaration : Stmt.Function, closure : Environment.Environment, is_initializer : bool):
self.declaration = declaration
self.closure = closure
self.is_initializer = is_initializer
def call(self, interpreter, arguments : List[Any]) -> Any:
env = Environment.Environment(self.closure)
for i, param in enumerate(self.declaration.params):
env.define(param.lexeme, arguments[i])
try:
interpreter.execute_block(self.declaration.body, env)
except Interpreter.Return as e:
if self.is_initializer:
return self.closure.get_at(0, "this")
return e.value
if self.is_initializer:
return self.closure.get_at(0, "this")
def bind(self, instance):
env = Environment.Environment(self.closure)
env.define("this", instance)
return LoxFunction(self.declaration, env, self.is_initializer)
def arity(self) -> int:
return len(self.declaration.params)
def __str__(self) -> str:
return f"<fn {self.declaration.name.lexeme}>"