-
Notifications
You must be signed in to change notification settings - Fork 1
/
ahcc.py
executable file
·74 lines (60 loc) · 2.57 KB
/
ahcc.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
#!/usr/bin/env python
import sys
from argparse import ArgumentParser
from distutils.ccompiler import new_compiler, CCompiler
from tempfile import NamedTemporaryFile
from subprocess import Popen
from compile import Compiler
from gentac import TacGenerator
from genc import CCodeGenerator
ccompiler = new_compiler()
class CmdlineOption(object):
pass
parser = ArgumentParser()
parser.add_argument("source_file")
parser.add_argument("-o", metavar="", help="The path to an executable to be generated")
parser.add_argument("--type", choices=["ahssembly", "ir", "immediate"], help="Generate an ahssembly, IR, or immediate code instead of an executable")
parser.add_argument("--unsafestack",
action="store_true",
help="Force program not to check the stacks and the queue at runtime. "
"It'll get rid of burden for checking overflows or underflows for each push or pop operation,"
" but it may lead unexpected behavior if overflow or underflow take place")
if __name__ == "__main__":
option = CmdlineOption()
args = parser.parse_args()
option.source_file = args.source_file
option.dest = args.o
option.type = args.type
option.unsafestack = args.unsafestack
asm_str = None
with open(option.source_file, "r") as f:
c = Compiler()
ah_src = f.read()
c.compile(ah_src)
c.optimize2()
asm_str = c.write_asm()
if option.type == "ahssembly":
with open(option.dest or "a.out.ahs", "w") as ahs_f:
ahs_f.write(asm_str)
else:
ir_list = TacGenerator().generate(asm_str)
if option.type == "ir":
with open(option.dest or "a.out.ir", "w") as ir_f:
for ir in ir_list:
ir_f.write(repr(ir))
ir_f.write("\n")
else:
ccode = CCodeGenerator().generate(ir_list)
if option.type == "immediate":
with open(option.dest or "a.out.c", "w") as imd_f:
imd_f.write(ccode)
else:
with NamedTemporaryFile("w", suffix=".c") as tempf:
tempf.write(ccode)
tempf.flush()
macros = []
# safe stack option
if not option.unsafestack:
macros.append(("CHECK_STACK", None))
objpath = ccompiler.compile([tempf.name], macros=macros, extra_postargs=["-O3"])[0]
ccompiler.link(CCompiler.EXECUTABLE, [objpath], option.dest or "a.out")