home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume30 / rc / part06 / tree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-05-30  |  4.5 KB  |  173 lines

  1. /* tree.c: functions for manipulating parse-trees. (create, copy, delete) */
  2.  
  3. #include "rc.h"
  4.  
  5. /* make a new node, pass it back to yyparse. Used to generate the parsetree. */
  6.  
  7. extern Node *mk(int /*nodetype*/ t,...) {
  8.     va_list ap;
  9.     Node *n;
  10.     va_start(ap, t);
  11.     switch (t) {
  12.     default:
  13.         panic("unexpected node in mk");
  14.         /* NOTREACHED */
  15.     case nDup:
  16.         n = nalloc(offsetof(Node, u[3]));
  17.         n->u[0].i = va_arg(ap, int);
  18.         n->u[1].i = va_arg(ap, int);
  19.         n->u[2].i = va_arg(ap, int);
  20.         break;
  21.     case nWord: case nQword:
  22.         n = nalloc(offsetof(Node, u[2]));
  23.         n->u[0].s = va_arg(ap, char *);
  24.         n->u[1].s = va_arg(ap, char *);
  25.         break;
  26.     case nBang: case nNowait:
  27.     case nCount: case nFlat: case nRmfn: case nSubshell:
  28.     case nVar: case nCase:
  29.         n = nalloc(offsetof(Node, u[1]));
  30.         n->u[0].p = va_arg(ap, Node *);
  31.         break;
  32.     case nAndalso: case nAssign: case nBackq: case nBody: case nBrace: case nConcat:
  33.     case nElse: case nEpilog: case nIf: case nNewfn: case nCbody:
  34.     case nOrelse: case nPre: case nArgs: case nSwitch:
  35.     case nMatch: case nVarsub: case nWhile: case nLappend:
  36.         n = nalloc(offsetof(Node, u[2]));
  37.         n->u[0].p = va_arg(ap, Node *);
  38.         n->u[1].p = va_arg(ap, Node *);
  39.         break;
  40.     case nForin:
  41.         n = nalloc(offsetof(Node, u[3]));
  42.         n->u[0].p = va_arg(ap, Node *);
  43.         n->u[1].p = va_arg(ap, Node *);
  44.         n->u[2].p = va_arg(ap, Node *);
  45.         break;
  46.     case nPipe:
  47.         n = nalloc(offsetof(Node, u[4]));
  48.         n->u[0].i = va_arg(ap, int);
  49.         n->u[1].i = va_arg(ap, int);
  50.         n->u[2].p = va_arg(ap, Node *);
  51.         n->u[3].p = va_arg(ap, Node *);
  52.         break;
  53.     case nRedir:
  54.     case nNmpipe:
  55.         n = nalloc(offsetof(Node, u[3]));
  56.         n->u[0].i = va_arg(ap, int);
  57.         n->u[1].i = va_arg(ap, int);
  58.         n->u[2].p = va_arg(ap, Node *);
  59.         break;
  60.      }
  61.     n->type = t;
  62.     va_end(ap);
  63.     return n;
  64. }
  65.  
  66. /* copy a tree to malloc space. Used when storing the definition of a function */
  67.  
  68. extern Node *treecpy(Node *s, void *(*alloc)(SIZE_T)) {
  69.     Node *n;
  70.     if (s == NULL)
  71.         return NULL;
  72.     switch (s->type) {
  73.     default:
  74.         panic("unexpected node in treecpy");
  75.         /* NOTREACHED */
  76.     case nDup:
  77.         n = (*alloc)(offsetof(Node, u[3]));
  78.         n->u[0].i = s->u[0].i;
  79.         n->u[1].i = s->u[1].i;
  80.         n->u[2].i = s->u[2].i;
  81.         break;
  82.     case nWord: case nQword:
  83.         n = (*alloc)(offsetof(Node, u[2]));
  84.         n->u[0].s = strcpy((char *) (*alloc)(strlen(s->u[0].s) + 1), s->u[0].s);
  85.         if (s->u[1].s != NULL) {
  86.             SIZE_T i = strlen(s->u[0].s);
  87.             n->u[1].s = (*alloc)(i);
  88.             memcpy(n->u[1].s, s->u[1].s, i);
  89.         } else
  90.             n->u[1].s = NULL;
  91.         break;
  92.     case nBang: case nNowait: case nCase:
  93.     case nCount: case nFlat: case nRmfn: case nSubshell: case nVar:
  94.         n = (*alloc)(offsetof(Node, u[1]));
  95.         n->u[0].p = treecpy(s->u[0].p, alloc);
  96.         break;
  97.     case nAndalso: case nAssign: case nBackq: case nBody: case nBrace: case nConcat:
  98.     case nElse: case nEpilog: case nIf: case nNewfn: case nCbody:
  99.     case nOrelse: case nPre: case nArgs: case nSwitch:
  100.     case nMatch: case nVarsub: case nWhile: case nLappend:
  101.         n = (*alloc)(offsetof(Node, u[2]));
  102.         n->u[0].p = treecpy(s->u[0].p, alloc);
  103.         n->u[1].p = treecpy(s->u[1].p, alloc);
  104.         break;
  105.     case nForin:
  106.         n = (*alloc)(offsetof(Node, u[3]));
  107.         n->u[0].p = treecpy(s->u[0].p, alloc);
  108.         n->u[1].p = treecpy(s->u[1].p, alloc);
  109.         n->u[2].p = treecpy(s->u[2].p, alloc);
  110.         break;
  111.     case nPipe:
  112.         n = (*alloc)(offsetof(Node, u[4]));
  113.         n->u[0].i = s->u[0].i;
  114.         n->u[1].i = s->u[1].i;
  115.         n->u[2].p = treecpy(s->u[2].p, alloc);
  116.         n->u[3].p = treecpy(s->u[3].p, alloc);
  117.         break;
  118.     case nRedir:
  119.     case nNmpipe:
  120.         n = (*alloc)(offsetof(Node, u[3]));
  121.         n->u[0].i = s->u[0].i;
  122.         n->u[1].i = s->u[1].i;
  123.         n->u[2].p = treecpy(s->u[2].p, alloc);
  124.         break;
  125.     }
  126.     n->type = s->type;
  127.     return n;
  128. }
  129.  
  130. /* free a function definition that is no longer needed */
  131.  
  132. extern void treefree(Node *s) {
  133.     if (s == NULL)
  134.         return;
  135.     switch (s->type) {
  136.     default:
  137.         panic("unexpected node in treefree");
  138.         /* NOTREACHED */
  139.     case nDup:
  140.         break;
  141.     case nWord: case nQword:
  142.         efree(s->u[0].s);
  143.         efree(s->u[1].s);
  144.         break;
  145.     case nBang: case nNowait:
  146.     case nCount: case nFlat: case nRmfn:
  147.     case nSubshell: case nVar: case nCase:
  148.         treefree(s->u[0].p);
  149.         break;
  150.     case nAndalso: case nAssign: case nBackq: case nBody: case nBrace: case nConcat:
  151.     case nElse: case nEpilog: case nIf: case nNewfn:
  152.     case nOrelse: case nPre: case nArgs: case nCbody:
  153.     case nSwitch: case nMatch:  case nVarsub: case nWhile:
  154.     case nLappend:
  155.         treefree(s->u[1].p);
  156.         treefree(s->u[0].p);
  157.         break;
  158.     case nForin:
  159.         treefree(s->u[2].p);
  160.         treefree(s->u[1].p);
  161.         treefree(s->u[0].p);
  162.         break;
  163.     case nPipe:
  164.         treefree(s->u[2].p);
  165.         treefree(s->u[3].p);
  166.         break;
  167.     case nRedir:
  168.     case nNmpipe:
  169.         treefree(s->u[2].p);
  170.     }
  171.     efree(s);
  172. }
  173.