-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
Copy pathdetree.c
173 lines (155 loc) · 4.28 KB
/
detree.c
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
#include "defs.h"
#define extern_
#include "data.h"
#undef extern_
#include "misc.h"
#include "tree.h"
// Deserialise an AST
// Copyright (c) 2023 Warren Toomey, GPL3
int showglue=0;
// Generate and return a new label number
// just for AST dumping purposes
static int dumpid = 1;
static int gendumplabel(void) {
return (dumpid++);
}
// List of AST node names
static char *astname[] = { NULL,
"ASSIGN", "ASPLUS", "ASMINUS", "ASSTAR",
"ASSLASH", "ASMOD", "TERNARY", "LOGOR",
"LOGAND", "OR", "XOR", "AND", "EQ", "NE", "LT",
"GT", "LE", "GE", "LSHIFT", "RSHIFT",
"ADD", "SUBTRACT", "MULTIPLY", "DIVIDE", "MOD",
"INTLIT", "STRLIT", "IDENT", "GLUE",
"IF", "WHILE", "FUNCTION", "WIDEN", "RETURN",
"FUNCCALL", "DEREF", "ADDR", "SCALE",
"PREINC", "PREDEC", "POSTINC", "POSTDEC",
"NEGATE", "INVERT", "LOGNOT", "TOBOOL", "BREAK",
"CONTINUE", "SWITCH", "CASE", "DEFAULT", "CAST"
};
// Given an AST node, print it out and then
// recursively deal with the sub-nodes.
void dumpAST(struct ASTnode *n, int label, int level) {
int Lfalse, Lstart, Lend;
int i;
struct ASTnode *nleft=NULL, *nmid=NULL, *nright=NULL;
if (n == NULL)
fatal("NULL AST node");
if (n->op > A_CAST)
fatald("Unknown dumpAST operator", n->op);
// Load in the sub-nodes
if (n->leftid) nleft=loadASTnode(n->leftid,0);
if (n->midid) nmid=loadASTnode(n->midid,0);
if (n->rightid) nright=loadASTnode(n->rightid,0);
// Deal with IF and WHILE statements specifically
switch (n->op) {
case A_IF:
Lfalse = gendumplabel();
for (i = 0; i < level; i++)
fprintf(stdout, " ");
fprintf(stdout, "IF");
if (nright) {
Lend = gendumplabel();
fprintf(stdout, ", end L%d", Lend);
}
fprintf(stdout, " (id %d)\n", n->nodeid);
dumpAST(nleft, Lfalse, level + 2);
dumpAST(nmid, NOLABEL, level + 2);
if (nright)
dumpAST(nright, NOLABEL, level + 2);
free(n);
return;
case A_WHILE:
Lstart = gendumplabel();
for (i = 0; i < level; i++)
fprintf(stdout, " ");
fprintf(stdout, "WHILE start L%d (id %d)\n", Lstart, n->nodeid);
Lend = gendumplabel();
dumpAST(nleft, Lend, level + 2);
if (nright)
dumpAST(nright, NOLABEL, level + 2);
free(n);
return;
}
// Reset level to -2 for A_GLUE nodes
if (n->op == A_GLUE) {
if (showglue) fprintf(stdout, "glue %d %d\n", n->leftid, n->rightid);
level -= 2;
} else {
// General AST node handling
for (i = 0; i < level; i++)
fprintf(stdout, " ");
fprintf(stdout, "%s", astname[n->op]);
if (n->symid != 0)
fprintf(stdout, " symid %d", n->symid);
switch (n->op) {
case A_FUNCTION:
case A_FUNCCALL:
case A_ADDR:
case A_PREINC:
case A_POSTINC:
if (n->name != NULL)
fprintf(stdout, " %s", n->name);
break;
case A_INTLIT:
fprintf(stdout, " %d", n->a_intvalue);
break;
case A_STRLIT:
fprintf(stdout, " rval \"%s\"", n->name);
break;
case A_IDENT:
if (n->name != NULL) {
if (n->rvalue)
fprintf(stdout, " rval %s", n->name);
else
fprintf(stdout, " %s", n->name);
}
break;
case A_DEREF:
if (n->rvalue)
fprintf(stdout, " rval");
break;
case A_SCALE:
fprintf(stdout, " %d", n->a_size);
break;
case A_CASE:
fprintf(stdout, " %d", n->a_intvalue);
break;
case A_CAST:
fprintf(stdout, " %d", n->type);
break;
}
fprintf(stdout, " (id %d)\n", n->nodeid);
}
// General AST node handling
if (nleft) dumpAST(nleft, NOLABEL, level + 2);
if (nmid) dumpAST(nmid, NOLABEL, level + 2);
if (nright) dumpAST(nright, NOLABEL, level + 2);
if (n->name!=NULL) free(n->name);
free(n);
}
int main(int argc, char **argv) {
struct ASTnode *node;
int fileid= 1;
if (argc !=2 && argc!=3) {
fprintf(stderr, "Usage: %s [-g] astfile\n", argv[0]); exit(1);
}
if (!strcmp(argv[1], "-g")) {
showglue=1; fileid=2;
}
Infile= fopen(argv[fileid], "r");
if (Infile==NULL) {
fprintf(stderr, "Unable to open %s\n", argv[fileid]); exit(1);
}
Idxfile= tmpfile();
mkASTidxfile(); // Build the AST index offset file
// Loop reading the next function's top node in from file
while (1) {
node= loadASTnode(0, 1);
if (node==NULL) break;
// Dump the function's tree
dumpAST(node, NOLABEL, 0);
printf("\n\n");
}
return (0);
}