Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2. ** Small-C Compiler -- Part 3 -- Expression Analyzer.
  3. ** Copyright 1982, 1983, 1985, 1988 J. E. Hendrix
  4. ** Copyright 1998 H T Walheim
  5. ** All rights reserved.
  6. */
  7.  
  8. #include <stdio.h>
  9. #include "cc.h"
  10.  
  11. #define ST 0   /* is[ST] - symbol table address, else 0 */
  12. #define TI 1   /* is[TI] - type of indirect obj to fetch, else 0 */
  13. #define TA 2   /* is[TA] - type of address, else 0 */
  14. #define TC 3   /* is[TC] - type of constant (INT or UINT), else 0 */
  15. #define CV 4   /* is[CV] - value of constant (+ auxiliary uses) */
  16. #define OP 5   /* is[OP] - code of highest/last binary operator */
  17. #define SA 6   /* is[SA] - stage address of "op 0" code, else 0 */
  18.  
  19. extern char
  20.  *litq, *glbptr, *lptr,  ssname[NAMESIZE],  quote[2];
  21. extern int
  22.   ch,  csp,  litlab,  litptr,  nch,  op[16],  op2[16],
  23.   opindex,  opsize, *snext;
  24.  
  25. /***************** lead-in functions *******************/
  26.  
  27. constexpr(val) int *val; {
  28.   int constant;
  29.   int *before, *start;
  30.   setstage(&before, &start);
  31.   expression(&constant, val);
  32.   clearstage(before, 0);     /* scratch generated code */
  33.   if(constant == 0) error("must be constant expression");
  34.   return constant;
  35.   }
  36.  
  37. null_is (is)
  38. int is[7];
  39.   {
  40.     int i;
  41.  
  42.     for (i = 0; i < 7; ++i)
  43.       {
  44.         is[i] = 0;      /* <-- */
  45.       }
  46.   }
  47.    
  48.  
  49. expression(con, val) int *con, *val;
  50.   {
  51.     int i;
  52.     int is[7];
  53.  
  54.     null_is (is);
  55.    
  56.   if(level1(is)) fetch(is);
  57.   *con = is[TC];
  58.   *val = is[CV];
  59.   }
  60.  
  61. test(label, parens)  int label, parens;  {
  62.   int is[7];
  63.   int *before, *start;
  64.  
  65.   null_is (is);
  66.  
  67.   if(parens) need("(");
  68.   while(1) {
  69.     setstage(&before, &start);
  70.     if(level1(is)) fetch(is);
  71.     if(match(",")) clearstage(before, start);
  72.     else break;
  73.     }
  74.   if(parens) need(")");
  75.   if(is[TC]) {             /* constant expression */
  76.     clearstage(before, 0);
  77.     if(is[CV]) return;
  78.     gen(JMPm, label);
  79.     return;
  80.     }
  81.   if(is[SA]) {             /* stage address of "oper 0" code */
  82.     switch(is[OP]) {       /* operator code */
  83.       case EQ12:
  84.       case LE12u: zerojump(EQ10f, label, is); break;
  85.       case NE12:
  86.       case GT12u: zerojump(NE10f, label, is); break;
  87.       case GT12:  zerojump(GT10f, label, is); break;
  88.       case GE12:  zerojump(GE10f, label, is); break;
  89.       case GE12u: clearstage(is[SA], 0);      break;
  90.       case LT12:  zerojump(LT10f, label, is); break;
  91.       case LT12u: zerojump(JMPm,  label, is); break;
  92.       case LE12:  zerojump(LE10f, label, is); break;
  93.       default:    gen(NE10f, label);          break;
  94.       }
  95.     }
  96.   else gen(NE10f, label);
  97.   clearstage(before, start);
  98.   }
  99.  
  100. /*
  101. ** test primary register against zero and jump if false
  102. */
  103. zerojump(oper, label, is) int oper, label, is[]; {
  104.   clearstage(is[SA], 0);       /* purge conventional code */
  105.   gen(oper, label);
  106.   }
  107.  
  108. /***************** precedence levels ******************/
  109. #ifdef _MSC_VER
  110. level2();
  111. level3();
  112. level4();
  113. level5();
  114. level6();
  115. level7();
  116. level8();
  117. level9();
  118. level10();
  119. level11();
  120. level12();
  121. level13();
  122. #endif
  123.  
  124. level1(is) int is[];  {
  125.   int k, is2[7], is3[2], oper, oper2;
  126.  
  127.   null_is (is2);
  128.   null_is (is3);
  129.  
  130.   k = down1(level2, is);
  131.   if(is[TC])
  132.     {
  133. #ifdef INT32
  134.       gen(GETd1n, is[CV]);
  135. #else
  136.       gen(GETw1n, is[CV]);
  137. #endif
  138.     }
  139.        if(match("|="))  {oper =        oper2 = OR12;}
  140.   else if(match("^="))  {oper =        oper2 = XOR12;}
  141.   else if(match("&="))  {oper =        oper2 = AND12;}
  142.   else if(match("+="))  {oper =        oper2 = ADD12;}
  143.   else if(match("-="))  {oper =        oper2 = SUB12;}
  144.   else if(match("*="))  {oper = MUL12; oper2 = MUL12u;}
  145.   else if(match("/="))  {oper = DIV12; oper2 = DIV12u;}
  146.   else if(match("%="))  {oper = MOD12; oper2 = MOD12u;}
  147.   else if(match(">>=")) {oper =        oper2 = ASR12;}
  148.   else if(match("<<=")) {oper =        oper2 = ASL12;}
  149.   else if(match("="))   {oper =        oper2 = 0;}
  150.   else return k;
  151.                         /* have an assignment operator */
  152.   if(k == 0) {
  153.     needlval();
  154.     return 0;
  155.     }
  156.   is3[ST] = is[ST];
  157.   is3[TI] = is[TI];
  158.   if(is[TI]) {                             /* indirect target */
  159.     if(oper) {                             /* ?= */
  160.       gen(PUSH1, 0);                       /* save address */
  161.       fetch(is);                           /* fetch left side */
  162.       }
  163.     down2(oper, oper2, level1, is, is2);   /* parse right side */
  164.     if(oper) gen(POP2, 0);                 /* retrieve address */
  165.     }
  166.   else {                                   /* direct target */
  167.     if(oper) {                             /* ?= */
  168.       fetch(is);                           /* fetch left side */
  169.       down2(oper, oper2, level1, is, is2); /* parse right side */
  170.       }
  171.     else {                                 /*  = */
  172.       if(level1(is2)) fetch(is2);          /* parse right side */
  173.       }
  174.     }
  175.   store(is3);                              /* store result */
  176.   return 0;
  177.   }
  178.  
  179. level2(is1)  int is1[]; {
  180.   int is2[7], is3[7], k, flab, endlab, *before, *after;
  181.  
  182.   null_is (is2);
  183.   null_is (is3);
  184.  
  185.   k = down1(level3, is1);                   /* expression 1 */
  186.   if(match("?") == 0) return k;
  187.   dropout(k, NE10f, flab = getlabel(), is1);
  188.   if(down1(level2, is2)) fetch(is2);        /* expression 2 */
  189.   else if(is2[TC])
  190.     {
  191. #ifdef INT32
  192.       gen(GETd1n, is2[CV]);
  193. #else
  194.       gen(GETw1n, is2[CV]);
  195. #endif
  196.     }
  197.   need(":");
  198.   gen(JMPm, endlab = getlabel());
  199.   gen(LABm, flab);
  200.   if(down1(level2, is3)) fetch(is3);        /* expression 3 */
  201.   else if(is3[TC])
  202.     {
  203. #ifdef INT32
  204.       gen(GETd1n, is3[CV]);
  205. #else
  206.       gen(GETw1n, is3[CV]);
  207. #endif
  208.     }
  209.   gen(LABm, endlab);
  210.  
  211.   is1[TC] = is1[CV] = 0;
  212.   if(is2[TC] && is3[TC]) {                  /* expr1 ? const2 : const3 */
  213.     is1[TA] = is1[TI] = is1[SA] = 0;
  214.     }
  215.   else if(is3[TC]) {                        /* expr1 ? var2 : const3 */
  216.     is1[TA] = is2[TA];
  217.     is1[TI] = is2[TI];
  218.     is1[SA] = is2[SA];
  219.     }
  220.   else if((is2[TC])                         /* expr1 ? const2 : var3 */
  221.        || (is2[TA] == is3[TA])) {           /* expr1 ? same2 : same3 */
  222.     is1[TA] = is3[TA];
  223.     is1[TI] = is3[TI];
  224.     is1[SA] = is3[SA];
  225.     }
  226.   else error("mismatched expressions");
  227.   return 0;
  228.   }
  229.  
  230. level3 (is) int is[]; {return skim("||", EQ10f, 1, 0, level4,  is);}
  231. level4 (is) int is[]; {return skim("&&", NE10f, 0, 1, level5,  is);}
  232. level5 (is) int is[]; {return down("|",            0, level6,  is);}
  233. level6 (is) int is[]; {return down("^",            1, level7,  is);}
  234. level7 (is) int is[]; {return down("&",            2, level8,  is);}
  235. level8 (is) int is[]; {return down("== !=",        3, level9,  is);}
  236. level9 (is) int is[]; {return down("<= >= < >",    5, level10, is);}
  237. level10(is) int is[]; {return down(">> <<",        9, level11, is);}
  238. level11(is) int is[]; {return down("+ -",         11, level12, is);}
  239. level12(is) int is[]; {return down("* / %",       13, level13, is);}
  240.  
  241. level13(is)  int is[];  {
  242.   int k;
  243.   char *ptr;
  244.   if(match("++")) {                 /* ++lval */
  245.     if(level13(is) == 0) {
  246.       needlval();
  247.       return 0;
  248.       }
  249.     step(rINC1, is, 0);
  250.     return 0;
  251.     }
  252.   else if(match("--")) {            /* --lval */
  253.     if(level13(is) == 0) {
  254.       needlval();
  255.       return 0;
  256.       }
  257.     step(rDEC1, is, 0);
  258.     return 0;
  259.     }
  260.   else if(match("~")) {             /* ~ */
  261.     if(level13(is)) fetch(is);
  262.     gen(COM1, 0);
  263.     is[CV] = ~ is[CV];
  264.     return (is[SA] = 0);
  265.     }
  266.   else if(match("!")) {             /* ! */
  267.     if(level13(is)) fetch(is);
  268.     gen(LNEG1, 0);
  269.     is[CV] = ! is[CV];
  270.     return (is[SA] = 0);
  271.     }
  272.   else if(match("-")) {             /* unary - */
  273.     if(level13(is)) fetch(is);
  274.     gen(ANEG1, 0);
  275.     is[CV] = -is[CV];
  276.     return (is[SA] = 0);
  277.     }
  278.   else if(match("*")) {             /* unary * */
  279.     if(level13(is)) fetch(is);
  280.     if(ptr = is[ST]) is[TI] = ptr[TYPE];
  281.     else             is[TI] = INT;
  282.     is[SA] =       /* no (op 0) stage address */
  283.     is[TA] =       /* not an address */
  284.     is[TC] = 0;    /* not a constant */
  285.     is[CV] = 1;    /* omit fetch() on func call */
  286.     return 1;
  287.     }
  288.   else if(amatch("sizeof", 6)) {    /* sizeof() */
  289.     int sz, p;  char *ptr, sname[NAMESIZE];
  290.     if(match("(")) p = 1;
  291.     else           p = 0;
  292.     sz = 0;
  293.     if     (amatch("unsigned", 8))  sz = INTSIZE;
  294.     if     (amatch("int",      3))  sz = INTSIZE;
  295.     else if(amatch("char",     4))  sz = 1;
  296.     if(sz) {if(match("*"))          sz = PTRSIZE;}
  297.     else if(symname(sname)
  298.          && ((ptr = findloc(sname)) ||
  299.              (ptr = findglb(sname)))
  300.          && ptr[IDENT] != FUNCTION
  301.          && ptr[IDENT] != LABEL)    sz = getint(ptr+SIZE, INTSIZE);
  302.     else if(sz == 0) error("must be object or type");
  303.     if(p) need(")");
  304.     is[TC] = INT;
  305.     is[CV] = sz;
  306.     is[TA] = is[TI] = is[ST] = 0;
  307.     return 0;
  308.     }
  309.   else if(match("&")) {             /* unary & */
  310.     if(level13(is) == 0) {
  311.       error("illegal address");
  312.       return 0;
  313.       }
  314.     ptr = is[ST];
  315.     is[TA] = ptr[TYPE];
  316.     if(is[TI]) return 0;
  317.     gen(POINT1m, ptr);
  318.     is[TI] = ptr[TYPE];
  319.     return 0;
  320.     }
  321.   else {
  322.     k = level14(is);
  323.     if(match("++")) {               /* lval++ */
  324.       if(k == 0) {
  325.         needlval();
  326.         return 0;
  327.         }
  328.       step(rINC1, is, rDEC1);
  329.       return 0;
  330.       }
  331.     else if(match("--")) {          /* lval-- */
  332.       if(k == 0) {
  333.         needlval();
  334.         return 0;
  335.         }
  336.       step(rDEC1, is, rINC1);
  337.       return 0;
  338.       }
  339.     else return k;
  340.     }
  341.   }
  342.  
  343. level14(is)  int *is; {
  344.   int k, consta, val;
  345.   char *ptr, *before, *start;
  346.   k = primary(is);
  347.   ptr = is[ST];
  348.   blanks();
  349.   if(ch == '[' || ch == '(') {
  350.     int is2[7];                     /* allocate only if needed */
  351.  
  352.     null_is (is2);
  353.    
  354.     while(1) {
  355.       if(match("[")) {              /* [subscript] */
  356.         if(ptr == 0) {
  357.           error("can't subscript");
  358.           skip();
  359.           need("]");
  360.           return 0;
  361.           }
  362.         if(is[TA]) {if(k) fetch(is);}
  363.         else       {error("can't subscript"); k = 0;}
  364.         setstage(&before, &start);
  365.         is2[TC] = 0;
  366.         down2(0, 0, level1, is2, is2);
  367.         need("]");
  368.         if(is2[TC]) {
  369.           clearstage(before, 0);
  370.           if(is2[CV])
  371.             {             /* only add if non-zero */
  372.               if(ptr[TYPE] >> 2 == BPD)
  373.                 {
  374. #ifdef INT32
  375.                   gen(GETd2n, is2[CV] << LBPD);
  376. #else
  377.                   gen(GETw2n, is2[CV] << LBPD);
  378. #endif
  379.                 }
  380.               else if(ptr[TYPE] >> 2 == BPW)
  381.                 {
  382. #ifdef INT32
  383.                   gen(GETd2n, is2[CV] << LBPW);
  384. #else
  385.                   gen(GETw2n, is2[CV] << LBPW);
  386. #endif
  387.                 }
  388.               else
  389.                 {
  390. #ifdef INT32
  391.                   gen(GETd2n, is2[CV]);
  392. #else
  393.                   gen(GETw2n, is2[CV]);
  394. #endif
  395.                 }
  396.               gen(ADD12, 0);
  397.             }
  398.           }
  399.         else
  400.           {
  401.             if(ptr[TYPE] >> 2 == BPD)
  402.               {
  403.                 gen(DBL1, 0);
  404.                 gen(DBL1, 0);
  405.               }
  406.             else if(ptr[TYPE] >> 2 == BPW)
  407.               {
  408.                 gen(DBL1, 0);
  409.               }
  410.             gen(ADD12, 0);
  411.           }
  412.         is[TA] = 0;
  413.         is[TI] = ptr[TYPE];
  414.         k = 1;
  415.         }
  416.       else if(match("(")) {         /* function(...) */
  417.         if(ptr == 0) callfunc(0);
  418.         else if(ptr[IDENT] != FUNCTION) {
  419.           if(k && !is[CV]) fetch(is);
  420.           callfunc(0);
  421.           }
  422.         else callfunc(ptr);
  423.         k = is[ST] = is[TC] = is[CV] = 0;
  424.         }
  425.       else return k;
  426.       }
  427.     }
  428.   if(ptr && ptr[IDENT] == FUNCTION) {
  429.     gen(POINT1m, ptr);
  430.     is[ST] = 0;
  431.     return 0;
  432.     }
  433.   return k;
  434.   }
  435.  
  436. primary(is)  int *is; {
  437.   char *ptr, sname[NAMESIZE];
  438.   int k;
  439.   if(match("(")) {                  /* (subexpression) */
  440.     do k = level1(is); while(match(","));
  441.     need(")");
  442.     return k;
  443.     }
  444.   putint(0, is, 7 << LBPW);         /* clear "is" array */
  445.   if(symname(sname)) {              /* is legal symbol */
  446.     if(ptr = findloc(sname)) {      /* is local */
  447.       if(ptr[IDENT] == LABEL) {
  448.         experr();
  449.         return 0;
  450.         }
  451.       gen(POINT1s, getint(ptr+OFFSET, INTSIZE));
  452.       is[ST] = ptr;
  453.       is[TI] = ptr[TYPE];
  454.       if(ptr[IDENT] == ARRAY) {
  455.         is[TA] = ptr[TYPE];
  456.         return 0;
  457.         }
  458.       if(ptr[IDENT] == POINTER) {
  459.         is[TI] = UINT;
  460.         is[TA] = ptr[TYPE];
  461.         }
  462.       return 1;
  463.       }
  464.     if(ptr = findglb(sname)) {      /* is global */
  465.       is[ST] = ptr;
  466.       if(ptr[IDENT] != FUNCTION) {
  467.         if(ptr[IDENT] == ARRAY) {
  468.           gen(POINT1m, ptr);
  469.           is[TI] =
  470.           is[TA] = ptr[TYPE];
  471.           return 0;
  472.           }
  473.         if(ptr[IDENT] == POINTER)
  474.           is[TA] = ptr[TYPE];
  475.         return 1;
  476.         }
  477.       }
  478.     else is[ST] = addsym(sname, FUNCTION, INT, 0, 0, &glbptr, AUTOEXT);
  479.     return 0;
  480.     }
  481.   if(constant(is) == 0) experr();
  482.   return 0;
  483.   }
  484.  
  485. experr() {
  486.   error("invalid expression");
  487. #ifdef INT32
  488.   gen(GETd1n, 0);
  489. #else
  490.   gen(GETw1n, 0);
  491. #endif
  492.   skip();
  493.   }
  494.  
  495. /* attempt at right to left - do it later */
  496. #ifdef LATER
  497. pushargs (ptr, nargs)
  498. char *ptr;
  499. int nargs;
  500.   {
  501.     if (streq(lptr, ")") != 0)
  502.       return;
  503.  
  504.     if(endst())
  505.       return;
  506.  
  507.     if(ptr)
  508.       {
  509.         expression(&consta, &val);
  510.         gen(PUSH1, 0);
  511.       }
  512.     else
  513.       {
  514.         gen(PUSH1, 0);
  515.         expression(&consta, &val);
  516.         gen(SWAP1s, 0);            /* don't push addr */
  517.       }
  518.     nargs = nargs + INTSIZE;         /* count args*BPW */
  519.  
  520.     if(match(",") == 0) break;
  521.    
  522.   }
  523. #endif
  524.  
  525. callfunc(ptr)
  526. char *ptr;      /* symbol table entry or 0 */
  527.   {
  528.     int nargs, consta, val;
  529.    
  530.     nargs = 0;
  531.     blanks();                      /* already saw open paren */
  532.  
  533.     while(streq(lptr, ")") == 0)
  534.       {
  535.         if(endst())
  536.           break;
  537.         if(ptr)
  538.           {
  539.             expression(&consta, &val);
  540.             gen(PUSH1, 0);
  541.           }
  542.         else
  543.           {
  544.             gen(PUSH1, 0);
  545.             expression(&consta, &val);
  546.             gen(SWAP1s, 0);            /* don't push addr */
  547.           }
  548.         nargs = nargs + INTSIZE;         /* count args*BPW */
  549.  
  550.         if(match(",") == 0) break;
  551.       }
  552.     need(")");
  553.     if(ptr && (streq(ptr + NAME, "CCARGC") == 0))       /* accessing ... like va_args */
  554. #ifdef INT32
  555.       gen(ARGCNTn, nargs >> LBPD);              /* to get start of frame */
  556. #else
  557.       gen(ARGCNTn, nargs >> LBPW);              /* to get start of frame */
  558. #endif
  559.      
  560.     if(ptr)
  561.       gen(CALLm, ptr);
  562.     else
  563.       gen(CALL1, 0);
  564.     gen(ADDSP, csp + nargs);
  565.   }
  566.  
  567. /*
  568. ** true if is2's operand should be doubled
  569. */
  570. fdouble (oper, is1, is2)
  571. int oper, is1[], is2[];
  572. {
  573.   //////////////////////////////////////////////////////
  574.   // This is a 'magic' function, its usage and function
  575.   // are not so obvious
  576.   //
  577.   // Purpose:  when indexing an address we must know
  578.   // what we are pointing at so that the indexsize is
  579.   // proper, e,g,
  580.   // charptr++,  should multiply index by a 1
  581.   // shortptr++, should multiply index by a 2
  582.   // intptr++,   should multiply index by a 4
  583.   //
  584.   // Algorithm:
  585.   // IF
  586.   // operation is ADD12 or SUB12
  587.   // AND
  588.   // is1 is an address (pointer, array or via & operator
  589.   // AND
  590.   // is2 is NOT an address (pointer, array or via & operator
  591.   // THEN
  592.   // return the multiplication factor based on s1 (or true)
  593.   // ELSE
  594.   // return 0 (or false)
  595.   //
  596.   // Usage: The return value is used as a 'boolean'
  597.   // for nonconstant values, indicating that runtime code
  598.   // is necessary to do the necessary multiplication
  599.   // For contant value the return value is used to do a compile-time
  600.   // multiplication (shift actually)
  601.   //
  602.  
  603.   if ((oper == ADD12 || oper == SUB12)
  604.       && (is2[TA] == 0))
  605.     {
  606.       switch (is1[TA]>>2)
  607.         {
  608.           default:
  609.           case 1:               // char
  610.             return (0);
  611.           case 2:               // short
  612.             return (1);
  613.           case 4:               // int
  614.             return (2);
  615.         }
  616.     }
  617.  
  618.   return (0);
  619.  
  620.  
  621.  
  622. /*
  623.   - original code -
  624.   if((oper != ADD12 && oper != SUB12)
  625.      || (is1[TA] >> 2 != BPW)
  626.      || (is2[TA]))
  627.    
  628.     return 0;
  629.  
  630.  
  631.   return 1;
  632. */
  633. }
  634.  
  635.  
  636. step (oper, is, oper2) int oper, is[], oper2; {
  637.   fetch(is);
  638.   gen(oper, is[TA] ? (is[TA] >> 2) : 1);
  639.   store(is);
  640.   if(oper2) gen(oper2, is[TA] ? (is[TA] >> 2) : 1);
  641.   }
  642.  
  643. store(is)
  644. int is[];
  645.   {
  646.     char *ptr;
  647.    
  648.     if(is[TI])
  649.       {                     /* putstk */
  650.         if(is[TI] >> 2 == 1)
  651.           {
  652.             gen(PUTbp1, 0);
  653.           }
  654.         else if(is[TI] >> 2 == 2)
  655.           {
  656.             gen(PUTwp1, 0);
  657.           }
  658.         else
  659.           {
  660.             gen(PUTdp1, 0);
  661.           }
  662.       }
  663.     else
  664.       {                          /* putmem */
  665.         ptr = is[ST];
  666.         if(ptr[IDENT] == POINTER)
  667.           {
  668. #ifdef INT32    /* int and ptr-size are ALWAYS the same */
  669.           gen(PUTdm1, ptr);
  670. #else
  671.           gen(PUTwm1, ptr);
  672. #endif
  673.           }
  674.         else if (ptr[TYPE] >> 2 == 1)
  675.           {
  676.             gen(PUTbm1, ptr);
  677.           }
  678.         else if (ptr[TYPE] >> 2 == BPW)
  679.           {
  680.             gen(PUTwm1, ptr);
  681.           }
  682.         else
  683.           {
  684.             gen(PUTdm1, ptr);
  685.           }
  686.       }
  687.   }
  688.  
  689. fetch(is)
  690. int is[];
  691.   {
  692.     char *ptr;
  693.    
  694.     ptr = is[ST];
  695.     if(is[TI])                          /* indirect */
  696.       {
  697.         if(is[TI] >> 2 == BPD)          /* pointer to DWORD */
  698.           {
  699.             gen(GETd1p,  0);
  700.           }
  701.         else if(is[TI] >> 2 == BPW)     /* pointer to WORD */
  702.           {
  703.             /* if INT32 must make distinction between signed/unsigned <-- */
  704.             gen(GETw1p,  0);
  705.           }
  706.         else
  707.           {
  708.             if(ptr[TYPE] & UNSIGNED)
  709.               gen(GETb1pu, 0);
  710.             else
  711.               gen(GETb1p,  0);
  712.           }
  713.       }
  714.     else
  715.       {                                 /* direct */
  716.      
  717.         if(ptr[IDENT] == POINTER)
  718.           {
  719. #ifdef INT32
  720.             gen(GETd1m,  ptr);
  721. #else
  722.             gen(GETw1m,  ptr);
  723. #endif     
  724.           }
  725.         else if (ptr[TYPE] >> 2 == BPD)
  726.           {
  727.             gen(GETd1m,  ptr);
  728.           }
  729.         else if (ptr[TYPE] >> 2 == BPW)
  730.           {
  731.             gen(GETw1m,  ptr);
  732.           }
  733.         else
  734.           {
  735.             if(ptr[TYPE] & UNSIGNED)
  736.               gen(GETb1mu, ptr);
  737.             else
  738.               gen(GETb1m,  ptr);
  739.           }
  740.       }
  741.   }
  742.  
  743. constant(is)
  744. int is[];
  745.   {
  746.     int offset;
  747.    
  748.     if (is[TC] = number(is + CV))
  749.       {
  750. #ifdef INT32
  751.         gen(GETd1n,  is[CV]);
  752. #else
  753.         gen(GETw1n,  is[CV]);
  754. #endif
  755.       }
  756.     else if(is[TC] = chrcon(is + CV))
  757.       {
  758. #ifdef INT32
  759.         gen(GETd1n,  is[CV]);
  760. #else
  761.         gen(GETw1n,  is[CV]);
  762. #endif
  763.       }
  764.     else if(string(&offset))
  765.       {
  766.         gen(POINT1l, offset);
  767.       }
  768.     else
  769.       {
  770.         return 0;
  771.       }
  772.     return 1;
  773.   }
  774.  
  775. number(value)  int *value; {
  776.   int k, minus;
  777.   k = minus = 0;
  778.   while(1) {
  779.     if(match("+")) ;
  780.     else if(match("-")) minus = 1;
  781.     else break;
  782.     }
  783.   if(isdigit(ch) == 0) return 0;
  784.   if(ch == '0') {
  785.     while(ch == '0') inbyte();
  786.     if(toupper(ch) == 'X') {
  787.       inbyte();
  788.       while(isxdigit(ch)) {
  789.         if(isdigit(ch))
  790.              k = k*16 + (inbyte() - '0');
  791.         else k = k*16 + 10 + (toupper(inbyte()) - 'A');
  792.         }
  793.       }
  794.     else while (ch >= '0' && ch <= '7')
  795.       k = k*8 + (inbyte() - '0');
  796.     }
  797.   else while (isdigit(ch)) k = k*10 + (inbyte() - '0');
  798.   if(minus) {
  799.     *value = -k;
  800.     return (INT);
  801.     }
  802.   if((*value = k) < 0) return (UINT);
  803.   else                 return (INT);
  804.   }
  805.  
  806. chrcon(value)
  807. int *value;
  808.   {
  809.     int k;
  810.    
  811.     k = 0;
  812.     if(match("'") == 0)
  813.       return 0;
  814.     while(ch != '\'')
  815.       k = (k << 8) + (litchar() & 255);
  816.     gch();
  817.     *value = k;
  818.     return (INT);
  819.   }
  820.  
  821. string(offset) int *offset; {
  822.   char c;
  823.   if(match(quote) == 0) return 0;
  824.   *offset = litptr;
  825.   while (ch != '"') {
  826.     if(ch == 0) break;
  827.     stowlit(litchar(), 1);
  828.     }
  829.   gch();
  830.   litq[litptr++] = 0;
  831.   return 1;
  832.   }
  833.  
  834. stowlit(value, size) int value, size; {
  835.   if((litptr+size) >= LITMAX) {
  836.     error("literal queue overflow");
  837.     exit(ERRCODE);
  838.     }
  839.   putint(value, litq+litptr, size);
  840.   litptr += size;
  841.   }
  842.  
  843. litchar() {
  844.   int i, oct;
  845.   if(ch != '\\' || nch == 0) return gch();
  846.   gch();
  847.   switch(ch) {
  848.     case 'n': gch(); return NEWLINE;
  849.     case 't': gch(); return  9;  /* HT */
  850.     case 'b': gch(); return  8;  /* BS */
  851.     case 'f': gch(); return 12;  /* FF */
  852.     }
  853.   i = 3;
  854.   oct = 0;
  855.   while((i--) > 0 && ch >= '0' && ch <= '7')
  856.     oct = (oct << 3) + gch() - '0';
  857.   if(i == 2) return gch();
  858.   else       return oct;
  859.   }
  860.  
  861. /***************** pipeline functions ******************/
  862.  
  863. /*
  864. ** skim over terms adjoining || and && operators
  865. */
  866. skim(opstr, tcode, dropval, endval, level, is)
  867.   char *opstr;
  868.   int tcode, dropval, endval, (*level)(), is[]; {
  869.   int k, droplab, endlab;
  870.   droplab = 0;
  871.   while(1) {
  872.     k = down1(level, is);
  873.     if(nextop(opstr)) {
  874.       bump(opsize);
  875.       if(droplab == 0) droplab = getlabel();
  876.       dropout(k, tcode, droplab, is);
  877.       }
  878.     else if(droplab) {
  879.       dropout(k, tcode, droplab, is);
  880. #ifdef INT32
  881.       gen(GETd1n, endval);
  882. #else
  883.       gen(GETw1n, endval);
  884. #endif
  885.       gen(JMPm, endlab = getlabel());
  886.       gen(LABm, droplab);
  887. #ifdef INT32
  888.       gen(GETd1n, dropval);
  889. #else
  890.       gen(GETw1n, dropval);
  891. #endif
  892.       gen(LABm, endlab);
  893.       is[TI] = is[TA] = is[TC] = is[CV] = is[SA] = 0;
  894.       return 0;
  895.       }
  896.     else return k;
  897.     }
  898.   }
  899.  
  900. /*
  901. ** test for early dropout from || or && sequences
  902. */
  903. dropout(k, tcode, exit1, is)
  904.   int k, tcode, exit1, is[]; {
  905.   if(k) fetch(is);
  906.   else if(is[TC])
  907.     {
  908. #ifdef INT32
  909.       gen(GETd1n, is[CV]);
  910. #else
  911.       gen(GETw1n, is[CV]);
  912. #endif
  913.     }
  914.   gen(tcode, exit1);          /* jumps on false */
  915.   }
  916.  
  917. /*
  918. ** drop to a lower level
  919. */
  920. down(opstr, opoff, level, is)
  921.   char *opstr;  int opoff, (*level)(), is[]; {
  922.   int k;
  923.   k = down1(level, is);
  924.   if(nextop(opstr) == 0) return k;
  925.   if(k) fetch(is);
  926.   while(1) {
  927.     if(nextop(opstr)) {
  928.       int is2[7];     /* allocate only if needed */
  929.  
  930.       null_is (is2);
  931.      
  932.       bump(opsize);
  933.       opindex += opoff;
  934.       down2(op[opindex], op2[opindex], level, is, is2);
  935.       }
  936.     else return 0;
  937.     }
  938.   }
  939.  
  940. /*
  941. ** unary drop to a lower level
  942. */
  943. down1(level, is) int (*level)(), is[]; {
  944.   int k, *before, *start;
  945.   setstage(&before, &start);
  946.   k = (*level)(is);
  947.   if(is[TC]) clearstage(before, 0);  /* load constant later */
  948.   return k;
  949.   }
  950.  
  951. /*
  952. ** binary drop to a lower level
  953. */
  954. down2(oper, oper2, level, is, is2)
  955.   int oper, oper2, (*level)(), is[], is2[]; {
  956.   int *before, *start;
  957.   char *ptr;
  958.   int value;
  959.   setstage(&before, &start);
  960.   is[SA] = 0;                     /* not "... op 0" syntax */
  961.   if(is[TC]) {                    /* consant op unknown */
  962.     if(down1(level, is2)) fetch(is2);
  963.     if(is[CV] == 0) is[SA] = snext;
  964.     gen(GETw2n, is[CV] << fdouble(oper, is2, is));
  965.     }
  966.   else {                          /* variable op unknown */
  967.     gen(PUSH1, 0);                /* at start in the buffer */
  968.     if(down1(level, is2)) fetch(is2);
  969.     if(is2[TC]) {                 /* variable op constant */
  970.       if(is2[CV] == 0) is[SA] = start;
  971. #ifdef INT32
  972.       csp += BPD;                 /* adjust stack and */
  973. #else
  974.       csp += BPW;                 /* adjust stack and */
  975. #endif
  976.       clearstage(before, 0);      /* discard the PUSH */
  977.       if(oper == ADD12) {         /* commutative */
  978. #ifdef INT32
  979.         gen(GETd2n, is2[CV] << fdouble(oper, is, is2));
  980. #else
  981.         gen(GETw2n, is2[CV] << fdouble(oper, is, is2));
  982. #endif
  983.         }
  984.       else {                      /* non-commutative */
  985.         gen(MOVE21, 0);
  986. #ifdef INT32
  987.         gen(GETd1n, is2[CV] << fdouble(oper, is, is2));
  988. #else
  989.         gen(GETw1n, is2[CV] << fdouble(oper, is, is2));
  990. #endif
  991.         }
  992.       }
  993.     else {                        /* variable op variable */
  994.       gen(POP2, 0);
  995.       if(value = fdouble(oper, is, is2))
  996.         {
  997.           gen(DBL1, 0);         // index size 2
  998.           if (value > 1)
  999.             gen(DBL1, 0);       // .. or even 4
  1000.         }
  1001.       if(value = fdouble(oper, is2, is))
  1002.         {
  1003.           gen(DBL2, 0);
  1004.           if (value > 1)
  1005.             gen(DBL2, 0);
  1006.         }
  1007.       }
  1008.     }
  1009.   if(oper) {
  1010.     if(nosign(is) || nosign(is2)) oper = oper2;
  1011.     if(is[TC] = is[TC] & is2[TC]) {               /* constant result */
  1012.       is[CV] = calc(is[CV], oper, is2[CV]);
  1013.       clearstage(before, 0);  
  1014.       if(is2[TC] == UINT) is[TC] = UINT;
  1015.       }
  1016.     else {                                        /* variable result */
  1017.       gen(oper, 0);
  1018.       if(oper == SUB12
  1019.       && is [TA] >> 2 == BPW
  1020.       && is2[TA] >> 2 == BPW) { /* difference of two word addresses */
  1021.         gen(SWAP12, 0);
  1022.         gen(GETw1n, 1);
  1023.         gen(ASR12, 0);          /* div by 2 */
  1024.         }
  1025.       is[OP] = oper;            /* identify the operator */
  1026.       }
  1027.     if(oper == SUB12 || oper == ADD12) {
  1028.       if(is[TA] && is2[TA])     /*  addr +/- addr */
  1029.         is[TA] = 0;
  1030.       else if(is2[TA]) {        /* value +/- addr */
  1031.         is[ST] = is2[ST];
  1032.         is[TI] = is2[TI];
  1033.         is[TA] = is2[TA];
  1034.         }
  1035.       }
  1036.     if(is[ST] == 0 || ((ptr = is2[ST]) && (ptr[TYPE] & UNSIGNED)))
  1037.       is[ST] = is2[ST];
  1038.     }
  1039.   }
  1040.  
  1041. /*
  1042. ** unsigned operand?
  1043. */
  1044. nosign(is) int is[]; {
  1045.   char *ptr;
  1046.   if(is[TA]
  1047.   || is[TC] == UINT
  1048.   || ((ptr = is[ST]) && (ptr[TYPE] & UNSIGNED))
  1049.     ) return 1;
  1050.   return 0;
  1051.   }
  1052.  
  1053. /*
  1054. ** calcualte signed constant result
  1055. */
  1056. calc(left, oper, right) int left, oper, right; {
  1057.   switch(oper) {
  1058.     case ADD12: return (left  +  right);
  1059.     case SUB12: return (left  -  right);
  1060.     case MUL12: return (left  *  right);
  1061.     case DIV12: return (left  /  right);
  1062.     case MOD12: return (left  %  right);
  1063.     case EQ12:  return (left  == right);
  1064.     case NE12:  return (left  != right);
  1065.     case LE12:  return (left  <= right);
  1066.     case GE12:  return (left  >= right);
  1067.     case LT12:  return (left  <  right);
  1068.     case GT12:  return (left  >  right);
  1069.     case AND12: return (left  &  right);
  1070.     case OR12:  return (left  |  right);
  1071.     case XOR12: return (left  ^  right);
  1072.     case ASR12: return (left  >> right);
  1073.     case ASL12: return (left  << right);
  1074.     }
  1075.   return (calc2(left, oper, right));
  1076.   }
  1077.  
  1078. /*
  1079. ** calcualte unsigned constant result
  1080. */
  1081. calc2(left, oper, right) unsigned left, right; int oper; {
  1082.   switch(oper) {
  1083.     case MUL12u: return (left  *  right);
  1084.     case DIV12u: return (left  /  right);
  1085.     case MOD12u: return (left  %  right);
  1086.     case LE12u:  return (left  <= right);
  1087.     case GE12u:  return (left  >= right);
  1088.     case LT12u:  return (left  <  right);
  1089.     case GT12u:  return (left  >  right);
  1090.     }
  1091.   return (0);
  1092.   }
  1093.  
  1094.