def call(self, interpreter, args: List[Any]): environment = Environment(self.environment) for token, expression in zip(self.declaration.params, args): environment.define(token.lexeme, expression) try: interpreter.execute_block(self.declaration.body, environment) except ReturnValue as return_val: if self.is_initializer: return self.environment.get_at(0, 'this') else: return return_val.val if self.is_initializer: return self.environment.get_at(0, 'this')
class LoxFunction(LoxCallable): def __init__(self, declaration, closure): self.declaration = declaration self.closure = closure def __call__(self, interpreter, arguments): self.environment = Environment(self.closure) for i in range(len(self.declaration.params)): self.environment.define( self.declaration.params[i].lexeme, arguments[i]) try: interpreter._execute_block(self.declaration.body, self.environment) except Return as ret: return ret.value @property def arity(self): return len(self.declaration.params) def __str__(self): return f"<fn {self.declaration.name.lexeme}>"
class LoxFunction(LoxCallable): """Runtime for function.""" def __init__(self, name: "LoxToken", fundec: FunctionExp, closure): self.name = name self.fundec = fundec self.call_env = None self.closure = closure def arity(self) -> int: return len(self.fundec.params) def call(self, interpreter, arguments: List[object]): # create an environment for this call, inside the calling env self.call_env = Environment(self.closure) # Add the parameters to this env with their "calling" value for i in range(len(arguments)): self.call_env.define(self.fundec.params[i].lexeme, arguments[i]) # call the function: execute the block wit the current env try: interpreter.executeblock(self.fundec.body, self.call_env) except ReturnException as exc: if self.fundec.functiontype is FunctionType.INIT: return self.closure.getat(0, Tk.lexeme_from_type[Tk.THIS]) return exc.value def bind(self, instance): """Bind the instance to the method.""" this_env = Environment(self.closure) this_env.define(Tk.lexeme_from_type[Tk.THIS], instance) return LoxFunction(self.name, self.fundec, this_env) def __str__(self): if self.name is None: return "<function>" else: return "<function: " + self.name.lexeme + ">"
def bind(self, instance): env = Environment(self.environment) env.define('this', instance) return LoxCallable(self.declaration, env)
def bind(self, instance): """Bind the instance to the method.""" this_env = Environment(self.closure) this_env.define(Tk.lexeme_from_type[Tk.THIS], instance) return LoxFunction(self.name, self.fundec, this_env)