118 lines
3.2 KiB
Python
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
|