home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / struct / 3.loop.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  3.1 KB  |  153 lines

  1. #include <stdio.h>
  2. #include "def.h"
  3. #include "3.def.h"
  4.  
  5. #define ARCCOUNT(v)    REACH(v)
  6.  
  7.  
  8. fixhd(v,hd,head)
  9. VERT v,hd,*head;
  10.     {
  11.     VERT w,newhd;
  12.     int i;
  13.     head[v] = hd;
  14.     newhd = (NTYPE(v) == ITERVX) ? v : hd;
  15.     for (i = 0; i < CHILDNUM(v); ++i)
  16.         for (w = LCHILD(v,i); DEFINED(w); w = RSIB(w))
  17.             fixhd(w,newhd,head);
  18.     }
  19.  
  20. getloop()
  21.     {
  22.     cntarcs();
  23.     fixloop(START);
  24.     }
  25.  
  26.  
  27. cntarcs()    /* count arcs entering each node */
  28.     {
  29.     VERT w,v;
  30.     int i;
  31.     for (v = 0; v < nodenum; ++v)
  32.         ARCCOUNT(v) = 0;
  33.     for (v = 0; v < nodenum; ++v)
  34.         for (i = 0; i < ARCNUM(v); ++i)
  35.             {
  36.             w = ARC(v,i);
  37.             if (!DEFINED(w)) continue;
  38.             ++ARCCOUNT(w);
  39.             }
  40.     }
  41.  
  42.  
  43. fixloop(v)        /* find WHILE loops  */
  44. VERT v;
  45.     {
  46.     int recvar;
  47.     if (NTYPE(v) == LOOPVX)
  48.         {
  49.         ASSERT(DEFINED(ARC(v,0)),fixloop);
  50.         NXT(ARC(v,0)) = ARC(v,0);
  51.         if (!getwh(v))
  52.             getun(v);
  53.         }
  54.     else if (NTYPE(v) == IFVX && arbcase)
  55.         getswitch(v);
  56.     else if (NTYPE(v)==DOVX)
  57.         {
  58.         ASSERT(DEFINED(ARC(v,0)),fixloop);
  59.         NXT(ARC(v,0))=ARC(v,0);
  60.         }
  61.     RECURSE(fixloop,v,recvar);
  62.     }
  63.  
  64.  
  65. getwh(v)
  66. VERT v;
  67.     {
  68.     VERT vchild, vgrand,vgreat;
  69.     ASSERT(NTYPE(v) == LOOPVX,getwh);
  70.     vchild = LCHILD(v,0);
  71.     ASSERT(DEFINED(vchild),getwh);
  72.     ASSERT(NTYPE(vchild) == ITERVX,getwh);
  73.     vgrand = LCHILD(vchild,0);
  74.     if (!DEFINED(vgrand) || !IFTHEN(vgrand) )
  75.         return(FALSE);
  76.     vgreat = LCHILD(vgrand,THEN);
  77.     if (DEFINED(vgreat) && NTYPE(vgreat) == GOVX && ARC(vgreat,0) == BRK(vchild))
  78.         {
  79.         /* turn into WHILE */
  80.         NTYPE(v) = WHIVX;
  81.         NEG(vgrand) = !NEG(vgrand);
  82.         LPRED(vchild) = vgrand; 
  83.         LCHILD(vchild,0) = RSIB(vgrand);
  84.         RSIB(vgrand) = UNDEFINED;
  85.         return(TRUE);
  86.         }
  87.     return(FALSE);
  88.     }
  89.  
  90.  
  91.  
  92. getun(v)        /* change loop to REPEAT UNTIL if possible */
  93. VERT v;
  94.     {
  95.     VERT vchild, vgrand,  vgreat, before, ch;
  96.     ASSERT(NTYPE(v) == LOOPVX,getun);
  97.     vchild = LCHILD(v,0);
  98.     ASSERT(DEFINED(vchild), getun);
  99.     if (ARCCOUNT(vchild) > 2) 
  100.         return(FALSE);        /* loop can be iterated without passing through predicate of UNTIL */
  101.     vgrand = ARC(vchild,0);
  102.     if (!DEFINED(vgrand))
  103.         return(FALSE);
  104.     for (ch = vgrand,before = UNDEFINED; DEFINED(RSIB(ch)); ch = RSIB(ch))
  105.         before = ch;
  106.     if (!IFTHEN(ch))
  107.         return(FALSE);
  108.     vgreat = LCHILD(ch,THEN);
  109.     if (DEFINED(vgreat) && NTYPE(vgreat) == GOVX && ARC(vgreat,0) == BRK(vchild))
  110.         {
  111.         /* create  UNTIL node */
  112.         NTYPE(v) = UNTVX;
  113.         NXT(vchild) = ch;
  114.         LPRED(vchild)=ch;
  115.         RSIB(before) = UNDEFINED;
  116.         return(TRUE);
  117.         }
  118.     return(FALSE);
  119.     }
  120.  
  121.  
  122. #define FORMCASE(w)    (DEFINED(w) && !DEFINED(RSIB(w)) && NTYPE(w) == IFVX && ARCCOUNT(w) == 1)
  123.  
  124. getswitch(v)
  125. VERT v;
  126.     {
  127.     VERT ch, grand, temp;
  128.     /* must be of form if ... else if ... else if ... */
  129.     if (NTYPE(v) != IFVX) return(FALSE);
  130.     ch = LCHILD(v,ELSE);
  131.     if (!FORMCASE(ch)) return(FALSE);
  132.     grand = LCHILD(ch,ELSE);
  133.     if (!FORMCASE(grand)) return(FALSE);
  134.  
  135.     temp = create(SWCHVX,0);
  136.     exchange(&graph[temp],&graph[v]);    /* want arcs to enter switch, not first case*/
  137.     BEGCOM(v) = UNDEFINED;
  138.     RSIB(v) = RSIB(temp);        /* statements which followed IFVX should follow switch */
  139.     EXP(v) = UNDEFINED;
  140.     LCHILD(v,0) = temp;
  141.     NTYPE(temp) = ACASVX;
  142.     for (ch = LCHILD(temp,ELSE); FORMCASE(ch); )
  143.         {
  144.         LCHILD(temp,ELSE) = UNDEFINED;
  145.         RSIB(temp) = ch;
  146.         NTYPE(ch) = ACASVX;
  147.         temp = ch;
  148.         ch = LCHILD(temp,ELSE);
  149.         }
  150.     ASSERT(!DEFINED(RSIB(temp)),getswitch);
  151.     return(TRUE);
  152.     }
  153.