-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.py
101 lines (77 loc) · 2.56 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
99
100
101
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 lex, 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)
# tac_prog.printTo()
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, p.globalVars)
asm = Asm(riscvAsmEmitter, BruteRegAlloc(riscvAsmEmitter))
prog = asm.transform(p)
return prog
def main():
args = parseArgs()
def _parse():
r = step_parse(args)
#print("\nParsed AST:\n")
#printer = TreePrinter(indentLen=2)
#printer.work(r)
return r
def _tac():
tac = step_tac(_parse())
#print("\nGenerated TAC:\n")
# tac.printTo()
return tac
def _asm():
asm = step_asm(_tac())
#print("\nGenerated ASM:\n")
#print(asm)
return asm
if args.riscv:
prog = _asm()
elif args.tac:
prog = _tac()
elif args.parse:
prog = _parse()
print(prog)
return
if __name__ == "__main__":
main()