view mc-tree.c @ 563:588bb765b301

*** empty log message ***
author kono
date Tue, 10 Jan 2006 10:28:55 +0900
parents 0a156c491f81
children 25f431685d80
line wrap: on
line source

/* Micro-C tree print routine */
/* $Id$ */

#include <stdio.h>
#include "mc.h"
#include "mc-parse.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",""},
    {VOID,"void",""},
    {EXTRN,"extern",""},
    {SHORT,"short",""},
    {USHORT,"unsigned short",""},
    {LONG,"long",""},
    {TYPE,"type",""},
    {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"},
};

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=e%200;
    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;
}

void type_print1(int type,NMTBL *n,FILE *out,int cont)
{
    int t; 
    tree_node_type *tn;
    NMTBL *td;
    int args;

    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)==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);
}

/* end */