Mercurial > hg > CbC > old > device
view mc-tree.c @ 935:7672a37e7545 default tip
Raspbery PI ARM support begin
author | kono |
---|---|
date | Sat, 24 Dec 2016 03:02:57 +0000 |
parents | f7803d618f36 |
children |
line wrap: on
line source
/* Micro-C tree print routine */ /************************************************************************ ** Copyright (C) 2006 Shinji Kono ** 連絡先: 琉球大学情報工学科 河野 真治 ** (E-Mail Address: kono@ie.u-ryukyu.ac.jp) ** ** このソースのいかなる複写,改変,修正も許諾します。ただし、 ** その際には、誰が貢献したを示すこの部分を残すこと。 ** 再配布や雑誌の付録などの問い合わせも必要ありません。 ** 営利利用も上記に反しない範囲で許可します。 ** バイナリの配布の際にはversion messageを保存することを条件とします。 ** このプログラムについては特に何の保証もしない、悪しからず。 ** ** Everyone is permitted to do anything on this program ** including copying, modifying, improving, ** as long as you don't try to pretend that you wrote it. ** i.e., the above copyright notice has to appear in all copies. ** Binary distribution requires original version messages. ** You don't have to ask before copying, redistribution or publishing. ** THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE. ***********************************************************************/ #include <stdio.h> #include "mc.h" #include "mc-parse.h" #include "mc-codegen.h" extern void tree_print(int e); extern void tree_parse(int e); extern void tree_print_t(int e,int t); extern void type_print(int type,NMTBL *n,FILE *out); extern void type_print1(int type,NMTBL *n,FILE *out,int cont); extern void sym_print(int type,FILE *out); static void print_function_call(int e, FILE *out); static void print_operator(int e, FILE *vout); static void print_statement(int e, FILE *vout); /* ascendant order for binary search */ typedef struct tree_node { int tree_type; char *tree_name; char *tree_args; int tree_order; } tree_node_type; static int tree_nodes(int id, char **name, char **args, int *order) { int found = 1; switch(id%SOP) { case DOTS: *name = "..."; *args=""; *order=-1; break; case LMACRO: *name = "lmacro"; *args=""; *order=-1; break; case FMACRO: *name = "fmacro"; *args=""; *order=-1; break; case KONST: *name = "const"; *args=""; *order=-1; break; case DEFINED: *name = "defined"; *args=""; *order=14; break; case ENVIRONMENT: *name = "environment"; *args=""; *order=14; break; case CODE: *name = "code"; *args=""; *order=-1; break; case C_FILE: *name = "__FILE__"; *args=""; *order=14; break; case C_FUNCTION: *name = "__FUNCTION__"; *args=""; *order=14; break; case C_LINE: *name = "__LINE__"; *args=""; *order=14; break; case REGISTER: *name = "register"; *args=""; *order=-1; break; case CAST: *name = "cast"; *args="e"; *order=14; break; case ASM: *name = "__asm__"; *args="eeee"; *order=-1; break; case ST_ASM: *name = "__asm__"; *args="eeee"; *order=-1; break; case VOID: *name = "void"; *args=""; *order=-1; break; case EXTRN: *name = "extern"; *args=""; *order=14; break; case EXTRN1: *name = "extern"; *args=""; *order=14; break; case SHORT: *name = "short"; *args=""; *order=-1; break; case USHORT: *name = "unsigned short"; *args=""; *order=-1; break; case LONG: *name = "long"; *args=""; *order=-1; break; case TYPE: *name = "type"; *args=""; *order=-1; break; case VOLATILE: *name = "volatile"; *args=""; *order=-1; break; case SIZEOF: *name = "sizeof"; *args="e"; *order=13; break; case TYPEDEF: *name = "typedef"; *args=""; *order=-1; break; case FLABEL: *name = "flabel"; *args=""; *order=-1; break; case BLABEL: *name = "blabel"; *args=""; *order=-1; break; case LABEL: *name = "label"; *args="e"; *order=-1; break; case ST_LABEL: *name = "label"; *args="e"; *order=-1; break; case MACRO: *name = "macro"; *args=""; *order=-1; break; case STRING: *name = "string"; *args=""; *order=14; break; case IDENT: *name = "ident"; *args=""; *order=14; break; case ENUM: *name = "enum"; *args=""; *order=14; break; case FIELD: *name = "field"; *args=""; *order=-1; break; case TAG: *name = "tag"; *args=""; *order=-1; break; case RESERVE: *name = "reserve"; *args=""; *order=-1; break; case ST_DEFAULT: *name = "default"; *args=""; *order=-1; break; case ATTRIBUTE: *name = "__attribute__"; *args=""; *order=-1; break; case ST_CASE: *name = "case"; *args=""; *order=-1; break; case ST_SWITCH: *name = "switch"; *args=""; *order=-1; break; case ST_WHILE: *name = "while"; *args=""; *order=-1; break; case ST_DO: *name = "do"; *args=""; *order=-1; break; case ST_FOR: *name = "for"; *args=""; *order=-1; break; case ELSE: *name = "else"; *args=""; *order=-1; break; case ST_IF: *name = "if"; *args=""; *order=-1; break; case CONTINUE: *name = "continue"; *args=""; *order=-1; break; case BREAK: *name = "break"; *args=""; *order=-1; break; case ST_RETURN: *name = "return"; *args="e"; *order=-1; break; case RETURN: *name = "return"; *args=""; *order=14; break; case ST_GOTO: *name = "goto"; *args=""; *order=-1; break; case JUMP: *name = "goto"; *args=""; *order=-1; break; case STATIC: *name = "static"; *args=""; *order=14; break; case EMPTY: *name = "empty"; *args=""; *order=-1; break; case FUNCTION: *name = "function"; *args="t"; *order=15; break; case UNION: *name = "union"; *args=""; *order=-1; break; case STRUCT: *name = "struct"; *args="vt"; *order=-1; break; case ARRAY: *name = "array"; *args="tv"; *order=16; break; case POINTER: *name = "*"; *args="t"; *order=-1; break; case UNSIGNED: *name = "unsigned"; *args=""; *order=-1; break; case INLINE: *name = "inline"; *args=""; *order=-1; break; case SIGNED: *name = "signed"; *args=""; *order=-1; break; case CHAR: *name = "char"; *args=""; *order=-1; break; case UCHAR: *name = "unsigned char"; *args=""; *order=-1; break; case INT: *name = "int"; *args=""; *order=-1; break; case FLOAT: *name = "float"; *args=""; *order=-1; break; case DOUBLE: *name = "double"; *args=""; *order=-1; break; case LONGLONG: *name = "long long"; *args=""; *order=-1; break; case ULONGLONG: *name = "unsigned long long"; *args=""; *order=-1; break; case GVAR: *name = "gvar"; *args="vs"; *order=14; break; case IVAR: *name = "ivar"; *args="vs"; *order=14; break; case RGVAR: *name = "rgvar"; *args="vs"; *order=14; break; case CRGVAR: *name = "crgvar"; *args="vs"; *order=14; break; case LVAR: *name = "lvar"; *args="v"; *order=14; break; case RLVAR: *name = "rlvar"; *args="v"; *order=14; break; case CRLVAR: *name = "crlvar"; *args="v"; *order=14; break; case CONST: *name = "const"; *args="v"; *order=14; break; case FNAME: *name = "fname"; *args="n"; *order=14; break; case MUL: *name = "*"; *args="e"; *order=-1; break; case RINDIRECT: *name = "*"; *args="e"; *order=13; break; case CRINDIRECT: *name = "*"; *args="e"; *order=13; break; case ADDRESS: *name = "&"; *args="e"; *order=13; break; case BAND: *name = "&"; *args="e"; *order=7; break; case MINUS: *name = "-"; *args="e"; *order=13; break; case LNOT: *name = "!"; *args="e"; *order=13; break; case BNOT: *name = "~"; *args="e"; *order=13; break; case INC: *name = "++"; *args=""; *order=13; break; case ALLOCA: *name = "alloca"; *args="e"; *order=13; break; case BUILTINP: *name = "__builtinp"; *args="e"; *order=13; break; case BUILTIN_EXPECT: *name = "__builtin_expect"; *args="ee"; *order=13; break; case BUILTIN_FABSF: *name = "__builtin_fabsf"; *args="e"; *order=13; break; case BUILTIN_FABS: *name = "__builtin_fbas"; *args="e"; *order=13; break; case BUILTIN_FABSL: *name = "__builtin_fbasl"; *args="e"; *order=13; break; case BUILTIN_INFF: *name = "__builtin_inff"; *args=""; *order=13; break; case BUILTIN_INF: *name = "__builtin_inf"; *args=""; *order=13; break; case BUILTIN_INFL: *name = "__builtin_infl"; *args=""; *order=13; break; case POSTINC: *name = "++"; *args="ee"; *order=13; break; case BPOSTINC: *name = "++"; *args="ee"; *order=13; break; case PREINC: *name = "++"; *args="ee"; *order=13; break; case CPOSTINC: *name = "++"; *args="ee"; *order=13; break; case CPREINC: *name = "++"; *args="ee"; *order=13; break; case DEC: *name = "--"; *args="e"; *order=13; break; case DIV: *name = "/"; *args="ee"; *order=12; break; case UDIV: *name = "/"; *args="ee"; *order=12; break; case UMUL: *name = "*"; *args="ee"; *order=12; break; case MOD: *name = "%"; *args="ee"; *order=12; break; case UMOD: *name = "%"; *args="ee"; *order=12; break; case ADD: *name = "+"; *args="ee"; *order=11; break; case SUB: *name = "-"; *args="ee"; *order=11; break; case RSHIFT: *name = ">>"; *args="ee"; *order=10; break; case URSHIFT: *name = ">>"; *args="ee"; *order=10; break; case LSHIFT: *name = "<<"; *args="ee"; *order=10; break; case ULSHIFT: *name = "<<"; *args="ee"; *order=10; break; case GT: *name = ">"; *args="ee"; *order=9; break; case UGT: *name = ">"; *args="ee"; *order=9; break; case GE: *name = ">="; *args="ee"; *order=9; break; case UGE: *name = ">="; *args="ee"; *order=9; break; case LT: *name = "<"; *args="ee"; *order=9; break; case ULT: *name = "<"; *args="ee"; *order=9; break; case LE: *name = "<="; *args="ee"; *order=9; break; case ULE: *name = "<="; *args="ee"; *order=9; break; case EQ: *name = "=="; *args="ee"; *order=8; break; case NEQ: *name = "!="; *args="ee"; *order=8; break; case EOR: *name = "^"; *args="ee"; *order=6; break; case BOR: *name = "|"; *args="ee"; *order=5; break; case LAND: *name = "&&"; *args="ee"; *order=4; break; case LOR: *name = "||"; *args="ee"; *order=-1; break; case COND: *name = "?"; *args="eee"; *order=2; break; case ASS: *name = "="; *args="ee"; *order=1; break; case ASSOP: *name = "assop"; *args="eev"; *order=1; break; case CASSOP: *name = "cassop"; *args="eev"; *order=1; break; case COMMA: *name = ","; *args="ee"; *order=0; break; case LPAR: *name = "("; *args=""; *order=-1; break; case RPAR: *name = ")"; *args=""; *order=-1; break; case LBRA: *name = "["; *args=""; *order=-1; break; case RBRA: *name = "]"; *args=""; *order=-1; break; case LC: *name = "{"; *args=""; *order=-1; break; case RC: *name = "}"; *args=""; *order=-1; break; case COLON: *name = ":"; *args="ee"; *order=-1; break; case SM: *name = ";"; *args=""; *order=-1; break; case PERIOD: *name = "."; *args=""; *order=16; break; case ARROW: *name = "->"; *args=""; *order=16; break; case SASS: *name = "sass"; *args=""; *order=-1; break; case AS+MUL: *name = "*="; *args="ee"; *order=1; break; case AS+UMUL: *name = "*="; *args="ee"; *order=1; break; case AS+DIV: *name = "/="; *args="ee"; *order=1; break; case AS+UDIV: *name = "/="; *args="ee"; *order=1; break; case AS+MOD: *name = "%="; *args="ee"; *order=1; break; case AS+UMOD: *name = "%="; *args="ee"; *order=1; break; case AS+ADD: *name = "+="; *args="ee"; *order=1; break; case AS+MINUS: *name = "-="; *args="ee"; *order=1; break; case AS+RSHIFT: *name = ">>="; *args="ee"; *order=1; break; case AS+URSHIFT: *name = ">>="; *args="ee"; *order=1; break; case AS+LSHIFT: *name = "<<="; *args="ee"; *order=1; break; case AS+ULSHIFT: *name = "<<="; *args="ee"; *order=1; break; case AS+BAND: *name = "&="; *args="ee"; *order=1; break; case AS+EOR: *name = "^="; *args="ee"; *order=1; break; case AS+BOR: *name = "|="; *args="ee"; *order=1; break; case RESTRICT: *name = "restrict"; *args=""; *order=1; break; case TYPEOF: *name = "typeof"; *args="e"; *order=1; break; case BUILTIN_TYPES_COMPATIBLE_P: *name = "__builtin_types_compatible_p"; *args="e"; *order=1; break; case FOR: *name = "for"; *args="eee"; *order=1; break; case IF: *name = "if"; *args="ee"; *order=1; break; case SWITCH: *name = "switch"; *args="ee"; *order=1; break; case CASE: *name = "case"; *args="e"; *order=1; break; case DEFAULT: *name = "default"; *args=""; *order=1; break; case WHILE: *name = "while"; *args="ee"; *order=1; break; case GOTO: *name = "goto"; *args="e"; *order=1; break; case DO: *name = "do"; *args="ee"; *order=1; break; default: found = 0; fprintf(stderr,"Unknown ID %d [%d]in find node\n",id,OP(id)); } return found; } static int attr_print(int t) { while (t>0 && car(t)==ATTRIBUTE) { switch (caddr(t)) { case KONST: printf( "const"); break; case VOLATILE: printf( "volatile"); break; case RESTRICT: printf( "restrict"); break; case INLINE: printf( "inline"); break; } t = cadr(t); } return t; } void tree_print_t(int e,int t) { printf("# type: "); tree_print(t); printf("expr: "); tree_print(e); printf("\n"); } void tree_print(int e) { printf("* generate code on type:\n* "); tree_parse(type); printf("\n* expr:\n* "); tree_parse(e); printf("\n"); } static int tree_level; void tree_parse(int e) { tree_node_type node_type,*t; int i,j; char *s, **p; NMTBL **n; t = &node_type; t->tree_type=e; if(e<0) { if (tree_nodes(e,&t->tree_name,&t->tree_args,&t->tree_order)) { for(j=0;j<tree_level;j++) putchar(' '); printf("list(%s)",t->tree_name); } } else { i = car(e); if (tree_nodes(e,&t->tree_name,&t->tree_args,&t->tree_order)) { tree_level++; for(j=0;j<tree_level;j++) putchar(' '); printf("list(%s",t->tree_name); for(i=1,s=t->tree_args;*s;s++,i++) { switch(*s) { case 'e': case 't': printf(",\n*"); tree_parse(heap[e+i]); break; case 'v': printf(",%d",heap[e+i]); break; case 'n': n = (NMTBL**)&(heap[e+i]); printf(",%s",(*n)->nm); break; case 's': p = (char**)&(heap[e+i]); printf(",%s",*p); break; case 'i': printf(",%d",heap[e+i]); break; } } tree_level--; printf(")"); } } } void struct_type_print(int type,FILE *out) { NMTBL *n; int tags; if((n=ncadddr(type))) { fprintf(out,"%s ",n->nm); return; } if((tags=caddr(type))) { fprintf(out,"{"); while(tags) { n=ncaddr(tags); type_print(car(tags),n,out); fprintf(out,";"); tags = cadr(tags); } fprintf(out,"}"); } } void function_type_print1(int type,NMTBL *n,FILE *out,int cont) { int args; type_print1(cadr(type),0,out,cont); if(n) fprintf(out," %s",n->nm); fprintf(out,"("); if((args=caddr(type))) { while (args) { type_print(car(args),0,out); args=cadr(args); if (args) fprintf(out,","); } } fprintf(out,")"); } void function_type_print(int type,NMTBL *n,FILE *out) { function_type_print1(type,n,out,0); } void sym_print(int sym,FILE *out) { tree_node_type tn; if (!(tree_nodes(sym,&tn.tree_name,&tn.tree_args,&tn.tree_order))) { error(-1); return; } fprintf(out,"%s",tn.tree_name); } NMTBL * typedef_search(int t,int type) { while(t) { if ((ncaddr(t))->ty==type) return ncaddr(t); t=cadr(t); } return 0; } static void n_attr_print(int attr, FILE *out) { for(;attr;attr=cadr(attr)) { switch(car(attr)) { case INLINE: fprintf(out,"inline "); break; case CONST: fprintf(out,"const "); break; case VOLATILE: fprintf(out,"const "); break; case RESTRICT: fprintf(out,"const "); break; } } } void type_print1(int type,NMTBL *n,FILE *out,int cont) { int t; tree_node_type *tn,tn0; NMTBL *td; int args; tn = &tn0; if (n) { if (n->attr) n_attr_print(n->attr,out); while(type>0 && car(type)==ATTRIBUTE) type=cadr(type); } else type = attr_print(type); if(type>0&&(td=typedef_search(typedefed,type))) { if (!cont) fprintf(out,"%s ",td->nm); } else if(type>0&&(td=typedef_search(gtypedefed,type))) { if (!cont) fprintf(out,"%s ",td->nm); } else if (type<0) { t=type; if (!(tree_nodes(t,&tn->tree_name,&tn->tree_args,&tn->tree_order))) { error(-1); return; } if (!cont) fprintf(out,"%s ",tn->tree_name); } else if ((t=car(type))) { if (!(tree_nodes(t,&tn->tree_name,&tn->tree_args,&tn->tree_order))) { error(-1); return; } if(t==STRUCT||t==UNION) { if (!cont) { fprintf(out,"%s ",tn->tree_name); struct_type_print(type,out); } } else if(t==CODE) { // if (!cont) { fprintf(out,"%s ",tn->tree_name); } function_type_print1(type,n,out,cont); return; } else if(t==FUNCTION) { function_type_print1(type,n,out,cont); return; } else if(t==ARRAY) { type_print1(cadr(type),n,out,cont); if (caddr(type)) fprintf(out,"[%d]",caddr(type)); else fprintf(out,"[]"); return; } else if(t==POINTER) { t=cadr(type); if(t<0) { type_print1(t,0,out,cont); fprintf(out,"*"); } else if(car(t)==FUNCTION) { type_print1(cadr(t),0,out,cont); fprintf(out,"(*"); if(n) fprintf(out,"%s",n->nm); fprintf(out,")"); fprintf(out,"("); if((args=caddr(t))) { while (args) { type_print(car(args),0,out); args=cadr(args); if (args) fprintf(out,","); } } fprintf(out,")"); return; } else if(car(t)==CODE) { type_print1(cadr(t),0,out,cont); fprintf(out,"(*"); if(n) fprintf(out,"%s",n->nm); fprintf(out,")"); fprintf(out,"("); if((args=caddr(t))) { while (args) { type_print(car(args),0,out); args=cadr(args); if (args) fprintf(out,","); } } fprintf(out,")"); return; } else if(car(t)==ARRAY) { fprintf(out,"(*"); type_print(cadr(t),n,out); if (caddr(type)) fprintf(out,")[%d]",caddr(type)); else fprintf(out,")[]"); return; } else { type_print1(t,0,out,cont); fprintf(out,"*"); } } } if(n) fprintf(out,"%s",n->nm); } void type_print(int type,NMTBL *n,FILE *out) { type_print1(type,n,out,0); } /* parse tree を印刷する 正しく括弧とかを付けるアルゴリズムが不明... 先読みして、優先順位を判別する必要があるはず。 そういえば、cast とかは、落ちて変換コードに変わっている はず。cast を木にしないとだめか。 */ void print_expr(int e, FILE *vout) { NMTBL *nptr,*n; if (e==0) { // can't happen in normal C language fprintf(vout,"#"); return; } switch (car(e)%SOP) { case LVAR: case RLVAR: case URLVAR: if ((nptr = ncaddr(e))) { fprintf(vout,"%s",nptr->nm); } else { // anonymous variable fprintf(vout,"_%d",caddr(e)); } break; case GVAR: case RGVAR: case URGVAR: if ((nptr = ncaddr(e))) { fprintf(vout,"%s",nptr->nm); } else { // anonymous variable fprintf(vout,"_%d",caddr(e)); } if (cadr(e)) { // offset // certainly this is wrong fprintf(vout,"+%d",caddr(e)); } break; case REGISTER: if ((nptr = ncaddr(e))) { fprintf(vout,"%s",nptr->nm); } else { // anonymous register variable fprintf(vout,"_%d",caddr(e)); } break; case IDENT: nptr = ncaddr(e); fprintf(vout,"%s",nptr->nm); break; case CONST: switch(car(e)) { case CONST: fprintf(vout,"%d",cadr(e)); break; #if FLOAT_CODE case FCONST: fprintf(vout,"%g",dcadr(e)); break; case DCONST: fprintf(vout,"%g",dcadr(e)); break; #endif #if LONGLONG_CODE case LCONST: fprintf(vout,"%lld",lcadr(e)); break; #endif } break; case ADDRESS: if (car(cadr(e))!=STRING) { fprintf(vout,"&"); print_expr(cadr(e),vout); break; } case STRING: { int c; char *s; int i; nptr = ncaddr(e); s = nptr->nm;i=nptr->dsp; fprintf(vout,"\""); while(--i>0) { c=*s++; if(c=='\n') fprintf(vout,"\\n"); else if(c=='\r') fprintf(vout,"\\r"); else if(c=='\t') fprintf(vout,"\\t"); else if(c=='\e') fprintf(vout,"\\e"); else if(c=='"') fprintf(vout,"\\\""); else if(c=='\\') fprintf(vout,"\\\\"); else if(!(' '<=c&&c<=0x7f)) fprintf(vout,"\\%03o",c); else fprintf(vout,"%c",c); } fprintf(vout,"\""); } break; case ARRAY: print_expr(cadr(e),vout); fprintf(vout,"["); print_expr(caddr(e),vout); fprintf(vout,"]"); break; case PERIOD: print_expr(cadr(e),vout); n = ncaddr(e); fprintf(vout,".%s",n->nm); break; case ARROW: print_expr(cadr(e),vout); n = ncaddr(e); fprintf(vout,"->%s",n->nm); break; case INDIRECT: case RINDIRECT: case URINDIRECT: fprintf(vout,"*"); print_expr(cadr(e),vout); break; case FNAME: n = ncaddr(e); fprintf(vout,"%s",n->nm); break; case FUNCTION: print_function_call(e,vout); break; /* case ADD: fprintf(vout,"("); print_expr(cadr(e),vout); fprintf(vout,"+"); print_expr(caddr(e),vout); fprintf(vout,")"); break; */ default: print_operator(e, vout); } } static void print_expr_paren(int order,char *args,int e) { } static void print_operator(int e, FILE *vout) { char *name; char *args; int order ; if (tree_nodes(car(e), &name, &args, &order) ) { if (order>0) { int i = 0; for(;*args;args++,i++) { print_expr_paren(order,args,heap[e+i]); } } else { print_statement(e, vout); } } } static void print_decl(int e, FILE *vout) { NMTBL *n = ncaddr(e); int e1 = cadddr(e); // int mode = car(e1); int stmode = cadr(e1); int ctmode = caddr(e1); if (n==&null_nptr) { error(-1); // can't happen return; } if (stmode==STATIC) { fprintf(vout,"static "); } else if (stmode==EXTRN||stmode==EXTRN1) { fprintf(vout,"extern "); } type_print(n->ty,n,vout); if (ctmode & KONST_BIT) { fprintf(vout,"const "); } if (ctmode & VOLATILE_BIT) { fprintf(vout,"volatile "); } if (ctmode & RESTRICT_BIT) { fprintf(vout,"restrict "); } fprintf(vout,"%s; ",nptr->nm); } static void print_statement(int e, FILE *vout) { int e1; NMTBL *n; for (;e!=0; e = cadr(e)) { switch (car(e)) { case ST_DECL: print_decl(e, vout); break; case ST_IF: fprintf(vout,"if "); break; case ST_DO: fprintf(vout,"do "); break; case ST_WHILE: fprintf(vout,"while "); break; case ST_FOR: fprintf(vout,"for "); break; case ST_SWITCH: fprintf(vout,"switch "); break; case ST_COMP: fprintf(vout,"{"); fprintf(vout,"}"); break; case ST_BREAK: fprintf(vout,"break; "); break; case ST_CONTINUE: fprintf(vout,"continue; "); break; case ST_CASE: for(e1 = caddr(e);e1;e1 = cadr(e1)) { fprintf(vout,"case "); fprintf(vout,"%d: ",car(e1)); } break; case ST_DEFAULT: fprintf(vout,"default: "); break; case ST_RETURN: fprintf(vout,"return "); if (( e1 = caddr(e))) { print_expr(e1,vout); } fprintf(vout,"; "); break; case ST_GOTO: fprintf(vout,"goto "); break; case ST_ASM: fprintf(vout,"__asm__ "); break; case ST_LABEL: n = ncaddr(caddr(e)); fprintf(vout,"%s:", n->nm); break; case ST_OP: e1 = caddr(e); print_expr(list3(cadr(e),car(e1),cadr(e1)),vout); break; case ST_COMMENT: fprintf(vout,"\n# %s\n",scaddr(e)); break; default: fprintf(stderr,"Unknown Statement ID %d\n",car(e)); } } } static void print_function_call(int e1,FILE *vout) { int e2,e3; NMTBL *fn = 0; e2 = cadr(e1); if (car(e2) == FNAME) { fn=ncaddr(e2); fprintf(vout,"%s",fn->nm); } else { if (car(e2)==INDIRECT) e2=cadr(e2); // (*func)(i) case fprintf(vout,"("); print_expr(e2,vout); fprintf(vout,")"); } fprintf(vout,"("); for (e3 = e1 = reverse0(caddr(e1)); e3; e3 = cadr(e3)) { print_expr(car(e3),vout); if (cadr(e3)) { fprintf(vout,","); } } fprintf(vout,")"); reverse0(e1); // make it normal order } /* end */