1
|
1 /* Micro-C tree print routine */
|
607
|
2
|
|
3 /************************************************************************
|
|
4 ** Copyright (C) 2006 Shinji Kono
|
|
5 ** 連絡先: 琉球大学情報工学科 河野 真治
|
|
6 ** (E-Mail Address: kono@ie.u-ryukyu.ac.jp)
|
|
7 **
|
|
8 ** このソースのいかなる複写,改変,修正も許諾します。ただし、
|
|
9 ** その際には、誰が貢献したを示すこの部分を残すこと。
|
|
10 ** 再配布や雑誌の付録などの問い合わせも必要ありません。
|
|
11 ** 営利利用も上記に反しない範囲で許可します。
|
|
12 ** バイナリの配布の際にはversion messageを保存することを条件とします。
|
|
13 ** このプログラムについては特に何の保証もしない、悪しからず。
|
|
14 **
|
|
15 ** Everyone is permitted to do anything on this program
|
|
16 ** including copying, modifying, improving,
|
|
17 ** as long as you don't try to pretend that you wrote it.
|
|
18 ** i.e., the above copyright notice has to appear in all copies.
|
|
19 ** Binary distribution requires original version messages.
|
|
20 ** You don't have to ask before copying, redistribution or publishing.
|
|
21 ** THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
|
|
22 ***********************************************************************/
|
1
|
23
|
327
|
24 #include <stdio.h>
|
0
|
25 #include "mc.h"
|
327
|
26 #include "mc-parse.h"
|
596
|
27 #include "mc-codegen.h"
|
0
|
28
|
680
|
29 extern void tree_print(int e);
|
|
30 extern void tree_parse(int e);
|
|
31 extern void tree_print_t(int e,int t);
|
|
32 extern void type_print(int type,NMTBL *n,FILE *out);
|
|
33 extern void type_print1(int type,NMTBL *n,FILE *out,int cont);
|
|
34 extern void sym_print(int type,FILE *out);
|
|
35 static void print_function_call(int e, FILE *out);
|
|
36 static void print_operator(int e, FILE *vout);
|
|
37 static void print_statement(int e, FILE *vout);
|
|
38
|
|
39 /* ascendant order for binary search */
|
|
40
|
0
|
41 typedef
|
|
42 struct tree_node {
|
|
43 int tree_type;
|
|
44 char *tree_name;
|
|
45 char *tree_args;
|
680
|
46 int tree_order;
|
0
|
47 } tree_node_type;
|
|
48
|
680
|
49 static int
|
|
50 tree_nodes(int id, char **name, char **args, int *order) {
|
|
51 int found = 1;
|
|
52 switch(id%SOP) {
|
|
53 case DOTS: *name = "..."; *args=""; *order=-1; break;
|
|
54 case LMACRO: *name = "lmacro"; *args=""; *order=-1; break;
|
|
55 case FMACRO: *name = "fmacro"; *args=""; *order=-1; break;
|
|
56 case KONST: *name = "const"; *args=""; *order=-1; break;
|
|
57 case DEFINED: *name = "defined"; *args=""; *order=14; break;
|
|
58 case ENVIRONMENT: *name = "environment"; *args=""; *order=14; break;
|
|
59 case CODE: *name = "code"; *args=""; *order=-1; break;
|
|
60 case C_FILE: *name = "__FILE__"; *args=""; *order=14; break;
|
|
61 case C_FUNCTION: *name = "__FUNCTION__"; *args=""; *order=14; break;
|
|
62 case C_LINE: *name = "__LINE__"; *args=""; *order=14; break;
|
|
63 case REGISTER: *name = "register"; *args=""; *order=-1; break;
|
|
64 case CAST: *name = "cast"; *args="e"; *order=14; break;
|
|
65 case ASM: *name = "__asm__"; *args="eeee"; *order=-1; break;
|
|
66 case ST_ASM: *name = "__asm__"; *args="eeee"; *order=-1; break;
|
|
67 case VOID: *name = "void"; *args=""; *order=-1; break;
|
|
68 case EXTRN: *name = "extern"; *args=""; *order=14; break;
|
|
69 case EXTRN1: *name = "extern"; *args=""; *order=14; break;
|
|
70 case SHORT: *name = "short"; *args=""; *order=-1; break;
|
|
71 case USHORT: *name = "unsigned short"; *args=""; *order=-1; break;
|
|
72 case LONG: *name = "long"; *args=""; *order=-1; break;
|
|
73 case TYPE: *name = "type"; *args=""; *order=-1; break;
|
|
74 case VOLATILE: *name = "volatile"; *args=""; *order=-1; break;
|
|
75 case SIZEOF: *name = "sizeof"; *args="e"; *order=13; break;
|
|
76 case TYPEDEF: *name = "typedef"; *args=""; *order=-1; break;
|
|
77 case FLABEL: *name = "flabel"; *args=""; *order=-1; break;
|
|
78 case BLABEL: *name = "blabel"; *args=""; *order=-1; break;
|
|
79 case LABEL: *name = "label"; *args="e"; *order=-1; break;
|
|
80 case ST_LABEL: *name = "label"; *args="e"; *order=-1; break;
|
|
81 case MACRO: *name = "macro"; *args=""; *order=-1; break;
|
|
82 case STRING: *name = "string"; *args=""; *order=14; break;
|
|
83 case IDENT: *name = "ident"; *args=""; *order=14; break;
|
|
84 case ENUM: *name = "enum"; *args=""; *order=14; break;
|
|
85 case FIELD: *name = "field"; *args=""; *order=-1; break;
|
|
86 case TAG: *name = "tag"; *args=""; *order=-1; break;
|
|
87 case RESERVE: *name = "reserve"; *args=""; *order=-1; break;
|
|
88 case ST_DEFAULT: *name = "default"; *args=""; *order=-1; break;
|
|
89 case ATTRIBUTE: *name = "__attribute__"; *args=""; *order=-1; break;
|
|
90 case ST_CASE: *name = "case"; *args=""; *order=-1; break;
|
|
91 case ST_SWITCH: *name = "switch"; *args=""; *order=-1; break;
|
|
92 case ST_WHILE: *name = "while"; *args=""; *order=-1; break;
|
|
93 case ST_DO: *name = "do"; *args=""; *order=-1; break;
|
|
94 case ST_FOR: *name = "for"; *args=""; *order=-1; break;
|
|
95 case ELSE: *name = "else"; *args=""; *order=-1; break;
|
|
96 case ST_IF: *name = "if"; *args=""; *order=-1; break;
|
|
97 case CONTINUE: *name = "continue"; *args=""; *order=-1; break;
|
|
98 case BREAK: *name = "break"; *args=""; *order=-1; break;
|
|
99 case ST_RETURN: *name = "return"; *args="e"; *order=-1; break;
|
|
100 case RETURN: *name = "return"; *args=""; *order=14; break;
|
|
101 case ST_GOTO: *name = "goto"; *args=""; *order=-1; break;
|
|
102 case JUMP: *name = "goto"; *args=""; *order=-1; break;
|
|
103 case STATIC: *name = "static"; *args=""; *order=14; break;
|
|
104 case EMPTY: *name = "empty"; *args=""; *order=-1; break;
|
|
105 case FUNCTION: *name = "function"; *args="t"; *order=15; break;
|
|
106 case UNION: *name = "union"; *args=""; *order=-1; break;
|
|
107 case STRUCT: *name = "struct"; *args="vt"; *order=-1; break;
|
|
108 case ARRAY: *name = "array"; *args="tv"; *order=16; break;
|
|
109 case POINTER: *name = "*"; *args="t"; *order=-1; break;
|
|
110 case UNSIGNED: *name = "unsigned"; *args=""; *order=-1; break;
|
|
111 case INLINE: *name = "inline"; *args=""; *order=-1; break;
|
|
112 case SIGNED: *name = "signed"; *args=""; *order=-1; break;
|
|
113 case CHAR: *name = "char"; *args=""; *order=-1; break;
|
|
114 case UCHAR: *name = "unsigned char"; *args=""; *order=-1; break;
|
|
115 case INT: *name = "int"; *args=""; *order=-1; break;
|
|
116 case FLOAT: *name = "float"; *args=""; *order=-1; break;
|
|
117 case DOUBLE: *name = "double"; *args=""; *order=-1; break;
|
|
118 case LONGLONG: *name = "long long"; *args=""; *order=-1; break;
|
|
119 case ULONGLONG: *name = "unsigned long long"; *args=""; *order=-1; break;
|
37
|
120
|
680
|
121 case GVAR: *name = "gvar"; *args="vs"; *order=14; break;
|
|
122 case IVAR: *name = "ivar"; *args="vs"; *order=14; break;
|
|
123 case RGVAR: *name = "rgvar"; *args="vs"; *order=14; break;
|
|
124 case CRGVAR: *name = "crgvar"; *args="vs"; *order=14; break;
|
|
125 case LVAR: *name = "lvar"; *args="v"; *order=14; break;
|
|
126 case RLVAR: *name = "rlvar"; *args="v"; *order=14; break;
|
|
127 case CRLVAR: *name = "crlvar"; *args="v"; *order=14; break;
|
|
128 case CONST: *name = "const"; *args="v"; *order=14; break;
|
|
129 case FNAME: *name = "fname"; *args="n"; *order=14; break;
|
|
130 case MUL: *name = "*"; *args="e"; *order=-1; break;
|
|
131 case RINDIRECT: *name = "*"; *args="e"; *order=13; break;
|
|
132 case CRINDIRECT: *name = "*"; *args="e"; *order=13; break;
|
|
133 case ADDRESS: *name = "&"; *args="e"; *order=13; break;
|
|
134 case BAND: *name = "&"; *args="e"; *order=7; break;
|
|
135 case MINUS: *name = "-"; *args="e"; *order=13; break;
|
|
136 case LNOT: *name = "!"; *args="e"; *order=13; break;
|
|
137 case BNOT: *name = "~"; *args="e"; *order=13; break;
|
|
138 case INC: *name = "++"; *args=""; *order=13; break;
|
|
139 case ALLOCA: *name = "alloca"; *args="e"; *order=13; break;
|
|
140 case BUILTINP: *name = "__builtinp"; *args="e"; *order=13; break;
|
|
141 case BUILTIN_EXPECT: *name = "__builtin_expect"; *args="ee"; *order=13; break;
|
|
142 case BUILTIN_FABSF: *name = "__builtin_fabsf"; *args="e"; *order=13; break;
|
|
143 case BUILTIN_FABS: *name = "__builtin_fbas"; *args="e"; *order=13; break;
|
|
144 case BUILTIN_FABSL: *name = "__builtin_fbasl"; *args="e"; *order=13; break;
|
|
145 case BUILTIN_INFF: *name = "__builtin_inff"; *args=""; *order=13; break;
|
|
146 case BUILTIN_INF: *name = "__builtin_inf"; *args=""; *order=13; break;
|
|
147 case BUILTIN_INFL: *name = "__builtin_infl"; *args=""; *order=13; break;
|
|
148 case POSTINC: *name = "++"; *args="ee"; *order=13; break;
|
|
149 case BPOSTINC: *name = "++"; *args="ee"; *order=13; break;
|
|
150 case PREINC: *name = "++"; *args="ee"; *order=13; break;
|
|
151 case CPOSTINC: *name = "++"; *args="ee"; *order=13; break;
|
|
152 case CPREINC: *name = "++"; *args="ee"; *order=13; break;
|
|
153 case DEC: *name = "--"; *args="e"; *order=13; break;
|
|
154 case DIV: *name = "/"; *args="ee"; *order=12; break;
|
|
155 case UDIV: *name = "/"; *args="ee"; *order=12; break;
|
|
156
|
|
157 case UMUL: *name = "*"; *args="ee"; *order=12; break;
|
|
158 case MOD: *name = "%"; *args="ee"; *order=12; break;
|
|
159 case UMOD: *name = "%"; *args="ee"; *order=12; break;
|
|
160 case ADD: *name = "+"; *args="ee"; *order=11; break;
|
|
161 case SUB: *name = "-"; *args="ee"; *order=11; break;
|
|
162 case RSHIFT: *name = ">>"; *args="ee"; *order=10; break;
|
|
163 case URSHIFT: *name = ">>"; *args="ee"; *order=10; break;
|
|
164 case LSHIFT: *name = "<<"; *args="ee"; *order=10; break;
|
|
165 case ULSHIFT: *name = "<<"; *args="ee"; *order=10; break;
|
|
166 case GT: *name = ">"; *args="ee"; *order=9; break;
|
|
167 case UGT: *name = ">"; *args="ee"; *order=9; break;
|
|
168 case GE: *name = ">="; *args="ee"; *order=9; break;
|
|
169 case UGE: *name = ">="; *args="ee"; *order=9; break;
|
|
170 case LT: *name = "<"; *args="ee"; *order=9; break;
|
|
171 case ULT: *name = "<"; *args="ee"; *order=9; break;
|
|
172 case LE: *name = "<="; *args="ee"; *order=9; break;
|
|
173 case ULE: *name = "<="; *args="ee"; *order=9; break;
|
|
174 case EQ: *name = "=="; *args="ee"; *order=8; break;
|
|
175 case NEQ: *name = "!="; *args="ee"; *order=8; break;
|
|
176
|
|
177 case EOR: *name = "^"; *args="ee"; *order=6; break;
|
|
178 case BOR: *name = "|"; *args="ee"; *order=5; break;
|
|
179 case LAND: *name = "&&"; *args="ee"; *order=4; break;
|
|
180 case LOR: *name = "||"; *args="ee"; *order=-1; break;
|
|
181 case COND: *name = "?"; *args="eee"; *order=2; break;
|
|
182 case ASS: *name = "="; *args="ee"; *order=1; break;
|
|
183 case ASSOP: *name = "assop"; *args="eev"; *order=1; break;
|
|
184 case CASSOP: *name = "cassop"; *args="eev"; *order=1; break;
|
|
185 case COMMA: *name = "; *args=","ee"; *order=0; break;
|
|
186 case LPAR: *name = "("; *args=""; *order=-1; break;
|
|
187 case RPAR: *name = ")"; *args=""; *order=-1; break;
|
|
188 case LBRA: *name = "["; *args=""; *order=-1; break;
|
|
189 case RBRA: *name = "]"; *args=""; *order=-1; break;
|
|
190 case LC: *name = "{"; *args=""; *order=-1; break;
|
|
191 case RC: *name = "}"; *args=""; *order=-1; break;
|
|
192 case COLON: *name = ":"; *args="ee"; *order=-1; break;
|
|
193 case SM: *name = ";"; *args=""; *order=-1; break;
|
|
194 case PERIOD: *name = "."; *args=""; *order=16; break;
|
|
195 case ARROW: *name = "->"; *args=""; *order=16; break;
|
|
196 case SASS: *name = "sass"; *args=""; *order=-1; break;
|
|
197 case RSTRUCT: *name = "rstruct"; *args=""; *order=-1; break;
|
|
198 case AS+MUL: *name = "*="; *args="ee"; *order=1; break;
|
|
199 case AS+UMUL: *name = "*="; *args="ee"; *order=1; break;
|
|
200 case AS+DIV: *name = "/="; *args="ee"; *order=1; break;
|
|
201 case AS+UDIV: *name = "/="; *args="ee"; *order=1; break;
|
|
202 case AS+MOD: *name = "%="; *args="ee"; *order=1; break;
|
|
203 case AS+UMOD: *name = "%="; *args="ee"; *order=1; break;
|
|
204 case AS+ADD: *name = "+="; *args="ee"; *order=1; break;
|
|
205 case AS+MINUS: *name = "-="; *args="ee"; *order=1; break;
|
|
206 case AS+RSHIFT: *name = ">>="; *args="ee"; *order=1; break;
|
|
207 case AS+URSHIFT: *name = ">>="; *args="ee"; *order=1; break;
|
|
208 case AS+LSHIFT: *name = "<<="; *args="ee"; *order=1; break;
|
|
209 case AS+ULSHIFT: *name = "<<="; *args="ee"; *order=1; break;
|
|
210 case AS+BAND: *name = "&="; *args="ee"; *order=1; break;
|
|
211 case AS+EOR: *name = "^="; *args="ee"; *order=1; break;
|
|
212 case AS+BOR: *name = "|="; *args="ee"; *order=1; break;
|
|
213 default: found = 0;
|
|
214 fprintf(stderr,"Unknown ID %d [%d]in find node\n",id,OP(id));
|
|
215
|
|
216 }
|
|
217 return found;
|
|
218 }
|
0
|
219
|
564
|
220 static int
|
|
221 attr_print(int t)
|
|
222 {
|
|
223 while (t>0 && car(t)==ATTRIBUTE) {
|
|
224 switch (caddr(t)) {
|
|
225 case KONST: printf( "const"); break;
|
|
226 case VOLATILE: printf( "volatile"); break;
|
|
227 case RESTRICT: printf( "restrict"); break;
|
|
228 case INLINE: printf( "inline"); break;
|
|
229 }
|
|
230 t = cadr(t);
|
|
231 }
|
|
232 return t;
|
|
233 }
|
|
234
|
18
|
235 void
|
50
|
236 tree_print_t(int e,int t)
|
|
237 {
|
|
238 printf("# type: ");
|
|
239 tree_print(t);
|
|
240 printf("expr: ");
|
|
241 tree_print(e);
|
|
242 printf("\n");
|
|
243 }
|
|
244
|
|
245 void
|
0
|
246 tree_print(int e)
|
|
247 {
|
|
248 printf("* generate code on type:\n* ");
|
|
249 tree_parse(type);
|
|
250 printf("\n* expr:\n* ");
|
|
251 tree_parse(e);
|
|
252 printf("\n");
|
|
253 }
|
|
254
|
18
|
255 static
|
0
|
256 int tree_level;
|
|
257
|
18
|
258 void
|
0
|
259 tree_parse(int e)
|
|
260 {
|
680
|
261 tree_node_type node_type,*t;
|
0
|
262 int i,j;
|
712
|
263 char *s, **p;
|
|
264 NMTBL **n;
|
0
|
265
|
680
|
266 t = &node_type; t->tree_type=e;
|
|
267
|
0
|
268 if(e<0) {
|
680
|
269 if (tree_nodes(e,&t->tree_name,&t->tree_args,&t->tree_order)) {
|
67
|
270 for(j=0;j<tree_level;j++) putchar(' ');
|
|
271 printf("list(%s)",t->tree_name);
|
0
|
272 }
|
|
273 } else {
|
|
274 i = car(e);
|
680
|
275 if (tree_nodes(e,&t->tree_name,&t->tree_args,&t->tree_order)) {
|
67
|
276 tree_level++;
|
|
277 for(j=0;j<tree_level;j++) putchar(' ');
|
|
278 printf("list(%s",t->tree_name);
|
|
279 for(i=1,s=t->tree_args;*s;s++,i++) {
|
|
280 switch(*s) {
|
|
281 case 'e':
|
|
282 case 't':
|
|
283 printf(",\n*");
|
|
284 tree_parse(heap[e+i]); break;
|
|
285 case 'v':
|
|
286 printf(",%d",heap[e+i]); break;
|
|
287 case 'n':
|
712
|
288 n = (NMTBL**)&(heap[e+i]);
|
|
289 printf(",%s",(*n)->nm); break;
|
67
|
290 case 's':
|
712
|
291 p = (char**)&(heap[e+i]);
|
|
292 printf(",%s",*p); break;
|
67
|
293 case 'i':
|
|
294 printf(",%d",heap[e+i]); break;
|
0
|
295 }
|
|
296 }
|
67
|
297 tree_level--;
|
|
298 printf(")");
|
0
|
299 }
|
|
300 }
|
|
301 }
|
67
|
302
|
|
303 void struct_type_print(int type,FILE *out)
|
|
304 {
|
|
305 NMTBL *n;
|
|
306 int tags;
|
712
|
307 if((n=ncadddr(type))) {
|
67
|
308 fprintf(out,"%s ",n->nm);
|
|
309 return;
|
|
310 }
|
|
311 if((tags=caddr(type))) {
|
|
312 fprintf(out,"{");
|
|
313 while(tags) {
|
711
|
314 n=ncaddr(tags);
|
67
|
315 type_print(car(tags),n,out);
|
|
316 fprintf(out,";");
|
|
317 tags = cadr(tags);
|
|
318 }
|
|
319 fprintf(out,"}");
|
|
320 }
|
|
321 }
|
|
322
|
74
|
323 void function_type_print1(int type,NMTBL *n,FILE *out,int cont)
|
67
|
324 {
|
|
325 int args;
|
74
|
326 type_print1(cadr(type),0,out,cont);
|
67
|
327 if(n) fprintf(out," %s",n->nm);
|
|
328 fprintf(out,"(");
|
|
329 if((args=caddr(type))) {
|
|
330 while (args) {
|
|
331 type_print(car(args),0,out);
|
|
332 args=cadr(args);
|
|
333 if (args) fprintf(out,",");
|
|
334 }
|
|
335 }
|
|
336 fprintf(out,")");
|
|
337 }
|
|
338
|
74
|
339 void function_type_print(int type,NMTBL *n,FILE *out)
|
|
340 {
|
|
341 function_type_print1(type,n,out,0);
|
|
342 }
|
|
343
|
68
|
344 void sym_print(int sym,FILE *out)
|
|
345 {
|
680
|
346 tree_node_type tn;
|
|
347 if (!(tree_nodes(sym,&tn.tree_name,&tn.tree_args,&tn.tree_order))) { error(-1); return; }
|
|
348 fprintf(out,"%s",tn.tree_name);
|
68
|
349 }
|
|
350
|
70
|
351 NMTBL *
|
468
|
352 typedef_search(int t,int type)
|
70
|
353 {
|
|
354 while(t) {
|
712
|
355 if ((ncaddr(t))->ty==type)
|
|
356 return ncaddr(t);
|
70
|
357 t=cadr(t);
|
|
358 }
|
|
359 return 0;
|
|
360 }
|
|
361
|
564
|
362 static void n_attr_print(int attr, FILE *out)
|
|
363 {
|
|
364 for(;attr;attr=cadr(attr)) {
|
|
365 switch(car(attr)) {
|
|
366 case INLINE: fprintf(out,"inline "); break;
|
|
367 case CONST: fprintf(out,"const "); break;
|
|
368 case VOLATILE: fprintf(out,"const "); break;
|
|
369 case RESTRICT: fprintf(out,"const "); break;
|
|
370 }
|
|
371 }
|
|
372 }
|
|
373
|
74
|
374 void type_print1(int type,NMTBL *n,FILE *out,int cont)
|
67
|
375 {
|
|
376 int t;
|
680
|
377 tree_node_type *tn,tn0;
|
70
|
378 NMTBL *td;
|
72
|
379 int args;
|
680
|
380 tn = &tn0;
|
70
|
381
|
564
|
382 if (n) {
|
|
383 if (n->attr) n_attr_print(n->attr,out);
|
|
384 while(type>0 && car(type)==ATTRIBUTE) type=cadr(type);
|
|
385 } else
|
|
386 type = attr_print(type);
|
75
|
387 if(type>0&&(td=typedef_search(typedefed,type))) {
|
74
|
388 if (!cont)
|
72
|
389 fprintf(out,"%s ",td->nm);
|
75
|
390 } else if(type>0&&(td=typedef_search(gtypedefed,type))) {
|
74
|
391 if (!cont)
|
70
|
392 fprintf(out,"%s ",td->nm);
|
|
393 } else if (type<0) {
|
67
|
394 t=type;
|
680
|
395 if (!(tree_nodes(t,&tn->tree_name,&tn->tree_args,&tn->tree_order))) { error(-1); return; }
|
74
|
396 if (!cont)
|
|
397 fprintf(out,"%s ",tn->tree_name);
|
67
|
398 } else if ((t=car(type))) {
|
680
|
399 if (!(tree_nodes(t,&tn->tree_name,&tn->tree_args,&tn->tree_order))) { error(-1); return; }
|
67
|
400 if(t==STRUCT||t==UNION) {
|
74
|
401 if (!cont) {
|
|
402 fprintf(out,"%s ",tn->tree_name);
|
|
403 struct_type_print(type,out);
|
|
404 }
|
67
|
405 } else if(t==CODE) {
|
596
|
406 // if (!cont) { fprintf(out,"%s ",tn->tree_name); }
|
74
|
407 function_type_print1(type,n,out,cont);
|
67
|
408 return;
|
|
409 } else if(t==FUNCTION) {
|
74
|
410 function_type_print1(type,n,out,cont);
|
67
|
411 return;
|
|
412 } else if(t==ARRAY) {
|
74
|
413 type_print1(cadr(type),n,out,cont);
|
70
|
414 if (caddr(type))
|
|
415 fprintf(out,"[%d]",caddr(type));
|
|
416 else
|
|
417 fprintf(out,"[]");
|
67
|
418 return;
|
|
419 } else if(t==POINTER) {
|
|
420 t=cadr(type);
|
563
|
421 if(t<0) {
|
|
422 type_print1(t,0,out,cont);
|
|
423 fprintf(out,"*");
|
|
424 } else if(car(t)==FUNCTION) {
|
74
|
425 type_print1(cadr(t),0,out,cont);
|
72
|
426 fprintf(out,"(*");
|
|
427 if(n) fprintf(out,"%s",n->nm);
|
|
428 fprintf(out,")");
|
67
|
429 fprintf(out,"(");
|
72
|
430 if((args=caddr(t))) {
|
|
431 while (args) {
|
|
432 type_print(car(args),0,out);
|
|
433 args=cadr(args);
|
|
434 if (args) fprintf(out,",");
|
|
435 }
|
|
436 }
|
67
|
437 fprintf(out,")");
|
72
|
438 return;
|
596
|
439 } else if(car(t)==CODE) {
|
|
440 type_print1(cadr(t),0,out,cont);
|
|
441 fprintf(out,"(*");
|
|
442 if(n) fprintf(out,"%s",n->nm);
|
|
443 fprintf(out,")");
|
|
444 fprintf(out,"(");
|
|
445 if((args=caddr(t))) {
|
|
446 while (args) {
|
|
447 type_print(car(args),0,out);
|
|
448 args=cadr(args);
|
|
449 if (args) fprintf(out,",");
|
|
450 }
|
|
451 }
|
|
452 fprintf(out,")");
|
|
453 return;
|
72
|
454 } else if(car(t)==ARRAY) {
|
|
455 fprintf(out,"(*");
|
|
456 type_print(cadr(t),n,out);
|
|
457 if (caddr(type))
|
|
458 fprintf(out,")[%d]",caddr(type));
|
|
459 else
|
|
460 fprintf(out,")[]");
|
|
461 return;
|
|
462 } else {
|
74
|
463 type_print1(t,0,out,cont);
|
72
|
464 fprintf(out,"*");
|
|
465 }
|
67
|
466 }
|
|
467 }
|
|
468 if(n) fprintf(out,"%s",n->nm);
|
|
469 }
|
|
470
|
74
|
471 void type_print(int type,NMTBL *n,FILE *out)
|
|
472 {
|
|
473 type_print1(type,n,out,0);
|
|
474 }
|
|
475
|
609
|
476 /*
|
|
477 parse tree を印刷する
|
|
478
|
|
479 正しく括弧とかを付けるアルゴリズムが不明...
|
|
480 先読みして、優先順位を判別する必要があるはず。
|
680
|
481
|
|
482 そういえば、cast とかは、落ちて変換コードに変わっている
|
|
483 はず。cast を木にしないとだめか。
|
609
|
484 */
|
|
485
|
|
486 void
|
|
487 print_expr(int e, FILE *vout)
|
|
488 {
|
|
489 NMTBL *nptr,*n;
|
|
490
|
660
|
491 if (e==0) {
|
680
|
492 // can't happen in normal C language
|
|
493 fprintf(vout,"#");
|
660
|
494 return;
|
|
495 }
|
609
|
496 switch (car(e)%SOP) {
|
|
497 case LVAR:
|
|
498 case RLVAR:
|
680
|
499 case URLVAR:
|
711
|
500 if ((nptr = ncaddr(e))) {
|
609
|
501 fprintf(vout,"%s",nptr->nm);
|
|
502 } else {
|
|
503 // anonymous variable
|
|
504 fprintf(vout,"_%d",caddr(e));
|
|
505 }
|
|
506 break;
|
|
507 case GVAR:
|
|
508 case RGVAR:
|
680
|
509 case URGVAR:
|
711
|
510 if ((nptr = ncaddr(e))) {
|
609
|
511 fprintf(vout,"%s",nptr->nm);
|
|
512 } else {
|
|
513 // anonymous variable
|
|
514 fprintf(vout,"_%d",caddr(e));
|
|
515 }
|
|
516 if (cadr(e)) {
|
|
517 // offset
|
|
518 // certainly this is wrong
|
|
519 fprintf(vout,"+%d",caddr(e));
|
|
520 }
|
|
521 break;
|
|
522 case REGISTER:
|
711
|
523 if ((nptr = ncaddr(e))) {
|
609
|
524 fprintf(vout,"%s",nptr->nm);
|
|
525 } else {
|
|
526 // anonymous register variable
|
|
527 fprintf(vout,"_%d",caddr(e));
|
|
528 }
|
|
529 break;
|
|
530 case IDENT:
|
712
|
531 nptr = ncaddr(e);
|
609
|
532 fprintf(vout,"%s",nptr->nm); break;
|
|
533 case CONST:
|
|
534 switch(car(e)) {
|
|
535 case CONST:
|
|
536 fprintf(vout,"%d",cadr(e)); break;
|
|
537 #if FLOAT_CODE
|
|
538 case FCONST:
|
|
539 fprintf(vout,"%g",dcadr(e)); break;
|
|
540 case DCONST:
|
|
541 fprintf(vout,"%g",dcadr(e)); break;
|
|
542 #endif
|
|
543 #if LONGLONG_CODE
|
|
544 case LCONST:
|
|
545 fprintf(vout,"%lld",lcadr(e)); break;
|
|
546 #endif
|
|
547 }
|
|
548 break;
|
|
549 case ADDRESS:
|
|
550 if (car(cadr(e))!=STRING) {
|
|
551 fprintf(vout,"&");
|
|
552 print_expr(cadr(e),vout);
|
|
553 break;
|
|
554 }
|
|
555 case STRING:
|
|
556 {
|
620
|
557 int c; char *s; int i;
|
711
|
558 nptr = ncaddr(e); s = nptr->nm;i=nptr->dsp;
|
609
|
559 fprintf(vout,"\"");
|
|
560 while(--i>0) {
|
|
561 c=*s++;
|
|
562 if(c=='\n') fprintf(vout,"\\n");
|
|
563 else if(c=='\r') fprintf(vout,"\\r");
|
|
564 else if(c=='\t') fprintf(vout,"\\t");
|
|
565 else if(c=='\e') fprintf(vout,"\\e");
|
|
566 else if(c=='"') fprintf(vout,"\\\"");
|
|
567 else if(c=='\\') fprintf(vout,"\\\\");
|
|
568 else if(!(' '<=c&&c<=0x7f)) fprintf(vout,"\\%03o",c);
|
|
569 else fprintf(vout,"%c",c);
|
|
570 }
|
|
571 fprintf(vout,"\"");
|
|
572 }
|
|
573 break;
|
|
574 case ARRAY:
|
|
575 print_expr(cadr(e),vout);
|
|
576 fprintf(vout,"[");
|
|
577 print_expr(caddr(e),vout);
|
|
578 fprintf(vout,"]");
|
|
579 break;
|
|
580 case PERIOD:
|
|
581 print_expr(cadr(e),vout);
|
711
|
582 n = ncaddr(e);
|
609
|
583 fprintf(vout,".%s",n->nm);
|
|
584 break;
|
|
585 case ARROW:
|
|
586 print_expr(cadr(e),vout);
|
711
|
587 n = ncaddr(e);
|
609
|
588 fprintf(vout,"->%s",n->nm);
|
|
589 break;
|
|
590 case INDIRECT:
|
|
591 case RINDIRECT:
|
680
|
592 case URINDIRECT:
|
609
|
593 fprintf(vout,"*");
|
|
594 print_expr(cadr(e),vout);
|
|
595 break;
|
|
596 case FNAME:
|
711
|
597 n = ncaddr(e);
|
609
|
598 fprintf(vout,"%s",n->nm);
|
|
599 break;
|
680
|
600 case FUNCTION:
|
|
601 print_function_call(e,vout);
|
|
602 break;
|
|
603 /*
|
609
|
604 case ADD:
|
|
605 fprintf(vout,"(");
|
|
606 print_expr(cadr(e),vout);
|
|
607 fprintf(vout,"+");
|
|
608 print_expr(caddr(e),vout);
|
|
609 fprintf(vout,")");
|
|
610 break;
|
680
|
611 */
|
660
|
612 case RSTRUCT:
|
|
613 print_expr(cadr(e),vout);
|
|
614 break;
|
609
|
615 default:
|
680
|
616 print_operator(e, vout);
|
|
617 }
|
|
618 }
|
|
619
|
|
620 static void
|
|
621 print_expr_paren(int order,char *args,int e)
|
|
622 {
|
|
623 }
|
|
624
|
|
625 static void
|
|
626 print_operator(int e, FILE *vout)
|
|
627 {
|
|
628 char *name; char *args; int order ;
|
|
629 if (tree_nodes(car(e), &name, &args, &order) ) {
|
|
630 if (order>0) {
|
|
631 int i = 0;
|
|
632 for(;*args;args++,i++) {
|
|
633 print_expr_paren(order,args,heap[e+i]);
|
|
634 }
|
|
635 } else {
|
|
636 print_statement(e, vout);
|
|
637 }
|
609
|
638 }
|
|
639 }
|
|
640
|
680
|
641 static void
|
|
642 print_decl(int e, FILE *vout)
|
|
643 {
|
711
|
644 NMTBL *n = ncaddr(e);
|
680
|
645 int e1 = cadddr(e);
|
|
646 // int mode = car(e1);
|
|
647 int stmode = cadr(e1);
|
|
648 int ctmode = caddr(e1);
|
|
649
|
|
650 if (n==&null_nptr) {
|
|
651 error(-1); // can't happen
|
|
652 return;
|
|
653 }
|
|
654 if (stmode==STATIC) {
|
681
|
655 fprintf(vout,"static ");
|
680
|
656 } else if (stmode==EXTRN||stmode==EXTRN1) {
|
681
|
657 fprintf(vout,"extern ");
|
680
|
658 }
|
|
659 type_print(n->ty,n,vout);
|
681
|
660 if (ctmode & KONST_BIT) {
|
|
661 fprintf(vout,"const ");
|
|
662 }
|
|
663 if (ctmode & VOLATILE_BIT) {
|
|
664 fprintf(vout,"volatile ");
|
|
665 }
|
|
666 if (ctmode & RESTRICT_BIT) {
|
|
667 fprintf(vout,"restrict ");
|
680
|
668 }
|
|
669 fprintf(vout,"%s; ",nptr->nm);
|
|
670 }
|
|
671
|
|
672 static void
|
|
673 print_statement(int e, FILE *vout)
|
|
674 {
|
|
675 int e1;
|
|
676 NMTBL *n;
|
|
677 for (;e!=0; e = cadr(e)) {
|
|
678 switch (car(e)) {
|
|
679 case ST_DECL:
|
|
680 print_decl(e, vout); break;
|
|
681 case ST_IF:
|
|
682 fprintf(vout,"if "); break;
|
|
683 case ST_DO:
|
|
684 fprintf(vout,"do "); break;
|
|
685 case ST_WHILE:
|
|
686 fprintf(vout,"while "); break;
|
|
687 case ST_FOR:
|
|
688 fprintf(vout,"for "); break;
|
|
689 case ST_SWITCH:
|
|
690 fprintf(vout,"switch "); break;
|
|
691 case ST_COMP:
|
|
692 fprintf(vout,"{");
|
|
693 fprintf(vout,"}");
|
|
694 break;
|
|
695 case ST_BREAK:
|
|
696 fprintf(vout,"break; "); break;
|
|
697 case ST_CONTINUE:
|
|
698 fprintf(vout,"continue; "); break;
|
|
699 case ST_CASE:
|
|
700 for(e1 = caddr(e);e1;e1 = cadr(e1)) {
|
|
701 fprintf(vout,"case ");
|
|
702 fprintf(vout,"%d: ",car(e1));
|
|
703 }
|
|
704 break;
|
|
705 case ST_DEFAULT:
|
|
706 fprintf(vout,"default: "); break;
|
|
707 case ST_RETURN:
|
|
708 fprintf(vout,"return ");
|
|
709 if (( e1 = caddr(e))) {
|
|
710 print_expr(e1,vout);
|
|
711 }
|
|
712 fprintf(vout,"; ");
|
|
713 break;
|
|
714 case ST_GOTO:
|
|
715 fprintf(vout,"goto "); break;
|
|
716 case ST_ASM:
|
|
717 fprintf(vout,"__asm__ "); break;
|
|
718 case ST_LABEL:
|
711
|
719 n = ncaddr(caddr(e));
|
680
|
720 fprintf(vout,"%s:", n->nm); break;
|
|
721 case ST_OP:
|
|
722 e1 = caddr(e);
|
|
723 print_expr(list3(cadr(e),car(e1),cadr(e1)),vout);
|
|
724 break;
|
|
725 case ST_COMMENT:
|
712
|
726 fprintf(vout,"\n# %s\n",scaddr(e));
|
680
|
727 break;
|
|
728 default:
|
|
729 fprintf(stderr,"Unknown Statement ID %d\n",car(e));
|
|
730 }
|
|
731 }
|
|
732 }
|
|
733
|
|
734 static void
|
|
735 print_function_call(int e1,FILE *vout)
|
|
736 {
|
|
737 int e2,e3;
|
|
738 NMTBL *fn = 0;
|
|
739
|
|
740 e2 = cadr(e1);
|
|
741 if (car(e2) == FNAME) {
|
711
|
742 fn=ncaddr(e2);
|
680
|
743 fprintf(vout,"%s",fn->nm);
|
|
744 } else {
|
|
745 if (car(e2)==INDIRECT) e2=cadr(e2); // (*func)(i) case
|
|
746 fprintf(vout,"(");
|
|
747 print_expr(e2,vout);
|
|
748 fprintf(vout,")");
|
|
749 }
|
|
750
|
|
751 fprintf(vout,"(");
|
|
752 for (e3 = e1 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {
|
|
753 print_expr(car(e3),vout);
|
|
754 if (cadr(e3)) {
|
|
755 fprintf(vout,",");
|
|
756 }
|
|
757 }
|
|
758 fprintf(vout,")");
|
|
759 reverse0(e1); // make it normal order
|
|
760
|
|
761 }
|
|
762
|
|
763
|
67
|
764 /* end */
|