Esempio n. 1
0
    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')
Esempio n. 2
0
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}>"
Esempio n. 3
0
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 + ">"
Esempio n. 4
0
 def bind(self, instance):
     env = Environment(self.environment)
     env.define('this', instance)
     return LoxCallable(self.declaration, env)
Esempio n. 5
0
 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)