home *** CD-ROM | disk | FTP | other *** search
/ Total Destruction / Total_Destruction.iso / addons / Lccwin32.exe / Lccwin32 / lccpub / src / Tree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-11-11  |  5.6 KB  |  276 lines

  1. #include "c.h"
  2.  
  3. static int where = STMT;
  4. static int nid = 1;        /* identifies trees & nodes in debugging output */
  5. static struct nodeid {
  6.     int printed;
  7.     Tree node;
  8. } ids[500];            /* if ids[i].node == p, then p's id is i */
  9.  
  10. static void printtree1 ARGS((Tree, int, int));
  11.  
  12. Tree tree(int op,Type type,Tree left,Tree right) {
  13.     Tree p;
  14.  
  15.     NEW0(p, where);
  16.     p->op = op;
  17.     p->type = type;
  18.     p->kids[0] = left;
  19.     p->kids[1] = right;
  20.     return p;
  21. }
  22.  
  23. Tree texpr(Tree (*f)(int), int tok,int a)
  24. {
  25.     int save = where;
  26.     Tree p;
  27.  
  28.     where = a;
  29.     p = (*f)(tok);
  30.     where = save;
  31.     return p;
  32. }
  33. /* right - return (RIGHT, root(p), q) or just p/q if q/p==0;
  34.    if ty==NULL, use q->type, or q->type/p->type */
  35. Tree right(Tree p,Tree q)
  36. {
  37.     assert(p || q);
  38.     if (p && q)
  39.         return tree(RIGHT, q->type, root(p), q);
  40.     else if (p)
  41.         return p;
  42.     else
  43.         return q;
  44. }
  45.  
  46. Tree root(Tree p)
  47. {
  48.     if (p == NULL)
  49.         return p;
  50.     switch (generic(p->op)) {
  51.     case COND: {
  52.         Tree q = p->kids[1];
  53.         assert(q && q->op == RIGHT);
  54.         if (p->u.sym && q->kids[0] && generic(q->kids[0]->op) == ASGN)
  55.             q->kids[0] = root(q->kids[0]->kids[1]);
  56.         else
  57.             q->kids[0] = root(q->kids[0]);
  58.         if (p->u.sym && q->kids[1] && generic(q->kids[1]->op) == ASGN)
  59.             q->kids[1] = root(q->kids[1]->kids[1]);
  60.         else
  61.             q->kids[1] = root(q->kids[1]);
  62.         p->u.sym = 0;
  63.         if (q->kids[0] == 0 && q->kids[1] == 0)
  64.             p = root(p->kids[0]);
  65.         }
  66.         break;
  67.     case AND: case OR:
  68.         if ((p->kids[1] = root(p->kids[1])) == 0)
  69.             p = root(p->kids[0]);
  70.         break;
  71.     case NOT:
  72.         return root(p->kids[0]);
  73.     case RIGHT:
  74.         if (p->kids[1] == 0)
  75.             return root(p->kids[0]);
  76.         if (p->kids[0] && p->kids[0]->op == CALL+B
  77.         &&  p->kids[1] && p->kids[1]->op == INDIR+B)
  78.             /* avoid premature release of the CALL+B temporary */
  79.             return p->kids[0];
  80.         if (p->kids[0] && p->kids[0]->op == RIGHT
  81.         &&  p->kids[1] == p->kids[0]->kids[0])
  82.             /* de-construct e++ construction */
  83.             return p->kids[0]->kids[1];
  84.         /* fall thru */
  85.     case EQ:  case NE:  case GT:   case GE:  case LE:  case LT: 
  86.     case ADD: case SUB: case MUL:  case DIV: case MOD:
  87.     case LSH: case RSH: case BAND: case BOR: case BXOR:
  88.         p = tree(RIGHT, p->type, root(p->kids[0]), root(p->kids[1]));
  89.         return p->kids[0] || p->kids[1] ? p : 0;
  90.     case INDIR:
  91.         if (p->type->size == 0 && unqual(p->type) != voidtype)
  92.             warning("reference to `%t' elided\n", p->type);
  93.         if (isptr(p->kids[0]->type) && isvolatile(p->kids[0]->type->type))
  94.             warning("reference to `volatile %t' elided\n", p->type);
  95.         /* fall thru */
  96.     case CVI: case CVF:  case CVD:   case CVU: case CVC: case CVS: case CVP:
  97.     case NEG: case BCOM: case FIELD:
  98.         return root(p->kids[0]);
  99.     case ADDRL: case ADDRG: case ADDRF: case CNST:
  100.         return 0;
  101.     case ARG: case ASGN: case CALL: case JUMP: case LABEL:
  102.         break;
  103.     default: assert(0);
  104.     }
  105.     return p;
  106. }
  107.  
  108. char *opname(int op)
  109. {
  110. #if 1
  111.     static char *opnames[] = {
  112.     "",
  113.     "CNST",
  114.     "ARG",
  115.     "ASGN",
  116.     "INDIR",
  117.     "CVC",
  118.     "CVD",
  119.     "CVF",
  120.     "CVI",
  121.     "CVP",
  122.     "CVS",
  123.     "CVU",
  124.     "NEG",
  125.     "CALL",
  126.     "LOAD",
  127.     "RET",
  128.     "ADDRG",
  129.     "ADDRF",
  130.     "ADDRL",
  131.     "ADD",
  132.     "SUB",
  133.     "LSH",
  134.     "MOD",
  135.     "RSH",
  136.     "BAND",
  137.     "BCOM",
  138.     "BOR",
  139.     "BXOR",
  140.     "DIV",
  141.     "MUL",
  142.     "EQ",
  143.     "GE",
  144.     "GT",
  145.     "LE",
  146.     "LT",
  147.     "NE",
  148.     "JUMP",
  149.     "LABEL",
  150.     "AND",
  151.     "NOT",
  152.     "OR",
  153.     "COND",
  154.     "RIGHT",
  155.     "FIELD"
  156.     }, typenames[] = " FDCSIUPVB";
  157. #else
  158.     static char *opnames[] = {
  159.     "",
  160.     "CONSTANT_",
  161.     "ARGUMENT_",
  162.     "ASIGN_",
  163.     "FETCH_",
  164.     "CHAR_TO_",
  165.     "DOUBLE_TO_",
  166.     "FLOAT_TO_",
  167.     "INT_TO_",
  168.     "POINTER_TO_",
  169.     "SHORT_TO_",
  170.     "UNS_TO_",
  171.     "NEG_",
  172.     "CALL_",
  173.     "LOAD_",
  174.     "RET_",
  175.     "ADDR_GLOBAL_",
  176.     "ADDR_PARAMETER_",
  177.     "ADDR_LOCAL_",
  178.     "ADD_",
  179.     "SUB_",
  180.     "LSH_",
  181.     "MOD_",
  182.     "RSH_",
  183.     "BIT_AND_",
  184.     "BIT_COMPLEMENT_",
  185.     "BIT_OR_",
  186.     "BIT_XOR_",
  187.     "DIV_",
  188.     "MUL_",
  189.     "JEQ",
  190.     "JGE",
  191.     "JGT",
  192.     "JLE",
  193.     "JLT",
  194.     "JNE",
  195.     "JUMP",
  196.     "LABEL",
  197.     "AND",
  198.     "NOT",
  199.     "OR",
  200.     "COND",
  201.     "RIGHT",
  202.     "FIELD"
  203.     }, typenames[] = " FDCSIUPVB";
  204. #endif
  205.     char *name;
  206.  
  207.     if (opindex(op) > 0 && opindex(op) < NELEMS(opnames))
  208.         name = opnames[opindex(op)];
  209.     else
  210.         name = stringd(opindex(op));
  211.     if (op >= AND && op <= FIELD)
  212.         return name;
  213.     else if (optype(op) > 0 && optype(op) < sizeof (typenames) - 1)
  214.         return stringf("%s%c", name, typenames[optype(op)]);
  215.     else
  216.         return stringf("%s+%d", name, optype(op));
  217. }
  218.  
  219. int nodeid(Tree p)
  220. {
  221.     int i = 1;
  222.  
  223.     ids[nid].node = p;
  224.     while (ids[i].node != p)
  225.         i++;
  226.     if (i == nid)
  227.         ids[nid++].printed = 0;
  228.     return i;
  229. }
  230.  
  231. /* printed - return pointer to ids[id].printed */
  232. int *printed(int id)
  233. {
  234.     if (id)
  235.         return &ids[id].printed;
  236.     nid = 1;
  237.     return 0;
  238. }
  239.  
  240. /* printtree - print tree p on fd */
  241. void printtree(Tree p,int fd)
  242. {
  243.     (void)printed(0);
  244.     printtree1(p, fd, 1);
  245. }
  246.  
  247. /* printtree1 - recursively print tree p */
  248. static void printtree1(Tree p,int fd,int lev)
  249. {
  250.     int i;
  251.     static char blanks[] = "                                         ";
  252.  
  253.     if (p == 0 || *printed(i = nodeid(p)))
  254.         return;
  255.     fprint(fd, "#%d%s%s", i, &"   "[i < 10 ? 0 : i < 100 ? 1 : 2],
  256.          &blanks[sizeof blanks - lev]);
  257.     fprint(fd, "%s %t", opname(p->op), p->type);
  258.     *printed(i) = 1;
  259.     for (i = 0; i < NELEMS(p->kids); i++)
  260.         if (p->kids[i])
  261.             fprint(fd, " #%d", nodeid(p->kids[i]));
  262.     if (p->op == FIELD && p->u.field)
  263.         fprint(fd, " %s %d..%d", p->u.field->name,
  264.             fieldsize(p->u.field) + fieldright(p->u.field), fieldright(p->u.field));
  265.     else if (generic(p->op) == CNST)
  266.         fprint(fd, " %s", vtoa(p->type, p->u.v));
  267.     else if (p->u.sym)
  268.         fprint(fd, " %s", p->u.sym->name);
  269.     if (p->node)
  270.         fprint(fd, " node=0x%x", p->node);
  271.     fprint(fd, "\n");
  272.     for (i = 0; i < NELEMS(p->kids); i++)
  273.         printtree1(p->kids[i], fd, lev + 1);
  274. }
  275.  
  276.