-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.py
98 lines (74 loc) · 2.44 KB
/
main.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
import argparse
import sys
from backend.asm import Asm
from backend.reg.bruteregalloc import BruteRegAlloc
from backend.riscv.riscvasmemitter import RiscvAsmEmitter
from frontend.ast.tree import Program
from frontend.lexer import lexer
from frontend.parser import parser
from frontend.tacgen.tacgen import TACGen
from frontend.typecheck.namer import Namer
from frontend.typecheck.typer import Typer
from utils.printtree import TreePrinter
from utils.riscv import Riscv
from utils.tac.tacprog import TACProg
def parseArgs():
parser = argparse.ArgumentParser(description="MiniDecaf compiler")
parser.add_argument("--input", type=str, help="the input C file")
parser.add_argument("--parse", action="store_true", help="output parsed AST")
parser.add_argument("--tac", action="store_true", help="output transformed TAC")
parser.add_argument("--riscv", action="store_true", help="output generated RISC-V")
return parser.parse_args()
def readCode(fileName):
with open(fileName, "r") as f:
return f.read()
# The parser stage: MiniDecaf code -> Abstract syntax tree
def step_parse(args: argparse.Namespace):
code = readCode(args.input)
r: Program = parser.parse(code, lexer=lexer)
errors = parser.error_stack
if errors:
print("\n".join(map(str, errors)), file=sys.stderr)
exit(1)
return r
# IR generation stage: Abstract syntax tree -> Three-address code
def step_tac(p: Program):
namer = Namer()
p = namer.transform(p)
typer = Typer()
p = typer.transform(p)
tacgen = TACGen()
tac_prog = tacgen.transform(p)
return tac_prog
# Target code generation stage: Three-address code -> RISC-V assembly code
def step_asm(p: TACProg):
riscvAsmEmitter = RiscvAsmEmitter(Riscv.AllocatableRegs, Riscv.CallerSaved)
asm = Asm(riscvAsmEmitter, BruteRegAlloc(riscvAsmEmitter))
prog = asm.transform(p)
return prog
# hope all of you happiness
# enjoy potato chips
def main():
args = parseArgs()
def _parse():
r = step_parse(args)
return r
def _tac():
tac = step_tac(_parse())
return tac
def _asm():
asm = step_asm(_tac())
return asm
if args.riscv:
prog = _asm()
print(prog)
elif args.tac:
prog = _tac()
prog.printTo()
elif args.parse:
prog = _parse()
printer = TreePrinter(indentLen=2)
printer.work(prog)
return
if __name__ == "__main__":
main()