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;
|
|
263 char *s;
|
|
264
|
680
|
265 t = &node_type; t->tree_type=e;
|
|
266
|
0
|
267 if(e<0) {
|
680
|
268 if (tree_nodes(e,&t->tree_name,&t->tree_args,&t->tree_order)) {
|
67
|
269 for(j=0;j<tree_level;j++) putchar(' ');
|
|
270 printf("list(%s)",t->tree_name);
|
0
|
271 }
|
|
272 } else {
|
|
273 i = car(e);
|
680
|
274 if (tree_nodes(e,&t->tree_name,&t->tree_args,&t->tree_order)) {
|
67
|
275 tree_level++;
|
|
276 for(j=0;j<tree_level;j++) putchar(' ');
|
|
277 printf("list(%s",t->tree_name);
|
|
278 for(i=1,s=t->tree_args;*s;s++,i++) {
|
|
279 switch(*s) {
|
|
280 case 'e':
|
|
281 case 't':
|
|
282 printf(",\n*");
|
|
283 tree_parse(heap[e+i]); break;
|
|
284 case 'v':
|
|
285 printf(",%d",heap[e+i]); break;
|
|
286 case 'n':
|
|
287 printf(",%s",((NMTBL *)heap[e+i])->nm); break;
|
|
288 case 's':
|
|
289 printf(",%s",(char *)heap[e+i]); break;
|
|
290 case 'i':
|
|
291 printf(",%d",heap[e+i]); break;
|
0
|
292 }
|
|
293 }
|
67
|
294 tree_level--;
|
|
295 printf(")");
|
0
|
296 }
|
|
297 }
|
|
298 }
|
67
|
299
|
|
300 void struct_type_print(int type,FILE *out)
|
|
301 {
|
|
302 NMTBL *n;
|
|
303 int tags;
|
|
304 if((n=(NMTBL*)cadddr(type))) {
|
|
305 fprintf(out,"%s ",n->nm);
|
|
306 return;
|
|
307 }
|
|
308 if((tags=caddr(type))) {
|
|
309 fprintf(out,"{");
|
|
310 while(tags) {
|
|
311 n=(NMTBL*)caddr(tags);
|
|
312 type_print(car(tags),n,out);
|
|
313 fprintf(out,";");
|
|
314 tags = cadr(tags);
|
|
315 }
|
|
316 fprintf(out,"}");
|
|
317 }
|
|
318 }
|
|
319
|
74
|
320 void function_type_print1(int type,NMTBL *n,FILE *out,int cont)
|
67
|
321 {
|
|
322 int args;
|
74
|
323 type_print1(cadr(type),0,out,cont);
|
67
|
324 if(n) fprintf(out," %s",n->nm);
|
|
325 fprintf(out,"(");
|
|
326 if((args=caddr(type))) {
|
|
327 while (args) {
|
|
328 type_print(car(args),0,out);
|
|
329 args=cadr(args);
|
|
330 if (args) fprintf(out,",");
|
|
331 }
|
|
332 }
|
|
333 fprintf(out,")");
|
|
334 }
|
|
335
|
74
|
336 void function_type_print(int type,NMTBL *n,FILE *out)
|
|
337 {
|
|
338 function_type_print1(type,n,out,0);
|
|
339 }
|
|
340
|
68
|
341 void sym_print(int sym,FILE *out)
|
|
342 {
|
680
|
343 tree_node_type tn;
|
|
344 if (!(tree_nodes(sym,&tn.tree_name,&tn.tree_args,&tn.tree_order))) { error(-1); return; }
|
|
345 fprintf(out,"%s",tn.tree_name);
|
68
|
346 }
|
|
347
|
70
|
348 NMTBL *
|
468
|
349 typedef_search(int t,int type)
|
70
|
350 {
|
|
351 while(t) {
|
|
352 if (((NMTBL*)car(t))->ty==type)
|
|
353 return (NMTBL*)car(t);
|
|
354 t=cadr(t);
|
|
355 }
|
|
356 return 0;
|
|
357 }
|
|
358
|
564
|
359 static void n_attr_print(int attr, FILE *out)
|
|
360 {
|
|
361 for(;attr;attr=cadr(attr)) {
|
|
362 switch(car(attr)) {
|
|
363 case INLINE: fprintf(out,"inline "); break;
|
|
364 case CONST: fprintf(out,"const "); break;
|
|
365 case VOLATILE: fprintf(out,"const "); break;
|
|
366 case RESTRICT: fprintf(out,"const "); break;
|
|
367 }
|
|
368 }
|
|
369 }
|
|
370
|
74
|
371 void type_print1(int type,NMTBL *n,FILE *out,int cont)
|
67
|
372 {
|
|
373 int t;
|
680
|
374 tree_node_type *tn,tn0;
|
70
|
375 NMTBL *td;
|
72
|
376 int args;
|
680
|
377 tn = &tn0;
|
70
|
378
|
564
|
379 if (n) {
|
|
380 if (n->attr) n_attr_print(n->attr,out);
|
|
381 while(type>0 && car(type)==ATTRIBUTE) type=cadr(type);
|
|
382 } else
|
|
383 type = attr_print(type);
|
75
|
384 if(type>0&&(td=typedef_search(typedefed,type))) {
|
74
|
385 if (!cont)
|
72
|
386 fprintf(out,"%s ",td->nm);
|
75
|
387 } else if(type>0&&(td=typedef_search(gtypedefed,type))) {
|
74
|
388 if (!cont)
|
70
|
389 fprintf(out,"%s ",td->nm);
|
|
390 } else if (type<0) {
|
67
|
391 t=type;
|
680
|
392 if (!(tree_nodes(t,&tn->tree_name,&tn->tree_args,&tn->tree_order))) { error(-1); return; }
|
74
|
393 if (!cont)
|
|
394 fprintf(out,"%s ",tn->tree_name);
|
67
|
395 } else if ((t=car(type))) {
|
680
|
396 if (!(tree_nodes(t,&tn->tree_name,&tn->tree_args,&tn->tree_order))) { error(-1); return; }
|
67
|
397 if(t==STRUCT||t==UNION) {
|
74
|
398 if (!cont) {
|
|
399 fprintf(out,"%s ",tn->tree_name);
|
|
400 struct_type_print(type,out);
|
|
401 }
|
67
|
402 } else if(t==CODE) {
|
596
|
403 // if (!cont) { fprintf(out,"%s ",tn->tree_name); }
|
74
|
404 function_type_print1(type,n,out,cont);
|
67
|
405 return;
|
|
406 } else if(t==FUNCTION) {
|
74
|
407 function_type_print1(type,n,out,cont);
|
67
|
408 return;
|
|
409 } else if(t==ARRAY) {
|
74
|
410 type_print1(cadr(type),n,out,cont);
|
70
|
411 if (caddr(type))
|
|
412 fprintf(out,"[%d]",caddr(type));
|
|
413 else
|
|
414 fprintf(out,"[]");
|
67
|
415 return;
|
|
416 } else if(t==POINTER) {
|
|
417 t=cadr(type);
|
563
|
418 if(t<0) {
|
|
419 type_print1(t,0,out,cont);
|
|
420 fprintf(out,"*");
|
|
421 } else if(car(t)==FUNCTION) {
|
74
|
422 type_print1(cadr(t),0,out,cont);
|
72
|
423 fprintf(out,"(*");
|
|
424 if(n) fprintf(out,"%s",n->nm);
|
|
425 fprintf(out,")");
|
67
|
426 fprintf(out,"(");
|
72
|
427 if((args=caddr(t))) {
|
|
428 while (args) {
|
|
429 type_print(car(args),0,out);
|
|
430 args=cadr(args);
|
|
431 if (args) fprintf(out,",");
|
|
432 }
|
|
433 }
|
67
|
434 fprintf(out,")");
|
72
|
435 return;
|
596
|
436 } else if(car(t)==CODE) {
|
|
437 type_print1(cadr(t),0,out,cont);
|
|
438 fprintf(out,"(*");
|
|
439 if(n) fprintf(out,"%s",n->nm);
|
|
440 fprintf(out,")");
|
|
441 fprintf(out,"(");
|
|
442 if((args=caddr(t))) {
|
|
443 while (args) {
|
|
444 type_print(car(args),0,out);
|
|
445 args=cadr(args);
|
|
446 if (args) fprintf(out,",");
|
|
447 }
|
|
448 }
|
|
449 fprintf(out,")");
|
|
450 return;
|
72
|
451 } else if(car(t)==ARRAY) {
|
|
452 fprintf(out,"(*");
|
|
453 type_print(cadr(t),n,out);
|
|
454 if (caddr(type))
|
|
455 fprintf(out,")[%d]",caddr(type));
|
|
456 else
|
|
457 fprintf(out,")[]");
|
|
458 return;
|
|
459 } else {
|
74
|
460 type_print1(t,0,out,cont);
|
72
|
461 fprintf(out,"*");
|
|
462 }
|
67
|
463 }
|
|
464 }
|
|
465 if(n) fprintf(out,"%s",n->nm);
|
|
466 }
|
|
467
|
74
|
468 void type_print(int type,NMTBL *n,FILE *out)
|
|
469 {
|
|
470 type_print1(type,n,out,0);
|
|
471 }
|
|
472
|
609
|
473 /*
|
|
474 parse tree を印刷する
|
|
475
|
|
476 正しく括弧とかを付けるアルゴリズムが不明...
|
|
477 先読みして、優先順位を判別する必要があるはず。
|
680
|
478
|
|
479 そういえば、cast とかは、落ちて変換コードに変わっている
|
|
480 はず。cast を木にしないとだめか。
|
609
|
481 */
|
|
482
|
|
483 void
|
|
484 print_expr(int e, FILE *vout)
|
|
485 {
|
|
486 NMTBL *nptr,*n;
|
|
487
|
660
|
488 if (e==0) {
|
680
|
489 // can't happen in normal C language
|
|
490 fprintf(vout,"#");
|
660
|
491 return;
|
|
492 }
|
609
|
493 switch (car(e)%SOP) {
|
|
494 case LVAR:
|
|
495 case RLVAR:
|
680
|
496 case URLVAR:
|
609
|
497 if ((nptr = (NMTBL*)caddr(e))) {
|
|
498 fprintf(vout,"%s",nptr->nm);
|
|
499 } else {
|
|
500 // anonymous variable
|
|
501 fprintf(vout,"_%d",caddr(e));
|
|
502 }
|
|
503 break;
|
|
504 case GVAR:
|
|
505 case RGVAR:
|
680
|
506 case URGVAR:
|
609
|
507 if ((nptr = (NMTBL*)caddr(e))) {
|
|
508 fprintf(vout,"%s",nptr->nm);
|
|
509 } else {
|
|
510 // anonymous variable
|
|
511 fprintf(vout,"_%d",caddr(e));
|
|
512 }
|
|
513 if (cadr(e)) {
|
|
514 // offset
|
|
515 // certainly this is wrong
|
|
516 fprintf(vout,"+%d",caddr(e));
|
|
517 }
|
|
518 break;
|
|
519 case REGISTER:
|
|
520 if ((nptr = (NMTBL*)caddr(e))) {
|
|
521 fprintf(vout,"%s",nptr->nm);
|
|
522 } else {
|
|
523 // anonymous register variable
|
|
524 fprintf(vout,"_%d",caddr(e));
|
|
525 }
|
|
526 break;
|
|
527 case IDENT:
|
|
528 nptr = (NMTBL*)cadr(e);
|
|
529 fprintf(vout,"%s",nptr->nm); break;
|
|
530 case CONST:
|
|
531 switch(car(e)) {
|
|
532 case CONST:
|
|
533 fprintf(vout,"%d",cadr(e)); break;
|
|
534 #if FLOAT_CODE
|
|
535 case FCONST:
|
|
536 fprintf(vout,"%g",dcadr(e)); break;
|
|
537 case DCONST:
|
|
538 fprintf(vout,"%g",dcadr(e)); break;
|
|
539 #endif
|
|
540 #if LONGLONG_CODE
|
|
541 case LCONST:
|
|
542 fprintf(vout,"%lld",lcadr(e)); break;
|
|
543 #endif
|
|
544 }
|
|
545 break;
|
|
546 case ADDRESS:
|
|
547 if (car(cadr(e))!=STRING) {
|
|
548 fprintf(vout,"&");
|
|
549 print_expr(cadr(e),vout);
|
|
550 break;
|
|
551 }
|
|
552 case STRING:
|
|
553 {
|
620
|
554 int c; char *s; int i;
|
|
555 nptr = (NMTBL*)cadr(e); s = nptr->nm;i=nptr->dsp;
|
609
|
556 fprintf(vout,"\"");
|
|
557 while(--i>0) {
|
|
558 c=*s++;
|
|
559 if(c=='\n') fprintf(vout,"\\n");
|
|
560 else if(c=='\r') fprintf(vout,"\\r");
|
|
561 else if(c=='\t') fprintf(vout,"\\t");
|
|
562 else if(c=='\e') fprintf(vout,"\\e");
|
|
563 else if(c=='"') fprintf(vout,"\\\"");
|
|
564 else if(c=='\\') fprintf(vout,"\\\\");
|
|
565 else if(!(' '<=c&&c<=0x7f)) fprintf(vout,"\\%03o",c);
|
|
566 else fprintf(vout,"%c",c);
|
|
567 }
|
|
568 fprintf(vout,"\"");
|
|
569 }
|
|
570 break;
|
|
571 case ARRAY:
|
|
572 print_expr(cadr(e),vout);
|
|
573 fprintf(vout,"[");
|
|
574 print_expr(caddr(e),vout);
|
|
575 fprintf(vout,"]");
|
|
576 break;
|
|
577 case PERIOD:
|
|
578 print_expr(cadr(e),vout);
|
|
579 n = (NMTBL*)caddr(e);
|
|
580 fprintf(vout,".%s",n->nm);
|
|
581 break;
|
|
582 case ARROW:
|
|
583 print_expr(cadr(e),vout);
|
|
584 n = (NMTBL*)caddr(e);
|
|
585 fprintf(vout,"->%s",n->nm);
|
|
586 break;
|
|
587 case INDIRECT:
|
|
588 case RINDIRECT:
|
680
|
589 case URINDIRECT:
|
609
|
590 fprintf(vout,"*");
|
|
591 print_expr(cadr(e),vout);
|
|
592 break;
|
|
593 case FNAME:
|
|
594 n = (NMTBL*)cadr(e);
|
|
595 fprintf(vout,"%s",n->nm);
|
|
596 break;
|
680
|
597 case FUNCTION:
|
|
598 print_function_call(e,vout);
|
|
599 break;
|
|
600 /*
|
609
|
601 case ADD:
|
|
602 fprintf(vout,"(");
|
|
603 print_expr(cadr(e),vout);
|
|
604 fprintf(vout,"+");
|
|
605 print_expr(caddr(e),vout);
|
|
606 fprintf(vout,")");
|
|
607 break;
|
680
|
608 */
|
660
|
609 case RSTRUCT:
|
|
610 print_expr(cadr(e),vout);
|
|
611 break;
|
609
|
612 default:
|
680
|
613 print_operator(e, vout);
|
|
614 }
|
|
615 }
|
|
616
|
|
617 static void
|
|
618 print_expr_paren(int order,char *args,int e)
|
|
619 {
|
|
620 }
|
|
621
|
|
622 static void
|
|
623 print_operator(int e, FILE *vout)
|
|
624 {
|
|
625 char *name; char *args; int order ;
|
|
626 if (tree_nodes(car(e), &name, &args, &order) ) {
|
|
627 if (order>0) {
|
|
628 int i = 0;
|
|
629 for(;*args;args++,i++) {
|
|
630 print_expr_paren(order,args,heap[e+i]);
|
|
631 }
|
|
632 } else {
|
|
633 print_statement(e, vout);
|
|
634 }
|
609
|
635 }
|
|
636 }
|
|
637
|
680
|
638 static void
|
|
639 print_decl(int e, FILE *vout)
|
|
640 {
|
|
641 NMTBL *n = (NMTBL*)caddr(e);
|
|
642 int e1 = cadddr(e);
|
|
643 // int mode = car(e1);
|
|
644 int stmode = cadr(e1);
|
|
645 int ctmode = caddr(e1);
|
|
646
|
|
647 if (n==&null_nptr) {
|
|
648 error(-1); // can't happen
|
|
649 return;
|
|
650 }
|
|
651 if (stmode==STATIC) {
|
|
652 fprintf(vout,"static ",nptr->nm);
|
|
653 } else if (stmode==EXTRN||stmode==EXTRN1) {
|
|
654 fprintf(vout,"extern ",nptr->nm);
|
|
655 }
|
|
656 type_print(n->ty,n,vout);
|
|
657 if (ctmode) {
|
|
658 fprintf(vout,"const ",nptr->nm);
|
|
659 }
|
|
660 fprintf(vout,"%s; ",nptr->nm);
|
|
661 }
|
|
662
|
|
663 static void
|
|
664 print_statement(int e, FILE *vout)
|
|
665 {
|
|
666 int e1;
|
|
667 NMTBL *n;
|
|
668 for (;e!=0; e = cadr(e)) {
|
|
669 switch (car(e)) {
|
|
670 case ST_DECL:
|
|
671 print_decl(e, vout); break;
|
|
672 case ST_IF:
|
|
673 fprintf(vout,"if "); break;
|
|
674 case ST_DO:
|
|
675 fprintf(vout,"do "); break;
|
|
676 case ST_WHILE:
|
|
677 fprintf(vout,"while "); break;
|
|
678 case ST_FOR:
|
|
679 fprintf(vout,"for "); break;
|
|
680 case ST_SWITCH:
|
|
681 fprintf(vout,"switch "); break;
|
|
682 case ST_COMP:
|
|
683 fprintf(vout,"{");
|
|
684 fprintf(vout,"}");
|
|
685 break;
|
|
686 case ST_BREAK:
|
|
687 fprintf(vout,"break; "); break;
|
|
688 case ST_CONTINUE:
|
|
689 fprintf(vout,"continue; "); break;
|
|
690 case ST_CASE:
|
|
691 for(e1 = caddr(e);e1;e1 = cadr(e1)) {
|
|
692 fprintf(vout,"case ");
|
|
693 fprintf(vout,"%d: ",car(e1));
|
|
694 }
|
|
695 break;
|
|
696 case ST_DEFAULT:
|
|
697 fprintf(vout,"default: "); break;
|
|
698 case ST_RETURN:
|
|
699 fprintf(vout,"return ");
|
|
700 if (( e1 = caddr(e))) {
|
|
701 print_expr(e1,vout);
|
|
702 }
|
|
703 fprintf(vout,"; ");
|
|
704 break;
|
|
705 case ST_GOTO:
|
|
706 fprintf(vout,"goto "); break;
|
|
707 case ST_ASM:
|
|
708 fprintf(vout,"__asm__ "); break;
|
|
709 case ST_LABEL:
|
|
710 n = (NMTBL*)(caddr(caddr(e)));
|
|
711 fprintf(vout,"%s:", n->nm); break;
|
|
712 case ST_OP:
|
|
713 e1 = caddr(e);
|
|
714 print_expr(list3(cadr(e),car(e1),cadr(e1)),vout);
|
|
715 break;
|
|
716 case ST_COMMENT:
|
|
717 fprintf(vout,"\n# %s\n",(char*)caddr(e));
|
|
718 break;
|
|
719 default:
|
|
720 fprintf(stderr,"Unknown Statement ID %d\n",car(e));
|
|
721 }
|
|
722 }
|
|
723 }
|
|
724
|
|
725 static void
|
|
726 print_function_call(int e1,FILE *vout)
|
|
727 {
|
|
728 int e2,e3;
|
|
729 NMTBL *fn = 0;
|
|
730
|
|
731 e2 = cadr(e1);
|
|
732 if (car(e2) == FNAME) {
|
|
733 fn=(NMTBL *)cadr(e2);
|
|
734 fprintf(vout,"%s",fn->nm);
|
|
735 } else {
|
|
736 if (car(e2)==INDIRECT) e2=cadr(e2); // (*func)(i) case
|
|
737 fprintf(vout,"(");
|
|
738 print_expr(e2,vout);
|
|
739 fprintf(vout,")");
|
|
740 }
|
|
741
|
|
742 fprintf(vout,"(");
|
|
743 for (e3 = e1 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) {
|
|
744 print_expr(car(e3),vout);
|
|
745 if (cadr(e3)) {
|
|
746 fprintf(vout,",");
|
|
747 }
|
|
748 }
|
|
749 fprintf(vout,")");
|
|
750 reverse0(e1); // make it normal order
|
|
751
|
|
752 }
|
|
753
|
|
754
|
67
|
755 /* end */
|