From b91c23da229ef6c81f30ba6f651d2fa76f8dfa1d Mon Sep 17 00:00:00 2001 From: Valentyn Yukhymenko Date: Thu, 11 May 2023 00:43:53 +0100 Subject: [PATCH] challenge 7.2 done --- pylox/cli.py | 12 +----------- pylox/interpreter.py | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/pylox/cli.py b/pylox/cli.py index 9e6ecad..e4db660 100644 --- a/pylox/cli.py +++ b/pylox/cli.py @@ -50,22 +50,12 @@ def run(self, src: str) -> None: tokens = Scanner(src).scan_tokens() ast = Parser(tokens, self.report_error).parse() if ast is not None: - print(self.stringify(self.interpreter.evaluate(ast))) + print(self.interpreter.interpret(ast)) except LoxSyntaxError as e: self.report_error(e) except LoxRuntimeError as e: self.report_runtime_error(e) - @staticmethod - def stringify(value: typing.Any) -> str: - if value is None: - return "nil" - - if type(value) is float and float(value).is_integer(): - return str(int(value)) - - return str(value) - @staticmethod def _build_error_string(err: LoxException) -> str: return f"{err.line + 1}: [bold red]{err.message}[/bold red]" diff --git a/pylox/interpreter.py b/pylox/interpreter.py index d4fda5d..6eefec2 100644 --- a/pylox/interpreter.py +++ b/pylox/interpreter.py @@ -6,6 +6,9 @@ class Interpreter(ast.ExprVisitor): + def interpret(self, expr: ast.Expr): + return self.stringify(self.evaluate(expr)) + def evaluate(self, expr: ast.Expr) -> typing.Any: return expr.accept(self) @@ -40,9 +43,12 @@ def visit_binary_expr(self, expr: ast.Binary): if type(left) is str and type(right) is str: return left + right + if type(left) is str or type(right) is str: + return str(left) + str(right) + raise LoxRuntimeError( expr.operator, - "Operands must be two numbers of two strings.", + "Operands must be numbers or strings.", ) case TokenType.SLASH: self.check_number_operands(expr.operator, left, right) @@ -96,3 +102,13 @@ def check_number_operands(op: Token, left, right: typing.Any) -> None: if Interpreter.is_number(left) and Interpreter.is_number(right): return raise LoxRuntimeError(op, "Operands must be a numbers.") + + @staticmethod + def stringify(value: typing.Any) -> str: + if value is None: + return "nil" + + if type(value) is float and float(value).is_integer(): + return str(int(value)) + + return str(value)