-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathan_important_interpreter.py
More file actions
119 lines (95 loc) · 3.63 KB
/
Copy pathan_important_interpreter.py
File metadata and controls
119 lines (95 loc) · 3.63 KB
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
118
119
"""---------------------------------------------------------------------------------------\
| This is An IMPORTANT Interpreter & Compiler for the IMPORTANT language |
-----------------------------------------------------------------------------------------|
"""
import argparse
import os
import sys
from important_cleaning import important_clean_program, important_get_file_info
from important_operations import execute, important_compile
def init_parser() -> argparse.ArgumentParser:
parser = argparse.ArgumentParser(
prog="important_interpreter",
usage="%(prog)s [file] [options]",
description="Interpret & execute IMPORTANT code files.",
fromfile_prefix_chars="@",
)
parser.add_argument(
"-v", "--version", action="version", version=f"{parser.prog} version: 1.0.1"
)
parser.add_argument(
"-m",
"--mode",
choices=["compile", "interpret"],
type=str,
required=True,
help="compiler or interpreter mode",
)
parser.add_argument(
"-o", "--output", type=str, help="output file name (extension will be .c)"
)
parser.add_argument("filename", type=str, nargs=1, help="file to execute")
return parser
def parse_file(filename: str) -> str:
with open(filename, "r", encoding="utf-8") as file:
content = file.read().replace("\n", "")
return content
def run_code(code_string: str) -> int:
"""Executes program."""
exit_code = 0
cleaned_code = important_clean_program(code_string)
# Process operations
try:
execute(cleaned_code)
except SyntaxError as err:
print("[interpreter] Error: {}".format(err))
return 1
except ValueError as err:
print(err.with_traceback(err.__traceback__))
return 2
except EOFError:
print("[interpreter] Unexpected end of file.")
return 100
except KeyboardInterrupt:
raise SystemExit("[interpreter] You exited. Bye!")
return exit_code
def compile_code(code_string: str) -> tuple[str, int]:
"""Compiles program to C language."""
exit_code = 0
cleaned_code = important_clean_program(code_string)
try:
compiled = important_compile(cleaned_code)
except SyntaxError as err:
print("[compiler] Error: {}".format(err))
compiled = ""
exit_code = 1
return compiled, exit_code
def save_compiled_code(
compiled_code_str: str, input_file: str, output_file: str
) -> None:
"""Saves compiled code to file"""
path, name = important_get_file_info(output_file, input_file)
print(f"[compiler] Saving to {path}\\{name}...")
with open(os.path.join(path, name), "w") as outfile:
outfile.write(compiled_code_str)
def main() -> None:
parser = init_parser()
args = parser.parse_args()
filename = args.filename[0]
try:
content = parse_file(filename)
except (FileNotFoundError, IsADirectoryError, PermissionError) as err:
raise SystemExit(f"[{sys.argv[0]}] {filename}: {err.strerror}")
mode = args.mode
if "interpret" in mode:
exit_code = run_code(content)
raise SystemExit(f"[interpreter] Process finished with exit code {exit_code}.")
elif "compile" in mode:
output = args.output if args.output is not None else filename
compiled_code, exit_code = compile_code(content)
if exit_code != 0:
raise SystemExit(f"[compiler] Process finished with exit code {exit_code}.")
save_compiled_code(compiled_code, filename, output)
raise SystemExit(f"[compiler] Process finished with exit code {exit_code}.")
if __name__ == "__main__":
main()