home *** CD-ROM | disk | FTP | other *** search
/ messroms.de / 2007-01-13_www.messroms.de.zip / VZ200 / TOOLS / ZCCSRC.ZIP / scc / primary.c < prev    next >
C/C++ Source or Header  |  2000-03-08  |  10KB  |  615 lines

  1. /*    File primary.c: 2.4 (84/11/27,16:26:07) */
  2. /*% cc -O -c %
  3.  *
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "defs.h"
  8. #include "data.h"
  9. #include "proto.h"
  10.  
  11. int primary(int *lval)
  12. {
  13.     char *ptr, sname[NAMESIZE];
  14.     int num[1];
  15.     int k;
  16.  
  17.     lval[2] = 0;                       /* clear pointer/array type */
  18.     if (match("("))
  19.     {
  20.         k = heir1(lval);
  21.         needbrack(")");
  22.         return (k);
  23.     }
  24.     if (amatch("sizeof", 6))
  25.     {
  26.         needbrack("(");
  27.         immed();
  28.         if (amatch("int", 3))
  29.             onum(intsize());
  30.         else if (amatch("char", 4))
  31.             onum(1);
  32.         else if (symname(sname))
  33.         {
  34.             if ((ptr = findloc(sname)) ||
  35.                 (ptr = findglb(sname)))
  36.             {
  37.                 if (ptr[STORAGE] == LSTATIC)
  38.                     error("sizeof local static");
  39.                 k = glint(ptr);
  40.                 if ((ptr[TYPE] == CINT) ||
  41.                     (ptr[IDENT] == POINTER))
  42.                     k *= intsize();
  43.                 onum(k);
  44.             }
  45.             else
  46.             {
  47.                 error("sizeof undeclared variable");
  48.                 onum(0);
  49.             }
  50.         }
  51.         else
  52.         {
  53.             error("sizeof only on type or variable");
  54.         }
  55.         needbrack(")");
  56.         nl();
  57.         return (lval[0] = lval[1] = 0);
  58.     }
  59.     if (symname(sname))
  60.     {
  61.         if (NULL!=(ptr = findloc(sname)))
  62.         {
  63.             getloc(ptr);
  64.             lval[0] = (int)ptr;
  65.             lval[1] = ptr[TYPE];
  66.             if (ptr[IDENT] == POINTER)
  67.             {
  68.                 lval[1] = CINT;
  69.                 lval[2] = ptr[TYPE];
  70.             }
  71.             if (ptr[IDENT] == ARRAY)
  72.             {
  73.                 lval[2] = ptr[TYPE];
  74.                 lval[2] = 0;
  75.                 return (0);
  76.             }
  77.             else
  78.                 return (1);
  79.         }
  80.         if (NULL!=(ptr = findglb(sname)))
  81.             if (ptr[IDENT] != FUNCTION)
  82.             {
  83.                 lval[0] = (int)ptr;
  84.                 lval[1] = 0;
  85.                 if (ptr[IDENT] != ARRAY)
  86.                 {
  87.                     if (ptr[IDENT] == POINTER)
  88.                         lval[2] = ptr[TYPE];
  89.                     return (1);
  90.                 }
  91.                 immed();
  92.                 prefix();
  93.                 outstr(ptr);
  94.                 nl();
  95.                 lval[1] = lval[2] = ptr[TYPE];
  96.                 lval[2] = 0;
  97.                 return (0);
  98.             }
  99.         blanks();
  100.         if (ch() != '(')
  101.             error("undeclared variable");
  102.         ptr = addglb(sname, FUNCTION, CINT, 0, PUBLIC);
  103.         lval[0] = (int)ptr;
  104.         lval[1] = 0;
  105.         return (0);
  106.     }
  107.     if (constant(num))
  108.         return (lval[0] = lval[1] = 0);
  109.     else
  110.     {
  111.         error("invalid expression");
  112.         immed();
  113.         onum(0);
  114.         nl();
  115.         junk();
  116.         return (0);
  117.     }
  118. }
  119.  
  120. /*
  121.  *    true if val1 -> int pointer or int array and val2 not pointer or array
  122.  */
  123. int dbltest(int val1[], int val2[])
  124. {
  125.     if (val1 == NULL)
  126.         return (FALSE);
  127.     if (val1[2] != CINT)
  128.         return (FALSE);
  129.     if (val2[2])
  130.         return (FALSE);
  131.     return (TRUE);
  132. }
  133.  
  134. /* Determine type of binary operation */
  135. void result(int lval[], int lval2[])
  136. {
  137.     if (lval[2] && lval2[2])
  138.         lval[2] = 0;
  139.     else
  140.     if (lval2[2])
  141.     {
  142.         lval[0] = lval2[0];
  143.         lval[1] = lval2[1];
  144.         lval[2] = lval2[2];
  145.     }
  146. }
  147.  
  148. int constant(int val[])
  149. {
  150.     if (snumber(val))
  151.         immed();
  152.     else
  153.     if (pstr(val))
  154.         immed();
  155.     else
  156.     if (qstr(val))
  157.     {
  158.         immed();
  159.         printlabel(litlab);
  160.         outbyte('+');
  161.     }
  162.     else
  163.         return (0);
  164.     onum(val[0]);
  165.     nl();
  166.     return (1);
  167. }
  168.  
  169. /* Check for constant comparison type operations */
  170. static int relop(void)
  171. {
  172.     int k = 0;
  173.     if (match("=="))
  174.         k = 1;
  175.     else
  176.     if (match("!="))
  177.         k = 2;
  178.     else
  179.     if (match("<="))
  180.         k = 3;
  181.     else
  182.     if (match(">="))
  183.         k = 4;
  184.     else
  185.     if (match("<"))
  186.         k = 5;
  187.     else
  188.     if (match(">"))
  189.         k = 6;
  190.     return k;
  191. }
  192.  
  193. /* Check for constant addition type operations */
  194. static int addop(void)
  195. {
  196.     int k = 0;
  197.     if (match("+"))
  198.         k = 1;
  199.     else
  200.     if (match("-"))
  201.         k = 2;
  202.     else
  203.     if (match("|"))
  204.         k = 3;
  205.     return k;
  206. }
  207.  
  208. /* Check for constant multiplication type operations */
  209. static int mulop(void)
  210. {
  211.     int k = 0;
  212.     if (match("*"))
  213.         k = 1;
  214.     else
  215.     if (match("/"))
  216.         k = 2;
  217.     else
  218.     if (match("%"))
  219.         k = 3;
  220.     else
  221.     if (match("&"))
  222.         k = 4;
  223.     return k;
  224. }
  225.  
  226. /* Check for constant expression */
  227. int cexpr(int val[])
  228. {
  229.     int k, lval;
  230.     k = csimple(val);
  231.     while (k)
  232.     {
  233.         switch (relop())
  234.         {
  235.         case 0:
  236.             return 1;
  237.         case 1: /* == */
  238.             lval = val[0];
  239.             k = csimple(val);
  240.             if (k)
  241.                 val[0] = lval == val[0];
  242.             break;
  243.         case 2: /* != */
  244.             lval = val[0];
  245.             k = csimple(val);
  246.             if (k)
  247.                 val[0] = lval != val[0];
  248.             break;
  249.         case 3: /* <= */
  250.             lval = val[0];
  251.             k = csimple(val);
  252.             if (k)
  253.                 val[0] = lval <= val[0];
  254.             break;
  255.         case 4: /* >= */
  256.             lval = val[0];
  257.             k = csimple(val);
  258.             if (k)
  259.                 val[0] = lval >= val[0];
  260.             break;
  261.         case 5: /* <  */
  262.             lval = val[0];
  263.             k = csimple(val);
  264.             if (k)
  265.                 val[0] = lval <  val[0];
  266.             break;
  267.         case 6: /* >  */
  268.             lval = val[0];
  269.             k = csimple(val);
  270.             if (k)
  271.                 val[0] = lval >  val[0];
  272.             break;
  273.         }
  274.     }
  275.     return k;
  276. }
  277.  
  278. /* Check for constant simple expression */
  279. int csimple(int val[])
  280. {
  281.     int k, lval;
  282.     k = cterm(val);
  283.     while (k)
  284.     {
  285.         switch (addop())
  286.         {
  287.         case 0:
  288.             return 1;
  289.         case 1: /* + */
  290.             lval = val[0];
  291.             k = csimple(val);
  292.             if (k)
  293.                 val[0] = lval + val[0];
  294.             break;
  295.         case 2: /* - */
  296.             lval = val[0];
  297.             k = csimple(val);
  298.             if (k)
  299.                 val[0] = lval - val[0];
  300.             break;
  301.         case 3: /* | */
  302.             lval = val[0];
  303.             k = csimple(val);
  304.             if (k)
  305.                 val[0] = lval | val[0];
  306.             break;
  307.         }
  308.     }
  309.     return k;
  310. }
  311.  
  312. /* Check for constant term */
  313. int cterm(int val[])
  314. {
  315.     int k, lval;
  316.     k = cfactor(val);
  317.     while (k)
  318.     {
  319.         switch (mulop())
  320.         {
  321.         case 0:
  322.             return 1;
  323.         case 1: /* * */
  324.             lval = val[0];
  325.             k = cterm(val);
  326.             if (k)
  327.                 val[0] = lval * val[0];
  328.             break;
  329.         case 2: /* / */
  330.             lval = val[0];
  331.             k = cterm(val);
  332.             if (k)
  333.                 val[0] = lval / val[0];
  334.             break;
  335.         case 3: /* % */
  336.             lval = val[0];
  337.             k = cterm(val);
  338.             if (k)
  339.                 val[0] = lval / val[0];
  340.             break;
  341.         case 4: /* & */
  342.             lval = val[0];
  343.             k = cterm(val);
  344.             if (k)
  345.                 val[0] = lval & val[0];
  346.             break;
  347.         }
  348.     }
  349.     return k;
  350. }
  351.  
  352. /* Check for constant factor */
  353. int cfactor(int val[])
  354. {
  355.     int k, minus;
  356.     k = minus = 1;
  357.     while (k)
  358.     {
  359.         k = 0;
  360.         if (match("+"))
  361.             k = 1;
  362.         if (match("-"))
  363.         {
  364.             minus = (-minus);
  365.             k = 1;
  366.         }
  367.     }
  368.     k = cprimary(val);
  369.     if (minus < 0)
  370.        val[0] = -val[0];
  371.     return k;
  372. }
  373.  
  374. /* Check for constant primary expression */
  375. int cprimary(int val[])
  376. {
  377.     int k;
  378.     if (match("("))
  379.     {
  380.         k = cexpr(val);
  381.         if (k)
  382.             needbrack(")");
  383.     }
  384.     else
  385.     if (match("~"))
  386.     {
  387.         k = cprimary(val);
  388.         val[0] = ~val[0];
  389.     }
  390.     else
  391.         k = cnumber(val);
  392.     return k;
  393. }
  394.  
  395. /* Check for (optionally signed) number */
  396. int snumber(int val[])
  397. {
  398.     int k, minus;
  399.     k = minus = 1;
  400.     while (k)
  401.     {
  402.         k = 0;
  403.         if (match("+"))
  404.             k = 1;
  405.         if (match("-"))
  406.         {
  407.             minus = (-minus);
  408.             k = 1;
  409.         }
  410.     }
  411.     k = cnumber(val);
  412.     if (minus < 0)
  413.        val[0] = -val[0];
  414.     return k;
  415. }
  416.  
  417. /* Check for constant number */
  418. int cnumber(int val[])
  419. {
  420.     int k, base;
  421.     char c;
  422.  
  423.     if (!numeric(c = ch()))
  424.         return (0);
  425.     k = 0;
  426.     if (match("0x") || match("0X"))
  427.     {
  428.         while (numeric(c = ch()) ||
  429.                (c >= 'a' && c <= 'f') ||
  430.                (c >= 'A' && c <= 'F'))
  431.         {
  432.             inbyte();
  433.             k = k * 16 + (numeric(c) ? c - '0' : (c & 07) + 9);
  434.         }
  435.     }
  436.     else
  437.     {
  438.         /* numbers starting with zero are octal, others decimal */
  439.         base = (c == '0') ? 8 : 10;
  440.         while (numeric(ch()))
  441.         {
  442.             c = inbyte();
  443.             k = k * base + (c - '0');
  444.         }
  445.     }
  446.     val[0] = k;
  447.     return (1);
  448. }
  449.  
  450. int pstr(int val[])
  451. {
  452.     int k;
  453.     char c;
  454.  
  455.     k = 0;
  456.     if (!match("'"))
  457.         return (0);
  458.     while ((c = gch()) != 39)
  459.     {
  460.         c = (c == '\\') ? spechar() : c;
  461.         k = (k & 255) * 256 + (c & 255);
  462.     }
  463.     val[0] = k;
  464.     return (1);
  465. }
  466.  
  467. int qstr(int val[])
  468. {
  469.     char c;
  470.     int k, n, litptr0;
  471.  
  472.     if (!match(quote))
  473.         return (0);
  474.     /* save end of literals pointer */
  475.     litptr0 = litptr;
  476.     val[0] = litptr;
  477.     do
  478.     {
  479.         while (ch() != '"')
  480.         {
  481.             if (ch() == 0)
  482.                 break;
  483.             if (litptr >= LITMAX)
  484.             {
  485.                 error("string space exhausted");
  486.                 while (!match(quote))
  487.                 {
  488.                     if (gch() == 0)
  489.                         break;
  490.                 }
  491.                 return (1);
  492.             }
  493.             c = gch();
  494.             litq[litptr++] = (c == '\\') ? spechar() : c;
  495.         }
  496.         gch();
  497.     } while (match(quote));
  498.  
  499.     litq[litptr++] = '\0';
  500.     n = litptr - litptr0;
  501.     for (k = 0; k < litptr0; k++)
  502.     {
  503.         /* duplicate string? */
  504.         if (memcmp(litq+k, litq+litptr0, n) == 0)
  505.         {
  506.             val[0] = k;         /* use this one instead of a new copy */
  507.             litptr = litptr0;    /* reset litptr to where we started */
  508.             break;
  509.         }
  510.     }
  511.     return (1);
  512. }
  513.  
  514. /* Decode special characters (preceeded by back slashes) */
  515. char spechar(void)
  516. {
  517.     char c;
  518.  
  519.     c = ch();
  520.  
  521.     if (c == 'n')   /* new line */
  522.         c = EOL;
  523.     else
  524.     if (c == 't')   /* tab */
  525.         c = TAB;
  526.     else
  527.     if (c == 'r')   /* carriage return */
  528.         c = CR;
  529.     else
  530.     if (c == 'f')   /* form feed */
  531.         c = FFEED;
  532.     else
  533.     if (c == 'b')   /* back space */
  534.         c = BKSP;
  535.     else
  536.     if (c == '0')   /* octal constant */
  537.     {
  538.         int k;
  539.  
  540.         gch();
  541.         k = 0;
  542.         while (numeric(c = ch()))
  543.         {
  544.             c = gch();
  545.             k = k * 8 + (c - '0');
  546.         }
  547.         return (k);
  548.     }
  549.     else
  550.     if (c == 'x')   /* hexadecimal constant */
  551.     {
  552.         int k;
  553.  
  554.         gch();    /* skip x */
  555.         k = 0;
  556.         while (numeric(c = ch()) ||
  557.             (c >= 'a' && c <= 'f') ||
  558.             (c >= 'A' && c <= 'F'))
  559.         {
  560.             c = gch();
  561.             k = k * 16 + (numeric(c) ? (c - '0') : ((c & 07) + 9));
  562.         }
  563.         return (k);
  564.     }
  565.     else
  566.     if (c == EOS)
  567.         return 0;
  568.  
  569.     gch();
  570.     return (c);
  571. }
  572.  
  573. /*
  574.  *    perform a function call
  575.  *
  576.  *    called from "heir11", this routine will either call the named
  577.  *    function, or if the supplied ptr is zero, will call the contents
  578.  *    of HL
  579.  *
  580.  */
  581. void callfunction(char *ptr)
  582. {
  583.     int nargs;
  584.  
  585.     nargs = 0;
  586.     blanks();
  587.     if (ptr == 0)
  588.         gpush();
  589.     while (!streq(line + lptr, ")"))
  590.     {
  591.         if (endst())
  592.             break;
  593.         expression(NO);
  594.         if (ptr == 0)
  595.             swapstk();
  596.         gpush();
  597.         nargs = nargs + intsize();
  598.         if (!match(","))
  599.             break;
  600.     }
  601.     needbrack(")");
  602.     if (aflag)
  603.         gnargs(nargs / intsize());
  604.     if (ptr)
  605.         gcall(ptr);
  606.     else
  607.         callstk();
  608.     stkp = modstk(stkp + nargs);
  609. }
  610.  
  611. void needlval(void)
  612. {
  613.     error("must be lvalue");
  614. }
  615.