class PyLox(object): """ Command-line runner to execute Lox source code. Provides an interface to run as REPL prompt or on a pylox source file. """ def __init__(self, verbose=False): self.verbose = verbose self.interpreter = Interpreter(self.verbose) def run_prompt(self): while True: source = input(PYLOX_PROMPT) self.try_read_and_evaluate(source) def run_file(self, path): with open(path) as f: source = f.read() self.try_read_and_evaluate(source) def try_read_and_evaluate(self, source): tokens = Scanner(source, verbose=self.verbose).scan_tokens() if self.verbose: print(" tokens -> {}".format(tokens)) parser = Parser(tokens) try: statements = parser.parse() except Exception as e: print("Error parsing statements: {}".format(e)) return if self.verbose: print(" statements -> {}".format(statements)) self.interpreter.interpret(statements)
class InterpreterTests_Expressions(unittest.TestCase): def setUp(self): self.interpreter = Interpreter() def test_grouping_should_equal_inner_value(self): inner_expression = Literal(1) grouping = Grouping(inner_expression) result = self.interpreter.visit_grouping_expression(grouping) self.assertEqual(result, 1) def test_literal_should_equal_value(self): literal = Literal(2) result = self.interpreter.visit_literal_expression(literal) self.assertEqual(result, 2) def test_unary_not(self): unary = Unary(new_token(t.BANG), Literal(False)) result = self.interpreter.visit_unary_expression(unary) self.assertEqual(result, True) def test_unary_minus(self): unary = Unary(new_token(t.MINUS), Literal(2)) result = self.interpreter.visit_unary_expression(unary) self.assertEqual(result, -2)
def test_var(self): line = 'var beverage = "espresso";\nprint beverage;' scanner = Scanner(line) tokens = scanner.scan_tokens() parser = Parser(tokens, "") statements = parser.parse() Interpreter().interpret(statements)
class InterpreterTests_BinaryEqualityExpressions(unittest.TestCase): def setUp(self): self.interpreter = Interpreter() def test_equality_numbers(self): binary = Binary(Literal(2), new_token(t.EQUAL_EQUAL), Literal(2)) result = self.interpreter.visit_binary_expression(binary) self.assertEqual(result, True) def test_equality_bools(self): binary = Binary(Literal(True), new_token(t.EQUAL_EQUAL), Literal(False)) result = self.interpreter.visit_binary_expression(binary) self.assertEqual(result, False) def test_equality_number_and_bool(self): binary = Binary(Literal(1), new_token(t.EQUAL_EQUAL), Literal(True)) result = self.interpreter.visit_binary_expression(binary) self.assertEqual(result, False) @unittest.skip( 'this is a known issue (see readme). Hopefully gets fixed in blog...') def test_double_equality(self): # 1 == 1 == 1 comparison = Binary( Binary(Literal(1), new_token(t.EQUAL_EQUAL), Literal(1)), new_token(t.EQUAL_EQUAL), Literal(1)) result = self.interpreter.visit_binary_expression(comparison) self.assertEqual(result, True)
class InterpreterTests_BinaryExpressions(unittest.TestCase): def setUp(self): self.interpreter = Interpreter() def test_multiply(self): binary = Binary(Literal(2), new_token(t.STAR), Literal(4)) result = self.interpreter.visit_binary_expression(binary) self.assertEqual(result, 8) def test_add_numbers(self): binary = Binary(Literal(1), new_token(t.PLUS), Literal(1)) result = self.interpreter.visit_binary_expression(binary) self.assertEqual(result, 2) def test_add_strings(self): binary = Binary(Literal("hello "), new_token(t.PLUS), Literal("kitty")) result = self.interpreter.visit_binary_expression(binary) self.assertEqual(result, "hello kitty") def test_add_number_and_string(self): binary = Binary(Literal(1), new_token(t.PLUS), Literal("kitty")) with self.assertRaises(InterpreterException) as context: result = self.interpreter.visit_binary_expression(binary) self.assertEqual(context.expression, binary) def test_comparison(self): comparison = Binary(Literal(1), new_token(t.LESS), Literal(2)) result = self.interpreter.visit_binary_expression(comparison) self.assertEqual(result, True) def test_equality(self): comparison = Binary(Literal(1), new_token(t.EQUAL_EQUAL), Literal(1)) result = self.interpreter.visit_binary_expression(comparison) self.assertEqual(result, True)
def __init__(self): self.had_error = False self.had_runtime_error = False self.interpreter = Interpreter()
class Lox: """ Lox class""" def __init__(self): self.had_error = False self.had_runtime_error = False self.interpreter = Interpreter() def run_file(self, file): """ Runs file :param file: input file """ with open(file) as content: program = content.read() self.run(program) if self.had_error: sys.exit(65) elif self.had_runtime_error: sys.exit(70) def run_prompt(self): """ Runs prompt """ print("Running prompt") while True: line = input(">> ") self.run(line) # If we had an error, we should reset at new prompt self.had_error = False self.had_runtime_error = False def run(self, line): """ Runs the input :param line: line to tokenize and eval """ scanner = Scanner(line) tokens = scanner.scan_tokens() parser = Parser(tokens, self.error) statements = parser.parse() self.interpreter.interpret(statements) if self.had_error: return def error(self, line, message): """ error :param line: the location of error :param message: error message """ self.report(line + " " + message) def runtimeerror(self, error): """ set runtimeerror message :param error: error message :return: None """ error_message = "{0} \n [line {1}]".format(error.get_message(), error.token.line) print(error_message) self.had_runtime_error = True def report(self, line, where=None, message=None): """ error :param line: line of error :param where: location of error :param: message: error message """ self.had_error = True raise Exception("[Line {0}] Error {1}: {2} ".format(line, where, message))
def __init__(self, verbose=False): self.verbose = verbose self.interpreter = Interpreter(self.verbose)
import sys import readline from typing import List from pylox import interpreter from pylox.scanner import Scanner from pylox.tokens import TokenType, Token from pylox.parser import Parser from pylox.ast_printer import AstPrinter from pylox.interpreter import RuntimeException, Interpreter ## static states gHadError = False gHadRuntimeError = False gInterpreter = Interpreter() ## run utils def run_file(path: str) -> None: with open(path, encoding='utf-8') as f: run(f.read()) if gHadError: sys.exit(65) if gHadRuntimeError: sys.exit(70) def run_prompt(prompt: str = "lox> ") -> None: while True:
def setUp(self): self.interpreter = Interpreter()