-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathshell.py
117 lines (97 loc) · 3.56 KB
/
shell.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
from frontend.Error import Error
from frontend.Lexer import *
from frontend.Parser import *
from backend.Interpreter import *
from backend.Environment import *
import os
ran = False
# Parsing for the IDE to allow error checking while typing
def incremental_parsing(source_code: str, file_path: str = "", x: bool = False):
global ran, environment
environment = create_global_environment(None, file_path)
lexer = Lexer(source_code, file_path)
tokens = lexer.tokenize()
if len(tokens) > 0 and isinstance(tokens[0], Error):
return tokens
parser = Parser(tokens, file_path)
ast = parser.generate_AST()
if not isinstance(ast, ProgramNode):
return ast
if not ran:
with open("ast.json", 'w') as f:
f.write(str(ast))
ran = True
return ast
def run(source_code: str, file_path: str = "") -> None | Error | ExportValue:
ast = incremental_parsing(source_code, file_path, True)
interpreter = Interpreter(file_path)
res = interpreter.evaluate(ast, environment)
if isinstance(res, (Error, ExportValue)):
return res
def debug(file_path: str) -> None:
with open(file_path, 'r') as f:
source_code = '\n'.join(f.readlines())
lexer = Lexer(source_code, file_path)
tokens = lexer.tokenize()
print(f"Tokens:\n{tokens}\n")
if len(tokens) > 0 and isinstance(tokens[0], Error):
return
parser = Parser(tokens, file_path)
ast = parser.generate_AST()
print(f"AST/Errors:\n{ast}\n")
with open("ast.json", 'w') as f:
f.write(str(ast))
env = create_global_environment(None, file_path)
interpreter = Interpreter(file_path)
result = interpreter.evaluate(ast, env)
print(f"Result:\n{result}")
if __name__ == "__main__":
while True:
command = input("phi > ")
cmd, *parameters = command.split(" ")
match cmd:
case "phi":
while True:
code = input("run > ")
if not code:
break
res = run(code)
if isinstance(res, Error):
print(res)
case "exit":
exit()
case "run":
if len(parameters) == 0:
print("Expected a filepath")
elif len(parameters) == 1:
file_path = parameters[0]
if os.path.isfile(file_path):
with open(file_path, 'r') as f:
source_code = f.read()
res = run(source_code, file_path)
if isinstance(res, Error):
print(res)
else:
print("File not found")
else:
print("Too many arguments")
case "debug":
if len(parameters) > 0:
debug(parameters[0])
else:
print("Please provide a file path")
case "clear" | "cls":
os.system("cls" if os.name == "nt" else "clear")
case "help":
helpMessage = """\
Commands:
---------
exit Exits the program
help Prints this message
phi [code] Executes the given Phi-code
run [file path] Runs the code in the given file
debug [file path] Debugs the code in the given file
"""
print(helpMessage)
case _:
print(f"'{cmd}' is not a valid command")