home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Professional / OS2PRO194.ISO / os2 / prgramer / pascal2c / pexpr.c < prev    next >
C/C++ Source or Header  |  1992-08-03  |  113KB  |  3,627 lines

  1. /* "p2c", a Pascal to C translator.
  2.    Copyright (C) 1989, 1990, 1991 Free Software Foundation.
  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.  
  19.  
  20. #define PROTO_PEXPR_C
  21. #include "trans.h"
  22.  
  23.  
  24.  
  25.  
  26. Expr *dots_n_hats(ex, target)
  27. Expr *ex;
  28. Type *target;
  29. {
  30.     Expr *ex2, *ex3;
  31.     Type *tp, *tp2;
  32.     Meaning *mp, *tvar;
  33.     int hassl;
  34.  
  35.     for (;;) {
  36.     if ((ex->val.type->kind == TK_PROCPTR ||
  37.          ex->val.type->kind == TK_CPROCPTR) &&
  38.         curtok != TOK_ASSIGN &&
  39.         ((mp = (tp2 = ex->val.type)->basetype->fbase) == NULL ||
  40.          (mp->isreturn && mp->xnext == NULL) ||
  41.          curtok == TOK_LPAR) &&
  42.         (tp2->basetype->basetype != tp_void || target == tp_void) &&
  43.         (!target || (target->kind != TK_PROCPTR &&
  44.              target->kind != TK_CPROCPTR))) {
  45.         hassl = tp2->escale;
  46.         ex2 = ex;
  47.         ex3 = copyexpr(ex2);
  48.         if (hassl != 0)
  49.         ex3 = makeexpr_cast(makeexpr_dotq(ex3, "proc", tp_anyptr),
  50.                     makepointertype(tp2->basetype));
  51.         ex = makeexpr_un(EK_SPCALL, tp2->basetype->basetype, ex3);
  52.         if (mp && mp->isreturn) {  /* pointer to buffer for return value */
  53.         tvar = makestmttempvar(ex->val.type->basetype,
  54.                        (ex->val.type->basetype->kind == TK_STRING) ? name_STRING : name_TEMP);
  55.         insertarg(&ex, 1, makeexpr_addr(makeexpr_var(tvar)));
  56.         mp = mp->xnext;
  57.         }
  58.         if (mp) {
  59.         if (wneedtok(TOK_LPAR)) {
  60.             ex = p_funcarglist(ex, mp, 0, 0);
  61.             skipcloseparen();
  62.         }
  63.         } else if (curtok == TOK_LPAR) {
  64.         gettok();
  65.         if (!wneedtok(TOK_RPAR))
  66.             skippasttoken(TOK_RPAR);
  67.         }
  68.         if (hassl != 1 || hasstaticlinks == 2) {
  69.         freeexpr(ex2);
  70.         } else {
  71.         ex2 = makeexpr_dotq(ex2, "link", tp_anyptr),
  72.         ex3 = copyexpr(ex);
  73.         insertarg(&ex3, ex3->nargs, copyexpr(ex2));
  74.         tp = maketype(TK_FUNCTION);
  75.         tp->basetype = tp2->basetype->basetype;
  76.         tp->fbase = tp2->basetype->fbase;
  77.         tp->issigned = 1;
  78.         ex3->args[0]->val.type = makepointertype(tp);
  79.         ex = makeexpr_cond(makeexpr_rel(EK_NE, ex2, makeexpr_nil()),
  80.                    ex3, ex);
  81.         }
  82.         if (tp2->basetype->fbase &&
  83.         tp2->basetype->fbase->isreturn &&
  84.         tp2->basetype->fbase->kind == MK_VARPARAM)
  85.         ex = makeexpr_hat(ex, 0);    /* returns pointer to structured result */
  86.         continue;
  87.     }
  88.         switch (curtok) {
  89.  
  90.             case TOK_HAT:
  91.         case TOK_ADDR:
  92.                 gettok();
  93.                 ex = makeexpr_hat(ex, 1);
  94.                 break;
  95.  
  96.             case TOK_LBR:
  97.                 do {
  98.                     gettok();
  99.             ex2 = p_ord_expr();
  100.             ex = p_index(ex, ex2);
  101.                 } while (curtok == TOK_COMMA);
  102.                 if (!wneedtok(TOK_RBR))
  103.             skippasttotoken(TOK_RBR, TOK_SEMI);
  104.                 break;
  105.  
  106.             case TOK_DOT:
  107.                 gettok();
  108.                 if (!wexpecttok(TOK_IDENT))
  109.             break;
  110.         if (ex->val.type->kind == TK_STRING) {
  111.             if (!strcicmp(curtokbuf, "LENGTH")) {
  112.             ex = makeexpr_bicall_1("strlen", tp_int, ex);
  113.             } else if (!strcicmp(curtokbuf, "BODY")) {
  114.             /* nothing to do */
  115.             }
  116.             gettok();
  117.             break;
  118.         }
  119.                 mp = curtoksym->fbase;
  120.                 while (mp && mp->rectype != ex->val.type)
  121.                     mp = mp->snext;
  122.                 if (mp)
  123.                     ex = makeexpr_dot(ex, mp);
  124.                 else {
  125.                     warning(format_s("No field called %s in that record [288]", curtokbuf));
  126.             ex = makeexpr_dotq(ex, curtokcase, tp_integer);
  127.         }
  128.                 gettok();
  129.                 break;
  130.  
  131.         case TOK_COLONCOLON:
  132.         gettok();
  133.         if (wexpecttok(TOK_IDENT)) {
  134.             ex = pascaltypecast(curtokmeaning->type, ex);
  135.             gettok();
  136.         }
  137.         break;
  138.  
  139.             default:
  140.                 return ex;
  141.         }
  142.     }
  143. }
  144.  
  145.  
  146. Expr *p_index(ex, ex2)
  147. Expr *ex, *ex2;
  148. {
  149.     Expr *ex3;
  150.     Type *tp, *ot;
  151.     Meaning *mp;
  152.     int bits;
  153.  
  154.     tp = ex->val.type;
  155.     if (tp->kind == TK_STRING) {
  156.     if (checkconst(ex2, 0))   /* is it "s[0]"? */
  157.         return makeexpr_bicall_1("strlen", tp_char, ex);
  158.     else
  159.         return makeexpr_index(ex, ex2, makeexpr_long(1));
  160.     } else if (tp->kind == TK_ARRAY ||
  161.            tp->kind == TK_SMALLARRAY) {
  162.     if (tp->smax) {
  163.         ord_range_expr(tp->indextype, &ex3, NULL);
  164.         ex2 = makeexpr_minus(ex2, copyexpr(ex3));
  165.         if (!nodependencies(ex2, 0) &&
  166.         *getbitsname == '*') {
  167.         mp = makestmttempvar(tp_integer, name_TEMP);
  168.         ex3 = makeexpr_assign(makeexpr_var(mp), ex2);
  169.         ex2 = makeexpr_var(mp);
  170.         } else
  171.         ex3 = NULL;
  172.         ex = makeexpr_bicall_3(getbitsname, tp_int,
  173.                    ex, ex2,
  174.                    makeexpr_long(tp->escale));
  175.         if (tp->kind == TK_ARRAY) {
  176.         if (tp->basetype == tp_sshort)
  177.             bits = 4;
  178.         else
  179.             bits = 3;
  180.         insertarg(&ex, 3, makeexpr_long(bits));
  181.         }
  182.         ex = makeexpr_comma(ex3, ex);
  183.         ot = ord_type(tp->smax->val.type);
  184.         if (ot->kind == TK_ENUM && ot->meaning && useenum)
  185.         ex = makeexpr_cast(ex, tp->smax->val.type);
  186.         ex->val.type = tp->smax->val.type;
  187.         return ex;
  188.     } else {
  189.         ord_range_expr(ex->val.type->indextype, &ex3, NULL);
  190.         if (debug>2) { fprintf(outf, "ord_range_expr returns "); dumpexpr(ex3); fprintf(outf, "\n"); }
  191.         return makeexpr_index(ex, ex2, copyexpr(ex3));
  192.     }
  193.     } else {
  194.     warning("Index on a non-array variable [287]");
  195.     return makeexpr_bin(EK_INDEX, tp_integer, ex, ex2);
  196.     }
  197. }
  198.  
  199.  
  200. Expr *fake_dots_n_hats(ex)
  201. Expr *ex;
  202. {
  203.     for (;;) {
  204.         switch (curtok) {
  205.  
  206.             case TOK_HAT:
  207.         case TOK_ADDR:
  208.             if (ex->val.type->kind == TK_POINTER)
  209.             ex = makeexpr_hat(ex, 0);
  210.         else {
  211.             ex->val.type = makepointertype(ex->val.type);
  212.             ex = makeexpr_un(EK_HAT, ex->val.type->basetype, ex);
  213.         }
  214.                 gettok();
  215.                 break;
  216.  
  217.             case TOK_LBR:
  218.                 do {
  219.                     gettok();
  220.                     ex = makeexpr_bin(EK_INDEX, tp_integer, ex, p_expr(tp_integer));
  221.                 } while (curtok == TOK_COMMA);
  222.                 if (!wneedtok(TOK_RBR))
  223.             skippasttotoken(TOK_RBR, TOK_SEMI);
  224.                 break;
  225.  
  226.             case TOK_DOT:
  227.                 gettok();
  228.                 if (!wexpecttok(TOK_IDENT))
  229.             break;
  230.                 ex = makeexpr_dotq(ex, curtokcase, tp_integer);
  231.                 gettok();
  232.                 break;
  233.  
  234.         case TOK_COLONCOLON:
  235.         gettok();
  236.         if (wexpecttok(TOK_IDENT)) {
  237.             ex = pascaltypecast(curtokmeaning->type, ex);
  238.             gettok();
  239.         }
  240.         break;
  241.  
  242.             default:
  243.                 return ex;
  244.         }
  245.     }
  246. }
  247.  
  248.  
  249.  
  250. Static void bindnames(ex)
  251. Expr *ex;
  252. {
  253.     int i;
  254.     Symbol *sp;
  255.     Meaning *mp;
  256.  
  257.     if (ex->kind == EK_NAME) {
  258.     sp = findsymbol_opt(fixpascalname(ex->val.s));
  259.     if (sp) {
  260.         mp = sp->mbase;
  261.         while (mp && !mp->isactive)
  262.         mp = mp->snext;
  263.         if (mp && !strcmp(mp->name, ex->val.s)) {
  264.         ex->kind = EK_VAR;
  265.         ex->val.i = (long)mp;
  266.         ex->val.type = mp->type;
  267.         }
  268.     }
  269.     }
  270.     i = ex->nargs;
  271.     while (--i >= 0)
  272.     bindnames(ex->args[i]);
  273. }
  274.  
  275.  
  276.  
  277. void var_reference(mp)
  278. Meaning *mp;
  279. {
  280.     Meaning *mp2;
  281.  
  282.     mp->refcount++;
  283.     if (mp->ctx && mp->ctx->kind == MK_FUNCTION &&
  284.     mp->ctx->needvarstruct &&
  285.     (mp->kind == MK_VAR ||
  286.      mp->kind == MK_VARREF ||
  287.      mp->kind == MK_VARMAC ||
  288.      mp->kind == MK_PARAM ||
  289.      mp->kind == MK_VARPARAM ||
  290.      (mp->kind == MK_CONST &&
  291.       (mp->type->kind == TK_ARRAY ||
  292.        mp->type->kind == TK_RECORD)))) {
  293.         if (debug>1) { fprintf(outf, "varstruct'ing %s\n", mp->name); }
  294.         if (!mp->varstructflag) {
  295.             mp->varstructflag = 1;
  296.             if (mp->constdefn &&      /* move init code into function body */
  297.         mp->kind != MK_VARMAC) {
  298.                 mp2 = addmeaningafter(mp, curtoksym, MK_VAR);
  299.                 curtoksym->mbase = mp2->snext;  /* hide this fake variable */
  300.                 mp2->snext = mp;      /* remember true variable */
  301.                 mp2->type = mp->type;
  302.                 mp2->constdefn = mp->constdefn;
  303.                 mp2->isforward = 1;   /* declare it "static" */
  304.                 mp2->refcount++;      /* so it won't be purged! */
  305.                 mp->constdefn = NULL;
  306.                 mp->isforward = 0;
  307.             }
  308.         }
  309.         for (mp2 = curctx->ctx; mp2 != mp->ctx; mp2 = mp2->ctx)
  310.             mp2->varstructflag = 1;
  311.         mp2->varstructflag = 1;
  312.     }
  313. }
  314.  
  315.  
  316.  
  317. Static Expr *p_variable(target)
  318. Type *target;
  319. {
  320.     Expr *ex, *ex2;
  321.     Meaning *mp;
  322.     Symbol *sym;
  323.  
  324.     if (curtok != TOK_IDENT) {
  325.         warning("Expected a variable [289]");
  326.     return makeexpr_long(0);
  327.     }
  328.     if (!curtokmeaning) {
  329.     sym = curtoksym;
  330.         ex = makeexpr_name(curtokcase, tp_integer);
  331.         gettok();
  332.         if (curtok == TOK_LPAR) {
  333.             ex = makeexpr_bicall_0(ex->val.s, tp_integer);
  334.             do {
  335.                 gettok();
  336.                 insertarg(&ex, ex->nargs, p_expr(NULL));
  337.             } while (curtok == TOK_COMMA || curtok == TOK_ASSIGN);
  338.             if (!wneedtok(TOK_RPAR))
  339.         skippasttotoken(TOK_RPAR, TOK_SEMI);
  340.         }
  341.     if (!tryfuncmacro(&ex, NULL))
  342.         undefsym(sym);
  343.         return fake_dots_n_hats(ex);
  344.     }
  345.     var_reference(curtokmeaning);
  346.     mp = curtokmeaning;
  347.     if (mp->kind == MK_FIELD) {
  348.         ex = makeexpr_dot(copyexpr(withexprs[curtokint]), mp);
  349.     } else if (mp->kind == MK_CONST &&
  350.            mp->type->kind == TK_SET &&
  351.            mp->constdefn) {
  352.     ex = copyexpr(mp->constdefn);
  353.     mp = makestmttempvar(ex->val.type, name_SET);
  354.         ex2 = makeexpr(EK_MACARG, 0);
  355.         ex2->val.type = ex->val.type;
  356.     ex = replaceexprexpr(ex, ex2, makeexpr_var(mp), 0);
  357.         freeexpr(ex2);
  358.     } else if (mp->kind == MK_CONST &&
  359.                (mp == mp_false ||
  360.                 mp == mp_true ||
  361.                 mp->anyvarflag ||
  362.                 (foldconsts > 0 &&
  363.                  (mp->type->kind == TK_INTEGER ||
  364.                   mp->type->kind == TK_BOOLEAN ||
  365.                   mp->type->kind == TK_CHAR ||
  366.                   mp->type->kind == TK_ENUM ||
  367.                   mp->type->kind == TK_SUBR ||
  368.                   mp->type->kind == TK_REAL)) ||
  369.                 (foldstrconsts > 0 &&
  370.                  (mp->type->kind == TK_STRING)))) {
  371.         if (mp->constdefn) {
  372.             ex = copyexpr(mp->constdefn);
  373.             if (ex->val.type == tp_int)   /* kludge! */
  374.                 ex->val.type = tp_integer;
  375.         } else
  376.             ex = makeexpr_val(copyvalue(mp->val));
  377.     } else if (mp->kind == MK_VARPARAM ||
  378.                mp->kind == MK_VARREF) {
  379.         ex = makeexpr_hat(makeexpr_var(mp), 0);
  380.     } else if (mp->kind == MK_VARMAC) {
  381.         ex = copyexpr(mp->constdefn);
  382.     bindnames(ex);
  383.         ex = gentle_cast(ex, mp->type);
  384.         ex->val.type = mp->type;
  385.     } else if (mp->kind == MK_SPVAR && mp->handler) {
  386.         gettok();
  387.         ex = (*mp->handler)(mp);
  388.         return dots_n_hats(ex, target);
  389.     } else if (mp->kind == MK_VAR ||
  390.                mp->kind == MK_CONST ||
  391.                mp->kind == MK_PARAM) {
  392.         ex = makeexpr_var(mp);
  393.     } else {
  394.         symclass(mp->sym);
  395.         ex = makeexpr_name(mp->name, tp_integer);
  396.     }
  397.     gettok();
  398.     return dots_n_hats(ex, target);
  399. }
  400.  
  401.  
  402.  
  403.  
  404. Expr *p_ord_expr()
  405. {
  406.     return makeexpr_charcast(p_expr(tp_integer));
  407. }
  408.  
  409.  
  410.  
  411. Static Expr *makesmallsetconst(bits, type)
  412. long bits;
  413. Type *type;
  414. {
  415.     Expr *ex;
  416.  
  417.     ex = makeexpr_long(bits);
  418.     ex->val.type = type;
  419.     if (smallsetconst != 2)
  420.         insertarg(&ex, 0, makeexpr_name("%#lx", tp_integer));
  421.     return ex;
  422. }
  423.  
  424.  
  425.  
  426. Expr *packset(ex, type)
  427. Expr *ex;
  428. Type *type;
  429. {
  430.     Meaning *mp;
  431.     Expr *ex2;
  432.     long max2;
  433.  
  434.     if (ex->kind == EK_BICALL) {
  435.         if (!strcmp(ex->val.s, setexpandname) &&
  436.             (mp = istempvar(ex->args[0])) != NULL) {
  437.             canceltempvar(mp);
  438.             return grabarg(ex, 1);
  439.         }
  440.         if (!strcmp(ex->val.s, setunionname) &&
  441.             (mp = istempvar(ex->args[0])) != NULL &&
  442.             !exproccurs(ex->args[1], ex->args[0]) &&
  443.             !exproccurs(ex->args[2], ex->args[0])) {
  444.             canceltempvar(mp);
  445.             return makeexpr_bin(EK_BOR, type, packset(ex->args[1], type),
  446.                                               packset(ex->args[2], type));
  447.         }
  448.         if (!strcmp(ex->val.s, setaddname)) {
  449.             ex2 = makeexpr_bin(EK_LSH, type,
  450.                                makeexpr_longcast(makeexpr_long(1), 1),
  451.                                ex->args[1]);
  452.             ex = packset(ex->args[0], type);
  453.             if (checkconst(ex, 0))
  454.                 return ex2;
  455.             else
  456.                 return makeexpr_bin(EK_BOR, type, ex, ex2);
  457.         }
  458.         if (!strcmp(ex->val.s, setaddrangename)) {
  459.             if (ord_range(type->indextype, NULL, &max2) && max2 == setbits-1)
  460.                 note("Range construction was implemented by a subtraction which may overflow [278]");
  461.             ex2 = makeexpr_minus(makeexpr_bin(EK_LSH, type,
  462.                                               makeexpr_longcast(makeexpr_long(1), 1),
  463.                                               makeexpr_plus(ex->args[2],
  464.                                                             makeexpr_long(1))),
  465.                                  makeexpr_bin(EK_LSH, type,
  466.                                               makeexpr_longcast(makeexpr_long(1), 1),
  467.                                               ex->args[1]));
  468.             ex = packset(ex->args[0], type);
  469.             if (checkconst(ex, 0))
  470.                 return ex2;
  471.             else
  472.                 return makeexpr_bin(EK_BOR, type, ex, ex2);
  473.         }
  474.     }
  475.     return makeexpr_bicall_1(setpackname, type, ex);
  476. }
  477.  
  478.  
  479.  
  480. #define MAXSETLIT 400
  481.  
  482. Expr *p_setfactor(target, sure)
  483. Type *target;
  484. int sure;
  485. {
  486.     Expr *ex, *exmax = NULL, *ex2;
  487.     Expr *first[MAXSETLIT], *last[MAXSETLIT];
  488.     char doneflag[MAXSETLIT];
  489.     int i, j, num, donecount;
  490.     int isconst, guesstype;
  491.     long maxv, max2;
  492.     Value val;
  493.     Type *tp, *type;
  494.     Meaning *tvar;
  495.  
  496.     if (curtok == TOK_LBRACE)
  497.     gettok();
  498.     else if (!wneedtok(TOK_LBR))
  499.     return makeexpr_long(0);
  500.     if (curtok == TOK_RBR || curtok == TOK_RBRACE) {        /* empty set */
  501.         gettok();
  502.         val.type = tp_smallset;
  503.         val.i = 0;
  504.         val.s = NULL;
  505.         return makeexpr_val(val);
  506.     }
  507.     type = target;
  508.     guesstype = !sure;
  509.     maxv = -1;
  510.     isconst = 1;
  511.     num = 0;
  512.     for (;;) {
  513.         if (num >= MAXSETLIT) {
  514.             warning(format_d("Too many elements in set literal; max=%d [290]", MAXSETLIT));
  515.             ex = p_expr(type);
  516.             while (curtok != TOK_RBR && curtok != TOK_RBRACE) {
  517.                 gettok();
  518.                 ex = p_expr(type);
  519.             }
  520.             break;
  521.         }
  522.         if (guesstype && num == 0) {
  523.             ex = p_ord_expr();
  524.         type = ex->val.type;
  525.         } else {
  526.             ex = p_expr(type);
  527.         }
  528.         first[num] = ex = gentle_cast(ex, type);
  529.         doneflag[num] = 0;
  530.         if (curtok == TOK_DOTS || curtok == TOK_COLON) {   /* UCSD? */
  531.             val = eval_expr(ex);
  532.             if (val.type) {
  533.         if (val.i > maxv) {     /* In case of [127..0] */
  534.             maxv = val.i;
  535.             exmax = ex;
  536.         }
  537.         } else
  538.                 isconst = 0;
  539.             gettok();
  540.             last[num] = ex = gentle_cast(p_expr(type), type);
  541.         } else {
  542.             last[num] = NULL;
  543.         }
  544.         val = eval_expr(ex);
  545.         if (val.type) {
  546.             if (val.i > maxv) {
  547.                 maxv = val.i;
  548.                 exmax = ex;
  549.             }
  550.         } else {
  551.             isconst = 0;
  552.             maxv = LONG_MAX;
  553.         }
  554.         num++;
  555.         if (curtok == TOK_COMMA)
  556.             gettok();
  557.         else
  558.             break;
  559.     }
  560.     if (curtok == TOK_RBRACE)
  561.     gettok();
  562.     else if (!wneedtok(TOK_RBR))
  563.     skippasttotoken(TOK_RBR, TOK_SEMI);
  564.     tp = first[0]->val.type;
  565.     if (guesstype) {      /* must determine type */
  566.         if (maxv == LONG_MAX) {
  567.         if (target && ord_range(target, NULL, &max2))
  568.         maxv = max2;
  569.             else if (ord_range(tp, NULL, &max2) && max2 < 1000000 &&
  570.              (max2 >= defaultsetsize || num == 1))
  571.                 maxv = max2;
  572.         else
  573.         maxv = defaultsetsize-1;
  574.             exmax = makeexpr_long(maxv);
  575.         } else
  576.             exmax = copyexpr(exmax);
  577.         if (!ord_range(tp, NULL, &max2) || maxv != max2)
  578.             tp = makesubrangetype(tp, makeexpr_long(0), exmax);
  579.         type = makesettype(tp);
  580.     } else
  581.     type = makesettype(type);
  582.     donecount = 0;
  583.     if (smallsetconst > 0) {
  584.         val.i = 0;
  585.         for (i = 0; i < num; i++) {
  586.             if (first[i]->kind == EK_CONST && first[i]->val.i < setbits &&
  587.                 (!last[i] || (last[i]->kind == EK_CONST &&
  588.                               last[i]->val.i >= 0 &&
  589.                               last[i]->val.i < setbits))) {
  590.                 if (last[i]) {
  591.                     for (j = first[i]->val.i; j <= last[i]->val.i; j++)
  592.                         val.i |= 1<<j;
  593.                 } else
  594.             val.i |= 1 << first[i]->val.i;
  595.                 doneflag[i] = 1;
  596.                 donecount++;
  597.             }
  598.         }
  599.     }
  600.     if (donecount) {
  601.         ex = makesmallsetconst(val.i, tp_smallset);
  602.     } else
  603.         ex = NULL;
  604.     if (type->kind == TK_SMALLSET) {
  605.         for (i = 0; i < num; i++) {
  606.             if (!doneflag[i]) {
  607.                 ex2 = makeexpr_bin(EK_LSH, type,
  608.                    makeexpr_longcast(makeexpr_long(1), 1),
  609.                    enum_to_int(first[i]));
  610.                 if (last[i]) {
  611.                     if (ord_range(type->indextype, NULL, &max2) && max2 == setbits-1)
  612.                         note("Range construction was implemented by a subtraction which may overflow [278]");
  613.                     ex2 = makeexpr_minus(makeexpr_bin(EK_LSH, type,
  614.                                                       makeexpr_longcast(makeexpr_long(1), 1),
  615.                                                       makeexpr_plus(enum_to_int(last[i]),
  616.                                                                     makeexpr_long(1))),
  617.                                          ex2);
  618.                 }
  619.                 if (ex)
  620.                     ex = makeexpr_bin(EK_BOR, type, makeexpr_longcast(ex, 1), ex2);
  621.                 else
  622.                     ex = ex2;
  623.             }
  624.         }
  625.     } else {
  626.         tvar = makestmttempvar(type, name_SET);
  627.         if (!ex) {
  628.             val.type = tp_smallset;
  629.         val.i = 0;
  630.         val.s = NULL;
  631.         ex = makeexpr_val(val);
  632.     }
  633.         ex = makeexpr_bicall_2(setexpandname, type,
  634.                                makeexpr_var(tvar), makeexpr_arglong(ex, 1));
  635.         for (i = 0; i < num; i++) {
  636.             if (!doneflag[i]) {
  637.                 if (last[i])
  638.                     ex = makeexpr_bicall_3(setaddrangename, type,
  639.                                            ex, makeexpr_arglong(enum_to_int(first[i]), 0),
  640.                                                makeexpr_arglong(enum_to_int(last[i]), 0));
  641.                 else
  642.                     ex = makeexpr_bicall_2(setaddname, type,
  643.                                            ex, makeexpr_arglong(enum_to_int(first[i]), 0));
  644.             }
  645.         }
  646.     }
  647.     return ex;
  648. }
  649.  
  650.  
  651.  
  652.  
  653. Expr *p_funcarglist(ex, args, firstarg, ismacro)
  654. Expr *ex;
  655. Meaning *args;
  656. int firstarg, ismacro;
  657. {
  658.     Meaning *mp, *mp2, *arglist = args, *prevarg = NULL;
  659.     Expr *ex2;
  660.     int i, fi, fakenum = -1, castit, isconf, isnonpos = 0;
  661.     Type *tp, *tp2;
  662.     char *name;
  663.  
  664.     castit = castargs;
  665.     if (castit < 0)
  666.     castit = (prototypes == 0);
  667.     while (args) {
  668.     if (isnonpos) {
  669.         while (curtok == TOK_COMMA)
  670.         gettok();
  671.         if (curtok == TOK_RPAR) {
  672.         args = arglist;
  673.         i = firstarg;
  674.         while (args) {
  675.             if (ex->nargs <= i)
  676.             insertarg(&ex, ex->nargs, NULL);
  677.             if (!ex->args[i]) {
  678.             if (args->constdefn)
  679.                 ex->args[i] = copyexpr(args->constdefn);
  680.             else {
  681.                 warning(format_s("Missing value for parameter %s [291]",
  682.                          args->name));
  683.                 ex->args[i] = makeexpr_long(0);
  684.             }
  685.             }
  686.             args = args->xnext;
  687.             i++;
  688.         }
  689.         break;
  690.         }
  691.     }
  692.     if (args->isreturn || args->fakeparam) {
  693.         if (args->fakeparam) {
  694.         if (fakenum < 0)
  695.             fakenum = ex->nargs;
  696.         if (args->constdefn)
  697.             insertarg(&ex, ex->nargs, copyexpr(args->constdefn));
  698.         else
  699.             insertarg(&ex, ex->nargs, makeexpr_long(0));
  700.         }
  701.         args = args->xnext;     /* return value parameter */
  702.         continue;
  703.     }
  704.     if (curtok == TOK_RPAR) {
  705.         if (args->constdefn) {
  706.         insertarg(&ex, ex->nargs, copyexpr(args->constdefn));
  707.         args = args->xnext;
  708.         continue;
  709.         } else {
  710.         if (ex->kind == EK_FUNCTION) {
  711.             name = ((Meaning *)ex->val.i)->name;
  712.             ex->kind = EK_BICALL;
  713.             ex->val.s = stralloc(name);
  714.         } else
  715.             name = "function";
  716.         warning(format_s("Too few arguments for %s [292]", name));
  717.         return ex;
  718.         }
  719.     }
  720.     if (curtok == TOK_COMMA) {
  721.         if (args->constdefn)
  722.         insertarg(&ex, ex->nargs, copyexpr(args->constdefn));
  723.         else {
  724.         warning(format_s("Missing parameter %s [293]", args->name));
  725.         insertarg(&ex, ex->nargs, makeexpr_long(0));
  726.         }
  727.         gettok();
  728.         args = args->xnext;
  729.         continue;
  730.     }
  731.     p_mech_spec(0);
  732.     if (curtok == TOK_IDENT) {
  733.         mp = arglist;
  734.         mp2 = NULL;
  735.         i = firstarg;
  736.         fi = -1;
  737.         while (mp && strcmp(curtokbuf, mp->sym->name)) {
  738.         if (mp->fakeparam) {
  739.             if (fi < 0)
  740.             fi = i;
  741.         } else
  742.             fi = -1;
  743.         i++;
  744.         mp2 = mp;
  745.         mp = mp->xnext;
  746.         }
  747.         if (mp &&
  748.         (peeknextchar() == ':' || !curtokmeaning || isnonpos)) {
  749.         gettok();
  750.         wneedtok(TOK_ASSIGN);
  751.         prevarg = mp2;
  752.         args = mp;
  753.         fakenum = fi;
  754.         isnonpos = 1;
  755.         } else
  756.         i = ex->nargs;
  757.     } else
  758.         i = ex->nargs;
  759.     while (ex->nargs <= i)
  760.         insertarg(&ex, ex->nargs, NULL);
  761.     if (ex->args[i])
  762.         warning(format_s("Multiple values for parameter %s [294]",
  763.                  args->name));
  764.     tp = args->type;
  765.     ex2 = p_expr(tp);
  766.     if (args->kind == MK_VARPARAM)
  767.         tp = tp->basetype;
  768.     if (isfiletype(tp, 1) && is_std_file(ex2)) {
  769.         mp2 = makestmttempvar(tp_bigtext, name_TEMP);
  770.         ex2 = makeexpr_comma(
  771.            makeexpr_comma(makeexpr_assign(filebasename(makeexpr_var(mp2)),
  772.                           ex2),
  773.                   makeexpr_assign(filenamepart(makeexpr_var(mp2)),
  774.                           makeexpr_string(""))),
  775.                  makeexpr_var(mp2));
  776.     }
  777.     tp2 = ex2->val.type;
  778.     isconf = ((tp->kind == TK_ARRAY ||
  779.            tp->kind == TK_STRING) && tp->structdefd);
  780.         switch (args->kind) {
  781.  
  782.             case MK_PARAM:
  783.             if (castit && tp->kind == TK_REAL &&
  784.             ex2->val.type->kind != TK_REAL)
  785.                     ex2 = makeexpr_cast(ex2, tp);
  786.                 else if (ord_type(tp)->kind == TK_INTEGER && !ismacro)
  787.                     ex2 = makeexpr_arglong(ex2, long_type(tp));
  788.                 else if (args->othername && args->rectype != tp &&
  789.                          tp->kind != TK_STRING && args->type == tp2)
  790.                     ex2 = makeexpr_addr(ex2);
  791.                 else
  792.                     ex2 = gentle_cast(ex2, tp);
  793.         ex->args[i] = ex2;
  794.                 break;
  795.  
  796.             case MK_VARPARAM:
  797.                 if (args->type == tp_strptr && args->anyvarflag) {
  798.             ex->args[i] = strmax_func(ex2);
  799.                     insertarg(&ex, ex->nargs-1, makeexpr_addr(ex2));
  800.             if (isnonpos)
  801.             note("Non-positional conformant parameters may not work [279]");
  802.                 } else {                        /* regular VAR parameter */
  803.             if (!expr_is_lvalue(ex2) ||
  804.             (tp->kind == TK_REAL &&
  805.              ord_type(tp2)->kind == TK_INTEGER)) {
  806.             mp2 = makestmttempvar(tp, name_TEMP);
  807.             ex2 = makeexpr_comma(makeexpr_assign(makeexpr_var(mp2),
  808.                                  ex2),
  809.                          makeexpr_addrf(makeexpr_var(mp2)));
  810.             } else
  811.             ex2 = makeexpr_addrf(ex2);
  812.                     if (args->anyvarflag ||
  813.                         (tp->kind == TK_POINTER && tp2->kind == TK_POINTER &&
  814.                          (tp == tp_anyptr || tp2 == tp_anyptr))) {
  815.             if (!ismacro)
  816.                 ex2 = makeexpr_cast(ex2, args->type);
  817.                     } else {
  818.                         if (tp2 != tp && !isconf &&
  819.                 (tp2->kind != TK_STRING ||
  820.                  tp->kind != TK_STRING))
  821.                             warning(format_s("Type mismatch in VAR parameter %s [295]",
  822.                                              args->name));
  823.                     }
  824.             ex->args[i] = ex2;
  825.                 }
  826.                 break;
  827.  
  828.         default:
  829.         intwarning("p_funcarglist",
  830.                format_s("Parameter type is %s [296]",
  831.                     meaningkindname(args->kind)));
  832.         break;
  833.         }
  834.     if (isconf &&   /* conformant array or string */
  835.         (!prevarg || prevarg->type != args->type)) {
  836.         while (tp->kind == TK_ARRAY && tp->structdefd) {
  837.         if (tp2->kind == TK_SMALLARRAY) {
  838.             warning("Trying to pass a small-array for a conformant array [297]");
  839.             /* this has a chance of working... */
  840.             ex->args[ex->nargs-1] =
  841.             makeexpr_addr(ex->args[ex->nargs-1]);
  842.         } else if (tp2->kind == TK_STRING) {
  843.             ex->args[fakenum++] =
  844.             makeexpr_arglong(makeexpr_long(1), integer16 == 0);
  845.             ex->args[fakenum++] =
  846.             makeexpr_arglong(strmax_func(ex->args[ex->nargs-1]),
  847.                      integer16 == 0);
  848.             break;
  849.             } else if (tp2->kind != TK_ARRAY) {
  850.             warning("Type mismatch for conformant array [298]");
  851.             break;
  852.         }
  853.         ex->args[fakenum++] =
  854.             makeexpr_arglong(copyexpr(tp2->indextype->smin),
  855.                      integer16 == 0);
  856.         ex->args[fakenum++] =
  857.             makeexpr_arglong(copyexpr(tp2->indextype->smax),
  858.                      integer16 == 0);
  859.         tp = tp->basetype;
  860.         tp2 = tp2->basetype;
  861.         }
  862.         if (tp->kind == TK_STRING && tp->structdefd) {
  863.         ex->args[fakenum] =
  864.             makeexpr_arglong(strmax_func(ex->args[ex->nargs-1]),
  865.                      integer16 == 0);
  866.         }
  867.     }
  868.     fakenum = -1;
  869.     if (!isnonpos) {
  870.         prevarg = args;
  871.         args = args->xnext;
  872.         if (args) {
  873.         if (curtok != TOK_RPAR && !wneedtok(TOK_COMMA))
  874.             skiptotoken2(TOK_RPAR, TOK_SEMI);
  875.         }
  876.     }
  877.     }
  878.     if (curtok == TOK_COMMA) {
  879.     if (ex->kind == EK_FUNCTION) {
  880.         name = ((Meaning *)ex->val.i)->name;
  881.         ex->kind = EK_BICALL;
  882.         ex->val.s = stralloc(name);
  883.     } else
  884.         name = "function";
  885.     warning(format_s("Too many arguments for %s [299]", name));
  886.     while (curtok == TOK_COMMA) {
  887.         gettok();
  888.         insertarg(&ex, ex->nargs, p_expr(tp_integer));
  889.     }
  890.     }
  891.     return ex;
  892. }
  893.  
  894.  
  895.  
  896. Expr *replacemacargs(ex, fex)
  897. Expr *ex, *fex;
  898. {
  899.     int i;
  900.     Expr *ex2;
  901.  
  902.     for (i = 0; i < ex->nargs; i++)
  903.         ex->args[i] = replacemacargs(ex->args[i], fex);
  904.     if (ex->kind == EK_MACARG) {
  905.     if (ex->val.i <= fex->nargs) {
  906.         ex2 = copyexpr(fex->args[ex->val.i - 1]);
  907.     } else {
  908.         ex2 = makeexpr_name("<meef>", tp_integer);
  909.         note("FuncMacro specified more arguments than call [280]");
  910.     }
  911.     freeexpr(ex);
  912.     return ex2;
  913.     }
  914.     return resimplify(ex);
  915. }
  916.  
  917.  
  918. Expr *p_noarglist(ex, mp, args)
  919. Expr *ex;
  920. Meaning *mp, *args;
  921. {
  922.     while (args && args->constdefn) {
  923.     insertarg(&ex, ex->nargs, copyexpr(args->constdefn));
  924.     args = args->xnext;
  925.     }
  926.     if (args) {
  927.     warning(format_s("Expected an argument list for %s [300]", mp->name));
  928.     ex->kind = EK_BICALL;
  929.     ex->val.s = stralloc(mp->name);
  930.     }
  931.     return ex;
  932. }
  933.  
  934.  
  935. void func_reference(func)
  936. Meaning *func;
  937. {
  938.     Meaning *mp;
  939.  
  940.     if (func->ctx && func->ctx != curctx &&func->ctx->kind == MK_FUNCTION &&
  941.     func->ctx->varstructflag && !curctx->ctx->varstructflag) {
  942.     for (mp = curctx->ctx; mp != func->ctx; mp = mp->ctx)
  943.         mp->varstructflag = 1;
  944.     }
  945. }
  946.  
  947.  
  948. Expr *p_funccall(mp)
  949. Meaning *mp;
  950. {
  951.     Meaning *mp2, *tvar;
  952.     Expr *ex, *ex2;
  953.     int firstarg = 0;
  954.  
  955.     func_reference(mp);
  956.     ex = makeexpr(EK_FUNCTION, 0);
  957.     ex->val.i = (long)mp;
  958.     ex->val.type = mp->type->basetype;
  959.     mp2 = mp->type->fbase;
  960.     if (mp2 && mp2->isreturn) {    /* pointer to buffer for return value */
  961.         tvar = makestmttempvar(ex->val.type->basetype,
  962.             (ex->val.type->basetype->kind == TK_STRING) ? name_STRING : name_TEMP);
  963.         insertarg(&ex, 0, makeexpr_addr(makeexpr_var(tvar)));
  964.         mp2 = mp2->xnext;
  965.     firstarg++;
  966.     }
  967.     if (mp2 && curtok != TOK_LPAR) {
  968.     ex = p_noarglist(ex, mp, mp2);
  969.     } else if (curtok == TOK_LPAR) {
  970.     gettok();
  971.         ex = p_funcarglist(ex, mp2, firstarg, (mp->constdefn != NULL));
  972.         skipcloseparen();
  973.     }
  974.     if (mp->constdefn) {
  975.         ex2 = replacemacargs(copyexpr(mp->constdefn), ex);
  976.     ex2 = gentle_cast(ex2, ex->val.type);
  977.     ex2->val.type = ex->val.type;
  978.         freeexpr(ex);
  979.         return ex2;
  980.     }
  981.     return ex;
  982. }
  983.  
  984.  
  985.  
  986.  
  987.  
  988.  
  989. Expr *accumulate_strlit()
  990. {
  991.     char buf[256], ch, *cp, *cp2;
  992.     int len, i, danger = 0;
  993.  
  994.     len = 0;
  995.     cp = buf;
  996.     for (;;) {
  997.         if (curtok == TOK_STRLIT) {
  998.             cp2 = curtokbuf;
  999.             i = curtokint;
  1000.             while (--i >= 0) {
  1001.                 if (++len <= 255) {
  1002.                     ch = *cp++ = *cp2++;
  1003.                     if (ch & 128)
  1004.                         danger++;
  1005.                 }
  1006.             }
  1007.         } else if (curtok == TOK_HAT) {    /* Turbo */
  1008.             i = getchartok() & 0x1f;
  1009.             if (++len <= 255)
  1010.                 *cp++ = i;
  1011.     } else if (curtok == TOK_LPAR) {   /* VAX */
  1012.         Value val;
  1013.         do {
  1014.         gettok();
  1015.         val = p_constant(tp_integer);
  1016.         if (++len <= 255)
  1017.             *cp++ = val.i;
  1018.         } while (curtok == TOK_COMMA);
  1019.         skipcloseparen();
  1020.         continue;
  1021.         } else
  1022.             break;
  1023.         gettok();
  1024.     }
  1025.     if (len > 255) {
  1026.         warning("String literal too long [301]");
  1027.         len = 255;
  1028.     }
  1029.     if (danger &&
  1030.         !(unsignedchar == 1 ||
  1031.           (unsignedchar != 0 && signedchars == 0)))
  1032.         note(format_s("Character%s >= 128 encountered [281]", (danger > 1) ? "s" : ""));
  1033.     return makeexpr_lstring(buf, len);
  1034. }
  1035.  
  1036.  
  1037.  
  1038. Expr *pascaltypecast(type, ex2)
  1039. Type *type;
  1040. Expr *ex2;
  1041. {
  1042.     if (type->kind == TK_POINTER || type->kind == TK_STRING ||
  1043.     type->kind == TK_ARRAY)
  1044.     ex2 = makeexpr_stringcast(ex2);
  1045.     else
  1046.     ex2 = makeexpr_charcast(ex2);
  1047.     if ((ex2->val.type->kind == TK_INTEGER ||
  1048.      ex2->val.type->kind == TK_CHAR ||
  1049.      ex2->val.type->kind == TK_BOOLEAN ||
  1050.      ex2->val.type->kind == TK_ENUM ||
  1051.      ex2->val.type->kind == TK_SUBR ||
  1052.      ex2->val.type->kind == TK_REAL ||
  1053.      ex2->val.type->kind == TK_POINTER ||
  1054.      ex2->val.type->kind == TK_STRING) &&
  1055.     (type->kind == TK_INTEGER ||
  1056.      type->kind == TK_CHAR ||
  1057.      type->kind == TK_BOOLEAN ||
  1058.      type->kind == TK_ENUM ||
  1059.      type->kind == TK_SUBR ||
  1060.      type->kind == TK_REAL ||
  1061.      type->kind == TK_POINTER)) {
  1062.     if (type->kind == TK_POINTER || ex2->val.type->kind == TK_POINTER)
  1063.         return makeexpr_un(EK_CAST, type, ex2);
  1064.     else
  1065.         return makeexpr_un(EK_ACTCAST, type, ex2);
  1066.     } else {
  1067.     return makeexpr_hat(makeexpr_cast(makeexpr_addr(ex2),
  1068.                       makepointertype(type)), 0);
  1069.     }
  1070. }
  1071.  
  1072.  
  1073.  
  1074.  
  1075. Static Expr *p_factor(target)
  1076. Type *target;
  1077. {
  1078.     Expr *ex, *ex2;
  1079.     Type *type;
  1080.     Meaning *mp, *mp2;
  1081.  
  1082.     switch (curtok) {
  1083.  
  1084.         case TOK_INTLIT:
  1085.             ex = makeexpr_long(curtokint);
  1086.             gettok();
  1087.             return ex;
  1088.  
  1089.         case TOK_HEXLIT:
  1090.             ex = makeexpr_long(curtokint);
  1091.             insertarg(&ex, 0, makeexpr_name("%#lx", tp_integer));
  1092.             gettok();
  1093.             return ex;
  1094.  
  1095.         case TOK_OCTLIT:
  1096.             ex = makeexpr_long(curtokint);
  1097.             insertarg(&ex, 0, makeexpr_name("%#lo", tp_integer));
  1098.             gettok();
  1099.             return ex;
  1100.  
  1101.         case TOK_MININT:
  1102.         strcat(curtokbuf, ".0");
  1103.  
  1104.     /* fall through */
  1105.         case TOK_REALLIT:
  1106.             ex = makeexpr_real(curtokbuf);
  1107.             gettok();
  1108.             return ex;
  1109.  
  1110.         case TOK_HAT:
  1111.         case TOK_STRLIT:
  1112.             ex = accumulate_strlit();
  1113.             return ex;
  1114.  
  1115.         case TOK_LPAR:
  1116.             gettok();
  1117.             ex = p_expr(target);
  1118.             skipcloseparen();
  1119.             return dots_n_hats(ex, target);
  1120.  
  1121.         case TOK_NOT:
  1122.     case TOK_TWIDDLE:
  1123.             gettok();
  1124.             ex = p_factor(tp_integer);
  1125.             if (ord_type(ex->val.type)->kind == TK_INTEGER)
  1126.                 return makeexpr_un(EK_BNOT, tp_integer, ex);
  1127.             else
  1128.                 return makeexpr_not(ex);
  1129.  
  1130.     case TOK_MINUS:
  1131.         gettok();
  1132.             if (curtok == TOK_MININT) {
  1133.                 gettok();
  1134.                 return makeexpr_long(MININT);
  1135.             } else
  1136.         return makeexpr_neg(p_factor(target));
  1137.         
  1138.         case TOK_PLUS:
  1139.         gettok();
  1140.         return p_factor(target);
  1141.  
  1142.         case TOK_ADDR:
  1143.             gettok();
  1144.         if (curtok == TOK_ADDR) {
  1145.         gettok();
  1146.         ex = p_factor(tp_proc);
  1147.         if (ex->val.type->kind == TK_PROCPTR && ex->kind == EK_COMMA)
  1148.             return grabarg(grabarg(grabarg(ex, 0), 1), 0);
  1149.         if (ex->val.type->kind != TK_CPROCPTR)
  1150.             warning("@@ allowed only for procedure pointers [302]");
  1151.         return makeexpr_addrf(ex);
  1152.         }
  1153.             if (curtok == TOK_IDENT && 0 &&  /***/
  1154.                 curtokmeaning && (curtokmeaning->kind == MK_FUNCTION ||
  1155.                                   curtokmeaning->kind == MK_SPECIAL)) {
  1156.                 if (curtokmeaning->ctx == nullctx)
  1157.                     warning(format_s("Can't take address of predefined object %s [303]",
  1158.                                      curtokmeaning->name));
  1159.                 ex = makeexpr_name(curtokmeaning->name, tp_anyptr);
  1160.                 gettok();
  1161.             } else {
  1162.         ex = p_factor(tp_proc);
  1163.         if (ex->val.type->kind == TK_PROCPTR) {
  1164.           /*  ex = makeexpr_dotq(ex, "proc", tp_anyptr);  */
  1165.         } else if (ex->val.type->kind == TK_CPROCPTR) {
  1166.             ex = makeexpr_cast(ex, tp_anyptr);
  1167.         } else
  1168.             ex = makeexpr_addrf(ex);
  1169.             }
  1170.             return ex;
  1171.  
  1172.         case TOK_LBR:
  1173.     case TOK_LBRACE:
  1174.             return p_setfactor(target && target->kind == TK_SET
  1175.                    ? target->indextype : NULL, 0);
  1176.  
  1177.         case TOK_NIL:
  1178.             gettok();
  1179.             return makeexpr_nil();
  1180.  
  1181.     case TOK_IF:    /* nifty Pascal extension */
  1182.         gettok();
  1183.         ex = p_expr(tp_boolean);
  1184.         wneedtok(TOK_THEN);
  1185.         ex2 = p_expr(tp_integer);
  1186.         if (wneedtok(TOK_ELSE))
  1187.         return makeexpr_cond(ex, ex2, p_factor(ex2->val.type));
  1188.         else
  1189.         return makeexpr_cond(ex, ex2, makeexpr_long(0));
  1190.  
  1191.         case TOK_IDENT:
  1192.             mp = curtokmeaning;
  1193.             switch ((mp) ? mp->kind : MK_VAR) {
  1194.  
  1195.                 case MK_TYPE:
  1196.                     gettok();
  1197.                     type = mp->type;
  1198.                     switch (curtok) {
  1199.  
  1200.                         case TOK_LPAR:    /* Turbo type cast */
  1201.                             gettok();
  1202.                             ex2 = p_expr(type);
  1203.                 ex = pascaltypecast(type, ex2);
  1204.                             skipcloseparen();
  1205.                             return dots_n_hats(ex, target);
  1206.  
  1207.                         case TOK_LBR:
  1208.             case TOK_LBRACE:
  1209.                             switch (type->kind) {
  1210.  
  1211.                                 case TK_SET:
  1212.                                 case TK_SMALLSET:
  1213.                                     return p_setfactor(type->indextype, 1);
  1214.  
  1215.                                 case TK_RECORD:
  1216.                                     return p_constrecord(type, 0);
  1217.  
  1218.                                 case TK_ARRAY:
  1219.                                 case TK_SMALLARRAY:
  1220.                                     return p_constarray(type, 0);
  1221.  
  1222.                                 case TK_STRING:
  1223.                                     return p_conststring(type, 0);
  1224.  
  1225.                                 default:
  1226.                                     warning("Bad type for constructor [304]");
  1227.                     skipparens();
  1228.                     return makeexpr_name(mp->name, mp->type);
  1229.                             }
  1230.  
  1231.             default:
  1232.                 wexpected("an expression");
  1233.                 return makeexpr_name(mp->name, mp->type);
  1234.                     }
  1235.  
  1236.                 case MK_SPECIAL:
  1237.                     if (mp->handler && mp->isfunction &&
  1238.             (curtok == TOK_LPAR || !target ||
  1239.              (target->kind != TK_PROCPTR &&
  1240.               target->kind != TK_CPROCPTR))) {
  1241.                         gettok();
  1242.                         if ((mp->sym->flags & LEAVEALONE) || mp->constdefn) {
  1243.                             ex = makeexpr_bicall_0(mp->name, tp_integer);
  1244.                             if (curtok == TOK_LPAR) {
  1245.                                 do {
  1246.                                     gettok();
  1247.                                     insertarg(&ex, ex->nargs, p_expr(NULL));
  1248.                                 } while (curtok == TOK_COMMA);
  1249.                                 skipcloseparen();
  1250.                             }
  1251.                             tryfuncmacro(&ex, mp);
  1252.                 return ex;
  1253.                         }
  1254.                         ex = (*mp->handler)(mp);
  1255.             if (!ex)
  1256.                 ex = makeexpr_long(0);
  1257.             return ex;
  1258.                     } else {
  1259.             if (target &&
  1260.                 (target->kind == TK_PROCPTR ||
  1261.                  target->kind == TK_CPROCPTR))
  1262.                 note("Using a built-in procedure as a procedure pointer [316]");
  1263.                         else
  1264.                 symclass(curtoksym);
  1265.                         gettok();
  1266.                         return makeexpr_name(mp->name, tp_integer);
  1267.                     }
  1268.  
  1269.                 case MK_FUNCTION:
  1270.                     mp->refcount++;
  1271.                     need_forward_decl(mp);
  1272.             gettok();
  1273.                     if (mp->isfunction &&
  1274.             (curtok == TOK_LPAR || !target ||
  1275.              (target->kind != TK_PROCPTR &&
  1276.               target->kind != TK_CPROCPTR))) {
  1277.                         ex = p_funccall(mp);
  1278.                         if (!mp->constdefn) {
  1279.                             if (mp->handler && !(mp->sym->flags & LEAVEALONE))
  1280.                                 ex = (*mp->handler)(ex);
  1281.             }
  1282.             if (mp->cbase->kind == MK_VARPARAM) {
  1283.                 ex = makeexpr_hat(ex, 0);    /* returns pointer to structured result */
  1284.                         }
  1285.                         return dots_n_hats(ex, target);
  1286.                     } else {
  1287.             if (mp->handler && !(mp->sym->flags & LEAVEALONE))
  1288.                 note("Using a built-in procedure as a procedure pointer [316]");
  1289.             if (target && target->kind == TK_CPROCPTR) {
  1290.                 type = maketype(TK_CPROCPTR);
  1291.                 type->basetype = mp->type;
  1292.                 type->escale = 0;
  1293.                 mp2 = makestmttempvar(type, name_TEMP);
  1294.                 ex = makeexpr_comma(
  1295.                                     makeexpr_assign(
  1296.                                        makeexpr_var(mp2),
  1297.                        makeexpr_name(mp->name, tp_text)),
  1298.                     makeexpr_var(mp2));
  1299.                 if (mp->ctx->kind == MK_FUNCTION)
  1300.                 warning("Procedure pointer to nested procedure [305]");
  1301.             } else {
  1302.                 type = maketype(TK_PROCPTR);
  1303.                 type->basetype = mp->type;
  1304.                 type->escale = 1;
  1305.                 mp2 = makestmttempvar(type, name_TEMP);
  1306.                 ex = makeexpr_comma(
  1307.                                     makeexpr_comma(
  1308.                                        makeexpr_assign(
  1309.                                           makeexpr_dotq(makeexpr_var(mp2),
  1310.                             "proc",
  1311.                             tp_anyptr),
  1312.                       makeexpr_name(mp->name, tp_text)),
  1313.                                           /* handy pointer type */
  1314.                        makeexpr_assign(
  1315.                                           makeexpr_dotq(makeexpr_var(mp2),
  1316.                             "link",
  1317.                             tp_anyptr),
  1318.                           makeexpr_ctx(mp->ctx))),
  1319.                     makeexpr_var(mp2));
  1320.             }
  1321.                         return ex;
  1322.                     }
  1323.  
  1324.                 default:
  1325.                     return p_variable(target);
  1326.             }
  1327.  
  1328.     default:
  1329.         wexpected("an expression");
  1330.         return makeexpr_long(0);
  1331.         
  1332.     }
  1333. }
  1334.  
  1335.  
  1336.  
  1337.  
  1338. Static Expr *p_powterm(target)
  1339. Type *target;
  1340. {
  1341.     Expr *ex = p_factor(target);
  1342.     Expr *ex2;
  1343.     int i, castit;
  1344.     long v;
  1345.  
  1346.     if (curtok == TOK_STARSTAR) {
  1347.     gettok();
  1348.     ex2 = p_powterm(target);
  1349.     if (ex->val.type->kind == TK_REAL ||
  1350.         ex2->val.type->kind == TK_REAL) {
  1351.         if (checkconst(ex2, 2)) {
  1352.         ex = makeexpr_sqr(ex, 0);
  1353.         } else if (checkconst(ex2, 3)) {
  1354.         ex = makeexpr_sqr(ex, 1);
  1355.         } else {
  1356.         castit = castargs >= 0 ? castargs : (prototypes == 0);
  1357.         if (ex->val.type->kind != TK_REAL && castit)
  1358.             ex = makeexpr_cast(ex, tp_longreal);
  1359.         if (ex2->val.type->kind != TK_REAL && castit)
  1360.             ex2 = makeexpr_cast(ex2, tp_longreal);
  1361.         ex = makeexpr_bicall_2("pow", tp_longreal, ex, ex2);
  1362.         }
  1363.     } else if (checkconst(ex, 2)) {
  1364.         freeexpr(ex);
  1365.         ex = makeexpr_bin(EK_LSH, tp_integer,
  1366.                   makeexpr_longcast(makeexpr_long(1), 1), ex2);
  1367.     } else if (checkconst(ex, 0) ||
  1368.            checkconst(ex, 1) ||
  1369.            checkconst(ex2, 1)) {
  1370.         freeexpr(ex2);
  1371.     } else if (checkconst(ex2, 0)) {
  1372.         freeexpr(ex);
  1373.         freeexpr(ex2);
  1374.         ex = makeexpr_long(1);
  1375.     } else if (isliteralconst(ex, NULL) == 2 &&
  1376.            isliteralconst(ex2, NULL) == 2 &&
  1377.            ex2->val.i > 0) {
  1378.         v = ex->val.i;
  1379.         i = ex2->val.i;
  1380.         while (--i > 0)
  1381.         v *= ex->val.i;
  1382.         freeexpr(ex);
  1383.         freeexpr(ex2);
  1384.         ex = makeexpr_long(v);
  1385.     } else if (checkconst(ex2, 2)) {
  1386.         ex = makeexpr_sqr(ex, 0);
  1387.     } else if (checkconst(ex2, 3)) {
  1388.         ex = makeexpr_sqr(ex, 1);
  1389.     } else {
  1390.         ex = makeexpr_bicall_2("ipow", tp_integer,
  1391.                    makeexpr_arglong(ex, 1),
  1392.                    makeexpr_arglong(ex2, 1));
  1393.     }
  1394.     }
  1395.     return ex;
  1396. }
  1397.  
  1398.  
  1399. Static Expr *p_term(target)
  1400. Type *target;
  1401. {
  1402.     Expr *ex = p_powterm(target);
  1403.     Expr *ex2;
  1404.     Type *type;
  1405.     Meaning *tvar;
  1406.     int useshort;
  1407.  
  1408.     for (;;) {
  1409.     checkkeyword(TOK_SHL);
  1410.     checkkeyword(TOK_SHR);
  1411.     checkkeyword(TOK_REM);
  1412.         switch (curtok) {
  1413.  
  1414.             case TOK_STAR:
  1415.                 gettok();
  1416.                 if (ex->val.type->kind == TK_SET ||
  1417.                     ex->val.type->kind == TK_SMALLSET) {
  1418.                     ex2 = p_powterm(ex->val.type);
  1419.                     type = mixsets(&ex, &ex2);
  1420.                     if (type->kind == TK_SMALLSET) {
  1421.                         ex = makeexpr_bin(EK_BAND, type, ex, ex2);
  1422.                     } else {
  1423.                         tvar = makestmttempvar(type, name_SET);
  1424.                         ex = makeexpr_bicall_3(setintname, type,
  1425.                                                makeexpr_var(tvar),
  1426.                                                ex, ex2);
  1427.                     }
  1428.                 } else
  1429.                     ex = makeexpr_times(ex, p_powterm(tp_integer));
  1430.                 break;
  1431.  
  1432.             case TOK_SLASH:
  1433.                 gettok();
  1434.                 if (ex->val.type->kind == TK_SET ||
  1435.                     ex->val.type->kind == TK_SMALLSET) {
  1436.                     ex2 = p_powterm(ex->val.type);
  1437.                     type = mixsets(&ex, &ex2);
  1438.                     if (type->kind == TK_SMALLSET) {
  1439.                         ex = makeexpr_bin(EK_BXOR, type, ex, ex2);
  1440.                     } else {
  1441.                         tvar = makestmttempvar(type, name_SET);
  1442.                         ex = makeexpr_bicall_3(setxorname, type,
  1443.                                                makeexpr_var(tvar),
  1444.                                                ex, ex2);
  1445.                     }
  1446.         } else
  1447.             ex = makeexpr_divide(ex, p_powterm(tp_integer));
  1448.                 break;
  1449.  
  1450.             case TOK_DIV:
  1451.                 gettok();
  1452.                 ex = makeexpr_div(ex, p_powterm(tp_integer));
  1453.                 break;
  1454.  
  1455.             case TOK_REM:
  1456.                 gettok();
  1457.                 ex = makeexpr_rem(ex, p_powterm(tp_integer));
  1458.                 break;
  1459.  
  1460.             case TOK_MOD:
  1461.                 gettok();
  1462.                 ex = makeexpr_mod(ex, p_powterm(tp_integer));
  1463.                 break;
  1464.  
  1465.             case TOK_AND:
  1466.         case TOK_AMP:
  1467.         useshort = (curtok == TOK_AMP);
  1468.                 gettok();
  1469.                 ex2 = p_powterm(tp_integer);
  1470.                 if (ord_type(ex->val.type)->kind == TK_INTEGER)
  1471.                     ex = makeexpr_bin(EK_BAND, ex->val.type, ex, ex2);
  1472.                 else if (partial_eval_flag || useshort ||
  1473.                          (shortopt && nosideeffects(ex2, 1)))
  1474.                     ex = makeexpr_and(ex, ex2);
  1475.                 else
  1476.                     ex = makeexpr_bin(EK_BAND, tp_boolean, ex, ex2);
  1477.                 break;
  1478.  
  1479.             case TOK_SHL:
  1480.                 gettok();
  1481.                 ex = makeexpr_bin(EK_LSH, ex->val.type, ex, p_powterm(tp_integer));
  1482.                 break;
  1483.  
  1484.             case TOK_SHR:
  1485.                 gettok();
  1486.                 ex = force_unsigned(ex);
  1487.                 ex = makeexpr_bin(EK_RSH, ex->val.type, ex, p_powterm(tp_integer));
  1488.                 break;
  1489.  
  1490.             default:
  1491.                 return ex;
  1492.         }
  1493.     }
  1494. }
  1495.  
  1496.  
  1497.  
  1498. Static Expr *p_sexpr(target)
  1499. Type *target;
  1500. {
  1501.     Expr *ex, *ex2;
  1502.     Type *type;
  1503.     Meaning *tvar;
  1504.     int useshort;
  1505.  
  1506.     switch (curtok) {
  1507.         case TOK_MINUS:
  1508.             gettok();
  1509.             if (curtok == TOK_MININT) {
  1510.                 gettok();
  1511.                 ex = makeexpr_long(MININT);
  1512.         break;
  1513.             }
  1514.             ex = makeexpr_neg(p_term(target));
  1515.             break;
  1516.         case TOK_PLUS:
  1517.             gettok();
  1518.         /* fall through */
  1519.         default:
  1520.             ex = p_term(target);
  1521.             break;
  1522.     }
  1523.     if (curtok == TOK_PLUS &&
  1524.         (ex->val.type->kind == TK_STRING ||
  1525.          ord_type(ex->val.type)->kind == TK_CHAR ||
  1526.          ex->val.type->kind == TK_ARRAY)) {
  1527.         while (curtok == TOK_PLUS) {
  1528.             gettok();
  1529.             ex = makeexpr_concat(ex, p_term(NULL), 0);
  1530.         }
  1531.         return ex;
  1532.     } else {
  1533.         for (;;) {
  1534.         checkkeyword(TOK_XOR);
  1535.             switch (curtok) {
  1536.  
  1537.                 case TOK_PLUS:
  1538.                     gettok();
  1539.                     if (ex->val.type->kind == TK_SET ||
  1540.                         ex->val.type->kind == TK_SMALLSET) {
  1541.                         ex2 = p_term(ex->val.type);
  1542.                         type = mixsets(&ex, &ex2);
  1543.                         if (type->kind == TK_SMALLSET) {
  1544.                             ex = makeexpr_bin(EK_BOR, type, ex, ex2);
  1545.                         } else {
  1546.                             tvar = makestmttempvar(type, name_SET);
  1547.                             ex = makeexpr_bicall_3(setunionname, type,
  1548.                                                    makeexpr_var(tvar),
  1549.                                                    ex, ex2);
  1550.                         }
  1551.                     } else
  1552.                         ex = makeexpr_plus(ex, p_term(tp_integer));
  1553.                     break;
  1554.  
  1555.                 case TOK_MINUS:
  1556.                     gettok();
  1557.                     if (ex->val.type->kind == TK_SET ||
  1558.                         ex->val.type->kind == TK_SMALLSET) {
  1559.                         ex2 = p_term(tp_integer);
  1560.                         type = mixsets(&ex, &ex2);
  1561.                         if (type->kind == TK_SMALLSET) {
  1562.                             ex = makeexpr_bin(EK_BAND, type, ex,
  1563.                                               makeexpr_un(EK_BNOT, type, ex2));
  1564.                         } else {
  1565.                             tvar = makestmttempvar(type, name_SET);
  1566.                             ex = makeexpr_bicall_3(setdiffname, type,
  1567.                                                    makeexpr_var(tvar), ex, ex2);
  1568.                         }
  1569.                     } else
  1570.                         ex = makeexpr_minus(ex, p_term(tp_integer));
  1571.                     break;
  1572.  
  1573.         case TOK_VBAR:
  1574.             if (modula2)
  1575.             return ex;
  1576.             /* fall through */
  1577.  
  1578.                 case TOK_OR:
  1579.             useshort = (curtok == TOK_VBAR);
  1580.                     gettok();
  1581.                     ex2 = p_term(tp_integer);
  1582.                     if (ord_type(ex->val.type)->kind == TK_INTEGER)
  1583.                         ex = makeexpr_bin(EK_BOR, ex->val.type, ex, ex2);
  1584.                     else if (partial_eval_flag || useshort ||
  1585.                              (shortopt && nosideeffects(ex2, 1)))
  1586.                         ex = makeexpr_or(ex, ex2);
  1587.                     else
  1588.                         ex = makeexpr_bin(EK_BOR, tp_boolean, ex, ex2);
  1589.                     break;
  1590.  
  1591.                 case TOK_XOR:
  1592.                     gettok();
  1593.                     ex2 = p_term(tp_integer);
  1594.                     ex = makeexpr_bin(EK_BXOR, ex->val.type, ex, ex2);
  1595.                     break;
  1596.  
  1597.                 default:
  1598.                     return ex;
  1599.             }
  1600.         }
  1601.     }
  1602. }
  1603.  
  1604.  
  1605.  
  1606. Expr *p_expr(target)
  1607. Type *target;
  1608. {
  1609.     Expr *ex = p_sexpr(target);
  1610.     Expr *ex2, *ex3, *ex4;
  1611.     Type *type;
  1612.     Meaning *tvar;
  1613.     long mask, smin, smax;
  1614.     int i, j;
  1615.  
  1616.     switch (curtok) {
  1617.  
  1618.         case TOK_EQ:
  1619.             gettok();
  1620.             return makeexpr_rel(EK_EQ, ex, p_sexpr(ex->val.type));
  1621.  
  1622.         case TOK_NE:
  1623.             gettok();
  1624.             return makeexpr_rel(EK_NE, ex, p_sexpr(ex->val.type));
  1625.  
  1626.         case TOK_LT:
  1627.             gettok();
  1628.             return makeexpr_rel(EK_LT, ex, p_sexpr(ex->val.type));
  1629.  
  1630.         case TOK_GT:
  1631.             gettok();
  1632.             return makeexpr_rel(EK_GT, ex, p_sexpr(ex->val.type));
  1633.  
  1634.         case TOK_LE:
  1635.             gettok();
  1636.             return makeexpr_rel(EK_LE, ex, p_sexpr(ex->val.type));
  1637.  
  1638.         case TOK_GE:
  1639.             gettok();
  1640.             return makeexpr_rel(EK_GE, ex, p_sexpr(ex->val.type));
  1641.  
  1642.         case TOK_IN:
  1643.             gettok();
  1644.             ex2 = p_sexpr(tp_smallset);
  1645.             ex = gentle_cast(ex, ex2->val.type->indextype);
  1646.             if (ex2->val.type->kind == TK_SMALLSET) {
  1647.                 if (!ord_range(ex->val.type, &smin, &smax)) {
  1648.                     smin = -1;
  1649.                     smax = setbits;
  1650.                 }
  1651.                 if (!nosideeffects(ex, 0)) {
  1652.                     tvar = makestmttempvar(ex->val.type, name_TEMP);
  1653.                     ex3 = makeexpr_assign(makeexpr_var(tvar), ex);
  1654.                     ex = makeexpr_var(tvar);
  1655.                 } else
  1656.                     ex3 = NULL;
  1657.                 ex4 = copyexpr(ex);
  1658.                 if (ex->kind == EK_CONST && smallsetconst)
  1659.                     ex = makesmallsetconst(1<<ex->val.i, ex2->val.type);
  1660.                 else
  1661.                     ex = makeexpr_bin(EK_LSH, ex2->val.type,
  1662.                                       makeexpr_longcast(makeexpr_long(1), 1),
  1663.                                       enum_to_int(ex));
  1664.                 ex = makeexpr_rel(EK_NE, makeexpr_bin(EK_BAND, tp_integer, ex, ex2),
  1665.                                          makeexpr_long(0));
  1666.                 if (*name_SETBITS ||
  1667.                     ((ex4->kind == EK_CONST) ? ((unsigned long)ex4->val.i >= setbits)
  1668.                                              : !(0 <= smin && smax < setbits))) {
  1669.                     ex = makeexpr_and(makeexpr_range(enum_to_int(ex4),
  1670.                                                      makeexpr_long(0),
  1671.                                                      makeexpr_setbits(), 0),
  1672.                                       ex);
  1673.                 } else
  1674.                     freeexpr(ex4);
  1675.                 ex = makeexpr_comma(ex3, ex);
  1676.                 return ex;
  1677.             } else {
  1678.                 ex3 = ex2;
  1679.                 while (ex3->kind == EK_BICALL &&
  1680.                        (!strcmp(ex3->val.s, setaddname) ||
  1681.                         !strcmp(ex3->val.s, setaddrangename)))
  1682.                     ex3 = ex3->args[0];
  1683.                 if (ex3->kind == EK_BICALL && !strcmp(ex3->val.s, setexpandname) &&
  1684.                     (tvar = istempvar(ex3->args[0])) != NULL && 
  1685.                     isconstexpr(ex3->args[1], &mask)) {
  1686.                     canceltempvar(tvar);
  1687.                     if (!nosideeffects(ex, 0)) {
  1688.                         tvar = makestmttempvar(ex->val.type, name_TEMP);
  1689.                         ex3 = makeexpr_assign(makeexpr_var(tvar), ex);
  1690.                         ex = makeexpr_var(tvar);
  1691.                     } else
  1692.                         ex3 = NULL;
  1693.                     type = ord_type(ex2->val.type->indextype);
  1694.                     ex4 = NULL;
  1695.                     i = 0;
  1696.                     while (i < setbits) {
  1697.                         if (mask & (1<<i++)) {
  1698.                             if (i+1 < setbits && (mask & (2<<i))) {
  1699.                                 for (j = i; j < setbits && (mask & (1<<j)); j++) ;
  1700.                                 ex4 = makeexpr_or(ex4,
  1701.                                         makeexpr_range(copyexpr(ex),
  1702.                                                        makeexpr_val(make_ord(type, i-1)),
  1703.                                                        makeexpr_val(make_ord(type, j-1)), 1));
  1704.                                 i = j;
  1705.                             } else {
  1706.                                 ex4 = makeexpr_or(ex4,
  1707.                                         makeexpr_rel(EK_EQ, copyexpr(ex),
  1708.                                                             makeexpr_val(make_ord(type, i-1))));
  1709.                             }
  1710.                         }
  1711.                     }
  1712.                     mask = 0;
  1713.                     for (;;) {
  1714.                         if (!strcmp(ex2->val.s, setaddrangename)) {
  1715.                             if (checkconst(ex2->args[1], 'a') &&
  1716.                                 checkconst(ex2->args[2], 'z')) {
  1717.                                 mask |= 0x1;
  1718.                             } else if (checkconst(ex2->args[1], 'A') &&
  1719.                                        checkconst(ex2->args[2], 'Z')) {
  1720.                                 mask |= 0x2;
  1721.                             } else if (checkconst(ex2->args[1], '0') &&
  1722.                                        checkconst(ex2->args[2], '9')) {
  1723.                                 mask |= 0x4;
  1724.                             } else {
  1725.                                 ex4 = makeexpr_or(ex4,
  1726.                                         makeexpr_range(copyexpr(ex), ex2->args[1], ex2->args[2], 1));
  1727.                             }
  1728.                         } else if (!strcmp(ex2->val.s, setaddname)) {
  1729.                             ex4 = makeexpr_or(ex4,
  1730.                                     makeexpr_rel(EK_EQ, copyexpr(ex), ex2->args[1]));
  1731.                         } else
  1732.                             break;
  1733.                         ex2 = ex2->args[0];
  1734.                     }
  1735.                     /* do these now so that EK_OR optimizations will work: */
  1736.                     if (mask & 0x1)
  1737.                         ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
  1738.                                                               makeexpr_char('a'),
  1739.                                                               makeexpr_char('z'), 1));
  1740.                     if (mask & 0x2)
  1741.                         ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
  1742.                                                               makeexpr_char('A'),
  1743.                                                               makeexpr_char('Z'), 1));
  1744.                     if (mask & 0x4)
  1745.                         ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
  1746.                                                               makeexpr_char('0'),
  1747.                                                               makeexpr_char('9'), 1));
  1748.                     freeexpr(ex);
  1749.                     return makeexpr_comma(ex3, ex4);
  1750.                 }
  1751.                 return makeexpr_bicall_2(setinname, tp_boolean,
  1752.                                          makeexpr_arglong(ex, 0), ex2);
  1753.             }
  1754.  
  1755.     default:
  1756.         return ex;
  1757.     }
  1758. }
  1759.  
  1760.  
  1761.  
  1762.  
  1763.  
  1764.  
  1765.  
  1766. /* Parse a C expression; used by VarMacro, etc. */
  1767.  
  1768. Type *nametotype(name)
  1769. char *name;
  1770. {
  1771.     if (!strcicmp(name, "malloc") ||
  1772.     !strcicmp(name, mallocname)) {
  1773.     return tp_anyptr;
  1774.     }
  1775.     return tp_integer;
  1776. }
  1777.  
  1778.  
  1779. int istypespec()
  1780. {
  1781.     switch (curtok) {
  1782.  
  1783.         case TOK_CONST:
  1784.             return 1;
  1785.  
  1786.         case TOK_IDENT:
  1787.             return !strcmp(curtokcase, "volatile") ||
  1788.                    !strcmp(curtokcase, "void") ||
  1789.                    !strcmp(curtokcase, "char") ||
  1790.                    !strcmp(curtokcase, "short") ||
  1791.                    !strcmp(curtokcase, "int") ||
  1792.                    !strcmp(curtokcase, "long") ||
  1793.                    !strcmp(curtokcase, "float") ||
  1794.                    !strcmp(curtokcase, "double") ||
  1795.                    !strcmp(curtokcase, "signed") ||
  1796.                    !strcmp(curtokcase, "unsigned") ||
  1797.                    !strcmp(curtokcase, "struct") ||
  1798.                    !strcmp(curtokcase, "union") ||
  1799.                    !strcmp(curtokcase, "class") ||
  1800.                    !strcmp(curtokcase, "enum") ||
  1801.                    !strcmp(curtokcase, "typedef") ||
  1802.                    (curtokmeaning &&
  1803.                     curtokmeaning->kind == MK_TYPE);
  1804.  
  1805.         default:
  1806.             return 0;
  1807.     }
  1808. }
  1809.  
  1810.  
  1811.  
  1812. Expr *pc_parentype(cp)
  1813. char *cp;
  1814. {
  1815.     Expr *ex;
  1816.  
  1817.     if (curtok == TOK_IDENT &&
  1818.          curtokmeaning &&
  1819.          curtokmeaning->kind == MK_TYPE) {
  1820.         ex = makeexpr_type(curtokmeaning->type);
  1821.         gettok();
  1822.         skipcloseparen();
  1823.     } else if (curtok == TOK_IDENT && !strcmp(curtokcase, "typedef")) {
  1824.         ex = makeexpr_name(getparenstr(inbufptr), tp_integer);
  1825.         gettok();
  1826.     } else {
  1827.         ex = makeexpr_name(getparenstr(cp), tp_integer);
  1828.         gettok();
  1829.     }
  1830.     return ex;
  1831. }
  1832.  
  1833.  
  1834.  
  1835.  
  1836. Expr *pc_expr2();
  1837.  
  1838. Expr *pc_factor()
  1839. {
  1840.     Expr *ex;
  1841.     char *cp;
  1842.     Strlist *sl;
  1843.     int i;
  1844.  
  1845.     switch (curtok) {
  1846.  
  1847.         case TOK_BANG:
  1848.             gettok();
  1849.             return makeexpr_not(pc_expr2(14));
  1850.  
  1851.         case TOK_TWIDDLE:
  1852.             gettok();
  1853.             return makeexpr_un(EK_BNOT, tp_integer, pc_expr2(14));
  1854.  
  1855.         case TOK_PLPL:
  1856.             gettok();
  1857.             ex = pc_expr2(14);
  1858.             return makeexpr_assign(ex, makeexpr_plus(copyexpr(ex), makeexpr_long(1)));
  1859.  
  1860.         case TOK_MIMI:
  1861.             gettok();
  1862.             ex = pc_expr2(14);
  1863.             return makeexpr_assign(ex, makeexpr_minus(copyexpr(ex), makeexpr_long(1)));
  1864.  
  1865.         case TOK_STAR:
  1866.             gettok();
  1867.             ex = pc_expr2(14);
  1868.             if (ex->val.type->kind != TK_POINTER)
  1869.                 ex->val.type = makepointertype(ex->val.type);
  1870.             return makeexpr_hat(ex, 0);
  1871.  
  1872.         case TOK_AMP:
  1873.             gettok();
  1874.             return makeexpr_addr(pc_expr2(14));
  1875.  
  1876.         case TOK_PLUS:
  1877.             gettok();
  1878.             return pc_expr2(14);
  1879.  
  1880.         case TOK_MINUS:
  1881.             gettok();
  1882.             return makeexpr_neg(pc_expr2(14));
  1883.  
  1884.         case TOK_LPAR:
  1885.             cp = inbufptr;
  1886.             gettok();
  1887.             if (istypespec()) {
  1888.                 ex = pc_parentype(cp);
  1889.                 return makeexpr_bin(EK_LITCAST, tp_integer, ex, pc_expr2(14));
  1890.             }
  1891.             ex = pc_expr();
  1892.             skipcloseparen();
  1893.             return ex;
  1894.  
  1895.         case TOK_IDENT:
  1896.             if (!strcmp(curtokcase, "sizeof")) {
  1897.                 gettok();
  1898.                 if (curtok != TOK_LPAR)
  1899.                     return makeexpr_sizeof(pc_expr2(14), 1);
  1900.                 cp = inbufptr;
  1901.                 gettok();
  1902.                 if (istypespec()) {
  1903.                     ex = makeexpr_sizeof(pc_parentype(cp), 1);
  1904.                 } else {
  1905.                     ex = makeexpr_sizeof(pc_expr(), 1);
  1906.                     skipcloseparen();
  1907.                 }
  1908.                 return ex;
  1909.             }
  1910.             if (curtoksym->flags & FMACREC) {
  1911.                 ex = makeexpr(EK_MACARG, 0);
  1912.                 ex->val.type = tp_integer;
  1913.                 ex->val.i = 0;
  1914.                 for (sl = funcmacroargs, i = 1; sl; sl = sl->next, i++) {
  1915.                     if (sl->value == (long)curtoksym) {
  1916.                         ex->val.i = i;
  1917.                         break;
  1918.                     }
  1919.                 }
  1920.             } else
  1921.                 ex = makeexpr_name(curtokcase, nametotype(curtokcase));
  1922.             gettok();
  1923.             return ex;
  1924.  
  1925.         case TOK_INTLIT:
  1926.             ex = makeexpr_long(curtokint);
  1927.             if (curtokbuf[strlen(curtokbuf)-1] == 'L')
  1928.                 ex = makeexpr_longcast(ex, 1);
  1929.             gettok();
  1930.             return ex;
  1931.  
  1932.         case TOK_HEXLIT:
  1933.             ex = makeexpr_long(curtokint);
  1934.             insertarg(&ex, 0, makeexpr_name("%#lx", tp_integer));
  1935.             if (curtokbuf[strlen(curtokbuf)-1] == 'L')
  1936.                 ex = makeexpr_longcast(ex, 1);
  1937.             gettok();
  1938.             return ex;
  1939.  
  1940.         case TOK_OCTLIT:
  1941.             ex = makeexpr_long(curtokint);
  1942.             insertarg(&ex, 0, makeexpr_name("%#lo", tp_integer));
  1943.             if (curtokbuf[strlen(curtokbuf)-1] == 'L')
  1944.                 ex = makeexpr_longcast(ex, 1);
  1945.             gettok();
  1946.             return ex;
  1947.  
  1948.         case TOK_REALLIT:
  1949.             ex = makeexpr_real(curtokbuf);
  1950.             gettok();
  1951.             return ex;
  1952.  
  1953.         case TOK_STRLIT:
  1954.             ex = makeexpr_lstring(curtokbuf, curtokint);
  1955.             gettok();
  1956.             return ex;
  1957.  
  1958.         case TOK_CHARLIT:
  1959.             ex = makeexpr_char(curtokint);
  1960.             gettok();
  1961.             return ex;
  1962.  
  1963.         default:
  1964.         wexpected("a C expression");
  1965.         return makeexpr_long(0);
  1966.     }
  1967. }
  1968.  
  1969.  
  1970.  
  1971.  
  1972. #define pc_prec(pr)  if (prec > (pr)) return ex; gettok();
  1973.  
  1974. Expr *pc_expr2(prec)
  1975. int prec;
  1976. {
  1977.     Expr *ex, *ex2;
  1978.     int i;
  1979.  
  1980.     ex = pc_factor();
  1981.     for (;;) {
  1982.         switch (curtok) {
  1983.  
  1984.             case TOK_COMMA:
  1985.                 pc_prec(1);
  1986.                 ex = makeexpr_comma(ex, pc_expr2(2));
  1987.                 break;
  1988.  
  1989.             case TOK_EQ:
  1990.                 pc_prec(2);
  1991.                 ex = makeexpr_assign(ex, pc_expr2(2));
  1992.                 break;
  1993.  
  1994.             case TOK_QM:
  1995.                 pc_prec(3);
  1996.                 ex2 = pc_expr();
  1997.                 if (wneedtok(TOK_COLON))
  1998.             ex = makeexpr_cond(ex, ex2, pc_expr2(3));
  1999.         else
  2000.             ex = makeexpr_cond(ex, ex2, makeexpr_long(0));
  2001.                 break;
  2002.  
  2003.             case TOK_OROR:
  2004.                 pc_prec(4);
  2005.                 ex = makeexpr_or(ex, pc_expr2(5));
  2006.                 break;
  2007.  
  2008.             case TOK_ANDAND:
  2009.                 pc_prec(5);
  2010.                 ex = makeexpr_and(ex, pc_expr2(6));
  2011.                 break;
  2012.  
  2013.             case TOK_VBAR:
  2014.                 pc_prec(6);
  2015.                 ex = makeexpr_bin(EK_BOR, tp_integer, ex, pc_expr2(7));
  2016.                 break;
  2017.  
  2018.             case TOK_HAT:
  2019.                 pc_prec(7);
  2020.                 ex = makeexpr_bin(EK_BXOR, tp_integer, ex, pc_expr2(8));
  2021.                 break;
  2022.  
  2023.             case TOK_AMP:
  2024.                 pc_prec(8);
  2025.                 ex = makeexpr_bin(EK_BAND, tp_integer, ex, pc_expr2(9));
  2026.                 break;
  2027.  
  2028.             case TOK_EQEQ:
  2029.                 pc_prec(9);
  2030.                 ex = makeexpr_rel(EK_EQ, ex, pc_expr2(10));
  2031.                 break;
  2032.  
  2033.             case TOK_BANGEQ:
  2034.                 pc_prec(9);
  2035.                 ex = makeexpr_rel(EK_NE, ex, pc_expr2(10));
  2036.                 break;
  2037.  
  2038.             case TOK_LT:
  2039.                 pc_prec(10);
  2040.                 ex = makeexpr_rel(EK_LT, ex, pc_expr2(11));
  2041.                 break;
  2042.  
  2043.             case TOK_LE:
  2044.                 pc_prec(10);
  2045.                 ex = makeexpr_rel(EK_LE, ex, pc_expr2(11));
  2046.                 break;
  2047.  
  2048.             case TOK_GT:
  2049.                 pc_prec(10);
  2050.                 ex = makeexpr_rel(EK_GT, ex, pc_expr2(11));
  2051.                 break;
  2052.  
  2053.             case TOK_GE:
  2054.                 pc_prec(10);
  2055.                 ex = makeexpr_rel(EK_GE, ex, pc_expr2(11));
  2056.                 break;
  2057.  
  2058.             case TOK_LTLT:
  2059.                 pc_prec(11);
  2060.                 ex = makeexpr_bin(EK_LSH, tp_integer, ex, pc_expr2(12));
  2061.                 break;
  2062.  
  2063.             case TOK_GTGT:
  2064.                 pc_prec(11);
  2065.                 ex = makeexpr_bin(EK_RSH, tp_integer, ex, pc_expr2(12));
  2066.                 break;
  2067.  
  2068.             case TOK_PLUS:
  2069.                 pc_prec(12);
  2070.                 ex = makeexpr_plus(ex, pc_expr2(13));
  2071.                 break;
  2072.  
  2073.             case TOK_MINUS:
  2074.                 pc_prec(12);
  2075.                 ex = makeexpr_minus(ex, pc_expr2(13));
  2076.                 break;
  2077.  
  2078.             case TOK_STAR:
  2079.                 pc_prec(13);
  2080.                 ex = makeexpr_times(ex, pc_expr2(14));
  2081.                 break;
  2082.  
  2083.             case TOK_SLASH:
  2084.                 pc_prec(13);
  2085.                 ex = makeexpr_div(ex, pc_expr2(14));
  2086.                 break;
  2087.  
  2088.             case TOK_PERC:
  2089.                 pc_prec(13);
  2090.                 ex = makeexpr_mod(ex, pc_expr2(14));
  2091.                 break;
  2092.  
  2093.             case TOK_PLPL:
  2094.                 pc_prec(15);
  2095.                 ex = makeexpr_un(EK_POSTINC, tp_integer, ex);
  2096.                 break;
  2097.  
  2098.             case TOK_MIMI:
  2099.                 pc_prec(15);
  2100.                 ex = makeexpr_un(EK_POSTDEC, tp_integer, ex);
  2101.                 break;
  2102.  
  2103.             case TOK_LPAR:
  2104.                 pc_prec(16);
  2105.                 if (ex->kind == EK_NAME) {
  2106.                     ex->kind = EK_BICALL;
  2107.                 } else {
  2108.                     ex = makeexpr_un(EK_SPCALL, tp_integer, ex);
  2109.                 }
  2110.                 while (curtok != TOK_RPAR) {
  2111.                     insertarg(&ex, ex->nargs, pc_expr2(2));
  2112.                     if (curtok != TOK_RPAR)
  2113.                         if (!wneedtok(TOK_COMMA))
  2114.                 skiptotoken2(TOK_RPAR, TOK_SEMI);
  2115.                 }
  2116.                 gettok();
  2117.                 break;
  2118.  
  2119.             case TOK_LBR:
  2120.                 pc_prec(16);
  2121.                 ex = makeexpr_index(ex, pc_expr(), NULL);
  2122.                 if (!wneedtok(TOK_RBR))
  2123.             skippasttoken(TOK_RBR);
  2124.                 break;
  2125.  
  2126.             case TOK_ARROW:
  2127.                 pc_prec(16);
  2128.                 if (!wexpecttok(TOK_IDENT))
  2129.             break;
  2130.                 if (ex->val.type->kind != TK_POINTER)
  2131.                     ex->val.type = makepointertype(ex->val.type);
  2132.                 ex = makeexpr_dotq(makeexpr_hat(ex, 0),
  2133.                                    curtokcase, tp_integer);
  2134.                 gettok();
  2135.                 break;
  2136.  
  2137.             case TOK_DOT:
  2138.                 pc_prec(16);
  2139.                 if (!wexpecttok(TOK_IDENT))
  2140.             break;
  2141.                 ex = makeexpr_dotq(ex, curtokcase, tp_integer);
  2142.                 gettok();
  2143.                 break;
  2144.  
  2145.         case TOK_COLONCOLON:
  2146.         if (prec > 16)
  2147.             return ex;
  2148.         i = C_lex;
  2149.         C_lex = 0;
  2150.         gettok();
  2151.         if (curtok == TOK_IDENT &&
  2152.             curtokmeaning && curtokmeaning->kind == MK_TYPE) {
  2153.             ex->val.type = curtokmeaning->type;
  2154.         } else if (curtok == TOK_LPAR) {
  2155.             gettok();
  2156.             ex->val.type = p_type(NULL);
  2157.             if (!wexpecttok(TOK_RPAR))
  2158.             skiptotoken(TOK_RPAR);
  2159.         } else
  2160.             wexpected("a type name");
  2161.         C_lex = i;
  2162.         gettok();
  2163.         break;
  2164.  
  2165.             default:
  2166.                 return ex;
  2167.         }
  2168.     }
  2169. }
  2170.  
  2171.  
  2172.  
  2173.  
  2174. Expr *pc_expr()
  2175. {
  2176.     return pc_expr2(0);
  2177. }
  2178.  
  2179.  
  2180.  
  2181. Expr *pc_expr_str(buf)
  2182. char *buf;
  2183. {
  2184.     Strlist *defsl, *sl;
  2185.     Expr *ex;
  2186.  
  2187.     defsl = NULL;
  2188.     sl = strlist_append(&defsl, buf);
  2189.     C_lex++;
  2190.     push_input_strlist(defsl, buf);
  2191.     ex = pc_expr();
  2192.     if (curtok != TOK_EOF)
  2193.         warning(format_s("Junk (%s) at end of C expression [306]",
  2194.              tok_name(curtok)));
  2195.     pop_input();
  2196.     C_lex--;
  2197.     strlist_empty(&defsl);
  2198.     return ex;
  2199. }
  2200.  
  2201.  
  2202.  
  2203.  
  2204.  
  2205.  
  2206. /* Simplify an expression */
  2207.  
  2208. Expr *fixexpr(ex, env)
  2209. Expr *ex;
  2210. int env;
  2211. {
  2212.     Expr *ex2, *ex3;
  2213.     Type *type, *type2;
  2214.     char *cp;
  2215.     char sbuf[5];
  2216.     int i, j;
  2217.     Value val;
  2218.  
  2219.     if (!ex)
  2220.         return NULL;
  2221.     if (debug>4) {fprintf(outf, "fixexpr("); dumpexpr(ex); fprintf(outf, ")\n");}
  2222.     switch (ex->kind) {
  2223.  
  2224.         case EK_BICALL:
  2225.             ex2 = fix_bicall(ex, env);
  2226.             if (ex2) {
  2227.                 ex = ex2;
  2228.                 break;
  2229.             }
  2230.             cp = ex->val.s;
  2231.             if (!strcmp(cp, "strlen")) {
  2232.                 if (ex->args[0]->kind == EK_BICALL &&
  2233.                     !strcmp(ex->args[0]->val.s, "sprintf") &&
  2234.                     sprintf_value == 0) {     /* does sprintf return char count? */
  2235.                     ex = grabarg(ex, 0);
  2236.                     strchange(&ex->val.s, "*sprintf");
  2237.                     ex = fixexpr(ex, env);
  2238.                 } else {
  2239.                     ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
  2240.                 }
  2241.             } else if (!strcmp(cp, name_SETIO)) {
  2242.                 ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  2243.             } else if (!strcmp(cp, "~~SETIO")) {
  2244.                 ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  2245.                 ex = makeexpr_cond(ex->args[0],
  2246.                                    makeexpr_long(0),
  2247.                                    makeexpr_bicall_1(name_ESCIO, tp_int, ex->args[1]));
  2248.             } else if (!strcmp(cp, name_CHKIO)) {
  2249.                 ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  2250.                 ex->args[2] = fixexpr(ex->args[2], env);
  2251.                 ex->args[3] = fixexpr(ex->args[3], env);
  2252.             } else if (!strcmp(cp, "~~CHKIO")) {
  2253.                 ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  2254.                 ex->args[2] = fixexpr(ex->args[2], env);
  2255.                 ex->args[3] = fixexpr(ex->args[3], env);
  2256.                 ex2 = makeexpr_bicall_1(name_ESCIO, tp_int, ex->args[1]);
  2257.                 if (ord_type(ex->args[3]->val.type)->kind != TK_INTEGER)
  2258.                     ex2 = makeexpr_cast(ex2, ex->args[3]->val.type);
  2259.                 ex = makeexpr_cond(ex->args[0], ex->args[2], ex2);
  2260.             } else if (!strcmp(cp, "assert")) {
  2261.                 ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  2262.         } else if ((!strcmp(cp, setaddname) ||
  2263.             !strcmp(cp, setaddrangename)) &&
  2264.                (ex2 = ex->args[0])->kind == EK_BICALL &&
  2265.                (!strcmp(ex2->val.s, setaddname) ||
  2266.             !strcmp(ex2->val.s, setaddrangename))) {
  2267.         while (ex2->kind == EK_BICALL &&
  2268.                (!strcmp(ex2->val.s, setaddname) ||
  2269.             !strcmp(ex2->val.s, setaddrangename) ||
  2270.             !strcmp(ex2->val.s, setexpandname)))
  2271.             ex2 = ex2->args[0];
  2272.         if (nosideeffects(ex2, 1)) {
  2273.             ex = makeexpr_comma(ex->args[0], ex);
  2274.             ex->args[1]->args[0] = ex2;
  2275.             ex = fixexpr(ex, env);
  2276.         } else
  2277.             for (i = 0; i < ex->nargs; i++)
  2278.             ex->args[i] = fixexpr(ex->args[i], ENV_EXPR);
  2279.         } else if (!strcmp(cp, setunionname) &&
  2280.                (ex3 = singlevar(ex->args[0])) != NULL &&
  2281.                ((i=1, exprsame(ex->args[0], ex->args[i], 0)) ||
  2282.             (i=2, exprsame(ex->args[0], ex->args[i], 0))) &&
  2283.                !exproccurs(ex3, ex->args[3-i]) &&
  2284.                ex->args[3-i]->kind == EK_BICALL &&
  2285.                (!strcmp(ex->args[3-i]->val.s, setaddname) ||
  2286.             !strcmp(ex->args[3-i]->val.s, setaddrangename) ||
  2287.             (!strcmp(ex->args[3-i]->val.s, setexpandname) &&
  2288.              checkconst(ex->args[3-i]->args[1], 0))) &&
  2289.                totempvar(ex->args[3-i])) {
  2290.         if (!strcmp(ex->args[3-i]->val.s, setexpandname)) {
  2291.             ex = grabarg(ex, 0);
  2292.         } else {
  2293.             ex = makeexpr_comma(ex, ex->args[3-i]);
  2294.             ex->args[0]->args[3-i] = ex->args[1]->args[0];
  2295.             ex->args[1]->args[0] = copyexpr(ex->args[0]->args[0]);
  2296.         }
  2297.         ex = fixexpr(ex, env);
  2298.         } else if (!strcmp(cp, setdiffname) && *setremname &&
  2299.                (ex3 = singlevar(ex->args[0])) != NULL &&
  2300.                exprsame(ex->args[0], ex->args[1], 0) &&
  2301.                !exproccurs(ex3, ex->args[2]) &&
  2302.                ex->args[2]->kind == EK_BICALL &&
  2303.                (!strcmp(ex->args[2]->val.s, setaddname) ||
  2304.             (!strcmp(ex->args[2]->val.s, setexpandname) &&
  2305.              checkconst(ex->args[2]->args[1], 0))) &&
  2306.                totempvar(ex->args[2])) {
  2307.         if (!strcmp(ex->args[2]->val.s, setexpandname)) {
  2308.             ex = grabarg(ex, 0);
  2309.         } else {
  2310.             ex = makeexpr_comma(ex, ex->args[2]);
  2311.             ex->args[0]->args[2] = ex->args[1]->args[0];
  2312.             ex->args[1]->args[0] = copyexpr(ex->args[0]->args[0]);
  2313.             strchange(&ex->args[1]->val.s, setremname);
  2314.         }
  2315.         ex = fixexpr(ex, env);
  2316.             } else {
  2317.                 for (i = 0; i < ex->nargs; i++)
  2318.                     ex->args[i] = fixexpr(ex->args[i], ENV_EXPR);
  2319.         ex = cleansprintf(ex);
  2320.                 if (!strcmp(cp, "sprintf")) {
  2321.                     if (checkstring(ex->args[1], "%s")) {
  2322.                         delfreearg(&ex, 1);
  2323.                         strchange(&ex->val.s, "strcpy");
  2324.                         ex = fixexpr(ex, env);
  2325.                     } else if (sprintf_value != 1 && env != ENV_STMT) {
  2326.                         if (*sprintfname) {
  2327.                             strchange(&ex->val.s, format_s("*%s", sprintfname));
  2328.                         } else {
  2329.                             strchange(&ex->val.s, "*sprintf");
  2330.                             ex = makeexpr_comma(ex, copyexpr(ex->args[0]));
  2331.                         }
  2332.                     }
  2333.                 } else if (!strcmp(cp, "strcpy")) {
  2334.                     if (env == ENV_STMT &&
  2335.                          ex->args[1]->kind == EK_BICALL &&
  2336.                          !strcmp(ex->args[1]->val.s, "strcpy") &&
  2337.                          nosideeffects(ex->args[1]->args[0], 1)) {
  2338.                         ex2 = ex->args[1];
  2339.                         ex->args[1] = copyexpr(ex2->args[0]);
  2340.                         ex = makeexpr_comma(ex2, ex);
  2341.                     }
  2342.                 } else if (!strcmp(cp, "memcpy")) {
  2343.                     strchange(&ex->val.s, format_s("*%s", memcpyname));
  2344.                     if (!strcmp(memcpyname, "*bcopy")) {
  2345.                         swapexprs(ex->args[0], ex->args[1]);
  2346.                         if (env != ENV_STMT)
  2347.                             ex = makeexpr_comma(ex, copyexpr(ex->args[1]));
  2348.                     }
  2349. #if 0
  2350.         } else if (!strcmp(cp, setunionname) &&
  2351.                (ex3 = singlevar(ex->args[0])) != NULL &&
  2352.                ((i=1, exprsame(ex->args[0], ex->args[i], 0)) ||
  2353.                 (i=2, exprsame(ex->args[0], ex->args[i], 0))) &&
  2354.                !exproccurs(ex3, ex->args[3-i])) {
  2355.             ep = &ex->args[3-i];
  2356.             while ((ex2 = *ep)->kind == EK_BICALL &&
  2357.                (!strcmp(ex2->val.s, setaddname) ||
  2358.                 !strcmp(ex2->val.s, setaddrangename)))
  2359.             ep = &ex2->args[0];
  2360.             if (ex2->kind == EK_BICALL &&
  2361.             !strcmp(ex2->val.s, setexpandname) &&
  2362.             checkconst(ex2->args[1], 0) &&
  2363.             (mp = istempvar(ex2->args[0])) != NULL) {
  2364.             if (ex2 == ex->args[3-i]) {
  2365.                 ex = grabarg(ex, i);
  2366.             } else {
  2367.                 freeexpr(ex2);
  2368.                 *ep = ex->args[i];
  2369.                 ex = ex->args[3-i];
  2370.             }
  2371.             }
  2372.         } else if (!strcmp(cp, setdiffname) && *setremname &&
  2373.                (ex3 = singlevar(ex->args[0])) != NULL &&
  2374.                exprsame(ex->args[0], ex->args[1], 0) &&
  2375.                !exproccurs(ex3, ex->args[2])) {
  2376.             ep = &ex->args[2];
  2377.             while ((ex2 = *ep)->kind == EK_BICALL &&
  2378.                !strcmp(ex2->val.s, setaddname))
  2379.             ep = &ex2->args[0];
  2380.             if (ex2->kind == EK_BICALL &&
  2381.             !strcmp(ex2->val.s, setexpandname) &&
  2382.             checkconst(ex2->args[1], 0) &&
  2383.             (mp = istempvar(ex2->args[0])) != NULL) {
  2384.             if (ex2 == ex->args[2]) {
  2385.                 ex = grabarg(ex, 1);
  2386.             } else {
  2387.                 ex2 = ex->args[2];
  2388.                 while (ex2->kind == EK_BICALL &&
  2389.                    !strcmp(ex2->val.s, setaddname)) {
  2390.                 strchange(&ex2->val.s, setremname);
  2391.                 ex2 = ex2->args[0];
  2392.                 }
  2393.                 freeexpr(ex2);
  2394.                 *ep = ex->args[1];
  2395.                 ex = ex->args[2];
  2396.             }
  2397.             }
  2398. #endif
  2399.                 } else if (!strcmp(cp, setexpandname) && env == ENV_STMT &&
  2400.                            checkconst(ex->args[1], 0)) {
  2401.                     ex = makeexpr_assign(makeexpr_hat(ex->args[0], 0),
  2402.                                          ex->args[1]);
  2403.                 } else if (!strcmp(cp, getbitsname)) {
  2404.             type = ex->args[0]->val.type;
  2405.             if (type->kind == TK_POINTER)
  2406.             type = type->basetype;
  2407.                     sbuf[0] = (type->issigned) ? 'S' : 'U';
  2408.                     sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
  2409.                     sbuf[2] = 0;
  2410.                     if (sbuf[1] == 'S' &&
  2411.                         type->smax->val.type == tp_boolean) {
  2412.                         ex = makeexpr_rel(EK_NE,
  2413.                                           makeexpr_bin(EK_BAND, tp_integer,
  2414.                                                        ex->args[0],
  2415.                                                        makeexpr_bin(EK_LSH, tp_integer,
  2416.                                                                     makeexpr_longcast(makeexpr_long(1),
  2417.                                                                                       type->basetype
  2418.                                                                                             == tp_unsigned),
  2419.                                                                     ex->args[1])),
  2420.                                           makeexpr_long(0));
  2421.                         ex = fixexpr(ex, env);
  2422.                     } else
  2423.                         strchange(&ex->val.s, format_s(cp, sbuf));
  2424.                 } else if (!strcmp(cp, putbitsname)) {
  2425.             type = ex->args[0]->val.type;
  2426.             if (type->kind == TK_POINTER)
  2427.             type = type->basetype;
  2428.                     sbuf[0] = (type->issigned) ? 'S' : 'U';
  2429.                     sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
  2430.                     sbuf[2] = 0;
  2431.                     if (sbuf[1] == 'S' &&
  2432.                         type->smax->val.type == tp_boolean) {
  2433.                         ex = makeexpr_assign(ex->args[0],
  2434.                                              makeexpr_bin(EK_BOR, tp_integer,
  2435.                                                           copyexpr(ex->args[0]),
  2436.                                                           makeexpr_bin(EK_LSH, tp_integer,
  2437.                                                                        makeexpr_longcast(ex->args[2],
  2438.                                                                                          type->basetype
  2439.                                                                                                == tp_unsigned),
  2440.                                                                        ex->args[1])));
  2441.                     } else
  2442.                         strchange(&ex->val.s, format_s(cp, sbuf));
  2443.                 } else if (!strcmp(cp, storebitsname)) {
  2444.             type = ex->args[0]->val.type;
  2445.             if (type->kind == TK_POINTER)
  2446.             type = type->basetype;
  2447.                     sbuf[0] = (type->issigned) ? 'S' : 'U';
  2448.                     sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
  2449.                     sbuf[2] = 0;
  2450.                     strchange(&ex->val.s, format_s(cp, sbuf));
  2451.                 } else if (!strcmp(cp, clrbitsname)) {
  2452.             type = ex->args[0]->val.type;
  2453.             if (type->kind == TK_POINTER)
  2454.             type = type->basetype;
  2455.                     sbuf[0] = (type->kind == TK_ARRAY) ? 'B' : 'S';
  2456.                     sbuf[1] = 0;
  2457.                     if (sbuf[0] == 'S' &&
  2458.                         type->smax->val.type == tp_boolean) {
  2459.                         ex = makeexpr_assign(ex->args[0],
  2460.                                              makeexpr_bin(EK_BAND, tp_integer,
  2461.                                                    copyexpr(ex->args[0]),
  2462.                                                    makeexpr_un(EK_BNOT, tp_integer,
  2463.                                                           makeexpr_bin(EK_LSH, tp_integer,
  2464.                                                                        makeexpr_longcast(makeexpr_long(1),
  2465.                                                                                          type->basetype
  2466.                                                                                                == tp_unsigned),
  2467.                                                                        ex->args[1]))));
  2468.                     } else
  2469.                         strchange(&ex->val.s, format_s(cp, sbuf));
  2470.                 } else if (!strcmp(cp, "fopen")) {
  2471.             if (which_lang == LANG_HP &&
  2472.             ex->args[0]->kind == EK_CONST &&
  2473.             ex->args[0]->val.type->kind == TK_STRING &&
  2474.             ex->args[0]->val.i >= 1 &&
  2475.             ex->args[0]->val.i <= 2 &&
  2476.             isdigit(ex->args[0]->val.s[0]) &&
  2477.             (ex->args[0]->val.i == 1 ||
  2478.              isdigit(ex->args[0]->val.s[1]))) {
  2479.             strchange(&ex->val.s, "fdopen");
  2480.             ex->args[0] = makeexpr_long(atoi(ex->args[0]->val.s));
  2481.             }
  2482.         }
  2483.             }
  2484.             break;
  2485.  
  2486.         case EK_NOT:
  2487.             ex = makeexpr_not(fixexpr(grabarg(ex, 0), ENV_BOOL));
  2488.             break;
  2489.  
  2490.         case EK_AND:
  2491.         case EK_OR:
  2492.             for (i = 0; i < ex->nargs; ) {
  2493.                 ex->args[i] = fixexpr(ex->args[i], ENV_BOOL);
  2494.         if (checkconst(ex->args[i], (ex->kind == EK_OR) ? 0 : 1) &&
  2495.             ex->nargs > 1)
  2496.             delfreearg(&ex, i);
  2497.         else if (checkconst(ex->args[i], (ex->kind == EK_OR) ? 1 : 0))
  2498.             return grabarg(ex, i);
  2499.         else
  2500.             i++;
  2501.         }
  2502.         if (ex->nargs == 1)
  2503.         ex = grabarg(ex, 0);
  2504.             break;
  2505.  
  2506.         case EK_EQ:
  2507.         case EK_NE:
  2508.             ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
  2509.             ex->args[1] = fixexpr(ex->args[1], ENV_EXPR);
  2510.             if (checkconst(ex->args[1], 0) && env == ENV_BOOL &&
  2511.                 ord_type(ex->args[1]->val.type)->kind != TK_ENUM &&
  2512.                 (implicitzero > 0 ||
  2513.                  (implicitzero < 0 && ex->args[0]->kind == EK_BICALL &&
  2514.                                       boolean_bicall(ex->args[0]->val.s)))) {
  2515.                 if (ex->kind == EK_EQ)
  2516.                     ex = makeexpr_not(grabarg(ex, 0));
  2517.                 else {
  2518.                     ex = grabarg(ex, 0);
  2519.                     ex->val.type = tp_boolean;
  2520.                 }
  2521.             }
  2522.             break;
  2523.  
  2524.         case EK_COND:
  2525.             ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  2526. #if 0
  2527.             val = eval_expr(ex->args[0]);
  2528. #else
  2529.         val = ex->args[0]->val;
  2530.         if (ex->args[0]->kind != EK_CONST)
  2531.         val.type = NULL;
  2532. #endif
  2533.             if (val.type == tp_boolean) {
  2534.                 ex = grabarg(ex, (val.i) ? 1 : 2);
  2535.                 ex = fixexpr(ex, env);
  2536.             } else {
  2537.                 ex->args[1] = fixexpr(ex->args[1], env);
  2538.                 ex->args[2] = fixexpr(ex->args[2], env);
  2539.             }
  2540.             break;
  2541.  
  2542.         case EK_COMMA:
  2543.             for (i = 0; i < ex->nargs; ) {
  2544.         j = (i < ex->nargs-1);
  2545.                 ex->args[i] = fixexpr(ex->args[i], j ? ENV_STMT : env);
  2546.                 if (nosideeffects(ex->args[i], 1) && j) {
  2547.                     delfreearg(&ex, i);
  2548.                 } else if (ex->args[i]->kind == EK_COMMA) {
  2549.             ex2 = ex->args[i];
  2550.             ex->args[i++] = ex2->args[0];
  2551.             for (j = 1; j < ex2->nargs; j++)
  2552.             insertarg(&ex, i++, ex2->args[j]);
  2553.             FREE(ex2);
  2554.         } else
  2555.                     i++;
  2556.             }
  2557.             if (ex->nargs == 1)
  2558.                 ex = grabarg(ex, 0);
  2559.             break;
  2560.  
  2561.         case EK_CHECKNIL:
  2562.             ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
  2563.             if (ex->nargs == 2) {
  2564.                 ex->args[1] = fixexpr(ex->args[1], ENV_EXPR);
  2565.                 ex2 = makeexpr_assign(copyexpr(ex->args[1]), ex->args[0]);
  2566.                 ex3 = ex->args[1];
  2567.             } else {
  2568.                 ex2 = copyexpr(ex->args[0]);
  2569.                 ex3 = ex->args[0];
  2570.             }
  2571.             type = ex->args[0]->val.type;
  2572.             type2 = ex->val.type;
  2573.             ex = makeexpr_cond(makeexpr_rel(EK_NE, ex2, makeexpr_nil()),
  2574.                                ex3,
  2575.                                makeexpr_cast(makeexpr_bicall_0(name_NILCHECK,
  2576.                                                                tp_int),
  2577.                                              type));
  2578.             ex->val.type = type2;
  2579.             ex = fixexpr(ex, env);
  2580.             break;
  2581.  
  2582.         case EK_CAST:
  2583.         case EK_ACTCAST:
  2584.             if (env == ENV_STMT) {
  2585.                 ex = fixexpr(grabarg(ex, 0), ENV_STMT);
  2586.             } else {
  2587.                 ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
  2588.             }
  2589.             break;
  2590.  
  2591.         default:
  2592.             for (i = 0; i < ex->nargs; i++)
  2593.                 ex->args[i] = fixexpr(ex->args[i], ENV_EXPR);
  2594.             break;
  2595.     }
  2596.     if (debug>4) {fprintf(outf, "fixexpr returns "); dumpexpr(ex); fprintf(outf, "\n");}
  2597.     return fix_expression(ex, env);
  2598. }
  2599.  
  2600.  
  2601.  
  2602.  
  2603.  
  2604.  
  2605.  
  2606.  
  2607. /* Output an expression */
  2608.  
  2609.  
  2610. #define bitOp(k)  ((k)==EK_BAND || (k)==EK_BOR || (k)==EK_BXOR)
  2611.  
  2612. #define shfOp(k)  ((k)==EK_LSH || (k)==EK_RSH)
  2613.  
  2614. #define logOp(k)  ((k)==EK_AND || (k)==EK_OR)
  2615.  
  2616. #define relOp(k)  ((k)==EK_EQ || (k)==EK_LT || (k)==EK_GT ||    \
  2617.            (k)==EK_NE || (k)==EK_GE || (k)==EK_LE)
  2618.  
  2619. #define mathOp(k) ((k)==EK_PLUS || (k)==EK_TIMES || (k)==EK_NEG ||   \
  2620.            (k)==EK_DIV || (k)==EK_DIVIDE || (k)==EK_MOD)
  2621.  
  2622. #define divOp(k)  ((k)==EK_DIV || (k)==EK_DIVIDE)
  2623.  
  2624.  
  2625. Static int incompat(ex, num, prec)
  2626. Expr *ex;
  2627. int num, prec;
  2628. {
  2629.     Expr *subex = ex->args[num];
  2630.  
  2631.     if (extraparens == 0)
  2632.     return prec;
  2633.     if (ex->kind == subex->kind) {
  2634.     if (logOp(ex->kind) || bitOp(ex->kind) ||
  2635.         (divOp(ex->kind) && num == 0))
  2636.         return -99;   /* not even invisible parens */
  2637.     else if (extraparens != 2)
  2638.         return prec;
  2639.     }
  2640.     if (extraparens == 2)
  2641.     return 15;
  2642.     if (divOp(ex->kind) && num == 0 &&
  2643.     (subex->kind == EK_TIMES || divOp(subex->kind)))
  2644.     return -99;
  2645.     if (bitOp(ex->kind) || shfOp(ex->kind))
  2646.     return 15;
  2647.     if (relOp(ex->kind) && relOp(subex->kind))
  2648.     return 15;
  2649.     if ((relOp(ex->kind) || logOp(ex->kind)) && bitOp(subex->kind))
  2650.     return 15;
  2651.     if (ex->kind == EK_COMMA)
  2652.     return 15;
  2653.     if (ex->kind == EK_ASSIGN && relOp(subex->kind))
  2654.     return 15;
  2655.     if (extraparens != 1)
  2656.     return prec;
  2657.     if (ex->kind == EK_ASSIGN)
  2658.     return prec;
  2659.     if (relOp(ex->kind) && mathOp(subex->kind))
  2660.     return prec;
  2661.     return 15;
  2662. }
  2663.  
  2664.  
  2665.  
  2666.  
  2667. #define EXTRASPACE() if (spaceexprs == 1) output(" ")
  2668. #define NICESPACE()  if (spaceexprs != 0) output(" ")
  2669.  
  2670. #define setprec(p) \
  2671.     if ((subprec=(p)) <= prec) { \
  2672.         parens = 1; output("("); \
  2673.     }
  2674.  
  2675. #define setprec2(p) \
  2676.     if ((subprec=(p)) <= prec) { \
  2677.         parens = 1; output("("); \
  2678.     } else if (prec != -99) { \
  2679.         parens = 2; output((breakparens == 1) ? "\010" : "\003"); \
  2680.     }
  2681.  
  2682. #define setprec3(p) \
  2683.     if ((subprec=(p)) <= prec) { \
  2684.          parens = 1; output("("); \
  2685.     } else if (prec != -99) { \
  2686.          parens = 2; output((prec > 2 && breakparens != 0) ? "\010" \
  2687.                                                : "\003"); \
  2688.     }
  2689.  
  2690.  
  2691. Static void outop3(breakbefore, name)
  2692. int breakbefore;
  2693. char *name;
  2694. {
  2695.     if (breakbefore & BRK_LEFT) {
  2696.     output("\002");
  2697.     if (breakbefore & BRK_RPREF)
  2698.         output("\013");
  2699.     }
  2700.     output(name);
  2701.     if (breakbefore & BRK_HANG)
  2702.     output("\015");
  2703.     if (breakbefore & BRK_RIGHT) {
  2704.     output("\002");
  2705.     if (breakbefore & BRK_LPREF)
  2706.         output("\013");
  2707.     }
  2708. }
  2709.  
  2710. #define outop(name) do { \
  2711.     NICESPACE(); outop3(breakflag, name); NICESPACE(); \
  2712. } while (0)
  2713.  
  2714. #define outop2(name) do { \
  2715.     EXTRASPACE(); outop3(breakflag, name); EXTRASPACE(); \
  2716. } while (0)
  2717.  
  2718. #define checkbreak(code) do { \
  2719.     breakflag=(code); \
  2720.     if ((prec != -99) && (breakflag & BRK_ALLNONE)) output("\007"); \
  2721. } while (0)
  2722.  
  2723.  
  2724. Static void out_ctx(ctx, address)
  2725. Meaning *ctx;
  2726. int address;
  2727. {
  2728.     Meaning *ctx2;
  2729.     int breakflag = breakbeforedot;
  2730.  
  2731.     if (ctx->kind == MK_FUNCTION && ctx->varstructflag) {
  2732.         if (curctx != ctx) {
  2733.         if (address && curctx->ctx && curctx->ctx != ctx) {
  2734.         output("\003");
  2735.         if (breakflag & BRK_ALLNONE)
  2736.             output("\007");
  2737.         }
  2738.             output(format_s(name_LINK, curctx->ctx->name));
  2739.             ctx2 = curctx->ctx;
  2740.             while (ctx2 && ctx2 != ctx) {
  2741.                 outop2("->");
  2742.                 output(format_s(name_LINK, ctx2->ctx->name));
  2743.                 ctx2 = ctx2->ctx;
  2744.             }
  2745.             if (ctx2 != ctx)
  2746.                 intwarning("out_ctx",
  2747.                            format_s("variable from %s not present in context path [307]",
  2748.                                      ctx->name));
  2749.         if (address && curctx->ctx && curctx->ctx != ctx)
  2750.         output("\004");
  2751.             if (!address)
  2752.                 outop2("->");
  2753.         } else {
  2754.             if (address) {
  2755.                 output("&");
  2756.         EXTRASPACE();
  2757.         }
  2758.             output(format_s(name_VARS, curctx->name));
  2759.             if (!address) {
  2760.                 outop2(".");
  2761.         }
  2762.         }
  2763.     } else {
  2764.         if (address)
  2765.             output("NULL");
  2766.     }
  2767. }
  2768.  
  2769.  
  2770.  
  2771. void out_var(mp, prec)
  2772. Meaning *mp;
  2773. int prec;
  2774. {
  2775.     switch (mp->kind) {
  2776.  
  2777.         case MK_CONST:
  2778.             output(mp->name);
  2779.             return;
  2780.  
  2781.         case MK_VAR:
  2782.         case MK_VARREF:
  2783.         case MK_VARMAC:
  2784.         case MK_PARAM:
  2785.         case MK_VARPARAM:
  2786.             if (mp->varstructflag) {
  2787.         output("\003");
  2788.                 out_ctx(mp->ctx, 0);
  2789.         output(mp->name);
  2790.         output("\004");
  2791.         } else
  2792.         output(mp->name);
  2793.             return;
  2794.  
  2795.     default:
  2796.         if (mp->name)
  2797.         output(mp->name);
  2798.         else
  2799.         intwarning("out_var", "mp->sym == NULL [308]");
  2800.         return;
  2801.     }
  2802. }
  2803.  
  2804.  
  2805.  
  2806. Static int scanfield(variants, unions, lev, mp, field)
  2807. Meaning **variants, *mp, *field;
  2808. short *unions;
  2809. int lev;
  2810. {
  2811.     int i, num, breakflag;
  2812.     Value v;
  2813.  
  2814.     unions[lev] = (mp && mp->kind == MK_VARIANT);
  2815.     while (mp && mp->kind == MK_FIELD) {
  2816.         if (mp == field) {
  2817.             for (i = 0; i < lev; i++) {
  2818.         v = variants[i]->val;    /* sidestep a Sun 386i compiler bug */
  2819.                 num = ord_value(v);
  2820.         breakflag = breakbeforedot;
  2821.                 if (!unions[i]) {
  2822.                     output(format_s(name_UNION, ""));
  2823.             outop2(".");
  2824.                 }
  2825.                 if (variants[i]->ctx->cnext ||
  2826.                     variants[i]->ctx->kind != MK_FIELD) {
  2827.                     output(format_s(name_VARIANT, variantfieldname(num)));
  2828.             outop2(".");
  2829.                 }
  2830.             }
  2831.             output(mp->name);
  2832.             return 1;
  2833.         }
  2834.         mp = mp->cnext;
  2835.     }
  2836.     while (mp && mp->kind == MK_VARIANT) {
  2837.         variants[lev] = mp;
  2838.         if (scanfield(variants, unions, lev+1, mp->ctx, field))
  2839.             return 1;
  2840.         mp = mp->cnext;
  2841.     }
  2842.     return 0;
  2843. }
  2844.  
  2845.  
  2846. void out_field(mp)
  2847. Meaning *mp;
  2848. {
  2849.     Meaning *variants[50];
  2850.     short unions[51];
  2851.  
  2852.     if (!scanfield(variants, unions, 0, mp->rectype->fbase, mp))
  2853.         intwarning("out_field", "field name not in tree [309]");
  2854.     else if (mp->warnifused) {
  2855.         if (mp->rectype->meaning)
  2856.             note(format_ss("Reference to field %s of record %s [282]", 
  2857.                            mp->name, mp->rectype->meaning->name));
  2858.         else
  2859.             note(format_s("Reference to field %s [282]", mp->name));
  2860.     }
  2861. }
  2862.  
  2863.  
  2864.  
  2865.  
  2866. Static void wrexpr(ex, prec)
  2867. Expr *ex;
  2868. int prec;
  2869. {
  2870.     short parens = 0;
  2871.     int subprec, i, j, minusflag, breakflag = 0;
  2872.     int saveindent;
  2873.     Expr *ex2, *ex3;
  2874.     char *cp;
  2875.     Meaning *mp;
  2876.     Symbol *sp;
  2877.  
  2878.     if (debug>2) { fprintf(outf,"wrexpr{"); dumpexpr(ex); fprintf(outf,", %d}\n", prec); }
  2879.     switch (ex->kind) {
  2880.  
  2881.         case EK_VAR:
  2882.             mp = (Meaning *)ex->val.i;
  2883.             if (mp->warnifused)
  2884.                 note(format_s("Reference to %s [283]", mp->name));
  2885.             out_var(mp, prec);
  2886.             break;
  2887.  
  2888.         case EK_NAME:
  2889.             output(ex->val.s);
  2890.             break;
  2891.  
  2892.         case EK_MACARG:
  2893.             output("<meef>");
  2894.             intwarning("wrexpr", "Stray EK_MACARG encountered [310]");
  2895.             break;
  2896.  
  2897.         case EK_CTX:
  2898.             out_ctx((Meaning *)ex->val.i, 1);
  2899.             break;
  2900.  
  2901.         case EK_CONST:
  2902.             if (ex->nargs > 0)
  2903.                 cp = value_name(ex->val, ex->args[0]->val.s, 0);
  2904.             else
  2905.                 cp = value_name(ex->val, NULL, 0);
  2906.             if (*cp == '-')
  2907.                 setprec(14);
  2908.             output(cp);
  2909.             break;
  2910.  
  2911.         case EK_LONGCONST:
  2912.             if (ex->nargs > 0)
  2913.                 cp = value_name(ex->val, ex->args[0]->val.s, 1);
  2914.             else
  2915.                 cp = value_name(ex->val, NULL, 1);
  2916.             if (*cp == '-')
  2917.                 setprec(14);
  2918.             output(cp);
  2919.             break;
  2920.  
  2921.         case EK_STRUCTCONST:
  2922.             ex3 = NULL;
  2923.             for (i = 0; i < ex->nargs; i++) {
  2924.                 ex2 = ex->args[i];
  2925.                 if (ex2->kind == EK_STRUCTOF) {
  2926.                     j = ex2->val.i;
  2927.                     ex2 = ex2->args[0];
  2928.                 } else
  2929.                     j = 1;
  2930.                 if (ex2->kind == EK_VAR) {
  2931.                     mp = (Meaning *)ex2->val.i;
  2932.                     if (mp->kind == MK_CONST &&
  2933.             mp->val.type &&
  2934.                         (mp->val.type->kind == TK_RECORD ||
  2935.                          mp->val.type->kind == TK_ARRAY)) {
  2936.                         if (foldconsts != 1)
  2937.                             note(format_s("Expanding constant %s into another constant [284]",
  2938.                                           mp->name));
  2939.                         ex2 = (Expr *)mp->val.i;
  2940.                     }
  2941.                 }
  2942.                 while (--j >= 0) {
  2943.                     if (ex3) {
  2944.                         if (ex3->kind == EK_STRUCTCONST ||
  2945.                             ex2->kind == EK_STRUCTCONST)
  2946.                             output(",\n");
  2947.                         else if (spacecommas)
  2948.                             output(",\001 ");
  2949.             else
  2950.                 output(",\001");
  2951.                     }
  2952.                     if (ex2->kind == EK_STRUCTCONST) {
  2953.                         output("{ \005");
  2954.             saveindent = outindent;
  2955.             moreindent(extrainitindent);
  2956.                         out_expr(ex2);
  2957.                         outindent = saveindent;
  2958.                         output(" }");
  2959.                     } else
  2960.                         out_expr(ex2);
  2961.                     ex3 = ex2;
  2962.                 }
  2963.             }
  2964.             break;
  2965.  
  2966.         case EK_FUNCTION:
  2967.             mp = (Meaning *)ex->val.i;
  2968.         sp = findsymbol_opt(mp->name);
  2969.         if ((sp && (sp->flags & WARNLIBR)) || mp->warnifused)
  2970.                 note(format_s("Called procedure %s [285]", mp->name));
  2971.             output(mp->name);
  2972.         if (spacefuncs)
  2973.         output(" ");
  2974.             output("(\002");
  2975.         j = sp ? (sp->flags & FUNCBREAK) : 0;
  2976.         if (j == FALLBREAK)
  2977.         output("\007");
  2978.             for (i = 0; i < ex->nargs; i++) {
  2979.         if ((j == FSPCARG1 && i == 1) ||
  2980.             (j == FSPCARG2 && i == 2) ||
  2981.             (j == FSPCARG3 && i == 3))
  2982.             if (spacecommas)
  2983.             output(",\011 ");
  2984.             else
  2985.             output(",\011");
  2986.                 else if (i > 0)
  2987.             if (spacecommas)
  2988.             output(",\002 ");
  2989.             else
  2990.             output(",\002");
  2991.                 out_expr(ex->args[i]);
  2992.             }
  2993.             if (mp->ctx->kind == MK_FUNCTION && mp->ctx->varstructflag) {
  2994.                 if (i > 0)
  2995.             if (spacecommas)
  2996.             output(",\002 ");
  2997.             else
  2998.             output(",\002");
  2999.                 out_ctx(mp->ctx, 1);
  3000.             }
  3001.             output(")");
  3002.             break;
  3003.  
  3004.         case EK_BICALL:
  3005.             cp = ex->val.s;
  3006.             while (*cp == '*')
  3007.                 cp++;
  3008.         sp = findsymbol_opt(cp);
  3009.         if (sp && (sp->flags & WARNLIBR))
  3010.                 note(format_s("Called library procedure %s [286]", cp));
  3011.             output(cp);
  3012.         if (spacefuncs)
  3013.         output(" ");
  3014.             output("(\002");
  3015.         j = sp ? (sp->flags & FUNCBREAK) : 0;
  3016.         if (j == FALLBREAK)
  3017.         output("\007");
  3018.             for (i = 0; i < ex->nargs; i++) {
  3019.         if ((j == FSPCARG1 && i == 1) ||
  3020.             (j == FSPCARG2 && i == 2) ||
  3021.             (j == FSPCARG3 && i == 3))
  3022.             if (spacecommas)
  3023.             output(",\011 ");
  3024.             else
  3025.             output(",\011");
  3026.                 else if (i > 0)
  3027.             if (spacecommas)
  3028.             output(",\002 ");
  3029.             else
  3030.             output(",\002");
  3031.                 out_expr(ex->args[i]);
  3032.             }
  3033.             output(")");
  3034.             break;
  3035.  
  3036.         case EK_SPCALL:
  3037.             setprec(16);
  3038.             if (starfunctions) {
  3039.                 output("(\002*");
  3040.                 wrexpr(ex->args[0], 13);
  3041.                 output(")");
  3042.             } else
  3043.                 wrexpr(ex->args[0], subprec-1);
  3044.         if (spacefuncs)
  3045.         output(" ");
  3046.             output("(\002");
  3047.             for (i = 1; i < ex->nargs; i++) {
  3048.                 if (i > 1)
  3049.             if (spacecommas)
  3050.             output(",\002 ");
  3051.             else
  3052.             output(",\002");
  3053.                 out_expr(ex->args[i]);
  3054.             }
  3055.             output(")");
  3056.             break;
  3057.  
  3058.         case EK_INDEX:
  3059.             setprec(16);
  3060.             wrexpr(ex->args[0], subprec-1);
  3061.         if (lookback(1) == ']')
  3062.         output("\001");
  3063.             output("[");
  3064.             out_expr(ex->args[1]);
  3065.             output("]");
  3066.             break;
  3067.  
  3068.         case EK_DOT:
  3069.             setprec2(16);
  3070.         checkbreak(breakbeforedot);
  3071.             if (ex->args[0]->kind == EK_HAT) {
  3072.                 wrexpr(ex->args[0]->args[0], subprec-1);
  3073.                 outop2("->");
  3074.             } else if (ex->args[0]->kind == EK_CTX) {
  3075.                 out_ctx((Meaning *)ex->args[0]->val.i, 0);
  3076.             } else {
  3077.                 wrexpr(ex->args[0], subprec-1);
  3078.                 outop2(".");
  3079.             }
  3080.             if (ex->val.i)
  3081.                 out_field((Meaning *)ex->val.i);
  3082.             else
  3083.                 output(ex->val.s);
  3084.             break;
  3085.  
  3086.         case EK_POSTINC:
  3087.         if (prec == 0 && !postincrement) {
  3088.         setprec(14);
  3089.         output("++");
  3090.         EXTRASPACE();
  3091.         wrexpr(ex->args[0], subprec);
  3092.         } else {
  3093.         setprec(15);
  3094.         wrexpr(ex->args[0], subprec);
  3095.         EXTRASPACE();
  3096.         output("++");
  3097.         }
  3098.             break;
  3099.  
  3100.         case EK_POSTDEC:
  3101.         if (prec == 0 && !postincrement) {
  3102.         setprec(14);
  3103.         output("--");
  3104.         EXTRASPACE();
  3105.         wrexpr(ex->args[0], subprec);
  3106.         } else {
  3107.         setprec(15);
  3108.         wrexpr(ex->args[0], subprec);
  3109.         EXTRASPACE();
  3110.         output("--");
  3111.         }
  3112.             break;
  3113.  
  3114.         case EK_HAT:
  3115.             setprec(14);
  3116.         if (lookback_prn(1) == '/')
  3117.         output(" ");
  3118.             output("*");
  3119.             EXTRASPACE();
  3120.             wrexpr(ex->args[0], subprec-1);
  3121.             break;
  3122.  
  3123.         case EK_ADDR:
  3124.             setprec(14);
  3125.         if (lookback_prn(1) == '&')
  3126.         output(" ");
  3127.             output("&");
  3128.             EXTRASPACE();
  3129.             wrexpr(ex->args[0], subprec-1);
  3130.             break;
  3131.  
  3132.         case EK_NEG:
  3133.             setprec(14);
  3134.             output("-");
  3135.             EXTRASPACE();
  3136.             if (ex->args[0]->kind == EK_TIMES)
  3137.                 wrexpr(ex->args[0], 12);
  3138.             else
  3139.                 wrexpr(ex->args[0], subprec-1);
  3140.             break;
  3141.  
  3142.         case EK_NOT:
  3143.             setprec(14);
  3144.             output("!");
  3145.             EXTRASPACE();
  3146.             wrexpr(ex->args[0], subprec-1);
  3147.             break;
  3148.  
  3149.         case EK_BNOT:
  3150.             setprec(14);
  3151.             output("~");
  3152.             EXTRASPACE();
  3153.             wrexpr(ex->args[0], subprec-1);
  3154.             break;
  3155.  
  3156.         case EK_CAST:
  3157.         case EK_ACTCAST:
  3158.             if (similartypes(ex->val.type, ex->args[0]->val.type)) {
  3159.                 wrexpr(ex->args[0], prec);
  3160.             } else if (ord_type(ex->args[0]->val.type)->kind == TK_ENUM &&
  3161.                        ex->val.type == tp_int && !useenum) {
  3162.                 wrexpr(ex->args[0], prec);
  3163.             } else {
  3164.                 setprec2(14);
  3165.                 output("(");
  3166.                 out_type(ex->val.type, 0);
  3167.                 output(")\002");
  3168.                 EXTRASPACE();
  3169.                 if (extraparens != 0)
  3170.                     wrexpr(ex->args[0], 15);
  3171.                 else
  3172.                     wrexpr(ex->args[0], subprec-1);
  3173.             }
  3174.             break;
  3175.  
  3176.         case EK_LITCAST:
  3177.             setprec2(14);
  3178.             output("(");
  3179.             out_expr(ex->args[0]);
  3180.             output(")\002");
  3181.             EXTRASPACE();
  3182.             if (extraparens != 0)
  3183.                 wrexpr(ex->args[1], 15);
  3184.             else
  3185.                 wrexpr(ex->args[1], subprec-1);
  3186.             break;
  3187.  
  3188.         case EK_SIZEOF:
  3189.             setprec(14);
  3190.             output("sizeof");
  3191.         if (spacefuncs)
  3192.         output(" ");
  3193.         output("(");
  3194.         out_expr(ex->args[0]);
  3195.             output(")");
  3196.             break;
  3197.  
  3198.     case EK_TYPENAME:
  3199.         out_type(ex->val.type, 1);
  3200.         break;
  3201.  
  3202.         case EK_TIMES:
  3203.         setprec2(13);
  3204.         checkbreak(breakbeforearith);
  3205.             ex2 = copyexpr(ex);
  3206.             if (expr_looks_neg(ex2->args[ex2->nargs-1])) {
  3207.                 ex2->args[0] = makeexpr_neg(ex2->args[0]);
  3208.                 ex2->args[ex2->nargs-1] = makeexpr_neg(ex2->args[ex2->nargs-1]);
  3209.             }
  3210.             wrexpr(ex2->args[0], incompat(ex2, 0, subprec-1));
  3211.             for (i = 1; i < ex2->nargs; i++) {
  3212.                 outop("*");
  3213.                 wrexpr(ex2->args[i], incompat(ex2, i, subprec));
  3214.             }
  3215.             freeexpr(ex2);
  3216.             break;
  3217.  
  3218.         case EK_DIV:
  3219.         case EK_DIVIDE:
  3220.             setprec2(13);
  3221.         checkbreak(breakbeforearith);
  3222.         wrexpr(ex->args[0], incompat(ex, 0, subprec-1));
  3223.             outop("/");
  3224.             wrexpr(ex->args[1], incompat(ex, 1, subprec));
  3225.             break;
  3226.  
  3227.         case EK_MOD:
  3228.             setprec2(13);
  3229.         checkbreak(breakbeforearith);
  3230.             wrexpr(ex->args[0], incompat(ex, 0, subprec-1));
  3231.             outop("%");
  3232.             wrexpr(ex->args[1], incompat(ex, 1, subprec));
  3233.             break;
  3234.  
  3235.         case EK_PLUS:
  3236.             setprec2(12);
  3237.         checkbreak(breakbeforearith);
  3238.             ex2 = copyexpr(ex);
  3239.             minusflag = 0;
  3240.             if (expr_looks_neg(ex2->args[0])) {
  3241.                 j = 1;
  3242.                 while (j < ex2->nargs && expr_looks_neg(ex2->args[j])) j++;
  3243.                 if (j < ex2->nargs)
  3244.                     swapexprs(ex2->args[0], ex2->args[j]);
  3245.             } else if (ex2->val.i && ex2->nargs == 2) {   /* this was originally "a-b" */
  3246.                 if (isliteralconst(ex2->args[1], NULL) != 2) {
  3247.                     if (expr_neg_cost(ex2->args[1]) <= 0) {
  3248.                         minusflag = 1;
  3249.                     } else if (expr_neg_cost(ex2->args[0]) <= 0) {
  3250.                         swapexprs(ex2->args[0], ex2->args[1]);
  3251.                         if (isliteralconst(ex2->args[0], NULL) != 2)
  3252.                             minusflag = 1;
  3253.                     }
  3254.                 }
  3255.             }
  3256.             wrexpr(ex2->args[0], incompat(ex, 0, subprec));
  3257.             for (i = 1; i < ex2->nargs; i++) {
  3258.                 if (expr_looks_neg(ex2->args[i]) || minusflag) {
  3259.                     outop("-");
  3260.                     ex2->args[i] = makeexpr_neg(ex2->args[i]);
  3261.                 } else
  3262.                     outop("+");
  3263.                 wrexpr(ex2->args[i], incompat(ex, i, subprec));
  3264.             }
  3265.             freeexpr(ex2);
  3266.             break;
  3267.  
  3268.         case EK_LSH:
  3269.             setprec3(11);
  3270.         checkbreak(breakbeforearith);
  3271.             wrexpr(ex->args[0], incompat(ex, 0, subprec));
  3272.             outop("<<");
  3273.             wrexpr(ex->args[1], incompat(ex, 1, subprec));
  3274.             break;
  3275.  
  3276.         case EK_RSH:
  3277.             setprec3(11);
  3278.         checkbreak(breakbeforearith);
  3279.         wrexpr(ex->args[0], incompat(ex, 0, subprec));
  3280.             outop(">>");
  3281.             wrexpr(ex->args[1], incompat(ex, 1, subprec));
  3282.             break;
  3283.  
  3284.         case EK_LT:
  3285.             setprec2(10);
  3286.         checkbreak(breakbeforerel);
  3287.             wrexpr(ex->args[0], incompat(ex, 0, subprec));
  3288.             outop("<");
  3289.             wrexpr(ex->args[1], incompat(ex, 0, subprec));
  3290.             break;
  3291.  
  3292.         case EK_GT:
  3293.             setprec2(10);
  3294.         checkbreak(breakbeforerel);
  3295.             wrexpr(ex->args[0], incompat(ex, 0, subprec));
  3296.             outop(">");
  3297.             wrexpr(ex->args[1], incompat(ex, 0, subprec));
  3298.             break;
  3299.  
  3300.         case EK_LE:
  3301.             setprec2(10);
  3302.         checkbreak(breakbeforerel);
  3303.             wrexpr(ex->args[0], incompat(ex, 0, subprec));
  3304.             outop("<=");
  3305.             wrexpr(ex->args[1], incompat(ex, 0, subprec));
  3306.             break;
  3307.  
  3308.         case EK_GE:
  3309.             setprec2(10);
  3310.         checkbreak(breakbeforerel);
  3311.             wrexpr(ex->args[0], incompat(ex, 0, subprec));
  3312.             outop(">=");
  3313.             wrexpr(ex->args[1], incompat(ex, 0, subprec));
  3314.             break;
  3315.  
  3316.         case EK_EQ:
  3317.             setprec2(9);
  3318.         checkbreak(breakbeforerel);
  3319.             wrexpr(ex->args[0], incompat(ex, 0, subprec));
  3320.             outop("==");
  3321.             wrexpr(ex->args[1], incompat(ex, 0, subprec));
  3322.             break;
  3323.  
  3324.         case EK_NE:
  3325.             setprec2(9);
  3326.         checkbreak(breakbeforerel);
  3327.             wrexpr(ex->args[0], incompat(ex, 0, subprec));
  3328.             outop("!=");
  3329.             wrexpr(ex->args[1], incompat(ex, 0, subprec));
  3330.             break;
  3331.  
  3332.         case EK_BAND:
  3333.             setprec3(8);
  3334.         if (ex->val.type == tp_boolean)
  3335.         checkbreak(breakbeforelog);
  3336.         else
  3337.         checkbreak(breakbeforearith);
  3338.             wrexpr(ex->args[0], incompat(ex, 0, subprec-1));
  3339.         outop("&");
  3340.             wrexpr(ex->args[1], incompat(ex, 1, subprec-1));
  3341.             break;
  3342.  
  3343.         case EK_BXOR:
  3344.             setprec3(7);
  3345.         checkbreak(breakbeforearith);
  3346.             wrexpr(ex->args[0], incompat(ex, 0, subprec-1));
  3347.             outop("^");
  3348.             wrexpr(ex->args[1], incompat(ex, 1, subprec-1));
  3349.             break;
  3350.  
  3351.         case EK_BOR:
  3352.             setprec3(6);
  3353.         if (ex->val.type == tp_boolean)
  3354.         checkbreak(breakbeforelog);
  3355.         else
  3356.         checkbreak(breakbeforearith);
  3357.             wrexpr(ex->args[0], incompat(ex, 0, subprec-1));
  3358.         outop("|");
  3359.             wrexpr(ex->args[1], incompat(ex, 1, subprec-1));
  3360.             break;
  3361.  
  3362.         case EK_AND:
  3363.             setprec3(5);
  3364.         checkbreak(breakbeforelog);
  3365.         wrexpr(ex->args[0], incompat(ex, 0, subprec-1));
  3366.             outop("&&");
  3367.         wrexpr(ex->args[1], incompat(ex, 1, subprec-1));
  3368.             break;
  3369.  
  3370.         case EK_OR:
  3371.             setprec3(4);
  3372.         checkbreak(breakbeforelog);
  3373.         wrexpr(ex->args[0], incompat(ex, 0, subprec-1));
  3374.             outop("||");
  3375.         wrexpr(ex->args[1], incompat(ex, 1, subprec-1));
  3376.             break;
  3377.  
  3378.         case EK_COND:
  3379.             setprec3(3);
  3380.         i = 0;
  3381.         for (;;) {
  3382.         i++;
  3383.         if (extraparens != 0)
  3384.             wrexpr(ex->args[0], 15);
  3385.         else
  3386.             wrexpr(ex->args[0], subprec);
  3387.         NICESPACE();
  3388.         output("\002?");
  3389.         NICESPACE();
  3390.         out_expr(ex->args[1]);
  3391.         if (ex->args[2]->kind == EK_COND) {
  3392.             NICESPACE();
  3393.             output("\002:");
  3394.             NICESPACE();
  3395.             ex = ex->args[2];
  3396.         } else {
  3397.             NICESPACE();
  3398.             output((i == 1) ? "\017:" : "\002:");
  3399.             NICESPACE();
  3400.             wrexpr(ex->args[2], subprec-1);
  3401.             break;
  3402.         }
  3403.         }
  3404.             break;
  3405.  
  3406.         case EK_ASSIGN:
  3407.             if (ex->args[1]->kind == EK_PLUS &&
  3408.                 exprsame(ex->args[1]->args[0], ex->args[0], 2) &&
  3409.                 ex->args[1]->args[1]->kind == EK_CONST &&
  3410.                 ex->args[1]->args[1]->val.type->kind == TK_INTEGER &&
  3411.                 abs(ex->args[1]->args[1]->val.i) == 1) {
  3412.         if (prec == 0 && postincrement) {
  3413.             setprec(15);
  3414.             wrexpr(ex->args[0], subprec);
  3415.             EXTRASPACE();
  3416.             if (ex->args[1]->args[1]->val.i == 1)
  3417.             output("++");
  3418.             else
  3419.             output("--");
  3420.         } else {
  3421.             setprec(14);
  3422.             if (ex->args[1]->args[1]->val.i == 1)
  3423.             output("++");
  3424.             else
  3425.             output("--");
  3426.             EXTRASPACE();
  3427.             wrexpr(ex->args[0], subprec-1);
  3428.         }
  3429.             } else {
  3430.                 setprec2(2);
  3431.         checkbreak(breakbeforeassign);
  3432.                 wrexpr(ex->args[0], subprec);
  3433.                 ex2 = copyexpr(ex->args[1]);
  3434.                 j = -1;
  3435.                 switch (ex2->kind) {
  3436.  
  3437.                     case EK_PLUS:
  3438.                     case EK_TIMES:
  3439.                     case EK_BAND:
  3440.                     case EK_BOR:
  3441.                     case EK_BXOR:
  3442.                         for (i = 0; i < ex2->nargs; i++) {
  3443.                             if (exprsame(ex->args[0], ex2->args[i], 2)) {
  3444.                                 j = i;
  3445.                                 break;
  3446.                             }
  3447.                             if (ex2->val.type->kind == TK_REAL)
  3448.                                 break;   /* non-commutative */
  3449.                         }
  3450.                         break;
  3451.  
  3452.                     case EK_DIVIDE:
  3453.                     case EK_DIV:
  3454.                     case EK_MOD:
  3455.                     case EK_LSH:
  3456.                     case EK_RSH:
  3457.                         if (exprsame(ex->args[0], ex2->args[0], 2))
  3458.                             j = 0;
  3459.                         break;
  3460.  
  3461.             default:
  3462.             break;
  3463.                 }
  3464.                 if (j >= 0) {
  3465.                     if (ex2->nargs == 2)
  3466.                         ex2 = grabarg(ex2, 1-j);
  3467.                     else
  3468.                         delfreearg(&ex2, j);
  3469.                     switch (ex->args[1]->kind) {
  3470.  
  3471.                         case EK_PLUS:
  3472.                             if (expr_looks_neg(ex2)) {
  3473.                                 outop("-=");
  3474.                                 ex2 = makeexpr_neg(ex2);
  3475.                             } else
  3476.                                 outop("+=");
  3477.                             break;
  3478.  
  3479.                         case EK_TIMES:
  3480.                             outop("*=");
  3481.                             break;
  3482.  
  3483.                         case EK_DIVIDE:
  3484.                         case EK_DIV:
  3485.                             outop("/=");
  3486.                             break;
  3487.  
  3488.                         case EK_MOD:
  3489.                             outop("%=");
  3490.                             break;
  3491.  
  3492.                         case EK_LSH:
  3493.                             outop("<<=");
  3494.                             break;
  3495.  
  3496.                         case EK_RSH:
  3497.                             outop(">>=");
  3498.                             break;
  3499.  
  3500.                         case EK_BAND:
  3501.                             outop("&=");
  3502.                             break;
  3503.  
  3504.                         case EK_BOR:
  3505.                             outop("|=");
  3506.                             break;
  3507.  
  3508.                         case EK_BXOR:
  3509.                             outop("^=");
  3510.                             break;
  3511.  
  3512.             default:
  3513.                 break;
  3514.                     }
  3515.                 } else {
  3516.             output(" ");
  3517.             outop3(breakbeforeassign, "=");
  3518.             output(" ");
  3519.                 }
  3520.                 if (extraparens != 0 &&
  3521.                     (ex2->kind == EK_EQ || ex2->kind == EK_NE ||
  3522.                      ex2->kind == EK_GT || ex2->kind == EK_LT ||
  3523.                      ex2->kind == EK_GE || ex2->kind == EK_LE ||
  3524.                      ex2->kind == EK_AND || ex2->kind == EK_OR))
  3525.                     wrexpr(ex2, 16);
  3526.                 else
  3527.                     wrexpr(ex2, subprec-1);
  3528.                 freeexpr(ex2);
  3529.             }
  3530.             break;
  3531.  
  3532.         case EK_COMMA:
  3533.             setprec3(1);
  3534.             for (i = 0; i < ex->nargs-1; i++) {
  3535.                 wrexpr(ex->args[i], subprec);
  3536.                 output(",\002");
  3537.         if (spacecommas)
  3538.             NICESPACE();
  3539.             }
  3540.             wrexpr(ex->args[ex->nargs-1], subprec);
  3541.             break;
  3542.  
  3543.         default:
  3544.             intwarning("wrexpr", "bad ex->kind [311]");
  3545.     }
  3546.     switch (parens) {
  3547.       case 1:
  3548.         output(")");
  3549.     break;
  3550.       case 2:
  3551.     output("\004");
  3552.     break;
  3553.     }
  3554. }
  3555.  
  3556.  
  3557.  
  3558. /* will parenthesize assignments and "," operators */
  3559.  
  3560. void out_expr(ex)
  3561. Expr *ex;
  3562. {
  3563.     wrexpr(ex, 2);
  3564. }
  3565.  
  3566.  
  3567.  
  3568. /* will not parenthesize anything at top level */
  3569.  
  3570. void out_expr_top(ex)
  3571. Expr *ex;
  3572. {
  3573.     wrexpr(ex, 0);
  3574. }
  3575.  
  3576.  
  3577.  
  3578. /* will parenthesize unless only writing a factor */
  3579.  
  3580. void out_expr_factor(ex)
  3581. Expr *ex;
  3582. {
  3583.     wrexpr(ex, 15);
  3584. }
  3585.  
  3586.  
  3587.  
  3588. /* will parenthesize always */
  3589.  
  3590. void out_expr_parens(ex)
  3591. Expr *ex;
  3592. {
  3593.     output("(");
  3594.     wrexpr(ex, 1);
  3595.     output(")");
  3596. }
  3597.  
  3598.  
  3599.  
  3600. /* evaluate expression for side effects only */
  3601. /* no top-level parentheses */
  3602.  
  3603. void out_expr_stmt(ex)
  3604. Expr *ex;
  3605. {
  3606.     wrexpr(ex, 0);
  3607. }
  3608.  
  3609.  
  3610.  
  3611. /* evaluate expression for boolean (zero/non-zero) result only */
  3612. /* parenthesizes like out_expr() */
  3613.  
  3614. void out_expr_bool(ex)
  3615. Expr *ex;
  3616. {
  3617.     wrexpr(ex, 2);
  3618. }
  3619.  
  3620.  
  3621.  
  3622.  
  3623. /* End. */
  3624.  
  3625.  
  3626.  
  3627.