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 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))