Mercurial > hg > CbC > old > device
view mc-tree.c @ 643:f5c0371c9401
*** empty log message ***
author | kono |
---|---|
date | Wed, 01 Nov 2006 15:55:24 +0900 |
parents | 0e7281ec9007 |
children | 3e1dba5758d8 |
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" typedef struct tree_node { int tree_type; char *tree_name; char *tree_args; } tree_node_type; extern void tree_print(int e); extern void tree_parse(int e); extern void tree_print_t(int e,int t); static tree_node_type * find_node(int e); 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); /* ascendant order for binary search */ static tree_node_type tree_nodes[] = { {DOTS,"...",""}, {LMACRO,"lmacro",""}, {FMACRO,"fmacro",""}, {KONST,"const",""}, {DEFINED,"defined",""}, {ENVIRONMENT,"environment",""}, {CODE,"code",""}, {REGISTER,"register",""}, {ASM,"__asm__",""}, {VOID,"void",""}, {EXTRN,"extern",""}, {SHORT,"short",""}, {USHORT,"unsigned short",""}, {LONG,"long",""}, {TYPE,"type",""}, {VOLATILE,"volatile",""}, {SIZEOF,"sizeof",""}, {TYPEDEF,"typedef",""}, {FLABEL,"flabel",""}, {BLABEL,"blabel",""}, {MACRO,"macro",""}, {STRING,"string",""}, {IDENT,"ident",""}, {FIELD,"field",""}, {TAG,"tag",""}, {RESERVE,"reserve",""}, {DEFAULT,"default",""}, {ATTRIBUTE,"__attribute__",""}, {CASE,"case",""}, {SWITCH,"switch",""}, {WHILE,"while",""}, {DO,"do",""}, {FOR,"for",""}, {ELSE,"else",""}, {IF,"if",""}, {CONTINUE,"continue",""}, {BREAK,"break",""}, {RETURN,"return",""}, {GOTO,"goto",""}, {STATIC,"static",""}, {EMPTY,"empty",""}, {FUNCTION,"function","t"}, {UNION,"union",""}, {STRUCT,"struct","vt"}, {ARRAY,"array","tv"}, {POINTER,"*","t"}, {UNSIGNED,"unsigned",""}, {INLINE,"inline",""}, {SIGNED,"signed",""}, {CHAR,"char",""}, {UCHAR,"unsigned char",""}, {INT,"int",""}, {FLOAT,"float",""}, {DOUBLE,"double",""}, {LONGLONG,"long long",""}, {ULONGLONG,"unsigned long long",""}, {GVAR,"gvar","vs"}, {RGVAR,"rgvar","vs"}, {CRGVAR,"crgvar","vs"}, {LVAR,"lvar","v"}, {RLVAR,"rlvar","v"}, {CRLVAR,"crlvar","v"}, {CONST,"const","v"}, {FNAME,"fname","n"}, {MUL,"*","e"}, {RINDIRECT,"rindirect","e"}, {CRINDIRECT,"crindirect","e"}, {BAND,"&","e"}, {MINUS,"-","e"}, {LNOT,"!","e"}, {BNOT,"~","e"}, {INC,"++",""}, {POSTINC,"postinc","e"}, {PREINC,"preinc","e"}, {CPOSTINC,"cpostinc","e"}, {CPREINC,"cpreinc","e"}, {DEC,"--",""}, {DIV,"/","ee"}, {UDIV,"/","ee"}, {MUL,"*","ee"}, {UMUL,"*","ee"}, {MOD,"%","ee"}, {UMOD,"%","ee"}, {ADD,"+","ee"}, {SUB,"-","ee"}, {RSHIFT,">>","ee"}, {URSHIFT,">>","ee"}, {LSHIFT,"<<","ee"}, {ULSHIFT,"<<","ee"}, {GT,">","ee"}, {UGT,">","ee"}, {GE,">=","ee"}, {UGE,">=","ee"}, {LT,"<","ee"}, {ULT,"<","ee"}, {LE,"<=","ee"}, {ULE,"<=","ee"}, {EQ,"==","ee"}, {NEQ,"!=","ee"}, {BAND,"&","ee"}, {EOR,"^","ee"}, {BOR,"|","ee"}, {LAND,"&&","ee"}, {LOR,"||","ee"}, {COND,"?","eee"}, {ASS,"=","ee"}, {ASSOP,"assop","eev"}, {CASSOP,"cassop","eev"}, {COMMA,",","ee"}, {LPAR,"(",""}, {RPAR,")",""}, {LBRA,"[",""}, {RBRA,"]",""}, {LC,"{",""}, {RC,"}",""}, {COLON,":","ee"}, {SM,";",""}, {PERIOD,".",""}, {ARROW,"->",""}, {SASS,"sass",""}, {RSTRUCT,"rstruct",""}, {AS+MUL,"*=","ee"}, {AS+UMUL,"*=","ee"}, {AS+DIV,"/=","ee"}, {AS+UDIV,"/=","ee"}, {AS+MOD,"%=","ee"}, {AS+UMOD,"%=","ee"}, {AS+ADD,"+=","ee"}, {AS+MINUS,"-=","ee"}, {AS+RSHIFT,">>=","ee"}, {AS+URSHIFT,">>=","ee"}, {AS+LSHIFT,"<<=","ee"}, {AS+ULSHIFT,"<<=","ee"}, {AS+BAND,"&=","ee"}, {AS+EOR,"^=","ee"}, {AS+BOR,"|=","ee"}, }; 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 *t; int i,j; char *s; if(e<0) { t=find_node(e); if(t->tree_type==e) { for(j=0;j<tree_level;j++) putchar(' '); printf("list(%s)",t->tree_name); } } else { i = car(e); t=find_node(e); if(t->tree_type==i) { 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': printf(",%s",((NMTBL *)heap[e+i])->nm); break; case 's': printf(",%s",(char *)heap[e+i]); break; case 'i': printf(",%d",heap[e+i]); break; } } tree_level--; printf(")"); } } } tree_node_type * find_node(int e) { int e1,e2; int first=0; int last=sizeof(tree_nodes)/sizeof(tree_node_type); // e2=-1; e2=OP(e); e1=0; while (first!=last) { #if 0 e1 = (first+last)/2; if(e2==e1) return 0; e2=e1; if (tree_nodes[e1].tree_type>e) last = e1; else if (tree_nodes[e1].tree_type==e) break; else if (tree_nodes[e1].tree_type<e) first = e1; #else if (tree_nodes[first].tree_type==e2) return &tree_nodes[first]; first++; #endif } fprintf(stderr,"Unknown ID %d [%d]in find note\n",e2,e); return &tree_nodes[e1]; } void struct_type_print(int type,FILE *out) { NMTBL *n; int tags; if((n=(NMTBL*)cadddr(type))) { fprintf(out,"%s ",n->nm); return; } if((tags=caddr(type))) { fprintf(out,"{"); while(tags) { n=(NMTBL*)caddr(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 (!(tn=find_node(sym))) { error(-1); return; } fprintf(out,"%s",tn->tree_name); } NMTBL * typedef_search(int t,int type) { while(t) { if (((NMTBL*)car(t))->ty==type) return (NMTBL*)car(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; NMTBL *td; int args; 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 (!(tn=find_node(t))) { error(-1); return; } if (!cont) fprintf(out,"%s ",tn->tree_name); } else if ((t=car(type))) { if (!(tn=find_node(t))) { 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 を印刷する 正しく括弧とかを付けるアルゴリズムが不明... 先読みして、優先順位を判別する必要があるはず。 */ void print_expr(int e, FILE *vout) { NMTBL *nptr,*n; switch (car(e)%SOP) { case LVAR: case RLVAR: if ((nptr = (NMTBL*)caddr(e))) { fprintf(vout,"%s",nptr->nm); } else { // anonymous variable fprintf(vout,"_%d",caddr(e)); } break; case GVAR: case RGVAR: if ((nptr = (NMTBL*)caddr(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 = (NMTBL*)caddr(e))) { fprintf(vout,"%s",nptr->nm); } else { // anonymous register variable fprintf(vout,"_%d",caddr(e)); } break; case IDENT: nptr = (NMTBL*)cadr(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 = (NMTBL*)cadr(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 = (NMTBL*)caddr(e); fprintf(vout,".%s",n->nm); break; case ARROW: print_expr(cadr(e),vout); n = (NMTBL*)caddr(e); fprintf(vout,"->%s",n->nm); break; case INDIRECT: case RINDIRECT: fprintf(vout,"*"); print_expr(cadr(e),vout); break; case FNAME: n = (NMTBL*)cadr(e); fprintf(vout,"%s",n->nm); break; case ADD: fprintf(vout,"("); print_expr(cadr(e),vout); fprintf(vout,"+"); print_expr(caddr(e),vout); fprintf(vout,")"); break; default: error(-1); } } /* end */