home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 379a.lha / p2c1_13a / src / src.zoo / expr5.c < prev    next >
C/C++ Source or Header  |  1990-03-11  |  39KB  |  1,338 lines

  1. /* "p2c", a Pascal to C translator.
  2.    Copyright (C) 1989 David Gillespie.
  3.    Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
  4.  
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation (any version).
  8.  
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. GNU General Public License for more details.
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with this program; see the file COPYING.  If not, write to
  16. the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  17.  
  18. #define PROTO_EXPR5_C
  19. #include "trans.h"
  20.  
  21. #define ISCONST(kind) ((kind)==EK_CONST || (kind)==EK_LONGCONST)
  22.  
  23. long po2m1(n)
  24. int n;
  25. {
  26.     if (n == 32)
  27.         return -1;
  28.     else if (n == 31)
  29.         return 0x7fffffff;
  30.     else
  31.         return (1<<n) - 1;
  32. }
  33.  
  34. int isarithkind(kind)
  35. enum exprkind kind;
  36. {
  37.     return (kind == EK_EQ || kind == EK_LT || kind == EK_GT ||
  38.         kind == EK_NE || kind == EK_LE || kind == EK_GE ||
  39.         kind == EK_PLUS || kind == EK_TIMES || kind == EK_DIVIDE ||
  40.         kind == EK_DIV || kind == EK_MOD || kind == EK_NEG ||
  41.         kind == EK_AND || kind == EK_OR || kind == EK_NOT ||
  42.         kind == EK_BAND || kind == EK_BOR || kind == EK_BXOR ||
  43.         kind == EK_LSH || kind == EK_RSH || kind == EK_BNOT ||
  44.         kind == EK_FUNCTION || kind == EK_BICALL);
  45. }
  46.  
  47.  
  48. Expr *makeexpr_assign(a, b)
  49. Expr *a, *b;
  50. {
  51.     int i, j;
  52.     Expr *ex, *ex2, *ex3, **ep;
  53.     Meaning *mp;
  54.     Type *tp;
  55.  
  56.     if (debug>2) { fprintf(outf,"makeexpr_assign("); dumpexpr(a); fprintf(outf,", "); dumpexpr(b); fprintf(outf,")\n"); }
  57.     if (stringtrunclimit > 0 &&
  58.     a->val.type->kind == TK_STRING &&
  59.     (i = strmax(a)) <= stringtrunclimit &&
  60.     strmax(b) > i) {
  61.     note("Possible string truncation in assignment [145]");
  62.     }
  63.     a = un_sign_extend(a);
  64.     b = gentle_cast(b, a->val.type);
  65.     if (b->kind == EK_BICALL && !strcmp(b->val.s, "sprintf") &&
  66.          (mp = istempvar(b->args[0])) != NULL &&
  67.          b->nargs >= 2 &&
  68.          b->args[1]->kind == EK_CONST &&              /* all this handles string appending */
  69.          b->args[1]->val.i > 2 &&                     /*   of the form, "s := s + ..." */
  70.          !strncmp(b->args[1]->val.s, "%s", 2) &&
  71.          exprsame(a, b->args[2], 1) &&
  72.          nosideeffects(a, 0) &&
  73.          (ex = singlevar(a)) != NULL) {
  74.         ex2 = copyexpr(b);
  75.         delfreearg(&ex2, 2);
  76.         freeexpr(ex2->args[1]);
  77.         ex2->args[1] = makeexpr_lstring(b->args[1]->val.s+2,
  78.                                         b->args[1]->val.i-2);
  79.         if (/*(ex = singlevar(a)) != NULL && */
  80.            /* noargdependencies(ex2) && */ !exproccurs(ex2, ex)) {
  81.             freeexpr(b);
  82.             if (ex2->args[1]->val.i == 2 &&     /* s := s + s2 */
  83.                 !strncmp(ex2->args[1]->val.s, "%s", 2)) {
  84.                 canceltempvar(mp);
  85.         tp = ex2->val.type;
  86.                 return makeexpr_bicall_2("strcat", tp,
  87.                                          makeexpr_addrstr(a), grabarg(ex2, 2));
  88.             } else if (sprintflength(ex2, 0) >= 0) {    /* s := s + 's2' */
  89.         tp = ex2->val.type;
  90.                 return makeexpr_bicall_2("strcat", tp,
  91.                                          makeexpr_addrstr(a), 
  92.                                          makeexpr_unsprintfify(ex2));
  93.             } else {                            /* general case */
  94.                 canceltempvar(mp);
  95.                 freeexpr(ex2->args[0]);
  96.                 ex = makeexpr_bicall_1("strlen", tp_int, copyexpr(a));
  97.                 ex2->args[0] = bumpstring(a, ex, 0);
  98.                 return ex2;
  99.             }
  100.         } else
  101.             freeexpr(ex2);
  102.     }
  103.     if (b->kind == EK_BICALL && !strcmp(b->val.s, "sprintf") &&
  104.          istempvar(b->args[0]) &&
  105.          (ex = singlevar(a)) != NULL) {
  106.         j = -1;     /* does lhs var appear exactly once on rhs? */
  107.         for (i = 2; i < b->nargs; i++) {
  108.             if (exprsame(b->args[i], ex, 1) && j < 0)
  109.                 j = i;
  110.             else if (exproccurs(b->args[i], ex))
  111.                 break;
  112.         }
  113.         if (i == b->nargs && j > 0) {
  114.             b->args[j] = makeexpr_bicall_2("strcpy", tp_str255,
  115.                                            makeexpr_addrstr(b->args[0]),
  116.                                            makeexpr_addrstr(b->args[j]));
  117.             b->args[0] = makeexpr_addrstr(a);
  118.             return b;
  119.         }
  120.     }
  121.     if (structuredfunc(b) && (ex2 = singlevar(a)) != NULL) {
  122.     ep = &b->args[0];
  123.     i = strlapfunc(b);
  124.     while (structuredfunc((ex = *ep))) {
  125.         i = i && strlapfunc(ex);
  126.         ep = &ex->args[0];
  127.     }
  128.     if ((mp = istempvar(ex)) != NULL &&
  129.         (i || !exproccurs(b, ex2))) {
  130.         canceltempvar(mp);
  131.         freeexpr(*ep);
  132.         *ep = makeexpr_addrstr(a);
  133.         return b;
  134.     }
  135.     }
  136.     if (a->val.type->kind == TK_PROCPTR &&
  137.         (mp = istempprocptr(b)) != NULL &&
  138.         nosideeffects(a, 0)) {
  139.         freeexpr(b->args[0]->args[0]->args[0]);
  140.         b->args[0]->args[0]->args[0] = copyexpr(a);
  141.     if (b->nargs == 3) {
  142.         freeexpr(b->args[1]->args[0]->args[0]);
  143.         b->args[1]->args[0]->args[0] = a;
  144.         delfreearg(&b, 2);
  145.     } else {
  146.         freeexpr(b->args[1]);
  147.         b->args[1] = makeexpr_assign(makeexpr_dotq(a, "link", tp_anyptr),
  148.                      makeexpr_nil());
  149.     }
  150.         canceltempvar(mp);
  151.         return b;
  152.     }
  153.     if (a->val.type->kind == TK_PROCPTR &&
  154.     (b->val.type->kind == TK_CPROCPTR ||
  155.      checkconst(b, 0))) {
  156.     ex = makeexpr_dotq(copyexpr(a), "proc", tp_anyptr);
  157.     b = makeexpr_comma(makeexpr_assign(ex, b),
  158.                makeexpr_assign(makeexpr_dotq(a, "link", tp_anyptr),
  159.                        makeexpr_nil()));
  160.     return b;
  161.     }
  162.     if (a->val.type->kind == TK_CPROCPTR &&
  163.     (mp = istempprocptr(b)) != NULL &&
  164.     nosideeffects(a, 0)) {
  165.     freeexpr(b->args[0]->args[0]);
  166.     b->args[0]->args[0] = a;
  167.     if (b->nargs == 3)
  168.         delfreearg(&b, 1);
  169.     delfreearg(&b, 1);
  170.     canceltempvar(mp);
  171.     return b;
  172.     }
  173.     if (a->val.type->kind == TK_CPROCPTR &&
  174.     b->val.type->kind == TK_PROCPTR) {
  175.     b = makeexpr_dotq(b, "proc", tp_anyptr);
  176.     }
  177.     if (a->val.type->kind == TK_STRING) {
  178.         if (b->kind == EK_CONST && b->val.i == 0 && !isretvar(a)) {
  179.                 /* optimizing retvar would mess up "return" optimization */
  180.             return makeexpr_assign(makeexpr_hat(a, 0),
  181.                                    makeexpr_char(0));
  182.         }
  183.         a = makeexpr_addrstr(a);
  184.         b = makeexpr_addrstr(b);
  185.         return makeexpr_bicall_2("strcpy", a->val.type, a, b);
  186.     }
  187.     if (a->kind == EK_BICALL && !strcmp(a->val.s, "strlen")) {
  188.         if (b->kind == EK_CAST &&
  189.              ord_type(b->args[0]->val.type)->kind == TK_INTEGER) {
  190.             b = grabarg(b, 0);
  191.         }
  192.         j = (b->kind == EK_PLUS &&      /* handle "s[0] := xxx" */
  193.              b->args[0]->kind == EK_BICALL &&
  194.              !strcmp(b->args[0]->val.s, "strlen") &&
  195.              exprsame(a->args[0], b->args[0]->args[0], 0) &&
  196.              isliteralconst(b->args[1], NULL) == 2);
  197.         if (j && b->args[1]->val.i > 0 &&
  198.                  b->args[1]->val.i <= 5) {     /* lengthening the string */
  199.             a = grabarg(a, 0);
  200.             i = b->args[1]->val.i;
  201.             freeexpr(b);
  202.             if (i == 1)
  203.                 b = makeexpr_string(" ");
  204.             else
  205.                 b = makeexpr_lstring("12345", i);
  206.             return makeexpr_bicall_2("strcat", a->val.type, a, b);
  207.         } else {      /* maybe shortening the string */
  208.             if (!j && !isconstexpr(b, NULL))
  209.                 note("Modification of string length may translate incorrectly [146]");
  210.             a = grabarg(a, 0);
  211.             b = makeexpr_ord(b);
  212.             return makeexpr_assign(makeexpr_index(a, b, NULL),
  213.                                    makeexpr_char(0));
  214.         }
  215.     }
  216.     if (a->val.type->kind == TK_ARRAY ||
  217.     (a->val.type->kind == TK_PROCPTR && copystructs < 1) ||
  218.     (a->val.type->kind == TK_RECORD &&
  219.      (copystructs < 1 || a->val.type != b->val.type))) {
  220.         ex = makeexpr_sizeof(copyexpr(a), 0);
  221.         ex2 = makeexpr_sizeof(copyexpr(b), 0);
  222.         if (!exprsame(ex, ex2, 1) &&
  223.             !(a->val.type->kind == TK_ARRAY &&
  224.               b->val.type->kind != TK_ARRAY))
  225.             warning("Incompatible types or sizes [167]");
  226.         freeexpr(ex2);
  227.         ex = makeexpr_arglong(ex, (size_t_long != 0));
  228.         a = makeexpr_addrstr(a);
  229.         b = makeexpr_addrstr(b);
  230.         return makeexpr_bicall_3("memcpy", a->val.type, a, b, ex);
  231.     }
  232.     if (a->val.type->kind == TK_SET) {
  233.         a = makeexpr_addrstr(a);
  234.         b = makeexpr_addrstr(b);
  235.         return makeexpr_bicall_2(setcopyname, a->val.type, a, b);
  236.     }
  237.     for (ep = &a; (ex3 = *ep); ) {
  238.         if (ex3->kind == EK_COMMA)
  239.             ep = &ex3->args[ex3->nargs-1];
  240.         else if (ex3->kind == EK_CAST || ex3->kind == EK_ACTCAST)
  241.             ep = &ex3->args[0];
  242.         else
  243.             break;
  244.     }
  245.     if (ex3->kind == EK_BICALL) {
  246.         if (!strcmp(ex3->val.s, getbitsname)) {
  247.         tp = ex3->args[0]->val.type;
  248.         if (tp->kind == TK_ARRAY)
  249.         ex3->args[0] = makeexpr_addr(ex3->args[0]);
  250.             ex3->val.type = tp_void;
  251.             if (checkconst(b, 0) && *clrbitsname) {
  252.                 strchange(&ex3->val.s, clrbitsname);
  253.             } else if (*putbitsname &&
  254.                        ((ISCONST(b->kind) &&
  255.                          (b->val.i | ~((1 << (1 << tp->escale)) - 1)) == -1) ||
  256.                         checkconst(b, (1 << (1 << tp->escale)) - 1))) {
  257.                 strchange(&ex3->val.s, putbitsname);
  258.                 insertarg(ep, 2, makeexpr_arglong(makeexpr_ord(b), 0));
  259.             } else {
  260.                 b = makeexpr_arglong(makeexpr_ord(b), 0);
  261.                 if (*storebitsname) {
  262.                     strchange(&ex3->val.s, storebitsname);
  263.                     insertarg(ep, 2, b);
  264.                 } else {
  265.                     if (exproccurs(b, ex3->args[0])) {
  266.                         mp = makestmttempvar(b->val.type, name_TEMP);
  267.                         ex2 = makeexpr_assign(makeexpr_var(mp), b);
  268.                         b = makeexpr_var(mp);
  269.                     } else
  270.                         ex2 = NULL;
  271.                     ex = copyexpr(ex3);
  272.                     strchange(&ex3->val.s, putbitsname);
  273.                     insertarg(&ex3, 2, b);
  274.                     strchange(&ex->val.s, clrbitsname);
  275.                     *ep = makeexpr_comma(ex2, makeexpr_comma(ex, ex3));
  276.                 }
  277.             }
  278.             return a;
  279.         } else if (!strcmp(ex3->val.s, getfbufname)) {
  280.         ex3->val.type = tp_void;
  281.         strchange(&ex3->val.s, putfbufname);
  282.         insertarg(ep, 2, b);
  283.         return a;
  284.         } else if (!strcmp(ex3->val.s, chargetfbufname)) {
  285.         ex3->val.type = tp_void;
  286.         if (*charputfbufname) {
  287.         strchange(&ex3->val.s, charputfbufname);
  288.         insertarg(ep, 1, b);
  289.         } else {
  290.         strchange(&ex3->val.s, putfbufname);
  291.         insertarg(ep, 1, makeexpr_type(ex3->val.type->basetype->basetype));
  292.         insertarg(ep, 2, b);
  293.         }
  294.         return a;
  295.         } else if (!strcmp(ex3->val.s, arraygetfbufname)) {
  296.         ex3->val.type = tp_void;
  297.         if (*arrayputfbufname) {
  298.         strchange(&ex3->val.s, arrayputfbufname);
  299.         insertarg(ep, 1, b);
  300.         } else {
  301.         strchange(&ex3->val.s, putfbufname);
  302.         insertarg(ep, 1, makeexpr_type(ex3->val.type->basetype->basetype));
  303.         insertarg(ep, 2, b);
  304.         }
  305.         return a;
  306.     }
  307.     }
  308.     while (a->kind == EK_CAST || a->kind == EK_ACTCAST) {
  309.     if (ansiC < 2 ||     /* in GNU C, a cast is an lvalue */
  310.         isarithkind(a->args[0]->kind) ||
  311.         (a->val.type->kind == TK_POINTER &&
  312.          a->args[0]->val.type->kind == TK_POINTER)) {
  313.         if (a->kind == EK_CAST)
  314.         b = makeexpr_cast(b, a->args[0]->val.type);
  315.         else
  316.         b = makeexpr_actcast(b, a->args[0]->val.type);
  317.             a = grabarg(a, 0);
  318.         } else
  319.         break;
  320.     }
  321.     if (a->kind == EK_NEG)
  322.     return makeexpr_assign(grabarg(a, 0), makeexpr_neg(b));
  323.     if (a->kind == EK_NOT)
  324.     return makeexpr_assign(grabarg(a, 0), makeexpr_not(b));
  325.     if (a->kind == EK_BNOT)
  326.     return makeexpr_assign(grabarg(a, 0),
  327.                    makeexpr_un(EK_BNOT, b->val.type, b));
  328.     if (a->kind == EK_PLUS) {
  329.     for (i = 0; i < a->nargs && a->nargs > 1; ) {
  330.         if (isconstantexpr(a->args[i])) {
  331.         b = makeexpr_minus(b, a->args[i]);
  332.         deletearg(&a, i);
  333.         } else
  334.         i++;
  335.     }
  336.     if (a->nargs == 1)
  337.         return makeexpr_assign(grabarg(a, 0), b);
  338.     }
  339.     if (a->kind == EK_TIMES) {
  340.     for (i = 0; i < a->nargs && a->nargs > 1; ) {
  341.         if (isconstantexpr(a->args[i])) {
  342.         if (a->val.type->kind == TK_REAL)
  343.             b = makeexpr_divide(b, a->args[i]);
  344.         else {
  345.             if (ISCONST(b->kind) && ISCONST(a->args[i]->kind) &&
  346.             (b->val.i % a->args[i]->val.i) != 0) {
  347.             break;
  348.             }
  349.             b = makeexpr_div(b, a->args[i]);
  350.         }
  351.         deletearg(&a, i);
  352.         } else
  353.         i++;
  354.     }
  355.     if (a->nargs == 1)
  356.         return makeexpr_assign(grabarg(a, 0), b);
  357.     }
  358.     if ((a->kind == EK_DIVIDE || a->kind == EK_DIV) &&
  359.      isconstantexpr(a->args[1])) {
  360.     b = makeexpr_times(b, a->args[1]);
  361.     return makeexpr_assign(a->args[0], b);
  362.     }
  363.     if (a->kind == EK_LSH && isconstantexpr(a->args[1])) {
  364.     if (ISCONST(b->kind) && ISCONST(a->args[1]->kind)) {
  365.         if ((b->val.i & ((1L << a->args[1]->val.i)-1)) == 0) {
  366.         b->val.i >>= a->args[1]->val.i;
  367.         return makeexpr_assign(grabarg(a, 0), b);
  368.         }
  369.     } else {
  370.         b = makeexpr_bin(EK_RSH, b->val.type, b, a->args[1]);
  371.         return makeexpr_assign(a->args[0], b);
  372.     }
  373.     }
  374.     if (a->kind == EK_RSH && isconstantexpr(a->args[1])) {
  375.     if (ISCONST(b->kind) && ISCONST(a->args[1]->kind))
  376.         b->val.i <<= a->args[1]->val.i;
  377.     else
  378.         b = makeexpr_bin(EK_LSH, b->val.type, b, a->args[1]);
  379.     return makeexpr_assign(a->args[0], b);
  380.     }
  381.     if (isarithkind(a->kind))
  382.     warning("Invalid assignment [168]");
  383.     return makeexpr_bin(EK_ASSIGN, a->val.type, a, makeexpr_unlongcast(b));
  384. }
  385.  
  386.  
  387.  
  388.  
  389. Expr *makeexpr_comma(a, b)
  390. Expr *a, *b;
  391. {
  392.     Type *type;
  393.  
  394.     if (!a || nosideeffects(a, 1))
  395.         return b;
  396.     if (!b)
  397.         return a;
  398.     type = b->val.type;
  399.     a = commute(a, b, EK_COMMA);
  400.     a->val.type = type;
  401.     return a;
  402. }
  403.  
  404.  
  405.  
  406.  
  407. int strmax(ex)
  408. Expr *ex;
  409. {
  410.     Meaning *mp;
  411.     long smin, smax;
  412.     Value val;
  413.     Type *type;
  414.  
  415.     type = ex->val.type;
  416.     if (type->kind == TK_POINTER)
  417.         type = type->basetype;
  418.     if (type->kind == TK_CHAR)
  419.         return 1;
  420.     if (type->kind == TK_ARRAY && type->basetype->kind == TK_CHAR) {
  421.         if (ord_range(type->indextype, &smin, &smax))
  422.             return smax - smin + 1;
  423.         else
  424.             return stringceiling;
  425.     }
  426.     if (type->kind != TK_STRING) {
  427.         intwarning("strmax", "strmax encountered a non-string value [169]");
  428.         return stringceiling;
  429.     }
  430.     if (ex->kind == EK_CONST)
  431.         return ex->val.i;
  432.     if (ex->kind == EK_VAR && foldstrconsts != 0 &&
  433.         (mp = (Meaning *)(ex->val.i))->kind == MK_CONST)
  434.         return mp->val.i;
  435.     if (ex->kind == EK_BICALL) {
  436.     if (!strcmp(ex->val.s, strsubname)) {
  437.         if (isliteralconst(ex->args[3], &val) && val.type)
  438.         return val.i;
  439.     }
  440.     }
  441.     if (ord_range(type->indextype, NULL, &smax))
  442.         return smax;
  443.     else
  444.         return stringceiling;
  445. }
  446.  
  447.  
  448.  
  449.  
  450. int strhasnull(val)
  451. Value val;
  452. {
  453.     int i;
  454.  
  455.     for (i = 0; i < val.i; i++) {
  456.         if (!val.s[i])
  457.             return (i == val.i-1) ? 1 : 2;
  458.     }
  459.     return 0;
  460. }
  461.  
  462.  
  463.  
  464. int istempsprintf(ex)
  465. Expr *ex;
  466. {
  467.     return (ex->kind == EK_BICALL && !strcmp(ex->val.s, "sprintf") &&
  468.             ex->nargs >= 2 &&
  469.             istempvar(ex->args[0]) && 
  470.             ex->args[1]->kind == EK_CONST && 
  471.             ex->args[1]->val.type->kind == TK_STRING);
  472. }
  473.  
  474.  
  475.  
  476. Expr *makeexpr_sprintfify(ex)
  477. Expr *ex;
  478. {
  479.     Meaning *tvar;
  480.     char stringbuf[500];
  481.     char *cp, ch;
  482.     int j, nnulls;
  483.     Expr *ex2;
  484.  
  485.     if (debug>2) { fprintf(outf,"makeexpr_sprintfify("); dumpexpr(ex); fprintf(outf,")\n"); }
  486.     if (istempsprintf(ex))
  487.         return ex;
  488.     ex = makeexpr_stringcast(ex);
  489.     tvar = makestmttempvar(tp_str255, name_STRING);
  490.     if (ex->kind == EK_CONST && ex->val.type->kind == TK_STRING) {
  491.         cp = stringbuf;
  492.         nnulls = 0;
  493.         for (j = 0; j < ex->val.i; j++) {
  494.             ch = ex->val.s[j];
  495.             if (!ch) {
  496.                 if (j < ex->val.i-1)
  497.                     note("Null character in sprintf control string [147]");
  498.                 else
  499.                     note("Null character at end of sprintf control string [148]");
  500.                 if (keepnulls) {
  501.                     *cp++ = '%';
  502.                     *cp++ = 'c';
  503.                     nnulls++;
  504.                 }
  505.             } else {
  506.                 *cp++ = ch;
  507.                 if (ch == '%')
  508.                     *cp++ = ch;
  509.             }
  510.         }
  511.         *cp = 0;
  512.         ex = makeexpr_bicall_2("sprintf", tp_str255,
  513.                                makeexpr_var(tvar),
  514.                                makeexpr_string(stringbuf));
  515.         while (--nnulls >= 0)
  516.             insertarg(&ex, 2, makeexpr_char(0));
  517.         return ex;
  518.     } else if (ex->val.type->kind == TK_ARRAY &&
  519.                ex->val.type->basetype->kind == TK_CHAR) {
  520.         ex2 = arraysize(ex->val.type, 0);
  521.         return cleansprintf(
  522.                 makeexpr_bicall_4("sprintf", tp_str255,
  523.                                   makeexpr_var(tvar),
  524.                                   makeexpr_string("%.*s"),
  525.                                   ex2,
  526.                                   makeexpr_addrstr(ex)));
  527.     } else {
  528.         if (ord_type(ex->val.type)->kind == TK_CHAR)
  529.             cp = "%c";
  530.         else if (ex->val.type->kind == TK_STRING)
  531.             cp = "%s";
  532.         else {
  533.             warning("Mixing non-strings with strings [170]");
  534.             return ex;
  535.         }
  536.         return makeexpr_bicall_3("sprintf", tp_str255,
  537.                                  makeexpr_var(tvar),
  538.                                  makeexpr_string(cp),
  539.                                  ex);
  540.     }
  541. }
  542.  
  543.  
  544.  
  545. Expr *makeexpr_unsprintfify(ex)
  546. Expr *ex;
  547. {
  548.     char stringbuf[500];
  549.     char *cp, ch;
  550.     int i;
  551.  
  552.     if (debug>2) { fprintf(outf,"makeexpr_unsprintfify("); dumpexpr(ex); fprintf(outf,")\n"); }
  553.     if (!istempsprintf(ex))
  554.         return ex;
  555.     canceltempvar(istempvar(ex->args[0]));
  556.     for (i = 2; i < ex->nargs; i++) {
  557.         if (ex->args[i]->val.type->kind != TK_CHAR ||
  558.             !checkconst(ex, 0))
  559.             return ex;
  560.     }
  561.     cp = stringbuf;
  562.     for (i = 0; i < ex->args[1]->val.i; i++) {
  563.         ch = ex->args[1]->val.s[i];
  564.         *cp++ = ch;
  565.         if (ch == '%') {
  566.             if (++i == ex->args[1]->val.i)
  567.                 return ex;
  568.             ch = ex->args[1]->val.s[i];
  569.             if (ch == 'c')
  570.                 cp[-1] = 0;
  571.             else if (ch != '%')
  572.                 return ex;
  573.         }
  574.     }
  575.     freeexpr(ex);
  576.     return makeexpr_lstring(stringbuf, cp - stringbuf);
  577. }
  578.  
  579.  
  580.  
  581. /* Returns >= 0 iff unsprintfify would return a string constant */
  582.  
  583. int sprintflength(ex, allownulls)
  584. Expr *ex;
  585. int allownulls;
  586. {
  587.     int i, len;
  588.  
  589.     if (!istempsprintf(ex))
  590.         return -1;
  591.     for (i = 2; i < ex->nargs; i++) {
  592.         if (!allownulls ||
  593.             ex->args[i]->val.type->kind != TK_CHAR ||
  594.             !checkconst(ex, 0))
  595.             return -1;
  596.     }
  597.     len = 0;
  598.     for (i = 0; i < ex->args[1]->val.i; i++) {
  599.         len++;
  600.         if (ex->args[1]->val.s[i] == '%') {
  601.             if (++i == ex->args[1]->val.i)
  602.                 return -1;
  603.             if (ex->args[1]->val.s[i] != 'c' &&
  604.                 ex->args[1]->val.s[i] != '%')
  605.                 return -1;
  606.         }
  607.     }
  608.     return len;
  609. }
  610.  
  611.  
  612.  
  613. Expr *makeexpr_concat(a, b, usesprintf)
  614. Expr *a, *b;
  615. int usesprintf;
  616. {
  617.     int i, ii, j, len, nargs;
  618.     Type *type;
  619.     Meaning *mp, *tvar;
  620.     Expr *ex, *args[2];
  621.     int akind[2];
  622.     Value val, val1, val2;
  623.     char formatstr[300];
  624.  
  625.     if (debug>2) { fprintf(outf,"makeexpr_concat("); dumpexpr(a); fprintf(outf,", "); dumpexpr(b); fprintf(outf,")\n"); }
  626.     if (!a)
  627.         return b;
  628.     if (!b)
  629.         return a;
  630.     a = makeexpr_stringcast(a);
  631.     b = makeexpr_stringcast(b);
  632.     if (checkconst(a, 0)) {
  633.         freeexpr(a);
  634.         return b;
  635.     }
  636.     if (checkconst(b, 0)) {
  637.         freeexpr(b);
  638.         return a;
  639.     }
  640.     len = strmax(a) + strmax(b);
  641.     type = makestringtype(len);
  642.     if (a->kind == EK_CONST && b->kind == EK_CONST) {
  643.         val1 = a->val;
  644.         val2 = b->val;
  645.         val.i = val1.i + val2.i;
  646.         val.s = ALLOC(val.i+1, char, literals);
  647.     val.s[val.i] = 0;
  648.         val.type = type;
  649.         memcpy(val.s, val1.s, val1.i);
  650.         memcpy(val.s + val1.i, val2.s, val2.i);
  651.         freeexpr(a);
  652.         freeexpr(b);
  653.         return makeexpr_val(val);
  654.     }
  655.     tvar = makestmttempvar(type, name_STRING);
  656.     if (sprintf_value != 2 || usesprintf) {
  657.         nargs = 2;                 /* Generate a call to sprintf(), unfolding */
  658.         args[0] = a;               /*  nested sprintf()'s. */
  659.         args[1] = b;
  660.         *formatstr = 0;
  661.         for (i = 0; i < 2; i++) {
  662. #if 1
  663.             ex = args[i] = makeexpr_sprintfify(args[i]);
  664.         if (!ex->args[1] || !ex->args[1]->val.s)
  665.         intwarning("makeexpr_concat", "NULL in ex->args[1]");
  666.         else
  667.         strncat(formatstr, ex->args[1]->val.s, ex->args[1]->val.i);
  668.             canceltempvar(istempvar(ex->args[0]));
  669.             nargs += (ex->nargs - 2);
  670.             akind[i] = 0;      /* now obsolete */
  671. #else
  672.             ex = args[i];
  673.             if (ex->kind == EK_CONST)
  674.                 ex = makeexpr_sprintfify(ex);
  675.             if (istempsprintf(ex)) {
  676.                 strncat(formatstr, ex->args[1]->val.s, ex->args[1]->val.i);
  677.                 canceltempvar(istempvar(ex->args[0]));
  678.                 nargs += (ex->nargs - 2);
  679.                 akind[i] = 0;
  680.             } else {
  681.                 strcat(formatstr, "%s");
  682.                 nargs++;
  683.                 akind[i] = 1;
  684.             }
  685. #endif
  686.         }
  687.         ex = makeexpr(EK_BICALL, nargs);
  688.         ex->val.type = type;
  689.         ex->val.s = stralloc("sprintf");
  690.         ex->args[0] = makeexpr_var(tvar);
  691.         ex->args[1] = makeexpr_string(formatstr);
  692.         j = 2;
  693.         for (i = 0; i < 2; i++) {
  694.             switch (akind[i]) {
  695.                 case 0:   /* flattened sub-sprintf */
  696.                     for (ii = 2; ii < args[i]->nargs; ii++)
  697.                         ex->args[j++] = copyexpr(args[i]->args[ii]);
  698.                     freeexpr(args[i]);
  699.                     break;
  700.                 case 1:   /* included string expr */
  701.                     ex->args[j++] = args[i];
  702.                     break;
  703.             }
  704.         }
  705.     } else {
  706.         ex = a;
  707.         while (ex->kind == EK_BICALL && !strcmp(ex->val.s, "strcat"))
  708.             ex = ex->args[0];
  709.         if (ex->kind == EK_BICALL && !strcmp(ex->val.s, "strcpy") &&
  710.             (mp = istempvar(ex->args[0])) != NULL) {
  711.             canceltempvar(mp);
  712.             freeexpr(ex->args[0]);
  713.             ex->args[0] = makeexpr_var(tvar);
  714.         } else {
  715.             a = makeexpr_bicall_2("strcpy", type, makeexpr_var(tvar), a);
  716.         }
  717.         ex = makeexpr_bicall_2("strcat", type, a, b);
  718.     }
  719.     if (debug>2) { fprintf(outf,"makeexpr_concat returns "); dumpexpr(ex); fprintf(outf,"\n"); }
  720.     return ex;
  721. }
  722.  
  723.  
  724.  
  725. Expr *cleansprintf(ex)
  726. Expr *ex;
  727. {
  728.     int fidx, i, j, k, len, changed = 0;
  729.     char *cp, *bp;
  730.     char fmtbuf[300];
  731.  
  732.     if (ex->kind != EK_BICALL)
  733.     return ex;
  734.     if (!strcmp(ex->val.s, "printf"))
  735.     fidx = 0;
  736.     else if (!strcmp(ex->val.s, "sprintf") ||
  737.          !strcmp(ex->val.s, "fprintf"))
  738.     fidx = 1;
  739.     else
  740.     return ex;
  741.     len = ex->args[fidx]->val.i;
  742.     cp = ex->args[fidx]->val.s;      /* printf("%*d",17,x)  =>  printf("%17d",x) */
  743.     bp = fmtbuf;
  744.     j = fidx + 1;
  745.     for (i = 0; i < len; i++) {
  746.         *bp++ = cp[i];
  747.         if (cp[i] == '%') {
  748.         if (cp[i+1] == 's' && ex->args[j]->kind == EK_CONST) {
  749.         bp--;
  750.         for (k = 0; k < ex->args[j]->val.i; k++)
  751.             *bp++ = ex->args[j]->val.s[k];
  752.         delfreearg(&ex, j);
  753.         changed = 1;
  754.         i++;
  755.         continue;
  756.         }
  757.             for (i++; i < len &&
  758.                       !(isalpha(cp[i]) && cp[i] != 'l'); i++) {
  759.                 if (cp[i] == '*') {
  760.                     if (isliteralconst(ex->args[j], NULL) == 2) {
  761.                         sprintf(bp, "%ld", ex->args[j]->val.i);
  762.                         bp += strlen(bp);
  763.                         delfreearg(&ex, j);
  764.                         changed = 1;
  765.                     } else {
  766.                         *bp++ = cp[i];
  767.                         j++;
  768.                     }
  769.                 } else
  770.                     *bp++ = cp[i];
  771.             }
  772.             if (i < len)
  773.                 *bp++ = cp[i];
  774.             j++;
  775.         }
  776.     }
  777.     *bp = 0;
  778.     if (changed) {
  779.         freeexpr(ex->args[fidx]);
  780.         ex->args[fidx] = makeexpr_string(fmtbuf);
  781.     }
  782.     return ex;
  783. }
  784.  
  785.  
  786.  
  787. Expr *makeexpr_substring(vex, ex, exi, exj)
  788. Expr *vex, *ex, *exi, *exj;
  789. {
  790.     exi = makeexpr_unlongcast(exi);
  791.     exj = makeexpr_longcast(exj, 0);
  792.     ex = bumpstring(ex, exi, 1);
  793.     return cleansprintf(makeexpr_bicall_4("sprintf", tp_str255,
  794.                                           vex,
  795.                                           makeexpr_string("%.*s"),
  796.                                           exj,
  797.                                           ex));
  798. }
  799.  
  800.  
  801.  
  802.  
  803. Expr *makeexpr_dot(ex, mp)
  804. Expr *ex;
  805. Meaning *mp;
  806. {
  807.     Type *ot1, *ot2;
  808.     Expr *ex2, *ex3, *nex;
  809.     Meaning *tvar;
  810.  
  811.     if (ex->kind == EK_FUNCTION && copystructfuncs > 0) {
  812.         tvar = makestmttempvar(ex->val.type, name_TEMP);
  813.         ex2 = makeexpr_assign(makeexpr_var(tvar), ex);
  814.         ex = makeexpr_var(tvar);
  815.     } else
  816.         ex2 = NULL;
  817.     if (mp->constdefn) {
  818.         nex = makeexpr(EK_MACARG, 0);
  819.         nex->val.type = tp_integer;
  820.         ex3 = replaceexprexpr(copyexpr(mp->constdefn), nex, ex);
  821.         freeexpr(ex);
  822.         freeexpr(nex);
  823.         ex = gentle_cast(ex3, mp->val.type);
  824.     } else {
  825.         ex = makeexpr_un(EK_DOT, mp->type, ex);
  826.         ex->val.i = (long)mp;
  827.         ot1 = ord_type(mp->type);
  828.         ot2 = ord_type(mp->val.type);
  829.         if (ot1->kind != ot2->kind && ot2->kind == TK_ENUM && ot2->meaning && useenum)
  830.             ex = makeexpr_cast(ex, mp->val.type);
  831.         else if (mp->val.i && !hassignedchar &&
  832.          (mp->type == tp_sint || mp->type == tp_abyte)) {
  833.             if (*signextname) {
  834.                 ex = makeexpr_bicall_2(signextname, tp_integer,
  835.                                        ex, makeexpr_long(mp->val.i));
  836.             } else
  837.                 note(format_s("Unable to sign-extend field %s [149]", mp->name));
  838.         }
  839.     }
  840.     ex->val.type = mp->val.type;
  841.     return makeexpr_comma(ex2, ex);
  842. }
  843.  
  844.  
  845.  
  846. Expr *makeexpr_dotq(ex, name, type)
  847. Expr *ex;
  848. char *name;
  849. Type *type;
  850. {
  851.     ex = makeexpr_un(EK_DOT, type, ex);
  852.     ex->val.s = stralloc(name);
  853.     return ex;
  854. }
  855.  
  856.  
  857.  
  858. Expr *strmax_func(ex)
  859. Expr *ex;
  860. {
  861.     Meaning *mp;
  862.     Expr *ex2;
  863.     Type *type;
  864.  
  865.     type = ex->val.type;
  866.     if (type->kind == TK_POINTER) {
  867.         intwarning("strmax_func", "got a pointer instead of a string [171]");
  868.         type = type->basetype;
  869.     }
  870.     if (type->kind == TK_CHAR)
  871.         return makeexpr_long(1);
  872.     if (type->kind != TK_STRING) {
  873.         warning("STRMAX of non-string value [172]");
  874.         return makeexpr_long(stringceiling);
  875.     }
  876.     if (ex->kind == EK_CONST)
  877.     return makeexpr_long(ex->val.i);
  878.     if (ex->kind == EK_VAR &&
  879.     (mp = (Meaning *)ex->val.i)->kind == MK_CONST &&
  880.     mp->type == tp_str255)
  881.     return makeexpr_long(mp->val.i);
  882.     if (ex->kind == EK_VAR &&
  883.         (mp = (Meaning *)ex->val.i)->kind == MK_VARPARAM &&
  884.         mp->type == tp_strptr) {
  885.     if (mp->anyvarflag) {
  886.         if (mp->ctx != curctx && mp->ctx->kind == MK_FUNCTION)
  887.         note(format_s("Reference to STRMAX of parent proc's \"%s\" must be fixed [150]",
  888.                   mp->name));
  889.         return makeexpr_name(format_s(name_STRMAX, mp->name), tp_int);
  890.     } else
  891.         note(format_s("STRMAX of \"%s\" wants VarStrings=1 [151]", mp->name));
  892.     }
  893.     ord_range_expr(type->indextype, NULL, &ex2);
  894.     return copyexpr(ex2);
  895. }
  896.  
  897.  
  898.  
  899.  
  900. Expr *makeexpr_nil()
  901. {
  902.     Expr *ex;
  903.  
  904.     ex = makeexpr(EK_CONST, 0);
  905.     ex->val.type = tp_anyptr;
  906.     ex->val.i = 0;
  907.     ex->val.s = NULL;
  908.     return ex;
  909. }
  910.  
  911.  
  912.  
  913. Expr *makeexpr_ctx(ctx)
  914. Meaning *ctx;
  915. {
  916.     Expr *ex;
  917.  
  918.     ex = makeexpr(EK_CTX, 0);
  919.     ex->val.type = tp_text;     /* handy pointer type */
  920.     ex->val.i = (long)ctx;
  921.     return ex;
  922. }
  923.  
  924.  
  925.  
  926.  
  927. Expr *force_signed(ex)
  928. Expr *ex;
  929. {
  930.     Type *tp;
  931.  
  932.     if (isliteralconst(ex, NULL) == 2 && ex->nargs == 0)
  933.         return ex;
  934.     tp = true_type(ex);
  935.     if (tp == tp_ushort || tp == tp_ubyte || tp == tp_uchar)
  936.     return makeexpr_cast(ex, tp_sshort);
  937.     else if (tp == tp_unsigned || tp == tp_uint) {
  938.     if (exprlongness(ex) < 0)
  939.         return makeexpr_cast(ex, tp_sint);
  940.     else
  941.         return makeexpr_cast(ex, tp_integer);
  942.     }
  943.     return ex;
  944. }
  945.  
  946.  
  947.  
  948. Expr *force_unsigned(ex)
  949. Expr *ex;
  950. {
  951.     Type *tp;
  952.  
  953.     if (isliteralconst(ex, NULL) == 2 && !expr_is_neg(ex))
  954.         return ex;
  955.     tp = true_type(ex);
  956.     if (tp == tp_unsigned || tp == tp_uint || tp == tp_ushort ||
  957.     tp == tp_ubyte || tp == tp_uchar)
  958.         return ex;
  959.     if (tp->kind == TK_CHAR)
  960.     return makeexpr_actcast(ex, tp_uchar);
  961.     else if (exprlongness(ex) < 0)
  962.         return makeexpr_cast(ex, tp_uint);
  963.     else
  964.         return makeexpr_cast(ex, tp_unsigned);
  965. }
  966.  
  967.  
  968.  
  969.  
  970. #define CHECKSIZE(size) (((size) > 0 && (size)%charsize == 0) ? (size)/charsize : 0)
  971.  
  972. long type_sizeof(type, pasc)
  973. Type *type;
  974. int pasc;
  975. {
  976.     long s1, smin, smax;
  977.     int charsize = (sizeof_char) ? sizeof_char : CHAR_BIT;      /* from <limits.h> */
  978.  
  979.     switch (type->kind) {
  980.  
  981.         case TK_INTEGER:
  982.             if (type == tp_integer ||
  983.                 type == tp_unsigned)
  984.                 return pasc ? 4 : CHECKSIZE(sizeof_integer);
  985.             else
  986.                 return pasc ? 2 : CHECKSIZE(sizeof_short);
  987.  
  988.         case TK_CHAR:
  989.         case TK_BOOLEAN:
  990.             return 1;
  991.  
  992.         case TK_SUBR:
  993.             type = findbasetype(type, 0);
  994.             if (pasc) {
  995.                 if (type == tp_integer || type == tp_unsigned)
  996.                     return 4;
  997.                 else
  998.                     return 2;
  999.             } else {
  1000.                 if (type == tp_abyte || type == tp_ubyte || type == tp_sbyte)
  1001.                     return 1;
  1002.                 else if (type == tp_ushort || type == tp_sshort)
  1003.                     return CHECKSIZE(sizeof_short);
  1004.                 else
  1005.                     return CHECKSIZE(sizeof_integer);
  1006.             }
  1007.  
  1008.         case TK_POINTER:
  1009.             return pasc ? 4 : CHECKSIZE(sizeof_pointer);
  1010.  
  1011.         case TK_REAL:
  1012.         if (type == tp_longreal)
  1013.         return pasc ? (which_lang == LANG_TURBO ? 6 : 8) : CHECKSIZE(sizeof_double);
  1014.         else
  1015.         return pasc ? 4 : CHECKSIZE(sizeof_float);
  1016.  
  1017.         case TK_ENUM:
  1018.         if (!pasc)
  1019.         return CHECKSIZE(sizeof_enum);
  1020.         type = findbasetype(type, 0);
  1021.             return type->kind != TK_ENUM ? type_sizeof(type, pasc)
  1022.            : CHECKSIZE(pascalenumsize);
  1023.  
  1024.         case TK_SMALLSET:
  1025.         case TK_SMALLARRAY:
  1026.             return pasc ? 0 : type_sizeof(type->basetype, pasc);
  1027.  
  1028.         case TK_ARRAY:
  1029.             s1 = type_sizeof(type->basetype, pasc);
  1030.             if (s1 && ord_range(type->indextype, &smin, &smax))
  1031.                 return s1 * (smax - smin + 1);
  1032.             else
  1033.                 return 0;
  1034.  
  1035.         case TK_RECORD:
  1036.             if (pasc && type->meaning) {
  1037.                 if (!strcmp(type->meaning->sym->name, "NA_WORD"))
  1038.                     return 2;
  1039.                 else if (!strcmp(type->meaning->sym->name, "NA_LONGWORD"))
  1040.                     return 4;
  1041.                 else if (!strcmp(type->meaning->sym->name, "NA_QUADWORD"))
  1042.                     return 8;
  1043.                 else
  1044.                     return 0;
  1045.             } else
  1046.                 return 0;
  1047.  
  1048.         default:
  1049.             return 0;
  1050.     }
  1051. }
  1052.  
  1053.  
  1054.  
  1055. Static Value eval_expr_either(ex, pasc)
  1056. Expr *ex;
  1057. int pasc;
  1058. {
  1059.     Value val, val2;
  1060.     Meaning *mp;
  1061.     int i;
  1062.  
  1063.     if (debug>2) { fprintf(outf,"eval_expr("); dumpexpr(ex); fprintf(outf,")\n"); }
  1064.     switch (ex->kind) {
  1065.  
  1066.         case EK_CONST:
  1067.         case EK_LONGCONST:
  1068.             return ex->val;
  1069.  
  1070.         case EK_VAR:
  1071.             mp = (Meaning *) ex->val.i;
  1072.             if (mp->kind == MK_CONST && 
  1073.                 (foldconsts != 0 ||
  1074.                  mp == mp_maxint || mp == mp_minint))
  1075.                 return mp->val;
  1076.             break;
  1077.  
  1078.         case EK_SIZEOF:
  1079.             i = type_sizeof(ex->args[0]->val.type, pasc);
  1080.             if (i)
  1081.                 return make_ord(tp_integer, i);
  1082.             break;
  1083.  
  1084.         case EK_PLUS:
  1085.             val = eval_expr_either(ex->args[0], pasc);
  1086.             if (!val.type || ord_type(val.type) != tp_integer)
  1087.                 val.type = NULL;
  1088.             for (i = 1; val.type && i < ex->nargs; i++) {
  1089.                 val2 = eval_expr_either(ex->args[i], pasc);
  1090.                 if (!val2.type || ord_type(val2.type) != tp_integer)
  1091.                     val.type = NULL;
  1092.                 else
  1093.                     val.i += val2.i;
  1094.             }
  1095.             return val;
  1096.  
  1097.         case EK_TIMES:
  1098.             val = eval_expr_either(ex->args[0], pasc);
  1099.             if (!val.type || ord_type(val.type) != tp_integer)
  1100.                 val.type = NULL;
  1101.             for (i = 1; val.type && i < ex->nargs; i++) {
  1102.                 val2 = eval_expr_either(ex->args[i], pasc);
  1103.                 if (!val2.type || ord_type(val2.type) != tp_integer)
  1104.                     val.type = NULL;
  1105.                 else
  1106.                     val.i *= val2.i;
  1107.             }
  1108.             return val;
  1109.  
  1110.         case EK_DIV:
  1111.             val = eval_expr_either(ex->args[0], pasc);
  1112.             val2 = eval_expr_either(ex->args[1], pasc);
  1113.             if (val.type && ord_type(val.type) == tp_integer &&
  1114.                 val2.type && ord_type(val2.type) == tp_integer && val2.i) {
  1115.                 val.i /= val2.i;
  1116.                 return val;
  1117.             }
  1118.             break;
  1119.  
  1120.         case EK_MOD:
  1121.             val = eval_expr_either(ex->args[0], pasc);
  1122.             val2 = eval_expr_either(ex->args[1], pasc);
  1123.             if (val.type && ord_type(val.type) == tp_integer &&
  1124.                 val2.type && ord_type(val2.type) == tp_integer && val2.i) {
  1125.                 val.i %= val2.i;
  1126.                 return val;
  1127.             }
  1128.             break;
  1129.  
  1130.         case EK_NEG:
  1131.             val = eval_expr_either(ex->args[0], pasc);
  1132.             if (val.type) {
  1133.                 val.i = -val.i;
  1134.                 return val;
  1135.             }
  1136.             break;
  1137.  
  1138.         case EK_LSH:
  1139.             val = eval_expr_either(ex->args[0], pasc);
  1140.             val2 = eval_expr_either(ex->args[1], pasc);
  1141.             if (val.type && val2.type) {
  1142.                 val.i <<= val2.i;
  1143.                 return val;
  1144.             }
  1145.             break;
  1146.  
  1147.         case EK_RSH:
  1148.             val = eval_expr_either(ex->args[0], pasc);
  1149.             val2 = eval_expr_either(ex->args[1], pasc);
  1150.             if (val.type && val2.type) {
  1151.                 val.i >>= val2.i;
  1152.                 return val;
  1153.             }
  1154.             break;
  1155.  
  1156.         case EK_BAND:
  1157.             val = eval_expr_either(ex->args[0], pasc);
  1158.             val2 = eval_expr_either(ex->args[1], pasc);
  1159.             if (val.type && val2.type) {
  1160.                 val.i &= val2.i;
  1161.                 return val;
  1162.             }
  1163.             break;
  1164.  
  1165.         case EK_BOR:
  1166.             val = eval_expr_either(ex->args[0], pasc);
  1167.             val2 = eval_expr_either(ex->args[1], pasc);
  1168.             if (val.type && val2.type) {
  1169.                 val.i |= val2.i;
  1170.                 return val;
  1171.             }
  1172.             break;
  1173.  
  1174.         case EK_BXOR:
  1175.             val = eval_expr_either(ex->args[0], pasc);
  1176.             val2 = eval_expr_either(ex->args[1], pasc);
  1177.             if (val.type && val2.type) {
  1178.                 val.i ^= val2.i;
  1179.                 return val;
  1180.             }
  1181.             break;
  1182.  
  1183.         case EK_BNOT:
  1184.             val = eval_expr_either(ex->args[0], pasc);
  1185.             if (val.type) {
  1186.                 val.i = ~val.i;
  1187.                 return val;
  1188.             }
  1189.             break;
  1190.  
  1191.         case EK_EQ:
  1192.         case EK_NE:
  1193.         case EK_GT:
  1194.         case EK_LT:
  1195.         case EK_GE:
  1196.         case EK_LE:
  1197.             val = eval_expr_either(ex->args[0], pasc);
  1198.             val2 = eval_expr_either(ex->args[1], pasc);
  1199.             if (val.type) {
  1200.                 if (val.i == val2.i)
  1201.                     val.i = (ex->kind == EK_EQ || ex->kind == EK_GE || ex->kind == EK_LE);
  1202.                 else if (val.i < val2.i)
  1203.                     val.i = (ex->kind == EK_LT || ex->kind == EK_LE || ex->kind == EK_NE);
  1204.                 else
  1205.                     val.i = (ex->kind == EK_GT || ex->kind == EK_GE || ex->kind == EK_NE);
  1206.                 val.type = tp_boolean;
  1207.                 return val;
  1208.             }
  1209.             break;
  1210.  
  1211.         case EK_NOT:
  1212.             val = eval_expr_either(ex->args[0], pasc);
  1213.             if (val.type)
  1214.                 val.i = !val.i;
  1215.             return val;
  1216.  
  1217.         case EK_AND:
  1218.             for (i = 0; i < ex->nargs; i++) {
  1219.                 val = eval_expr_either(ex->args[i], pasc);
  1220.                 if (!val.type || !val.i)
  1221.                     return val;
  1222.             }
  1223.             return val;
  1224.  
  1225.         case EK_OR:
  1226.             for (i = 0; i < ex->nargs; i++) {
  1227.                 val = eval_expr_either(ex->args[i], pasc);
  1228.                 if (!val.type || val.i)
  1229.                     return val;
  1230.             }
  1231.             return val;
  1232.  
  1233.         case EK_COMMA:
  1234.             return eval_expr_either(ex->args[ex->nargs-1], pasc);
  1235.  
  1236.     default:
  1237.         break;
  1238.     }
  1239.     val.type = NULL;
  1240.     return val;
  1241. }
  1242.  
  1243.  
  1244. Value eval_expr(ex)
  1245. Expr *ex;
  1246. {
  1247.     return eval_expr_either(ex, 0);
  1248. }
  1249.  
  1250.  
  1251. Value eval_expr_consts(ex)
  1252. Expr *ex;
  1253. {
  1254.     Value val;
  1255.     short save_fold = foldconsts;
  1256.  
  1257.     foldconsts = 1;
  1258.     val = eval_expr_either(ex, 0);
  1259.     foldconsts = save_fold;
  1260.     return val;
  1261. }
  1262.  
  1263.  
  1264. Value eval_expr_pasc(ex)
  1265. Expr *ex;
  1266. {
  1267.     return eval_expr_either(ex, 1);
  1268. }
  1269.  
  1270.  
  1271.  
  1272. int expr_is_const(ex)
  1273. Expr *ex;
  1274. {
  1275.     int i;
  1276.  
  1277.     switch (ex->kind) {
  1278.  
  1279.         case EK_CONST:
  1280.         case EK_LONGCONST:
  1281.         case EK_SIZEOF:
  1282.             return 1;
  1283.  
  1284.         case EK_VAR:
  1285.             return (((Meaning *)ex->val.i)->kind == MK_CONST);
  1286.  
  1287.         case EK_HAT:
  1288.         case EK_ASSIGN:
  1289.         case EK_POSTINC:
  1290.         case EK_POSTDEC:
  1291.             return 0;
  1292.  
  1293.         case EK_ADDR:
  1294.             if (ex->args[0]->kind == EK_VAR)
  1295.                 return 1;
  1296.             return 0;   /* conservative */
  1297.  
  1298.         case EK_FUNCTION:
  1299.             if (!nosideeffects_func(ex))
  1300.                 return 0;
  1301.             break;
  1302.  
  1303.         case EK_BICALL:
  1304.             if (!nosideeffects_func(ex))
  1305.                 return 0;
  1306.             break;
  1307.  
  1308.     default:
  1309.         break;
  1310.     }
  1311.     for (i = 0; i < ex->nargs; i++) {
  1312.         if (!expr_is_const(ex->args[i]))
  1313.             return 0;
  1314.     }
  1315.     return 1;
  1316. }
  1317.  
  1318.  
  1319.  
  1320.  
  1321.  
  1322. Expr *eatcasts(ex)
  1323. Expr *ex;
  1324. {
  1325.     while (ex->kind == EK_CAST)
  1326.         ex = grabarg(ex, 0);
  1327.     return ex;
  1328. }
  1329.  
  1330.  
  1331.  
  1332.  
  1333.  
  1334. /* End. */
  1335.  
  1336.  
  1337.  
  1338.