Files
pebble/src/runner.py

118 lines
3.2 KiB
Python

from pathlib import Path
from typing import Optional
from src.ast.stmt import Stmt
from src.formatter import Formatter
from src.interpreter.interpreter import Interpreter
from src.interpreter.resolver import Resolver
from src.lexer import Lexer
from src.parser.parser import Parser
from src.pebble import Pebble
from src.token import Token, TokenType
class Runner:
@staticmethod
def run_file(path: Path):
with open(path, "r") as f:
source: str = f.read()
Runner.run(source, path)
@staticmethod
def run(source: str, path: Optional[Path] = None):
lexer: Lexer = Lexer(source, path)
tokens: list[Token] = lexer.process()
print(list(filter(lambda t: t.type not in Parser.IGNORE, tokens)))
if Pebble.had_error:
return
parser: Parser = Parser(tokens)
program: list[Stmt] = parser.parse()
if Pebble.had_error:
return
interpreter: Interpreter = Interpreter()
resolver: Resolver = Resolver(interpreter)
resolver.resolve(*program)
if Pebble.had_error:
return
interpreter.interpret(program)
if Pebble.had_runtime_error:
return
formatter: Formatter = Formatter()
with open("formatted.peb", "w") as f:
f.write(formatter.print(program))
@staticmethod
def repl():
line: str
lexer: Lexer
tokens: list[Token]
parser: Parser
program: list[Stmt]
interpreter: Interpreter = Interpreter()
resolver: Resolver
brace_depth: int
paren_depth: int
buf: str = ""
while True:
try:
line = input(">>> " if len(buf) == 0 else "... ")
except EOFError:
print()
break
except KeyboardInterrupt:
buf = ""
print()
continue
buf += line + "\n"
lexer = Lexer(buf)
tokens = lexer.process()
if Pebble.had_error:
Pebble.had_error = False
continue
brace_depth = 0
paren_depth = 0
for token in tokens:
match token.type:
case TokenType.LEFT_BRACE:
brace_depth += 1
case TokenType.RIGHT_BRACE:
brace_depth = max(0, brace_depth - 1)
case TokenType.LEFT_PAREN:
paren_depth += 1
case TokenType.RIGHT_PAREN:
paren_depth = max(0, paren_depth - 1)
if brace_depth > 0 or paren_depth > 0:
continue
parser = Parser(tokens)
program = parser.parse()
buf = ""
if Pebble.had_error:
Pebble.had_error = False
continue
resolver: Resolver = Resolver(interpreter)
resolver.resolve(*program)
if Pebble.had_error:
Pebble.had_error = False
continue
interpreter.interpret(program)
if Pebble.had_runtime_error:
Pebble.had_runtime_error = False
continue