-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPyLox.py
75 lines (58 loc) · 2.06 KB
/
PyLox.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import sys
from lox.Scanner import *
from lox.Parser import *
from lox.Resolver import *
from lox.Interpreter import *
class Lox :
_hadError = False
_hadRuntimeError = False
_interpreter = Interpreter()
_resolver = Resolver(_interpreter)
@classmethod
def _hasAnyError(cls, step : object) -> bool :
if step is not None:
return step._hadError
return True
@classmethod
def runFile(cls, path : str) -> None:
try :
with open(path, "r") as reader :
cls.buffer = reader.read()
cls._run(cls.buffer)
except FileNotFoundError :
print("Error: Could not open file '{}': file not found.".format(path))
else :
if cls._hadError : sys.exit(65)
if cls._hadRuntimeError : sys.exit(70)
@classmethod
def runPrompt(cls) -> None:
cls._interpreter.isPromptSession = True
while True :
print (">", end = " ")
cls._run(input())
cls._hadError = False
@classmethod
def _run(cls, source : str) -> None:
scanner = Scanner(source)
tokens = scanner.Tokenize() #step 1
if cls._hasAnyError(scanner) :
cls._hadError = True; return
parser = Parser(tokens)
statements = parser.Parse() #step 2
if cls._hasAnyError(parser) :
cls._hadError = True; return
for statement in statements :
cls._resolver.Resolve(statement) #step 3
if cls._hasAnyError(cls._resolver) :
cls._hadError = True; return
cls._interpreter.Interpret(statements) #step 4
if cls._hasAnyError(cls._interpreter) :
cls._hadRuntimeError = True; return
if __name__ == "__main__" :
if len(sys.argv) > 2 :
print ("Usage PyLox [script]")
sys.exit(64)
elif len(sys.argv) == 2 :
Lox.runFile(sys.argv[1])
else :
Lox.runPrompt()