home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 2 / ctrom_ii_b.zip / ctrom_ii_b / PROGRAM / C / SMALL_C / CC31.C < prev    next >
Text File  |  1987-10-04  |  7KB  |  270 lines

  1. /*
  2. ** Small C - 8088/8086 version - modified by R. Grehan, BYTE Magazine
  3. **
  4. ** lval[0] - symbol table address, else 0 for constant
  5. ** lval[1] - type of indirect obj to fetch, else 0 for static
  6. ** lval[2] - type of pointer or array, else 0 for all other
  7. ** lval[3] - true if constant expression
  8. ** lval[4] - value of constant expression (+ auxiliary uses)
  9. ** lval[5] - true if secondary register altered
  10. ** lval[6] - function address of highest/last binary operator
  11. ** lval[7] - stage address of "oper 0" code, else 0
  12. */
  13.  
  14. /*
  15. ** skim over terms adjoining || and && operators
  16. */
  17. skim(opstr, testfunc, dropval, endval, hier, lval)
  18.   char *opstr;
  19.   int (*testfunc)(), dropval, endval, (*hier)(), lval[]; {
  20.   int k, hits, droplab, endlab;
  21.   hits=0;
  22.   while(1) {
  23.     k=plnge1(hier, lval);
  24.     if(nextop(opstr)) {
  25.       bump(opsize);
  26.       if(hits==0) {
  27.         hits=1;
  28.         droplab=getlabel();
  29.         }
  30.       dropout(k, testfunc, droplab, lval);
  31.       }
  32.     else if(hits) {
  33.       dropout(k, testfunc, droplab, lval);
  34.       const(endval);
  35.       jump(endlab=getlabel());
  36.       postlabel(droplab);
  37.       const(dropval);
  38.       postlabel(endlab);
  39.       lval[1]=lval[2]=lval[3]=lval[4]=lval[7]=0;
  40.       return 0;
  41.       }
  42.     else return k;
  43.     }
  44.   }
  45.  
  46. /*
  47. ** test for early dropout from || or && evaluations
  48. */
  49. dropout(k, testfunc, exit1, lval)
  50.   int k, (*testfunc)(), exit1, lval[]; {
  51.   if(k) rvalue(lval);
  52.   else if(lval[3]) const(lval[4]);
  53.   (*testfunc)(exit1);        /* jumps on false */
  54.   }
  55.  
  56. /*
  57. ** plunge to a lower level
  58. */
  59. plnge(opstr, opoff, hier, lval)
  60.   char *opstr;
  61.   int opoff, (*hier)(), lval[]; {
  62.   int k, lval2[8];
  63.   k=plnge1(hier, lval);
  64.   if(nextop(opstr)==0) return k;
  65.   if(k) rvalue(lval);
  66.   while(1) {
  67.     if(nextop(opstr)) {
  68.       bump(opsize);
  69.       opindex=opindex+opoff;
  70.       plnge2(op[opindex], op2[opindex], hier, lval, lval2);
  71.       }
  72.     else return 0;
  73.     }
  74.   }
  75.  
  76. /*
  77. ** unary plunge to lower level
  78. */
  79. plnge1(hier, lval) int (*hier)(), lval[]; {
  80.   char *before, *start;
  81.   int k;
  82.   setstage(&before, &start);
  83.   k=(*hier)(lval);
  84.   if(lval[3]) clearstage(before,0);    /* load constant later */
  85.   return k;
  86.   }
  87.  
  88. /*
  89. ** binary plunge to lower level
  90. */
  91. plnge2(oper, oper2, hier, lval, lval2)
  92.   int (*oper)(),(*oper2)(),(*hier)(),lval[],lval2[]; {
  93.   char *before, *start;
  94.   setstage(&before, &start);
  95.   lval[5]=1;        /* flag secondary register used */
  96.   lval[7]=0;        /* flag as not "... oper 0" syntax */
  97.   if(lval[3]) {        /* constant on left side not yet loaded */
  98.     if(plnge1(hier, lval2)) rvalue(lval2);
  99.     if(lval[4]==0) lval[7]=stagenext;
  100.     const2(lval[4]<<dbltest(oper, lval2, lval));
  101.     }
  102.   else {        /* non-constant on left side */
  103.     push();
  104.     if(plnge1(hier, lval2)) rvalue(lval2);
  105.     if(lval2[3]) {    /* constant on right side */
  106.       if(lval2[4]==0) lval[7]=start;
  107.       if(oper==ffadd) {    /* may test other commutative operators */
  108.         csp=csp+2;
  109.         clearstage(before, 0);
  110.         const2(lval2[4]<<dbltest(oper, lval, lval2));
  111.             /* load secondary */
  112.         }
  113.       else {
  114.         const(lval2[4]<<dbltest(oper, lval, lval2));
  115.             /* load primary */
  116.         smartpop(lval2, start);
  117.         }
  118.       }
  119.     else {        /* non-constants on both sides */
  120.       smartpop(lval2, start);
  121.       if(dbltest(oper, lval,lval2)) doublereg();
  122.       if(dbltest(oper, lval2,lval)) {
  123.         swap();
  124.         doublereg();
  125.         if(oper==ffsub) swap();
  126.         }
  127.       }
  128.     }
  129.   if(oper) {
  130.     if(lval[3]=lval[3]&lval2[3]) {
  131.       lval[4]=calc(lval[4], oper, lval2[4]);
  132.       clearstage(before, 0);  
  133.       lval[5]=0;
  134.       }
  135.     else {
  136.       if((lval[2]==0)&(lval2[2]==0)) {
  137.         (*oper)();
  138.         lval[6]=oper;            /* identify the operator */
  139.         }
  140.       else {
  141.         (*oper2)();
  142.         lval[6]=oper2;            /* identify the operator */
  143.         }
  144.       }
  145.     if(oper==ffsub) {
  146.       if((lval[2]==CINT)&(lval2[2]==CINT)) {
  147.         swap();
  148.         const(1);
  149.         ffasr();            /** div by 2 **/
  150.         }
  151.       }
  152.     if((oper==ffsub)|(oper==ffadd)) result(lval, lval2);
  153.     }
  154.   }
  155.  
  156. calc(left, oper, right) int left, (*oper)(), right; {
  157.        if(oper ==  ffor) return (left  |  right);
  158.   else if(oper == ffxor) return (left  ^  right);
  159.   else if(oper == ffand) return (left  &  right);
  160.   else if(oper ==  ffeq) return (left  == right);
  161.   else if(oper ==  ffne) return (left  != right);
  162.   else if(oper ==  ffle) return (left  <= right);
  163.   else if(oper ==  ffge) return (left  >= right);
  164.   else if(oper ==  fflt) return (left  <  right);
  165.   else if(oper ==  ffgt) return (left  >  right);
  166.   else if(oper == ffasr) return (left  >> right);
  167.   else if(oper == ffasl) return (left  << right);
  168.   else if(oper == ffadd) return (left  +  right);
  169.   else if(oper == ffsub) return (left  -  right);
  170.   else if(oper ==ffmult) return (left  *  right);
  171.   else if(oper == ffdiv) return (left  /  right);
  172.   else if(oper == ffmod) return (left  %  right);
  173.   else return 0;
  174.   }
  175.  
  176. expression(const, val) int *const, *val;  {
  177.   int lval[8];
  178.   if(hier1(lval)) rvalue(lval);
  179.   if(lval[3]) {
  180.     *const=1;
  181.     *val=lval[4];
  182.     }
  183.   else *const=0;
  184.   }
  185.  
  186. hier1(lval)  int lval[];  {
  187.   int k,lval2[8], lval3[2], oper;
  188.   k=plnge1(hier3, lval);
  189.   if(lval[3]) const(lval[4]);
  190.        if(match("|="))  oper=ffor;
  191.   else if(match("^="))  oper=ffxor;
  192.   else if(match("&="))  oper=ffand;
  193.   else if(match("+="))  oper=ffadd;
  194.   else if(match("-="))  oper=ffsub;
  195.   else if(match("*="))  oper=ffmult;
  196.   else if(match("/="))  oper=ffdiv;
  197.   else if(match("%="))  oper=ffmod;
  198.   else if(match(">>=")) oper=ffasr;
  199.   else if(match("<<=")) oper=ffasl;
  200.   else if(match("="))   oper=0;
  201.   else return k;
  202.   if(k==0) {
  203.     needlval();
  204.     return 0;
  205.     }
  206.   lval3[0] = lval[0];
  207.   lval3[1] = lval[1];
  208.   if(lval[1]) {
  209.     if(oper) {
  210.       push();
  211.       rvalue(lval);
  212.       }
  213.     plnge2(oper, oper, hier1, lval, lval2);
  214.     if(oper) pop();
  215.     }
  216.   else {
  217.     if(oper) {
  218.       rvalue(lval);
  219.       plnge2(oper, oper, hier1, lval, lval2);
  220.       }
  221.     else {
  222.       if(hier1(lval2)) rvalue(lval2);
  223.       lval[5]=lval2[5];
  224.       }
  225.     }
  226.   store(lval3);
  227.   return 0;
  228.   }
  229.  
  230. hier3(lval)  int lval[]; {
  231.   return skim("||", eq0, 1, 0, hier4, lval);
  232.   }
  233.  
  234. hier4(lval)  int lval[]; {
  235.   return skim("&&", ne0, 0, 1, hier5, lval);
  236.   }
  237.  
  238. hier5(lval)  int lval[]; {
  239.   return plnge("|", 0, hier6, lval);
  240.   }
  241.  
  242. hier6(lval)  int lval[]; {
  243.   return plnge("^", 1, hier7, lval);
  244.   }
  245.  
  246. hier7(lval)  int lval[]; {
  247.   return plnge("&", 2, hier8, lval);
  248.   }
  249.  
  250. hier8(lval)  int lval[];  {
  251.   return plnge("== !=", 3, hier9, lval);
  252.   }
  253.  
  254. hier9(lval)  int lval[];  {
  255.   return plnge("<= >= < >", 5, hier10, lval);
  256.   }
  257.  
  258. hier10(lval)  int lval[];  {
  259.   return plnge(">> <<", 9, hier11, lval);
  260.   }
  261.  
  262. hier11(lval)  int lval[];  {
  263.   return plnge("+ -", 11, hier12, lval);
  264.   }
  265.  
  266. hier12(lval)  int lval[];  {
  267.   return plnge("* / %", 13, hier13, lval);
  268.   }
  269.  
  270.