]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/cc/acid.c
merge
[plan9front.git] / sys / src / cmd / cc / acid.c
1 #include "cc.h"
2
3 static char *kwd[] =
4 {
5         "$adt", "$aggr", "$append", "$builtin", "$complex", "$defn",
6         "$delete", "$do", "$else", "$eval", "$head", "$if",
7         "$local", "$loop", "$return", "$tail", "$then",
8         "$union", "$whatis", "$while",
9 };
10
11 char*
12 amap(char *s)
13 {
14         int i, bot, top, new;
15
16         bot = 0;
17         top = bot + nelem(kwd) - 1;
18         while(bot <= top){
19                 new = bot + (top - bot)/2;
20                 i = strcmp(kwd[new]+1, s);
21                 if(i == 0)
22                         return kwd[new];
23
24                 if(i < 0)
25                         bot = new + 1;
26                 else
27                         top = new - 1;
28         }
29         return s;
30 }
31
32 Sym*
33 acidsue(Type *t)
34 {
35         int h;
36         Sym *s;
37
38         if(t != T)
39         for(h=0; h<nelem(hash); h++)
40                 for(s = hash[h]; s != S; s = s->link)
41                         if(s->suetag && s->suetag->link == t)
42                                 return s;
43         return 0;
44 }
45
46 Sym*
47 acidfun(Type *t)
48 {
49         int h;
50         Sym *s;
51
52         for(h=0; h<nelem(hash); h++)
53                 for(s = hash[h]; s != S; s = s->link)
54                         if(s->type == t)
55                                 return s;
56         return 0;
57 }
58
59 char    acidchar[NTYPE];
60 Init    acidcinit[] =
61 {
62         TCHAR,          'C',    0,
63         TUCHAR,         'b',    0,
64         TSHORT,         'd',    0,
65         TUSHORT,        'u',    0,
66         TLONG,          'D',    0,
67         TULONG,         'U',    0,
68         TVLONG,         'V',    0,
69         TUVLONG,        'W',    0,
70         TFLOAT,         'f',    0,
71         TDOUBLE,        'F',    0,
72         TARRAY,         'a',    0,
73         TIND,           'X',    0,
74         -1,             0,      0,
75 };
76
77 static void
78 acidinit(void)
79 {
80         Init *p;
81
82         for(p=acidcinit; p->code >= 0; p++)
83                 acidchar[p->code] = p->value;
84
85         acidchar[TINT] = acidchar[TLONG];
86         acidchar[TUINT] = acidchar[TULONG];
87         if(types[TINT]->width != types[TLONG]->width) {
88                 acidchar[TINT] = acidchar[TSHORT];
89                 acidchar[TUINT] = acidchar[TUSHORT];
90                 if(types[TINT]->width != types[TSHORT]->width)
91                         warn(Z, "acidmember int not long or short");
92         }
93         if(types[TIND]->width == types[TUVLONG]->width)
94                 acidchar[TIND] = 'Y';
95         
96 }
97
98 void
99 acidmember(Type *t, long off, int flag)
100 {
101         Sym *s, *s1;
102         Type *l;
103         static int acidcharinit = 0;
104
105         if(acidcharinit == 0) {
106                 acidinit();
107                 acidcharinit = 1;
108         }
109         s = t->sym;
110         switch(t->etype) {
111         default:
112                 Bprint(&outbuf, "       T%d\n", t->etype);
113                 break;
114
115         case TIND:
116                 if(s == S)
117                         break;
118                 if(flag) {
119                         for(l=t; l->etype==TIND; l=l->link)
120                                 ;
121                         if(typesu[l->etype]) {
122                                 s1 = acidsue(l->link);
123                                 if(s1 != S) {
124                                         Bprint(&outbuf, "       'A' %s %ld %s;\n",
125                                                 amap(s1->name),
126                                                 t->offset+off, amap(s->name));
127                                         break;
128                                 }
129                         }
130                 } else {
131                         Bprint(&outbuf,
132                                 "\tprint(\"\t%s\t\", addr.%s\\X, \"\\n\");\n",
133                                 amap(s->name), amap(s->name));
134                         break;
135                 }
136
137         case TINT:
138         case TUINT:
139         case TCHAR:
140         case TUCHAR:
141         case TSHORT:
142         case TUSHORT:
143         case TLONG:
144         case TULONG:
145         case TVLONG:
146         case TUVLONG:
147         case TFLOAT:
148         case TDOUBLE:
149         case TARRAY:
150                 if(s == S)
151                         break;
152                 if(flag) {
153                         Bprint(&outbuf, "       '%c' %ld %s;\n",
154                         acidchar[t->etype], t->offset+off, amap(s->name));
155                 } else {
156                         Bprint(&outbuf, "\tprint(\"\t%s\t\", addr.%s, \"\\n\");\n",
157                                 amap(s->name), amap(s->name));
158                 }
159                 break;
160
161         case TSTRUCT:
162         case TUNION:
163                 s1 = acidsue(t->link);
164                 if(s1 == S)
165                         break;
166                 if(flag) {
167                         if(s == S) {
168                                 Bprint(&outbuf, "       {\n");
169                                 for(l = t->link; l != T; l = l->down)
170                                         acidmember(l, t->offset+off, flag);
171                                 Bprint(&outbuf, "       };\n");
172                         } else {
173                                 Bprint(&outbuf, "       %s %ld %s;\n",
174                                         amap(s1->name),
175                                         t->offset+off, amap(s->name));
176                         }
177                 } else {
178                         if(s != S) {
179                                 Bprint(&outbuf, "\tprint(\"%s %s {\\n\");\n",
180                                         amap(s1->name), amap(s->name));
181                                 Bprint(&outbuf, "\t%s(addr.%s);\n",
182                                         amap(s1->name), amap(s->name));
183                                 Bprint(&outbuf, "\tprint(\"}\\n\");\n");
184                         } else {
185                                 Bprint(&outbuf, "\tprint(\"%s {\\n\");\n",
186                                         amap(s1->name));
187                                 Bprint(&outbuf, "\t\t%s(addr+%ld);\n",
188                                         amap(s1->name), t->offset+off);
189                                 Bprint(&outbuf, "\tprint(\"}\\n\");\n");
190                         }
191                 }
192                 break;
193         }
194 }
195
196 void
197 acidtype(Type *t)
198 {
199         Sym *s;
200         Type *l;
201         Io *i;
202         int n;
203         char *an;
204
205         if(!debug['a'])
206                 return;
207         if(debug['a'] > 1) {
208                 n = 0;
209                 for(i=iostack; i; i=i->link)
210                         n++;
211                 if(n > 1)
212                         return;
213         }
214         s = acidsue(t->link);
215         if(s == S)
216                 return;
217         switch(t->etype) {
218         default:
219                 Bprint(&outbuf, "T%d\n", t->etype);
220                 return;
221
222         case TUNION:
223         case TSTRUCT:
224                 if(debug['s'])
225                         goto asmstr;
226                 an = amap(s->name);
227                 Bprint(&outbuf, "sizeof%s = %ld;\n", an, t->width);
228                 Bprint(&outbuf, "aggr %s\n{\n", an);
229                 for(l = t->link; l != T; l = l->down)
230                         acidmember(l, 0, 1);
231                 Bprint(&outbuf, "};\n\n");
232
233                 Bprint(&outbuf, "defn\n%s(addr) {\n\tcomplex %s addr;\n", an, an);
234                 for(l = t->link; l != T; l = l->down)
235                         acidmember(l, 0, 0);
236                 Bprint(&outbuf, "};\n\n");
237                 break;
238         asmstr:
239                 if(s == S)
240                         break;
241                 for(l = t->link; l != T; l = l->down)
242                         if(l->sym != S)
243                                 Bprint(&outbuf, "#define\t%s.%s\t%ld\n",
244                                         s->name,
245                                         l->sym->name,
246                                         l->offset);
247                 break;
248         }
249 }
250
251 void
252 acidvar(Sym *s)
253 {
254         int n;
255         Io *i;
256         Type *t;
257         Sym *s1, *s2;
258
259         if(!debug['a'] || debug['s'])
260                 return;
261         if(debug['a'] > 1) {
262                 n = 0;
263                 for(i=iostack; i; i=i->link)
264                         n++;
265                 if(n > 1)
266                         return;
267         }
268         t = s->type;
269         while(t && t->etype == TIND)
270                 t = t->link;
271         if(t == T)
272                 return;
273         if(t->etype == TENUM) {
274                 Bprint(&outbuf, "%s = ", amap(s->name));
275                 if(!typefd[t->etype])
276                         Bprint(&outbuf, "%lld;\n", s->vconst);
277                 else
278                         Bprint(&outbuf, "%f\n;", s->fconst);
279                 return;
280         }
281         if(!typesu[t->etype])
282                 return;
283         s1 = acidsue(t->link);
284         if(s1 == S)
285                 return;
286         switch(s->class) {
287         case CAUTO:
288         case CPARAM:
289                 s2 = acidfun(thisfn);
290                 if(s2)
291                         Bprint(&outbuf, "complex %s %s:%s;\n",
292                                 amap(s1->name), amap(s2->name), amap(s->name));
293                 break;
294         
295         case CSTATIC:
296         case CEXTERN:
297         case CGLOBL:
298         case CLOCAL:
299                 Bprint(&outbuf, "complex %s %s;\n",
300                         amap(s1->name), amap(s->name));
301                 break;
302         }
303 }