code.c - scc - simple c99 compiler
(HTM) git clone git://git.simple-cc.org/scc
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
code.c (3407B)
---
1 #include <ctype.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 #include <scc/scc.h>
7
8 #include "cc2.h"
9
10 Inst *pc, *prog;
11
12 static void
13 nextpc(void)
14 {
15 Inst *new;
16
17 new = xcalloc(1, sizeof(*new)); /* TODO: create an arena */
18
19 if (!pc) {
20 prog = new;
21 } else {
22 new->next = pc->next;
23 pc->next = new;
24 }
25
26 /* SNONE being 0, calloc initialized {from1,from2,to}.kind for us */
27 new->prev = pc;
28 pc = new;
29 }
30
31 static void
32 addr(Node *np, Addr *addr)
33 {
34 Symbol *sym;
35
36 switch (np->op) {
37 case OMREG:
38 addr->kind = SREG;
39 addr->u.reg = np->u.reg;
40 break;
41 case OCONST:
42 addr->kind = SCONST;
43 /* TODO: Add support for more type of constants */
44 addr->u.i = np->u.i;
45 break;
46 case OINDEX:
47 addr->kind = SINDEX;
48 addr->u.off = np->u.off;
49 break;
50 case OREG:
51 case OTMP:
52 case OLABEL:
53 case OAUTO:
54 case OMEM:
55 sym = np->u.sym;
56 addr->kind = sym->kind;
57 addr->u.sym = sym;
58 break;
59 default:
60 abort();
61 }
62 }
63
64 void
65 pprint(char *s)
66 {
67 int c;
68 char *t;
69
70 putchar('"');
71 while ((c = *s++) != '\0') {
72 switch (c) {
73 case '\n':
74 t = "\\n";
75 goto print_str;
76 case '\v':
77 t = "\\v";
78 goto print_str;
79 case '\b':
80 t = "\\b";
81 goto print_str;
82 case '\t':
83 t = "\\t";
84 goto print_str;
85 case '\a':
86 t = "\\a";
87 goto print_str;
88 case '\f':
89 t = "\\f";
90 goto print_str;
91 case '\r':
92 t = "\\r";
93 goto print_str;
94 case '"':
95 t = "\\\"";
96 goto print_str;
97 case '\'':
98 t = "\\'";
99 goto print_str;
100 case '\?':
101 t = "\\\?";
102 goto print_str;
103 case '\\':
104 putchar('\\');
105 default:
106 if (!isprint(c))
107 printf("\\x%x", c);
108 else
109 putchar(c);
110 break;
111 print_str:
112 fputs(t, stdout);
113 break;
114 }
115 }
116 putchar('"');
117 }
118
119 Symbol *
120 newlabel(void)
121 {
122 Symbol *sym = getsym(TMPSYM);
123
124 sym->kind = SLABEL;
125 return sym;
126 }
127
128 Node *
129 labelstmt(Node *np, Symbol *sym)
130 {
131 if(!sym)
132 sym = newlabel();
133 if (!np)
134 np = node(ONOP);
135 np->label = sym;
136 sym->u.stmt = np;
137
138 return np;
139 }
140
141 Node *
142 label2node(Node *np, Symbol *sym)
143 {
144 if(!sym)
145 sym = newlabel();
146 if (!np)
147 np = node(OLABEL);
148 np->op = OLABEL;
149 np->u.sym = sym;
150
151 return np;
152 }
153
154 Node *
155 tmpnode(Type *tp, Symbol *sym)
156 {
157 unsigned short flags;
158 Node *np;
159
160 np = node(OTMP);
161 if (!sym) {
162 sym = getsym(TMPSYM);
163 sym->type = np->type = *tp;
164 sym->kind = STMP;
165 }
166
167 flags = tp->flags & ~(PARF|INITF);
168 sym->type.flags = np->type.flags = flags;
169 np->type = *tp;
170 np->left = np->right = NULL;
171 np->u.sym = sym;
172 np->op = OTMP;
173
174 return np;
175 }
176
177 Node *
178 idxnode(Node *np, long off)
179 {
180 if (!np)
181 np = node(OINDEX);
182 np->op = OINDEX;
183 np->left = np->right = NULL;
184 np->type = ptrtype;
185 np->u.off = off;
186 return np;
187 }
188
189 Node *
190 constnode(Node *np, TUINT n, Type *tp)
191 {
192 if (!np)
193 np = node(OCONST);
194 np->op = OCONST;
195 np->left = np->right = NULL;
196 np->type = *tp;
197 np->u.i = n;
198 return np;
199 }
200
201 void
202 setlabel(Symbol *sym)
203 {
204 if (!sym)
205 return;
206 code(ASLABEL, NULL, NULL, NULL);
207 pc->label = sym;
208 sym->u.inst = pc;
209 }
210
211 void
212 code(int op, Node *to, Node *from1, Node *from2)
213 {
214 nextpc();
215 if (from1)
216 addr(from1, &pc->from1);
217 if (from2)
218 addr(from2, &pc->from2);
219 if (to)
220 addr(to, &pc->to);
221 pc->op = op;
222 }
223
224 void
225 delcode(void)
226 {
227 Inst *prev = pc->prev, *next = pc->next;
228
229 free(pc);
230 if (!prev) {
231 prog = pc = next;
232 } else {
233 pc = prev;
234 prev->next = next;
235 if (next)
236 next->prev = prev;
237 }
238 }