home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume5 / smallc / part2 / primary.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  4.7 KB  |  295 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.  
  10. primary (lval)
  11. 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.         k = heir1 (lval);
  20.         needbrack (")");
  21.         return (k);
  22.     }
  23.     if (amatch("sizeof", 6)) {
  24.         needbrack("(");
  25.         immed();
  26.         if (amatch("int", 3)) onum(intsize());
  27.         else if (amatch("char", 4)) onum(1);
  28.         else if (symname(sname)) {
  29.             if ((ptr = findloc(sname)) ||
  30.                 (ptr = findglb(sname))) {
  31.                 if (ptr[STORAGE] == LSTATIC)
  32.                     error("sizeof local static");
  33.                 k = glint(ptr);
  34.                 if ((ptr[TYPE] == CINT) ||
  35.                     (ptr[IDENT] == POINTER))
  36.                     k *= intsize();
  37.                 onum(k);
  38.             } else {
  39.                 error("sizeof undeclared variable");
  40.                 onum(0);
  41.             }
  42.         } else {
  43.             error("sizeof only on type or variable");
  44.         }
  45.         needbrack(")");
  46.         nl();
  47.         return(lval[0] = lval[1] = 0);
  48.     }
  49.     if (symname (sname)) {
  50.         if (ptr = findloc (sname)) {
  51.             getloc (ptr);
  52.             lval[0] = ptr;
  53.             lval[1] =  ptr[TYPE];
  54.             if (ptr[IDENT] == POINTER) {
  55.                 lval[1] = CINT;
  56.                 lval[2] = ptr[TYPE];
  57.             }
  58.             if (ptr[IDENT] == ARRAY) {
  59.                 lval[2] = ptr[TYPE];
  60.                 lval[2] = 0;
  61.                 return (0);
  62.             }
  63.             else
  64.                 return (1);
  65.         }
  66.         if (ptr = findglb (sname))
  67.             if (ptr[IDENT] != FUNCTION) {
  68.                 lval[0] = ptr;
  69.                 lval[1] = 0;
  70.                 if (ptr[IDENT] != ARRAY) {
  71.                     if (ptr[IDENT] == POINTER)
  72.                         lval[2] = ptr[TYPE];
  73.                     return (1);
  74.                 }
  75.                 immed ();
  76.                 prefix ();
  77.                 outstr (ptr);
  78.                 nl ();
  79.                 lval[1] = lval[2] = ptr[TYPE];
  80.                 lval[2] = 0;
  81.                 return (0);
  82.             }
  83.         blanks ();
  84.         if (ch() != '(')
  85.             error("undeclared variable");
  86.         ptr = addglb (sname, FUNCTION, CINT, 0, PUBLIC);
  87.         lval[0] = ptr;
  88.         lval[1] = 0;
  89.         return (0);
  90.     }
  91.     if (constant (num))
  92.         return (lval[0] = lval[1] = 0);
  93.     else {
  94.         error ("invalid expression");
  95.         immed ();
  96.         onum (0);
  97.         nl ();
  98.         junk ();
  99.         return (0);
  100.     }
  101. }
  102.  
  103. /*
  104.  *    true if val1 -> int pointer or int array and val2 not pointer or array
  105.  */
  106. dbltest (val1, val2)
  107. int    val1[], val2[];
  108. {
  109.     if (val1 == NULL)
  110.         return (FALSE);
  111.     if (val1[2] != CINT)
  112.         return (FALSE);
  113.     if (val2[2])
  114.         return (FALSE);
  115.     return (TRUE);
  116. }
  117.  
  118. /*
  119.  *    determine type of binary operation
  120.  */
  121. result (lval, lval2)
  122. int    lval[],
  123.     lval2[];
  124. {
  125.     if (lval[2] && lval2[2])
  126.         lval[2] = 0;
  127.     else if (lval2[2]) {
  128.         lval[0] = lval2[0];
  129.         lval[1] = lval2[1];
  130.         lval[2] = lval2[2];
  131.     }
  132. }
  133.         
  134. constant (val)
  135. int    val[];
  136. {
  137.     if (number (val))
  138.         immed ();
  139.     else if (pstr (val))
  140.         immed ();
  141.     else if (qstr (val)) {
  142.         immed ();
  143.         printlabel (litlab);
  144.         outbyte ('+');
  145.     } else
  146.         return (0);
  147.     onum (val[0]);
  148.     nl ();
  149.     return (1);
  150. }
  151.  
  152. number (val)
  153. int    val[];
  154. {
  155.     int    k, minus, base;
  156.     char    c;
  157.  
  158.     k = minus = 1;
  159.     while (k) {
  160.         k = 0;
  161.         if (match ("+"))
  162.             k = 1;
  163.         if (match ("-")) {
  164.             minus = (-minus);
  165.             k = 1;
  166.         }
  167.     }
  168.     if (!numeric (c = ch ()))
  169.         return (0);
  170.     if (match ("0x") || match ("0X"))
  171.         while (numeric (c = ch ()) ||
  172.                (c >= 'a' && c <= 'f') ||
  173.                (c >= 'A' && c <= 'F')) {
  174.             inbyte ();
  175.             k = k * 16 +
  176.                 (numeric (c) ? (c - '0') : ((c & 07) + 9));
  177.         }
  178.     else {
  179.         base = (c == '0') ? 8 : 10;
  180.         while (numeric (ch ())) {
  181.             c = inbyte ();
  182.             k = k * base + (c - '0');
  183.         }
  184.     }
  185.     if (minus < 0)
  186.         k = (-k);
  187.     val[0] = k;
  188.     return (1);
  189. }
  190.  
  191. pstr (val)
  192. int    val[];
  193. {
  194.     int    k;
  195.     char    c;
  196.  
  197.     k = 0;
  198.     if (!match ("'"))
  199.         return (0);
  200.     while ((c = gch ()) != 39) {
  201.         c = (c == '\\') ? spechar(): c;
  202.         k = (k & 255) * 256 + (c & 255);
  203.     }
  204.     val[0] = k;
  205.     return (1);
  206. }
  207.  
  208. qstr (val)
  209. int    val[];
  210. {
  211.     char    c;
  212.  
  213.     if (!match (quote))
  214.         return (0);
  215.     val[0] = litptr;
  216.     while (ch () != '"') {
  217.         if (ch () == 0)
  218.             break;
  219.         if (litptr >= LITMAX) {
  220.             error ("string space exhausted");
  221.             while (!match (quote))
  222.                 if (gch () == 0)
  223.                     break;
  224.             return (1);
  225.         }
  226.         c = gch();
  227.         litq[litptr++] = (c == '\\') ? spechar(): c;
  228.     }
  229.     gch ();
  230.     litq[litptr++] = 0;
  231.     return (1);
  232. }
  233.  
  234. /*
  235.  *    decode special characters (preceeded by back slashes)
  236.  */
  237. spechar() {
  238.     char c;
  239.     c = ch();
  240.  
  241.     if    (c == 'n') c = EOL;
  242.     else if    (c == 't') c = TAB;
  243.     else if (c == 'r') c = CR;
  244.     else if (c == 'f') c = FFEED;
  245.     else if (c == 'b') c = BKSP;
  246.     else if (c == '0') c = EOS;
  247.     else if (c == EOS) return;
  248.  
  249.     gch();
  250.     return (c);
  251. }
  252.  
  253. /*
  254.  *    perform a function call
  255.  *
  256.  *    called from "heir11", this routine will either call the named
  257.  *    function, or if the supplied ptr is zero, will call the contents
  258.  *    of HL
  259.  *
  260.  */
  261. callfunction (ptr)
  262. char    *ptr;
  263. {
  264.     int    nargs;
  265.  
  266.     nargs = 0;
  267.     blanks ();
  268.     if (ptr == 0)
  269.         gpush ();
  270.     while (!streq (line + lptr, ")")) {
  271.         if (endst ())
  272.             break;
  273.         expression (NO);
  274.         if (ptr == 0)
  275.             swapstk ();
  276.         gpush ();
  277.         nargs = nargs + intsize();
  278.         if (!match (","))
  279.             break;
  280.     }
  281.     needbrack (")");
  282.     if (aflag)
  283.         gnargs(nargs / intsize());
  284.     if (ptr)
  285.         gcall (ptr);
  286.     else
  287.         callstk ();
  288.     stkp = modstk (stkp + nargs);
  289. }
  290.  
  291. needlval ()
  292. {
  293.     error ("must be lvalue");
  294. }
  295.