home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume5 / smallc / part2 / expr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  9.8 KB  |  614 lines

  1. /*    File expr.c: 2.2 (83/06/21,11:24:26) */
  2. /*% cc -O -c %
  3.  *
  4.  */
  5.  
  6. #include <stdio.h>
  7. #include "defs.h"
  8. #include "data.h"
  9.  
  10. /*
  11.  *    lval[0] - symbol table address, else 0 for constant
  12.  *    lval[1] - type indirect object to fetch, else 0 for static object
  13.  *    lval[2] - type pointer or array, else 0
  14.  */
  15.  
  16. expression (comma)
  17. int    comma;
  18. {
  19.     int    lval[3];
  20.  
  21.     do {
  22.         if (heir1 (lval))
  23.             rvalue (lval);
  24.         if (!comma)
  25.             return;
  26.     } while (match (","));
  27. }
  28.  
  29. heir1 (lval)
  30. int    lval[];
  31. {
  32.     int    k, lval2[3];
  33.     char    fc;
  34.  
  35.     k = heir1a (lval);
  36.     if (match ("=")) {
  37.         if (k == 0) {
  38.             needlval ();
  39.             return (0);
  40.         }
  41.         if (lval[1])
  42.             gpush ();
  43.         if (heir1 (lval2))
  44.             rvalue (lval2);
  45.         store (lval);
  46.         return (0);
  47.     } else
  48.     {    
  49.         fc = ch();
  50.         if  (match ("-=") ||
  51.             match ("+=") ||
  52.             match ("*=") ||
  53.             match ("/=") ||
  54.             match ("%=") ||
  55.             match (">>=") ||
  56.             match ("<<=") ||
  57.             match ("&=") ||
  58.             match ("^=") ||
  59.             match ("|=")) {
  60.             if (k == 0) {
  61.                 needlval ();
  62.                 return (0);
  63.             }
  64.             if (lval[1])
  65.                 gpush ();
  66.             rvalue (lval);
  67.             gpush ();
  68.             if (heir1 (lval2))
  69.                 rvalue (lval2);
  70.             switch (fc) {
  71.                 case '-':    {
  72.                     if (dbltest(lval,lval2))
  73.                         gaslint();
  74.                     gsub();
  75.                     result (lval, lval2);
  76.                     break;
  77.                 }
  78.                 case '+':    {
  79.                     if (dbltest(lval,lval2))
  80.                         gaslint();
  81.                     gadd (lval,lval2);
  82.                     result(lval,lval2);
  83.                     break;
  84.                 }
  85.                 case '*':    gmult (); break;
  86.                 case '/':    gdiv (); break;
  87.                 case '%':    gmod (); break;
  88.                 case '>':    gasr (); break;
  89.                 case '<':    gasl (); break;
  90.                 case '&':    gand (); break;
  91.                 case '^':    gxor (); break;
  92.                 case '|':    gor (); break;
  93.             }
  94.             store (lval);
  95.             return (0);
  96.         } else
  97.             return (k);
  98.     }
  99. }
  100.  
  101. heir1a (lval)
  102. int    lval[];
  103. {
  104.     int    k, lval2[3], lab1, lab2;
  105.  
  106.     k = heir1b (lval);
  107.     blanks ();
  108.     if (ch () != '?')
  109.         return (k);
  110.     if (k)
  111.         rvalue (lval);
  112.     FOREVER
  113.         if (match ("?")) {
  114.             testjump (lab1 = getlabel (), FALSE);
  115.             if (heir1b (lval2))
  116.                 rvalue (lval2);
  117.             jump (lab2 = getlabel ());
  118.             printlabel (lab1);
  119.             col ();
  120.             nl ();
  121.             blanks ();
  122.             if (!match (":")) {
  123.                 error ("missing colon");
  124.                 return (0);
  125.             }
  126.             if (heir1b (lval2))
  127.                 rvalue (lval2);
  128.             printlabel (lab2);
  129.             col ();
  130.             nl ();
  131.         } else
  132.             return (0);
  133. }
  134.  
  135. heir1b (lval)
  136. int    lval[];
  137. {
  138.     int    k, lval2[3], lab;
  139.  
  140.     k = heir1c (lval);
  141.     blanks ();
  142.     if (!sstreq ("||"))
  143.         return (k);
  144.     if (k)
  145.         rvalue (lval);
  146.     FOREVER
  147.         if (match ("||")) {
  148.             testjump (lab = getlabel (), TRUE);
  149.             if (heir1c (lval2))
  150.                 rvalue (lval2);
  151.             printlabel (lab);
  152.             col ();
  153.             nl ();
  154.             gbool();
  155.         } else
  156.             return (0);
  157. }
  158.  
  159. heir1c (lval)
  160. int    lval[];
  161. {
  162.     int    k, lval2[3], lab;
  163.  
  164.     k = heir2 (lval);
  165.     blanks ();
  166.     if (!sstreq ("&&"))
  167.         return (k);
  168.     if (k)
  169.         rvalue (lval);
  170.     FOREVER
  171.         if (match ("&&")) {
  172.             testjump (lab = getlabel (), FALSE);
  173.             if (heir2 (lval2))
  174.                 rvalue (lval2);
  175.             printlabel (lab);
  176.             col ();
  177.             nl ();
  178.             gbool();
  179.         } else
  180.             return (0);
  181. }
  182.  
  183. heir2 (lval)
  184. int    lval[];
  185. {
  186.     int    k, lval2[3];
  187.  
  188.     k = heir3 (lval);
  189.     blanks ();
  190.     if ((ch() != '|') | (nch() == '|') | (nch() == '='))
  191.         return (k);
  192.     if (k)
  193.         rvalue (lval);
  194.     FOREVER {
  195.         if ((ch() == '|') & (nch() != '|') & (nch() != '=')) {
  196.             inbyte ();
  197.             gpush ();
  198.             if (heir3 (lval2))
  199.                 rvalue (lval2);
  200.             gor ();
  201.             blanks();
  202.         } else
  203.             return (0);
  204.     }
  205. }
  206.  
  207. heir3 (lval)
  208. int    lval[];
  209. {
  210.     int    k, lval2[3];
  211.  
  212.     k = heir4 (lval);
  213.     blanks ();
  214.     if ((ch () != '^') | (nch() == '='))
  215.         return (k);
  216.     if (k)
  217.         rvalue (lval);
  218.     FOREVER {
  219.         if ((ch() == '^') & (nch() != '=')){
  220.             inbyte ();
  221.             gpush ();
  222.             if (heir4 (lval2))
  223.                 rvalue (lval2);
  224.             gxor ();
  225.             blanks();
  226.         } else
  227.             return (0);
  228.     }
  229. }
  230.  
  231. heir4 (lval)
  232. int    lval[];
  233. {
  234.     int    k, lval2[3];
  235.  
  236.     k = heir5 (lval);
  237.     blanks ();
  238.     if ((ch() != '&') | (nch() == '|') | (nch() == '='))
  239.         return (k);
  240.     if (k)
  241.         rvalue (lval);
  242.     FOREVER {
  243.         if ((ch() == '&') & (nch() != '&') & (nch() != '=')) {
  244.             inbyte ();
  245.             gpush ();
  246.             if (heir5 (lval2))
  247.                 rvalue (lval2);
  248.             gand ();
  249.             blanks();
  250.         } else
  251.             return (0);
  252.     }
  253. }
  254.  
  255. heir5 (lval)
  256. int    lval[];
  257. {
  258.     int    k, lval2[3];
  259.  
  260.     k = heir6 (lval);
  261.     blanks ();
  262.     if (!sstreq ("==") &
  263.         !sstreq ("!="))
  264.         return (k);
  265.     if (k)
  266.         rvalue (lval);
  267.     FOREVER {
  268.         if (match ("==")) {
  269.             gpush ();
  270.             if (heir6 (lval2))
  271.                 rvalue (lval2);
  272.             geq ();
  273.         } else if (match ("!=")) {
  274.             gpush ();
  275.             if (heir6 (lval2))
  276.                 rvalue (lval2);
  277.             gne ();
  278.         } else
  279.             return (0);
  280.     }
  281. }
  282.  
  283. heir6 (lval)
  284. int    lval[];
  285. {
  286.     int    k, lval2[3];
  287.  
  288.     k = heir7 (lval);
  289.     blanks ();
  290.     if (!sstreq ("<") &&
  291.         !sstreq ("<=") &&
  292.         !sstreq (">=") &&
  293.         !sstreq (">"))
  294.         return (k);
  295.     if (sstreq ("<<") || sstreq (">>"))
  296.         return (k);
  297.     if (k)
  298.         rvalue (lval);
  299.     FOREVER {
  300.         if (match ("<=")) {
  301.             gpush ();
  302.             if (heir7 (lval2))
  303.                 rvalue (lval2);
  304.             if (lval[2] || lval2[2]) {
  305.                 gule ();
  306.                 continue;
  307.             }
  308.             gle ();
  309.         } else if (match (">=")) {
  310.             gpush ();
  311.             if (heir7 (lval2))
  312.                 rvalue (lval2);
  313.             if (lval[2] || lval2[2]) {
  314.                 guge ();
  315.                 continue;
  316.             }
  317.             gge ();
  318.         } else if ((sstreq ("<")) &&
  319.                !sstreq ("<<")) {
  320.             inbyte ();
  321.             gpush ();
  322.             if (heir7 (lval2))
  323.                 rvalue (lval2);
  324.             if (lval[2] || lval2[2]) {
  325.                 gult ();
  326.                 continue;
  327.             }
  328.             glt ();
  329.         } else if ((sstreq (">")) &&
  330.                !sstreq (">>")) {
  331.             inbyte ();
  332.             gpush ();
  333.             if (heir7 (lval2))
  334.                 rvalue (lval2);
  335.             if (lval[2] || lval2[2]) {
  336.                 gugt ();
  337.                 continue;
  338.             }
  339.             ggt ();
  340.         } else
  341.             return (0);
  342.         blanks ();
  343.     }
  344. }
  345.  
  346. heir7 (lval)
  347. int    lval[];
  348. {
  349.     int    k, lval2[3];
  350.  
  351.     k = heir8 (lval);
  352.     blanks ();
  353.     if (!sstreq (">>") &&
  354.         !sstreq ("<<") || sstreq(">>=") || sstreq("<<="))
  355.         return (k);
  356.     if (k)
  357.         rvalue (lval);
  358.     FOREVER {
  359.         if (sstreq(">>") && ! sstreq(">>=")) {
  360.             inbyte(); inbyte();
  361.             gpush ();
  362.             if (heir8 (lval2))
  363.                 rvalue (lval2);
  364.             gasr ();
  365.         } else if (sstreq("<<") && ! sstreq("<<=")) {
  366.             inbyte(); inbyte();
  367.             gpush ();
  368.             if (heir8 (lval2))
  369.                 rvalue (lval2);
  370.             gasl ();
  371.         } else
  372.             return (0);
  373.         blanks();
  374.     }
  375. }
  376.  
  377. heir8 (lval)
  378. int    lval[];
  379. {
  380.     int    k, lval2[3];
  381.  
  382.     k = heir9 (lval);
  383.     blanks ();
  384.     if ((ch () != '+') & (ch () != '-') | nch() == '=')
  385.         return (k);
  386.     if (k)
  387.         rvalue (lval);
  388.     FOREVER {
  389.         if (match ("+")) {
  390.             gpush ();
  391.             if (heir9 (lval2))
  392.                 rvalue (lval2);
  393.             /* if left is pointer and right is int, scale right */
  394.             if (dbltest (lval, lval2))
  395.                 gaslint ();
  396.             /* will scale left if right int pointer and left int */
  397.             gadd (lval,lval2);
  398.             result (lval, lval2);
  399.         } else if (match ("-")) {
  400.             gpush ();
  401.             if (heir9 (lval2))
  402.                 rvalue (lval2);
  403.             /* if dbl, can only be: pointer - int, or
  404.                         pointer - pointer, thus,
  405.                 in first case, int is scaled up,
  406.                 in second, result is scaled down. */
  407.             if (dbltest (lval, lval2))
  408.                 gaslint ();
  409.             gsub ();
  410.             /* if both pointers, scale result */
  411.             if ((lval[2] == CINT) && (lval2[2] == CINT)) {
  412.                 gasrint(); /* divide by intsize */
  413.             }
  414.             result (lval, lval2);
  415.         } else
  416.             return (0);
  417.     }
  418. }
  419.  
  420. heir9 (lval)
  421. int    lval[];
  422. {
  423.     int    k, lval2[3];
  424.  
  425.     k = heir10 (lval);
  426.     blanks ();
  427.     if (((ch () != '*') && (ch () != '/') &&
  428.         (ch () != '%')) || (nch() == '='))
  429.         return (k);
  430.     if (k)
  431.         rvalue (lval);
  432.     FOREVER {
  433.         if (match ("*")) {
  434.             gpush ();
  435.             if (heir10 (lval2))
  436.                 rvalue (lval2);
  437.             gmult ();
  438.         } else if (match ("/")) {
  439.             gpush ();
  440.             if (heir10 (lval2))
  441.                 rvalue (lval2);
  442.             gdiv ();
  443.         } else if (match ("%")) {
  444.             gpush ();
  445.             if (heir10 (lval2))
  446.                 rvalue (lval2);
  447.             gmod ();
  448.         } else
  449.             return (0);
  450.     }
  451. }
  452.  
  453. heir10 (lval)
  454. int    lval[];
  455. {
  456.     int    k;
  457.     char    *ptr;
  458.  
  459.     if (match ("++")) {
  460.         if ((k = heir10 (lval)) == 0) {
  461.             needlval ();
  462.             return (0);
  463.         }
  464.         if (lval[1])
  465.             gpush ();
  466.         rvalue (lval);
  467.         ginc (lval);
  468.         store (lval);
  469.         return (0);
  470.     } else if (match ("--")) {
  471.         if ((k = heir10 (lval)) == 0) {
  472.             needlval ();
  473.             return (0);
  474.         }
  475.         if (lval[1])
  476.             gpush ();
  477.         rvalue (lval);
  478.         gdec (lval);
  479.         store (lval);
  480.         return (0);
  481.     } else if (match ("-")) {
  482.         k = heir10 (lval);
  483.         if (k)
  484.             rvalue (lval);
  485.         gneg ();
  486.         return (0);
  487.     } else if (match ("~")) {
  488.         k = heir10 (lval);
  489.         if (k)
  490.             rvalue (lval);
  491.         gcom ();
  492.         return (0);
  493.     } else if (match ("!")) {
  494.         k = heir10 (lval);
  495.         if (k)
  496.             rvalue (lval);
  497.         glneg ();
  498.         return (0);
  499.     } else if (ch()=='*' && nch() != '=') {
  500.         inbyte();
  501.         k = heir10 (lval);
  502.         if (k)
  503.             rvalue (lval);
  504.         if (ptr = lval[0])
  505.             lval[1] = ptr[TYPE];
  506.         else
  507.             lval[1] = CINT;
  508.         lval[2] = 0;  /* flag as not pointer or array */
  509.         return (1);
  510.     } else if (ch()=='&' && nch()!='&' && nch()!='=') {
  511.         inbyte();
  512.         k = heir10 (lval);
  513.         if (k == 0) {
  514.             error ("illegal address");
  515.             return (0);
  516.         }
  517.         ptr = lval[0];
  518.         lval[2] = ptr[TYPE];
  519.         if (lval[1])
  520.             return (0);
  521.         /* global and non-array */
  522.         immed ();
  523.         prefix ();
  524.         outstr (ptr = lval[0]);
  525.         nl ();
  526.         lval[1] = ptr[TYPE];
  527.         return (0);
  528.     } else {
  529.         k = heir11 (lval);
  530.         if (match ("++")) {
  531.             if (k == 0) {
  532.                 needlval ();
  533.                 return (0);
  534.             }
  535.             if (lval[1])
  536.                 gpush ();
  537.             rvalue (lval);
  538.             ginc (lval);
  539.             store (lval);
  540.             gdec (lval);
  541.             return (0);
  542.         } else if (match ("--")) {
  543.             if (k == 0) {
  544.                 needlval ();
  545.                 return (0);
  546.             }
  547.             if (lval[1])
  548.                 gpush ();
  549.             rvalue (lval);
  550.             gdec (lval);
  551.             store (lval);
  552.             ginc (lval);
  553.             return (0);
  554.         } else
  555.             return (k);
  556.     }
  557. }
  558.  
  559. heir11 (lval)
  560. int    *lval;
  561. {
  562.     int    k;
  563.     char    *ptr;
  564.  
  565.     k = primary (lval);
  566.     ptr = lval[0];
  567.     blanks ();
  568.     if ((ch () == '[') | (ch () == '('))
  569.         FOREVER {
  570.             if (match ("[")) {
  571.                 if (ptr == 0) {
  572.                     error ("can't subscript");
  573.                     junk ();
  574.                     needbrack ("]");
  575.                     return (0);
  576.                 } else if (ptr[IDENT] == POINTER)
  577.                     rvalue (lval);
  578.                 else if (ptr[IDENT] != ARRAY) {
  579.                     error ("can't subscript");
  580.                     k = 0;
  581.                 }
  582.                 gpush ();
  583.                 expression (YES);
  584.                 needbrack ("]");
  585.                 if (ptr[TYPE] == CINT)
  586.                     gaslint ();
  587.                 gadd (NULL,NULL);
  588.                 lval[0] = 0;
  589.                 lval[1] = ptr[TYPE];
  590.                 k = 1;
  591.             } else if (match ("(")) {
  592.                 if (ptr == 0)
  593.                     callfunction (0);
  594.                 else if (ptr[IDENT] != FUNCTION) {
  595.                     rvalue (lval);
  596.                     callfunction (0);
  597.                 } else
  598.                     callfunction (ptr);
  599.                 k = lval[0] = 0;
  600.             } else
  601.                 return (k);
  602.         }
  603.     if (ptr == 0)
  604.         return (k);
  605.     if (ptr[IDENT] == FUNCTION) {
  606.         immed ();
  607.         prefix ();
  608.         outstr (ptr);
  609.         nl ();
  610.         return (0);
  611.     }
  612.     return (k);
  613. }
  614.