#define EXTERN /**/
#include "mc.h"

typedef
struct tree_node {
    int type;
    char *name;
    char *args;
} tree_node;

tree_node tree_nodes[] = {
    {(-1),"INT",""},
    {(-2),"CHAR",""},
    {(-3),"UNSIGNED",""},
    {(-4),"POINTER","t"},
    {(-5),"ARRAY","tv"},
    {(-6),"STRUCT",""},
    {(-7),"UNION",""},
    {(-8),"FUNCTION","t"},
    {(-9),"EMPTY",""},
    {(-10),"STATIC",""},
    {(-11),"GOTO",""},
    {(-12),"RETURN",""},
    {(-13),"BREAK",""},
    {(-14),"CONTINUE",""},
    {(-15),"IF",""},
    {(-16),"ELSE",""},
    {(-17),"FOR",""},
    {(-18),"DO",""},
    {(-19),"WHILE",""},
    {(-20),"SWITCH",""},
    {(-21),"CASE",""},
    {(-22),"DEFAULT",""},
    {(-23),"RESERVE",""},
    {(-24),"TAG",""},
    {(-25),"FIELD",""},
    {(-26),"IDENT",""},
    {(-27),"STRING",""},
    {(-28),"MACRO",""},
    {(-29),"BLABEL",""},
    {(-30),"FLABEL",""},
    {(-31),"TYPEDEF",""},
    {(-32),"SIZEOF",""},
    {(-33),"TYPE",""},
    {(-34),"LONG",""},
    {(-35),"SHORT",""},
    {1,"GVAR","vs"},
    {2,"RGVAR","vs"},
    {3,"CRGVAR","vs"},
    {4,"LVAR","v"},
    {5,"RLVAR","v"},
    {6,"CRLVAR","v"},
    {7,"CONST","v"},
    {8,"FNAME","n"},
    {9,"INDIRECT","e"},
    {10,"RINDIRECT","e"},
    {11,"CRINDIRECT","e"},
    {12,"ADDRESS","e"},
    {13,"MINUS","e"},
    {14,"LNOT","e"},
    {15,"BNOT","e"},
    {16,"INC",""},
    {17,"POSTINC","e"},
    {18,"PREINC","e"},
    {19,"CPOSTINC","e"},
    {20,"CPREINC","e"},
    {21,"DEC",""},
    {22,"CPOSTDEC","e"},
    {23,"CPREDEC","e"},
    {24,"MUL","ee"},
    {25,"UMUL","ee"},
    {26,"DIV","ee"},
    {27,"UDIV","ee"},
    {28,"MOD","ee"},
    {29,"UMOD","ee"},
    {30,"ADD","ee"},
    {31,"SUB","ee"},
    {32,"RSHIFT","ee"},
    {33,"URSHIFT","ee"},
    {34,"LSHIFT","ee"},
    {35,"ULSHIFT","ee"},
    {36,"GT","ee"},
    {37,"UGT","ee"},
    {38,"GE","ee"},
    {39,"UGE","ee"},
    {40,"LT","ee"},
    {41,"ULT","ee"},
    {42,"LE","ee"},
    {43,"ULE","ee"},
    {44,"EQ","ee"},
    {45,"NEQ","ee"},
    {46,"BAND","ee"},
    {47,"EOR","ee"},
    {48,"BOR","ee"},
    {49,"LAND","ee"},
    {50,"LOR","ee"},
    {51,"COND","eee"},
    {52,"ASS","ee"},
    {53,"CASS","ee"},
    {54,"ASSOP","eev"},
    {55,"CASSOP","eev"},
    {56,"COMMA","ee"},
    {57,"LPAR",""},
    {58,"RPAR",""},
    {59,"LBRA",""},
    {60,"RBRA",""},
    {61,"LC",""},
    {62,"RC",""},
    {63,"COLON","ee"},
    {64,"SM",""},
    {65,"PERIOD",""},
    {66,"ARROW",""},
    {100,"AS",""},
};

tree_print(e)
int e;
{
    printf("* generate code on type:\n* ");
    tree_parse(type);
    printf("\n* expr:\n* ");
    tree_parse(e);
    printf("\n");
}

int tree_level;

tree_parse(e)
int e;
{
    tree_node *t;
    int i,j;
    char *s;

    if(e<0) {
	for(t=tree_nodes;t->type!=100;t++) {
	    if(t->type==e) {
		for(j=0;j<tree_level;j++) putchar(' ');
		printf("list(%s)",t->name);
		break;
	    }
	}
    } else {
	i = car(e);
	for(t=tree_nodes;t->type!=100;t++) {
	    if(t->type==i) {
		tree_level++;
		for(j=0;j<tree_level;j++) putchar(' ');
		printf("list(%s",t->name);
		for(i=1,s=t->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",heap[e+i]); break;
		    case 'i':
			printf(",%d",heap[e+i]); break;
		    }
		}
		tree_level--;
		printf(")");
		break;
	    }
	}
    }
}