-
Notifications
You must be signed in to change notification settings - Fork 0
/
cgen.cpp
100 lines (95 loc) · 3.14 KB
/
cgen.cpp
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
#include "cgen.h"
#include "code.h"
#include "symtab.h"
// * 全局变量, 假设有无数多个寄存器, 初始化变量时就保存到寄存器上了.
// * L的标号也是递增的, 从 L1 开始
int rs = 0;
int ls = 0;
string getL() {
ls++;
return "L" + to_string(ls);
}
string getR() {
rs++;
return "r" + to_string(rs);
}
string cGen(TreeNode* root) {
if (root == NULL) return "";
emitComment(root->nodekind);
TreeNode* p1, *p2, *p3;
if ("FunDecl" == root->nodekind) {
p1 = root->child[2];
p2 = root->child[3];
// TODO: 添加函数参数的中间代码
cGen(p2);
cGen(root->sibling);
} else if ("Compound" == root->nodekind) {
p1 = root->child[0];
p2 = root->child[1];
cGen(p1);
cGen(p2);
} else if ("LocVarDecl" == root->nodekind) {
// cGen(root->child[1]);
cGen(root->sibling);
} else if ("Assign" == root->nodekind) {
int addr = st_lookup(root->child[0]->name);
if (addr != -1) {
string left = getR();
emit("LD " + left + ", " + to_string(symtabs[root->child[0]->name].addr) + "\n");
string reg = cGen(root->child[1]);
// int right_addr = st_lookup(root->child[1]->name);
emit("[" + left + "]" + " = " + reg + "\n");
} else {
error("no such a id");
}
cGen(root->sibling);
} else if ("Selection" == root->nodekind) {
string cond = root->child[0]->name; // 条件
string l1 = getL(), l2 = getL();
emit("if " + cGen(root->child[0]));
emit(" goto ");
emit(l1 + "\n");
emit("goto ");
emit(l2 + "\n");
emit(l1 + ":\n");
cGen(root->child[1]);
emit(l2 + ":\n");
cGen(root->sibling); // * 这句一定要加
} else if ("Iteration" == root->nodekind) {
string l1 = getL(), l2 = getL();
emit(l1 + ":\n");
emit("if " + cGen(root->child[0]));
emit(" goto ");
emit(l2 + "\n");
cGen(root->child[1]);
emit(l2 + ":\n");
} else if ("CompareOp" == root->nodekind) {
// 比较操作符, 作为
string reg1 = getR(), reg2 = cGen(root->child[0]), reg3 = cGen(root->child[1]);
emit(reg1 + " = " + reg2 + " " + root->op + " " + reg3 + "\n");
return reg1;
} else if ("PMOp" == root->nodekind || "MDOp" == root->nodekind) {
string reg1 = getR(), reg2 = cGen(root->child[0]), reg3 = cGen(root->child[1]);
emit(reg1 + " = " + reg2 + " + " + reg3 + "\n");
return reg1;
} else if ("Id" == root->nodekind) {
if (st_lookup(root->name) != -1) {
string reg = getR();
emit("LD " + reg + ", [" + to_string(symtabs[root->name].addr) + "]\n");
return reg;
} else {
error("no such a id !!!");
return "";
}
} else if ("Const" == root->nodekind) {
string reg = getR();
emit("LD " + reg + " " + to_string(root->val) + "\n");
return reg;
}
return "";
}
void codeGen(TreeNode* root) {
emitComment("cminus IR generate");
cGen(root);
emit("halt");
}