def evaluate(self) -> lt.LoxLiteral: callee = self.callee.evaluate() if not isinstance(callee, lt.LoxCallable): message = f"{lu.lox_str(callee, repl=True)} is not callable." raise le.LoxRuntimeError(self.paren.line, message) arguments = [arg.evaluate() for arg in self.arguments] if callee.arity != len(arguments): message = f"Expected {callee.arity} arguments but got {len(arguments)}." raise le.LoxRuntimeError(self.paren.line, message) try: return callee.lox_call(arguments) except le.LoxRuntimeError as lre: if lre.line == "unknown": lre.line = self.paren.line raise lre
def super_class(self) -> tp.Optional[lc.LoxClass]: if self.super_class_var is None: return None value = self.super_class_var.evaluate() if not isinstance(value, lc.LoxClass): raise le.LoxRuntimeError(self.super_class_var.name.line, "Superclass must be a class") return value
def lox_len(string: str) -> float: # TODO: Change to a lox method available on strings? try: return float(len(string)) except TypeError as exc: import pylox.lox_utils as lu message = f"Type {lu.lox_type(string)} does not have a length." raise le.LoxRuntimeError(message) from exc
def evaluate(self) -> lt.LoxLiteral: target = self.assignee.object.evaluate() if not isinstance(target, lc.LoxInstance): raise le.LoxRuntimeError( self.assignee.name.line, "Only instances have fields." ) value = self.value.evaluate() target[self.assignee.name] = value return value
def evaluate(self) -> lt.LoxLiteral: right = self.right.evaluate() try: return lev.evaluate_lox_unary(self.operator.type, right) except TypeError as exc: message = ( f"Unary Operator {self.operator.lexeme} is not" f' supported for the type "{lu.lox_type(right)}"' ) raise le.LoxRuntimeError(self.operator.line, message) from exc
def evaluate(self) -> lt.LoxLiteral: lox_type = self.operator.type left = self.left.evaluate() right = self.right.evaluate() try: return lev.evaluate_lox_binary(lox_type, left, right) except TypeError: message = ( f'Infix Operator "{self.operator.lexeme}" is not supported for the' f' types "{lu.lox_type(left)}" and "{lu.lox_type(right)}"' ) except ZeroDivisionError: message = "Division by zero" raise le.LoxRuntimeError(self.operator.line, message)
def runtime_cast(self) -> le.LoxRuntimeError: lre = le.LoxRuntimeError() lre.__dict__ = self.__dict__ return lre
def evaluate(self) -> tp.NoReturn: raise le.LoxRuntimeError(ignore=True)
def evaluate(self) -> lt.LoxLiteral: if self.lox_class is None or self.lox_class.super_class is None: raise le.LoxRuntimeError(self.name.line, "Super used without a superclass") return self.lox_class.super_class.method_get(self.method)
def evaluate(self) -> lt.LoxLiteral: parent = self.object.evaluate() if isinstance(parent, lc.LoxInstance): return parent[self.name] raise le.LoxRuntimeError(self.name.line, "Only instances have properties")