node.c - scc - simple c99 compiler
HTML git clone git://git.simple-cc.org/scc
DIR Log
DIR Files
DIR Refs
DIR Submodules
DIR README
DIR LICENSE
---
node.c (3067B)
---
1 #include <stdlib.h>
2 #include <string.h>
3
4 #include <scc/scc.h>
5
6 #include "cc2.h"
7
8 #define NNODES 32
9
10 Symbol *curfun;
11
12 static Alloc *arena;
13 static Node *curstmt;
14
15 Node *
16 node(int op)
17 {
18 Node *np;
19
20 if (!arena)
21 arena = alloc(sizeof(Node), NNODES);
22 np = memset(new(arena), 0, sizeof(*np));
23 np->op = op;
24
25 return np;
26 }
27
28 #ifndef NDEBUG
29 #include <stdio.h>
30
31 static void
32 prnode(Node *np)
33 {
34 if (!np)
35 return;
36 prnode(np->left);
37 prnode(np->right);
38
39 switch (np->op) {
40 case OBRANCH:
41 case OJMP:
42 fprintf(stderr,
43 "\t%c -> L%u",
44 np->op, np->u.sym->numid);
45 break;
46 case OCONST:
47 fprintf(stderr,
48 "\t%c%lu{%llu}",
49 np->op, np->type.size, np->u.i);
50 break;
51 case OAUTO:
52 case OREG:
53 case OMEM:
54 case OLABEL:
55 case OTMP:
56 fprintf(stderr,
57 "\t%c%lu[%u]",
58 np->op, np->type.size, np->u.sym->numid);
59 break;
60 default:
61 fprintf(stderr,
62 "\t%c%lu",
63 np->op, np->type.size);
64 break;
65 }
66 fprintf(stderr,"(%d,%d)", np->complex, np->address);
67 }
68
69 void
70 prtree(Node *np)
71 {
72 Block *bb;
73
74 bb = np->bb;
75
76 if (np->flags & BBENTRY)
77 putc('>', stderr);
78 fprintf(stderr, "(%d)", bb ? bb->id : 0);
79 if (np->flags & BBEXIT)
80 putc('>', stderr);
81 putc('\t', stderr);
82 if (np->label)
83 fprintf(stderr, "L%u:", np->label->numid);
84
85 prnode(np);
86 putc('\n', stderr);
87 }
88
89 void
90 prforest(char *msg)
91 {
92 Node *np;
93
94 fprintf(stderr, "tree %s {\n", msg);
95 for (np = curfun->u.stmt; np; np = np->next)
96 prtree(np);
97 fputs("}\n", stderr);
98 }
99 #endif
100
101 Node *
102 insstmt(Node *np, Node *at)
103 {
104 Node *next;
105
106 next = at->next;
107 if (next)
108 next->prev = np;
109 at->next = np;
110
111 np->next = next;
112 np->prev = at;
113
114 return np;
115 }
116
117 Node *
118 unlinkstmt(Node *np)
119 {
120 Node *next, *prev;
121
122 next = np->next;
123 prev = np->prev;
124 if (next)
125 next->prev = prev;
126 if (prev)
127 prev->next = next;
128 np->next = np->prev = NULL;
129
130 return np;
131 }
132
133 Node *
134 prestmt(Node *np)
135 {
136 return insstmt(np, curstmt->prev);
137 }
138
139 Node *
140 savelabel(void)
141 {
142 Symbol *label = curstmt->label;
143
144 if (label) {
145 prestmt(labelstmt(NULL, label));
146 curstmt->label = NULL;
147 }
148 return curstmt;
149 }
150
151 Node *
152 addstmt(Node *np)
153 {
154 insstmt(np, curstmt);
155 return curstmt = np;
156 }
157
158 Node *
159 delstmt(Node *np)
160 {
161 Node *next;
162
163 next = np->next;
164 deltree(unlinkstmt(np));
165 return next;
166 }
167
168 void
169 delnode(Node *np)
170 {
171 delete(arena, np);
172 }
173
174 void
175 deltree(Node *np)
176 {
177 if (!np)
178 return;
179 deltree(np->left);
180 deltree(np->right);
181 delnode(np);
182 }
183
184 void
185 cleannodes(void)
186 {
187 if (arena) {
188 dealloc(arena);
189 arena = NULL;
190 }
191 curfun = NULL;
192 }
193
194 void
195 newfun(Symbol *sym, Node *np)
196 {
197 curfun = sym;
198 curstmt = curfun->u.stmt = np;
199 }
200
201 void
202 delrange(Node *begin, Node *end)
203 {
204 Node *lprev, *rnext, *next, *np;
205
206 lprev = begin->prev;
207 rnext = end->next;
208
209 if (lprev)
210 lprev->next = rnext;
211 if (rnext)
212 rnext->prev = lprev;
213
214 for (np = begin; np != rnext; np = next) {
215 next = np->next;
216 deltree(np);
217 }
218 }
219
220 void
221 apply(Node *(*fun)(Node *))
222 {
223 Node *np, *ocurstmt;
224
225 for (curstmt = curfun->u.stmt; curstmt; curstmt = np) {
226 ocurstmt = curstmt;
227 np = (*fun)(curstmt);
228 np = (np) ? np->next : delstmt(ocurstmt);
229 }
230 }