home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 163_01 / cc32.c < prev    next >
Text File  |  1990-11-21  |  8KB  |  316 lines

  1. /*
  2. ** Note: Return true if value loaded, false if not;
  3. */
  4. heir13(lval)  int lval[];  {
  5.   int k;
  6.   char *ptr;
  7.   if (match("++")) {                 /* ++lval */
  8.     if(heir13(lval)==0) {
  9.       needlval();
  10.       return 0;
  11.       }
  12.     step(inc, lval);
  13.     return 0;
  14.     }
  15.   else if (match("--")) {            /* --lval */
  16.     if(heir13(lval)==0) {
  17.       needlval();
  18.       return 0;
  19.       }
  20.     step(dec, lval);
  21.     return 0;
  22.     }
  23.   else if (match("~")) {             /* ~ */
  24.     if(heir13(lval)) rvalue(lval);
  25.     com();
  26.     lval[4] = ~lval[4];
  27.     return 0;
  28.     }
  29.   else if (match("!")) {             /* ! */
  30.     if(heir13(lval)) rvalue(lval);
  31.     lneg();
  32.     lval[4] = !lval[4];
  33.     return 0;
  34.     }
  35.   else if (match("-")) {             /* unary - */
  36.     if(heir13(lval)) rvalue(lval);
  37.     neg();
  38.     lval[4] = -lval[4];
  39.     return 0;
  40.     }
  41.   else if (match("*")) {             /* unary * */
  42.     if(heir13(lval)) rvalue(lval);
  43.     if(ptr=lval[0]) lval[1]=ptr[TYPE];
  44.     else lval[1]=CINT;
  45.     lval[2]=0;  /* flag as not pointer or array */
  46.     lval[3]=0;  /* flag as not constant         */
  47.     return 1;
  48.     }
  49.   else if (match("&")) {             /* unary & */
  50.     if(heir13(lval)==0) {
  51.       error("illegal address");
  52.       return 0;
  53.       }
  54.     ptr=lval[0];
  55.     lval[2]=ptr[TYPE];
  56.     if(lval[1]) return 0;
  57.     /* global & non-array */
  58.     address(ptr);
  59.     lval[1]=ptr[TYPE];
  60.     return 0;
  61.     }
  62.   else if (match("(int)")) { /* (int) cast */
  63.     if(heir13(lval)) rvalue(lval);
  64.     lval[0]=castint;
  65.     lval[1]=CINT;
  66.     lval[2]=0;
  67.     return 0;
  68.     }
  69.   else if (match("(char)")) { /* (char) cast */
  70.     if(heir13(lval)) rvalue(lval);
  71.     lval[0]=castchar;
  72.     lval[1]=CCHAR;
  73.     lval[2]=0;
  74.     return 0;
  75.     }
  76.   else if (match("(int *)")) { /* (int *) cast */
  77.     if(heir13(lval)) rvalue(lval);
  78.     lval[0]=castpint;
  79.     lval[1]=0;
  80.     lval[2]=CINT;
  81.     return 0;
  82.     }
  83.   else if (match("(char *)")) { /* (char *) cast */
  84.     if(heir13(lval)) rvalue(lval);
  85.     lval[0]=castpchar;
  86.     lval[1]=0;
  87.     lval[2]=CCHAR;
  88.     return 0;
  89.     }
  90.   else {
  91.     k=heir14(lval);
  92.     if(match("++")) {                /* lval++ */
  93.       if(k==0) {
  94.         needlval();
  95.         return 0;
  96.         }
  97.       step(inc, lval);
  98.       dec(lval[2]>>2);
  99.       return 0;
  100.       }
  101.     else if(match("--")) {           /* lval-- */
  102.       if(k==0) {
  103.         needlval();
  104.         return 0;
  105.         }
  106.       step(dec, lval);
  107.       inc(lval[2]>>2);
  108.       return 0;
  109.       }
  110.     else return k;
  111.     }
  112.   }
  113.  
  114. heir14(lval)  int *lval; {
  115.   int k, const, val, lval2[8];
  116.   char *ptr, *before, *start;
  117.   k=primary(lval);
  118.   ptr=lval[0];
  119.   blanks();
  120.   if((ch=='[')|(ch=='(')) {
  121.     lval[5]=1;   /* secondary register will be used */
  122.     while(1) {
  123.       if(match("[")) {               /* [subscript] */
  124.         if(ptr==0) {
  125.           error("can't subscript");
  126.           junk();
  127.           needtoken("]");
  128.           return 0;
  129.           }
  130.         else if(ptr[IDENT]==POINTER) rvalue(lval);
  131.         else if(ptr[IDENT]!=ARRAY) {
  132.           error("can't subscript");
  133.           k=0;
  134.           }
  135.         setstage(&before, &start);
  136.         lval2[3]=0;
  137.         plunge2(0, 0, heir1, lval2, lval2); /* lval2 deadend */
  138.     needtoken("]");
  139.     /* -- beginning of new code -- */
  140.     if(match("[")) { /* we have more dimensions */
  141.            if(ptr[NDIM] < 2 ) {
  142.              error("too many dimension"); /* variable declared with */
  143.              junk();  /* less dimensions */
  144.              needtoken("]");
  145.              return 0;
  146.            }
  147.            if(lval2[3]) { /* Test for index being constant */
  148.             clearstage(before, 0); /* ignore code generated by plunge2 */
  149.             ol("XCHG AX,BX");
  150. /*                  const(lval2[4]);    */
  151.             ot("MOV AX,");
  152.             outdec(lval2[4]);
  153.             nl();
  154.            }
  155.            ol("PUSH BX");
  156.            if((lval2[3] == 0) | lval2[4]) {
  157.                if(ptr[TYPE] == CINT) /* Get 2nd dimension size */
  158.                const2(ptr[CDIM] << LBPW); /* and adjust for type size */
  159.                else
  160.                const2(ptr[CDIM]);
  161.                mult(); /* AX gets C * i1 */
  162.            }
  163.            setstage(&before, &start);
  164.            lval2[3] = 0;  /* parse subscript 2 expression */
  165.            plunge2(0, 0, heir1, lval2, lval2);
  166.            needtoken("]");
  167.            if(lval2[3]) { /* if index is a constant */
  168.                clearstage(before, 0); /* dump plunge2 generated code */
  169.                if(lval2[4])  /* if index is non-zero */
  170.                    if(ptr[TYPE] == CINT) {
  171.                        ot("ADD AX,");
  172.                        outdec(lval2[4] << LBPW);
  173.                        nl();
  174.                   }
  175.                    else {
  176.                        ot("ADD AX,");
  177.                        outdec(lval2[4]);
  178.                    }
  179.            }
  180.            else {
  181.                if(ptr[TYPE] == CINT)
  182.                    doublereg();
  183.                add(); /* AX gets C*i1 + i2 */
  184.            }
  185.            ol("POP BX");
  186.            /* retrieve array base from stack */
  187.            add(); /* calculate segment address of target */
  188.     }
  189.     else { /*  only one dimension  */
  190.     /* -- end of new code -- */
  191.     if(lval2[3]) {
  192.           clearstage(before,0);
  193.           if(lval2[4]) {
  194.             if(ptr[TYPE]==CINT) const2(lval2[4]<<LBPW);
  195.             else                const2(lval2[4]);
  196.             add();
  197.             }
  198.           }
  199.         else {
  200.           if(ptr[TYPE]==CINT) doublereg();
  201.           add();
  202.       }
  203.     }
  204.         lval[0]=lval[2]=0;
  205.         lval[1]=ptr[TYPE];
  206.         k=1;
  207.         }
  208.       else if(match("(")) {          /* function(...) */
  209.         if(ptr==0) callfunction(0); /* call to an absolute address */
  210.         else if(ptr[IDENT]!=FUNCTION) {
  211.           rvalue(lval);
  212.           callfunction(0);
  213.           }
  214.         else callfunction(ptr);
  215.         k=lval[0]=lval[3]=0;
  216.         }
  217.       else return k;
  218.       }
  219.     }
  220.   if(ptr==0) return k; /* if constant, return */
  221.   if(ptr[IDENT]==FUNCTION) { /* if function name without "()", gen address */
  222.     address(ptr);
  223.     return 0;
  224.     }
  225.   return k;
  226.   }
  227.  
  228. /*
  229. ** fixed per A. Macpherson letter, DDJ #81
  230. */
  231. primary(lval)  int *lval; {
  232.   char *ptr;
  233.   int k;
  234.   if(match("(")) { /* (expression) */
  235.     do
  236.       k=heir1(lval);
  237.     while(match(",")); /* comma operator */
  238.     needtoken(")");
  239.     return k;
  240.     }
  241.   putint(0, lval, 8<<LBPW); /* clear lval array */
  242.   if(symname(ssname, YES)) {
  243.     if(ptr=findloc(ssname)) {
  244. #ifdef STGOTO
  245.       if(ptr[IDENT]==LABEL) {
  246.         experr();
  247.         return 0;
  248.         }
  249. #endif
  250.       ptr[STATUS] |= USED;
  251.       getloc(ptr);
  252.       lval[0]=ptr;
  253.       lval[1]=ptr[TYPE];
  254.       if(ptr[IDENT]==POINTER) {
  255.         lval[1]=CINT;
  256.         lval[2]=ptr[TYPE];
  257.         }
  258.       if(ptr[IDENT]==ARRAY) {
  259.         lval[2]=ptr[TYPE];
  260.         return 0;
  261.         }
  262.       else return 1;
  263.       }
  264.     if(ptr=findglb(ssname)) {
  265.       ptr[STATUS] |= USED;
  266.       if(ptr[IDENT]!=FUNCTION) {
  267.         lval[0]=ptr;
  268.         lval[1]=0;
  269.         if(ptr[IDENT]!=ARRAY) {
  270.           if(ptr[IDENT]==POINTER) lval[2]=ptr[TYPE];
  271.           return 1;
  272.           }
  273.         address(ptr);
  274.         lval[1]=lval[2]=ptr[TYPE];
  275.         return 0;
  276.         }
  277.       }
  278.     /* implicitly define (if necessary) */
  279.     ptr=addsym(ssname, FUNCTION, CINT, 0, &glbptr, STATIC, 0, 0);
  280.     ptr[STATUS] |= USED;
  281.     lval[0]=ptr;
  282.     lval[1]=0;
  283.     return 0;
  284.     }
  285.   if(constant(lval)==0) experr();
  286.   return 0;
  287.   }
  288.  
  289. experr() {
  290.   error("invalid expression");
  291.   const(0);
  292.   junk();
  293.   }
  294.  
  295. callfunction(ptr)  char *ptr; { /* symbol table entry or 0 */
  296.   int nargs, const, val;
  297.   nargs=0;
  298.   blanks();               /* already saw open paren */
  299.   if(ptr==0) push();      /* calling AX */
  300.   while(streq(lptr,")")==0) {
  301.     if(endst()) break;
  302.     expression(&const, &val);
  303.     if(ptr==0) swapstk(); /* don't push addr */
  304.     push();               /* push argument */
  305.     nargs=nargs+BPW;      /* count args*BPW */
  306.     if (match(",")==0) break;
  307.     }
  308.   needtoken(")");
  309.   if(streq(ptr+NAME, "CCARGC")==0) loadargc(nargs>>LBPW);
  310.   if(ptr) call(ptr+NAME);
  311.   else callstk();
  312.   csp=modstk(csp+nargs);
  313.   }
  314.  
  315.  
  316.