class Lox: def __init__(self): self.interpreter = Interpreter() self.error = LoxError() def run_prompt(self): errors = [] s = input("lox >") if s != "exit": if s[len(s) - 1] is not ";": s = s + ";" self.run(s, errors) self.run_prompt() def run_files(self, files): errors = [] for file in files: try: with open(file, 'r') as f: source = f.read() lox.run(source, errors) except: print("cannot read file {}".format(file)) def run(self, source, errors): #print("source : \n{}".format(source)) tokens = [] statements = [] scan_tokens(source, { 'start': 0, 'current': 0, 'line': 1 }, tokens, errors) if len(tokens) is 1: if tokens[0].type is Tk.EOF: LoxError.error(tokens[0], "Source file is empty.") parser = Parser(tokens) # print("Tokens:\n") # for t in tokens: # print(t) #print("Lox: ready to parse") statements = parser.parse() #print("Lox: ready to resolve") resolver = Resolver(self.interpreter) resolver.resolvelist(statements) if LoxError.haderror: print("Syntax errors detected during compilation") return #print("Lox: ready to interpret") self.interpreter.interpret(statements)
class Lox: def __init__(self): self.had_error = False self.had_runtime_error = False self.interpreter = Interpreter(self) self.resolver = Resolver(self, self.interpreter) def _report(self, line, where, message): # Should we pipe to `sys.stderr`? print(f'[Line {line}] Error{where}: {message}') def error(self, token, message): self.had_error = True if token.tokentype == TokenType.EOF: self._report(token.line, " at end", message) else: self._report(token.line, f" at '{token.lexeme}'", message) def runtime_error(self, err): print(f'[Line {err.token.line}] {err}') self.had_runtime_error = True def run_file(self, filename): with open(filename, 'r') as f: self.run(f.read()) EXIT_CODE = 0 if self.had_error: EXIT_CODE = 64 elif self.had_runtime_error: EXIT_CODE = 70 sys.exit(EXIT_CODE) def run_prompt(self): while True: reader = input('> ') self.run(reader) self.had_error = False def run(self, source): scanner = Scanner(source, self) tokens = scanner.scan_tokens() statements = Parser(tokens, self).parse() if self.had_error: return resolver = self.resolver.resolve(statements) if self.had_error: return self.interpreter.interpret(statements)
def test_interpreter(): from lox.scanner import Scanner from lox.parser import Parser from lox.ast.ast_printer import ASTPrinter from lox.interpreter import Interpreter source = """ 1 + 999 """ lox_scan = Scanner(source) tokens = lox_scan.scanTokens() print("Tokens:") for tok in tokens: print(tok) print("\n") lox_parser = Parser(tokens) result = lox_parser.parse() printer = ASTPrinter() print(printer.print(result)) print(Interpreter().evaluate(result))
def run(source): scan = Scanner(source) tokens = scan.scanTokens() # for token in tokens: # print(token) pars = Parser(tokens) result = pars.parse() print(ASTPrinter().print(result)) print(Interpreter().interpret(result))
class Lox: has_error = False has_runtime_error = False def __init__(self): self.interpreter = Interpreter(report_error=self.runtime_error) def run_code(self, source_code): scanner = Scanner(source_code, self.error) tokens = scanner.scan_tokens() parser = Parser(tokens, self.error_token) expr = parser.parse() if Lox.has_error: return # print(AstPrinter().print(expr)) self.interpreter.interpret(expr) def run_file(self, path): with open(path, 'r') as file: code_lines = file.readlines() code = '\n'.join(code_lines) self.run_code(code) if self.has_error: exit(65) if self.has_runtime_error: exit(70) def run_prompt(self, ): while True: self.run_code(input('>')) Lox.has_error = False Lox.has_runtime_error = False def run(self): if len(sys.argv) > 2: print("Usage: pylox [script]") exit(64) elif len(sys.argv) == 2: self.run_file(sys.argv[1]) else: self.run_prompt() @staticmethod def error(line: int, message: str): Lox.report(line, "", message) @staticmethod def error_token(token: Token, message: str): if token.type == TokenType.EOF: Lox.report(token.line, 'at end', message) else: Lox.report(token.line, f'at "{token.lexeme}"', message) @staticmethod def runtime_error(error: LoxRuntimeError): Lox.has_runtime_error = True print(f'[line {error.token.line}] {error.message}') @staticmethod def report(line: int, where: str, message: str): Lox.has_error = True print(f'[line {line}] Error {where}: {message}')
def __init__(self): self.interpreter = Interpreter(report_error=self.runtime_error)
def __init__(self): self.had_error = False self.had_runtime_error = False self.interpreter = Interpreter(self) self.resolver = Resolver(self, self.interpreter)
def __init__(self): self.interpreter = Interpreter() self.error = LoxError()
class Lox: interpreter = Interpreter() had_error = False had_runtime_error = False @staticmethod def repl_intro() -> None: python_version = '.'.join(str(i) for i in version_info[:3]) print('Lox REPL', f'[CPython {python_version}] on {platform}', 'Type "copyright", "credits" or "license" for more information.', 'Type "exit" or press Ctrl-D (i.e. EOF) to leave.', sep='\n') @staticmethod def usage(code: int) -> None: print('Usage: lox [file]') exit(code) @staticmethod def report(line: int, where: str, message: str) -> None: print(f'[line {line}] Error{where}: {message}') Lox.had_error = True @staticmethod def error(token: Token, message: str) -> None: if token.type == TokenType.EOF: Lox.report(token.line, ' at end', message) else: Lox.report(token.line, f" at '{token.lexeme}'", message) @staticmethod def runtime_error(error: LoxRuntimeError) -> None: print(f'{error}\n[line {error.token.line}]') Lox.had_runtime_error = True @staticmethod def run(source: str) -> None: try: scanner = Scanner(source) tokens = scanner.scan_tokens() parser = Parser(tokens) stmts = parser.parse() Lox.interpreter.interpret(stmts) except ParseError as pe: Lox.error(pe.token, str(pe)) except LoxRuntimeError as lre: Lox.runtime_error(lre) @staticmethod def run_file(filename) -> None: path = Path(filename).absolute() source = path.read_text(encoding='utf-8', errors='strict') Lox.run(source) if Lox.had_error: exit(65) elif Lox.had_runtime_error: exit(70) @staticmethod def prompt() -> None: Lox.repl_intro() while True: try: print('>>> ', end='') expr = input() first = expr.split(' ')[0] if first in COMMANDS: COMMANDS[first]() else: Lox.run(expr) Lox.had_error = False Lox.had_runtime_error = False except KeyboardInterrupt as ki: print(f'\n{ki.__class__.__name__}') except EOFError: exit(0)