This repository has been archived by the owner on Mar 18, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
uranc.py
94 lines (72 loc) · 2.67 KB
/
uranc.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
from src import lexer, parser, compiler
from src.config import Config
from src.formatter import Formatter
from src.debug_logging import Logger
from src.errors import UraniumError
from token_gen.xml_parser import XmlTokenParser
import os
def init():
# load all the options from config.toml
Config.read_config()
# load the tokens
XmlTokenParser.generate("u")
# init. the tokens and logger
Logger.init()
# we need the env. variable, thus th error
if os.environ.get("URANIUM_PATH") is None:
raise UraniumError("Environment variable 'URANIUM_PATH' does not exist!")
def compile(src:str) -> (compiler.UraniumCompiler, list):
# generate a list of tokens from the source code
uranium_lexer = lexer.UraniumLexer(src)
tokens = uranium_lexer.tokenize()
# run the parser
uranium_parser = parser.UraniumParser(tokens)
if Config.check_syntax:
uranium_parser.check_syntax(src)
tokens = uranium_parser.rearrange()
# generate the final C++ code
uranium_compiler = compiler.UraniumCompiler(tokens)
return uranium_compiler, uranium_compiler.generate_cpp()
def write_output(dest:str, cpp_code:list):
# start writing to output file
with open(dest, "w") as output_file:
# load in the template, which we need for the standard libraries
with open("template.cpp", "r") as template:
output_template = template.readlines()
output_file.writelines(output_template)
# start putting the source code together into a single string
for snippet in cpp_code:
final_snippet = snippet if snippet in ["\n", ";\n"] else snippet + " "
output_file.write(final_snippet)
# reformat the output if desired
if Config.reformat_cpp:
formatter = Formatter(dest)
with open(dest, "w") as output_file:
output_file.writelines(formatter.reformat())
if __name__ == '__main__':
init()
Logger.timestamp("Init took")
# run the compiler
src_path = "./_in/main.uran"
if Config.new_parser:
from src.parser.new_parser import NewerUraniumParser
# generate a list of tokens from the source code
uranium_lexer = lexer.UraniumLexer(src_path)
tokens = uranium_lexer.tokenize()
if Config.write_tokens:
with open("tokens_log.txt", "w") as f:
f.write("\n".join(map(lambda tok: str(tok), tokens)))
# parsing time baby
new_parser:NewerUraniumParser = NewerUraniumParser(tokens, src_path)
new_parser.check_syntax()
else:
uranium_compiler, cpp = compile(src_path)
Logger.timestamp("Compilation took")
# generate some output
cpp_path = "./_out/main.cpp"
write_output(cpp_path, cpp)
Logger.timestamp("Writing to output took")
# let a C++ compiler finish the compilation
uranium_compiler.compile(cpp_path)
Logger.timestamp("C++ Compiler took")
Logger.timestamp("Total time taken:", True)