pexpr.c.1
上传用户:upcnvip
上传日期:2007-01-06
资源大小:474k
文件大小:48k
源码类别:

编译器/解释器

开发平台:

C/C++

  1. /* "p2c", a Pascal to C translator.
  2.    Copyright (C) 1989 David Gillespie.
  3.    Author's address: daveg@csvax.caltech.edu; 256-80 Caltech/Pasadena CA 91125.
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation (any version).
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; see the file COPYING.  If not, write to
  13. the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
  14. #define PROTO_PEXPR_C
  15. #include "trans.h"
  16. Expr *dots_n_hats(ex, target)
  17. Expr *ex;
  18. Type *target;
  19. {
  20.     Expr *ex2, *ex3;
  21.     Type *tp, *tp2, *ot;
  22.     Meaning *mp, *tvar;
  23.     int bits, hassl;
  24.     for (;;) {
  25. if ((ex->val.type->kind == TK_PROCPTR ||
  26.      ex->val.type->kind == TK_CPROCPTR) &&
  27.     curtok != TOK_ASSIGN &&
  28.     ((mp = (tp2 = ex->val.type)->basetype->fbase) == NULL ||
  29.      (mp->isreturn && mp->xnext == NULL) ||
  30.      curtok == TOK_LPAR) &&
  31.     (tp2->basetype->basetype != tp_void || target == tp_void) &&
  32.     (!target || (target->kind != TK_PROCPTR &&
  33.  target->kind != TK_CPROCPTR))) {
  34.     hassl = tp2->escale;
  35.     ex2 = ex;
  36.     ex3 = copyexpr(ex2);
  37.     if (hassl != 0)
  38. ex3 = makeexpr_cast(makeexpr_dotq(ex3, "proc", tp_anyptr),
  39.     makepointertype(tp2->basetype));
  40.     ex = makeexpr_un(EK_SPCALL, tp2->basetype->basetype, ex3);
  41.     if (mp && mp->isreturn) {  /* pointer to buffer for return value */
  42. tvar = makestmttempvar(ex->val.type->basetype,
  43.        (ex->val.type->basetype->kind == TK_STRING) ? name_STRING : name_TEMP);
  44. insertarg(&ex, 1, makeexpr_addr(makeexpr_var(tvar)));
  45. mp = mp->xnext;
  46.     }
  47.     if (mp) {
  48. if (wneedtok(TOK_LPAR)) {
  49.     ex = p_funcarglist(ex, mp, 0, 0);
  50.     skipcloseparen();
  51. }
  52.     } else if (curtok == TOK_LPAR) {
  53. gettok();
  54. if (!wneedtok(TOK_RPAR))
  55.     skippasttoken(TOK_RPAR);
  56.     }
  57.     if (hassl != 1 || hasstaticlinks == 2) {
  58. freeexpr(ex2);
  59.     } else {
  60. ex2 = makeexpr_dotq(ex2, "link", tp_anyptr),
  61. ex3 = copyexpr(ex);
  62. insertarg(&ex3, ex3->nargs, copyexpr(ex2));
  63. tp = maketype(TK_FUNCTION);
  64. tp->basetype = tp2->basetype->basetype;
  65. tp->fbase = tp2->basetype->fbase;
  66. tp->issigned = 1;
  67. ex3->args[0]->val.type = makepointertype(tp);
  68. ex = makeexpr_cond(makeexpr_rel(EK_NE, ex2, makeexpr_nil()),
  69.    ex3, ex);
  70.     }
  71.     if (tp2->basetype->fbase &&
  72. tp2->basetype->fbase->isreturn &&
  73. tp2->basetype->fbase->kind == MK_VARPARAM)
  74. ex = makeexpr_hat(ex, 0);    /* returns pointer to structured result */
  75.     continue;
  76. }
  77.         switch (curtok) {
  78.             case TOK_HAT:
  79.     case TOK_ADDR:
  80.                 gettok();
  81.                 ex = makeexpr_hat(ex, 1);
  82.                 break;
  83.             case TOK_LBR:
  84.                 do {
  85.                     gettok();
  86.                     tp = ex->val.type;
  87.                     if (tp->kind == TK_STRING) {
  88.                         ex2 = p_expr(tp_integer);
  89.                         if (checkconst(ex2, 0))   /* is it "s[0]"? */
  90.                             ex = makeexpr_bicall_1("strlen", tp_char, ex);
  91.                         else
  92.                             ex = makeexpr_index(ex, ex2, makeexpr_long(1));
  93.                     } else if (tp->kind == TK_ARRAY ||
  94.                                tp->kind == TK_SMALLARRAY) {
  95.                         if (tp->smax) {
  96.                             ord_range_expr(tp->indextype, &ex2, NULL);
  97.                             ex2 = makeexpr_minus(p_ord_expr(),
  98.  copyexpr(ex2));
  99.                             if (!nodependencies(ex2, 0) &&
  100.                                 *getbitsname == '*') {
  101.                                 mp = makestmttempvar(tp_integer, name_TEMP);
  102.                                 ex3 = makeexpr_assign(makeexpr_var(mp), ex2);
  103.                                 ex2 = makeexpr_var(mp);
  104.                             } else
  105.                                 ex3 = NULL;
  106.                             ex = makeexpr_bicall_3(getbitsname, tp_int,
  107.                                                    ex, ex2,
  108.                                                    makeexpr_long(tp->escale));
  109.                             if (tp->kind == TK_ARRAY) {
  110.                                 if (tp->basetype == tp_sshort)
  111.                                     bits = 4;
  112.                                 else
  113.                                     bits = 3;
  114.                                 insertarg(&ex, 3, makeexpr_long(bits));
  115.                             }
  116.                             ex = makeexpr_comma(ex3, ex);
  117.                             ot = ord_type(tp->smax->val.type);
  118.                             if (ot->kind == TK_ENUM && ot->meaning && useenum)
  119.                                 ex = makeexpr_cast(ex, tp->smax->val.type);
  120.                             ex->val.type = tp->smax->val.type;
  121.                         } else {
  122.                             ord_range_expr(ex->val.type->indextype, &ex2, NULL);
  123.                             if (debug>2) { fprintf(outf, "ord_range_expr returns "); dumpexpr(ex2); fprintf(outf, "n"); }
  124.                             ex = makeexpr_index(ex, p_ord_expr(),
  125. copyexpr(ex2));
  126.                         }
  127.                     } else {
  128.                         warning("Index on a non-array variable [287]");
  129. ex = makeexpr_bin(EK_INDEX, tp_integer, ex, p_expr(tp_integer));
  130.     }
  131.                 } while (curtok == TOK_COMMA);
  132.                 if (!wneedtok(TOK_RBR))
  133.     skippasttotoken(TOK_RBR, TOK_SEMI);
  134.                 break;
  135.             case TOK_DOT:
  136.                 gettok();
  137.                 if (!wexpecttok(TOK_IDENT))
  138.     break;
  139. if (ex->val.type->kind == TK_STRING) {
  140.     if (!strcicmp(curtokbuf, "LENGTH")) {
  141. ex = makeexpr_bicall_1("strlen", tp_int, ex);
  142.     } else if (!strcicmp(curtokbuf, "BODY")) {
  143. /* nothing to do */
  144.     }
  145.     gettok();
  146.     break;
  147. }
  148.                 mp = curtoksym->fbase;
  149.                 while (mp && mp->rectype != ex->val.type)
  150.                     mp = mp->snext;
  151.                 if (mp)
  152.                     ex = makeexpr_dot(ex, mp);
  153.                 else {
  154.                     warning(format_s("No field called %s in that record [288]", curtokbuf));
  155.     ex = makeexpr_dotq(ex, curtokcase, tp_integer);
  156. }
  157.                 gettok();
  158.                 break;
  159.     case TOK_COLONCOLON:
  160. gettok();
  161. if (wexpecttok(TOK_IDENT)) {
  162.     ex = pascaltypecast(curtokmeaning->type, ex);
  163.     gettok();
  164. }
  165. break;
  166.             default:
  167.                 return ex;
  168.         }
  169.     }
  170. }
  171. Expr *fake_dots_n_hats(ex)
  172. Expr *ex;
  173. {
  174.     for (;;) {
  175.         switch (curtok) {
  176.             case TOK_HAT:
  177.     case TOK_ADDR:
  178.         if (ex->val.type->kind == TK_POINTER)
  179.     ex = makeexpr_hat(ex, 0);
  180. else {
  181.     ex->val.type = makepointertype(ex->val.type);
  182.     ex = makeexpr_un(EK_HAT, ex->val.type->basetype, ex);
  183. }
  184.                 gettok();
  185.                 break;
  186.             case TOK_LBR:
  187.                 do {
  188.                     gettok();
  189.                     ex = makeexpr_bin(EK_INDEX, tp_integer, ex, p_expr(tp_integer));
  190.                 } while (curtok == TOK_COMMA);
  191.                 if (!wneedtok(TOK_RBR))
  192.     skippasttotoken(TOK_RBR, TOK_SEMI);
  193.                 break;
  194.             case TOK_DOT:
  195.                 gettok();
  196.                 if (!wexpecttok(TOK_IDENT))
  197.     break;
  198.                 ex = makeexpr_dotq(ex, curtokcase, tp_integer);
  199.                 gettok();
  200.                 break;
  201.     case TOK_COLONCOLON:
  202. gettok();
  203. if (wexpecttok(TOK_IDENT)) {
  204.     ex = pascaltypecast(curtokmeaning->type, ex);
  205.     gettok();
  206. }
  207. break;
  208.             default:
  209.                 return ex;
  210.         }
  211.     }
  212. }
  213. Static void bindnames(ex)
  214. Expr *ex;
  215. {
  216.     int i;
  217.     Symbol *sp;
  218.     Meaning *mp;
  219.     if (ex->kind == EK_NAME) {
  220. sp = findsymbol_opt(fixpascalname(ex->val.s));
  221. if (sp) {
  222.     mp = sp->mbase;
  223.     while (mp && !mp->isactive)
  224. mp = mp->snext;
  225.     if (mp && !strcmp(mp->name, ex->val.s)) {
  226. ex->kind = EK_VAR;
  227. ex->val.i = (long)mp;
  228. ex->val.type = mp->type;
  229.     }
  230. }
  231.     }
  232.     i = ex->nargs;
  233.     while (--i >= 0)
  234. bindnames(ex->args[i]);
  235. }
  236. void var_reference(mp)
  237. Meaning *mp;
  238. {
  239.     Meaning *mp2;
  240.     mp->refcount++;
  241.     if (mp->ctx && mp->ctx->kind == MK_FUNCTION &&
  242. mp->ctx->needvarstruct &&
  243. (mp->kind == MK_VAR ||
  244.  mp->kind == MK_VARREF ||
  245.  mp->kind == MK_VARMAC ||
  246.  mp->kind == MK_PARAM ||
  247.  mp->kind == MK_VARPARAM ||
  248.  (mp->kind == MK_CONST &&
  249.   (mp->type->kind == TK_ARRAY ||
  250.    mp->type->kind == TK_RECORD)))) {
  251.         if (debug>1) { fprintf(outf, "varstruct'ing %sn", mp->name); }
  252.         if (!mp->varstructflag) {
  253.             mp->varstructflag = 1;
  254.             if (mp->constdefn &&      /* move init code into function body */
  255. mp->kind != MK_VARMAC) {
  256.                 mp2 = addmeaningafter(mp, curtoksym, MK_VAR);
  257.                 curtoksym->mbase = mp2->snext;  /* hide this fake variable */
  258.                 mp2->snext = mp;      /* remember true variable */
  259.                 mp2->type = mp->type;
  260.                 mp2->constdefn = mp->constdefn;
  261.                 mp2->isforward = 1;   /* declare it "static" */
  262.                 mp2->refcount++;      /* so it won't be purged! */
  263.                 mp->constdefn = NULL;
  264.                 mp->isforward = 0;
  265.             }
  266.         }
  267.         for (mp2 = curctx->ctx; mp2 != mp->ctx; mp2 = mp2->ctx)
  268.             mp2->varstructflag = 1;
  269.         mp2->varstructflag = 1;
  270.     }
  271. }
  272. Static Expr *p_variable(target)
  273. Type *target;
  274. {
  275.     Expr *ex, *ex2;
  276.     Meaning *mp;
  277.     Symbol *sym;
  278.     if (curtok != TOK_IDENT) {
  279.         warning("Expected a variable [289]");
  280. return makeexpr_long(0);
  281.     }
  282.     if (!curtokmeaning) {
  283. sym = curtoksym;
  284.         ex = makeexpr_name(curtokcase, tp_integer);
  285.         gettok();
  286.         if (curtok == TOK_LPAR) {
  287.             ex = makeexpr_bicall_0(ex->val.s, tp_integer);
  288.             do {
  289.                 gettok();
  290.                 insertarg(&ex, ex->nargs, p_expr(NULL));
  291.             } while (curtok == TOK_COMMA || curtok == TOK_ASSIGN);
  292.             if (!wneedtok(TOK_RPAR))
  293. skippasttotoken(TOK_RPAR, TOK_SEMI);
  294.         }
  295. if (!tryfuncmacro(&ex, NULL))
  296.     undefsym(sym);
  297.         return fake_dots_n_hats(ex);
  298.     }
  299.     var_reference(curtokmeaning);
  300.     mp = curtokmeaning;
  301.     if (mp->kind == MK_FIELD) {
  302.         ex = makeexpr_dot(copyexpr(withexprs[curtokint]), mp);
  303.     } else if (mp->kind == MK_CONST &&
  304.        mp->type->kind == TK_SET &&
  305.        mp->constdefn) {
  306. ex = copyexpr(mp->constdefn);
  307. mp = makestmttempvar(ex->val.type, name_SET);
  308.         ex2 = makeexpr(EK_MACARG, 0);
  309.         ex2->val.type = ex->val.type;
  310. ex = replaceexprexpr(ex, ex2, makeexpr_var(mp));
  311.         freeexpr(ex2);
  312.     } else if (mp->kind == MK_CONST &&
  313.                (mp == mp_false ||
  314.                 mp == mp_true ||
  315.                 mp->anyvarflag ||
  316.                 (foldconsts > 0 &&
  317.                  (mp->type->kind == TK_INTEGER ||
  318.                   mp->type->kind == TK_BOOLEAN ||
  319.                   mp->type->kind == TK_CHAR ||
  320.                   mp->type->kind == TK_ENUM ||
  321.                   mp->type->kind == TK_SUBR ||
  322.                   mp->type->kind == TK_REAL)) ||
  323.                 (foldstrconsts > 0 &&
  324.                  (mp->type->kind == TK_STRING)))) {
  325.         if (mp->constdefn) {
  326.             ex = copyexpr(mp->constdefn);
  327.             if (ex->val.type == tp_int)   /* kludge! */
  328.                 ex->val.type = tp_integer;
  329.         } else
  330.             ex = makeexpr_val(copyvalue(mp->val));
  331.     } else if (mp->kind == MK_VARPARAM ||
  332.                mp->kind == MK_VARREF) {
  333.         ex = makeexpr_hat(makeexpr_var(mp), 0);
  334.     } else if (mp->kind == MK_VARMAC) {
  335.         ex = copyexpr(mp->constdefn);
  336. bindnames(ex);
  337.         ex = gentle_cast(ex, mp->type);
  338.         ex->val.type = mp->type;
  339.     } else if (mp->kind == MK_SPVAR && mp->handler) {
  340.         gettok();
  341.         ex = (*mp->handler)(mp);
  342.         return dots_n_hats(ex, target);
  343.     } else if (mp->kind == MK_VAR ||
  344.                mp->kind == MK_CONST ||
  345.                mp->kind == MK_PARAM) {
  346.         ex = makeexpr_var(mp);
  347.     } else {
  348.         symclass(mp->sym);
  349.         ex = makeexpr_name(mp->name, tp_integer);
  350.     }
  351.     gettok();
  352.     return dots_n_hats(ex, target);
  353. }
  354. Expr *p_ord_expr()
  355. {
  356.     return makeexpr_charcast(p_expr(tp_integer));
  357. }
  358. Static Expr *makesmallsetconst(bits, type)
  359. long bits;
  360. Type *type;
  361. {
  362.     Expr *ex;
  363.     ex = makeexpr_long(bits);
  364.     ex->val.type = type;
  365.     if (smallsetconst != 2)
  366.         insertarg(&ex, 0, makeexpr_name("%#lx", tp_integer));
  367.     return ex;
  368. }
  369. Expr *packset(ex, type)
  370. Expr *ex;
  371. Type *type;
  372. {
  373.     Meaning *mp;
  374.     Expr *ex2;
  375.     long max2;
  376.     if (ex->kind == EK_BICALL) {
  377.         if (!strcmp(ex->val.s, setexpandname) &&
  378.             (mp = istempvar(ex->args[0])) != NULL) {
  379.             canceltempvar(mp);
  380.             return grabarg(ex, 1);
  381.         }
  382.         if (!strcmp(ex->val.s, setunionname) &&
  383.             (mp = istempvar(ex->args[0])) != NULL &&
  384.             !exproccurs(ex->args[1], ex->args[0]) &&
  385.             !exproccurs(ex->args[2], ex->args[0])) {
  386.             canceltempvar(mp);
  387.             return makeexpr_bin(EK_BOR, type, packset(ex->args[1], type),
  388.                                               packset(ex->args[2], type));
  389.         }
  390.         if (!strcmp(ex->val.s, setaddname)) {
  391.             ex2 = makeexpr_bin(EK_LSH, type,
  392.                                makeexpr_longcast(makeexpr_long(1), 1),
  393.                                ex->args[1]);
  394.             ex = packset(ex->args[0], type);
  395.             if (checkconst(ex, 0))
  396.                 return ex2;
  397.             else
  398.                 return makeexpr_bin(EK_BOR, type, ex, ex2);
  399.         }
  400.         if (!strcmp(ex->val.s, setaddrangename)) {
  401.             if (ord_range(type->indextype, NULL, &max2) && max2 == setbits-1)
  402.                 note("Range construction was implemented by a subtraction which may overflow [278]");
  403.             ex2 = makeexpr_minus(makeexpr_bin(EK_LSH, type,
  404.                                               makeexpr_longcast(makeexpr_long(1), 1),
  405.                                               makeexpr_plus(ex->args[2],
  406.                                                             makeexpr_long(1))),
  407.                                  makeexpr_bin(EK_LSH, type,
  408.                                               makeexpr_longcast(makeexpr_long(1), 1),
  409.                                               ex->args[1]));
  410.             ex = packset(ex->args[0], type);
  411.             if (checkconst(ex, 0))
  412.                 return ex2;
  413.             else
  414.                 return makeexpr_bin(EK_BOR, type, ex, ex2);
  415.         }
  416.     }
  417.     return makeexpr_bicall_1(setpackname, type, ex);
  418. }
  419. #define MAXSETLIT 400
  420. Expr *p_setfactor(type)
  421. Type *type;
  422. {
  423.     Expr *ex, *exmax = NULL, *ex2;
  424.     Expr *first[MAXSETLIT], *last[MAXSETLIT];
  425.     char doneflag[MAXSETLIT];
  426.     int i, j, num, donecount;
  427.     int isconst, guesstype = 0;
  428.     long maxv, max2;
  429.     Value val;
  430.     Type *tp;
  431.     Meaning *tvar;
  432.     if (curtok == TOK_LBRACE)
  433. gettok();
  434.     else if (!wneedtok(TOK_LBR))
  435. return makeexpr_long(0);
  436.     if (curtok == TOK_RBR || curtok == TOK_RBRACE) {        /* empty set */
  437.         gettok();
  438.         val.type = tp_smallset;
  439.         val.i = 0;
  440.         val.s = NULL;
  441.         return makeexpr_val(val);
  442.     }
  443.     if (!type)
  444.         guesstype = 1;
  445.     maxv = -1;
  446.     isconst = 1;
  447.     num = 0;
  448.     for (;;) {
  449.         if (num >= MAXSETLIT) {
  450.             warning(format_d("Too many elements in set literal; max=%d [290]", MAXSETLIT));
  451.             ex = p_expr(type);
  452.             while (curtok != TOK_RBR && curtok != TOK_RBRACE) {
  453.                 gettok();
  454.                 ex = p_expr(type);
  455.             }
  456.             break;
  457.         }
  458.         if (guesstype && num == 0) {
  459.             ex = p_ord_expr();
  460.             type = ord_type(ex->val.type);
  461.         } else {
  462.             ex = p_expr(type);
  463.         }
  464.         first[num] = ex = gentle_cast(ex, type);
  465.         doneflag[num] = 0;
  466.         if (curtok == TOK_DOTS) {
  467.             val = eval_expr(ex);
  468.             if (val.type) {
  469. if (val.i > maxv) {     /* In case of [127..0] */
  470.     maxv = val.i;
  471.     exmax = ex;
  472. }
  473.     } else
  474.                 isconst = 0;
  475.             gettok();
  476.             last[num] = ex = gentle_cast(p_expr(type), type);
  477.         } else {
  478.             last[num] = NULL;
  479.         }
  480.         val = eval_expr(ex);
  481.         if (val.type) {
  482.             if (val.i > maxv) {
  483.                 maxv = val.i;
  484.                 exmax = ex;
  485.             }
  486.         } else {
  487.             isconst = 0;
  488.             maxv = LONG_MAX;
  489.         }
  490.         num++;
  491.         if (curtok == TOK_COMMA)
  492.             gettok();
  493.         else
  494.             break;
  495.     }
  496.     if (curtok == TOK_RBRACE)
  497. gettok();
  498.     else if (!wneedtok(TOK_RBR))
  499. skippasttotoken(TOK_RBR, TOK_SEMI);
  500.     tp = ord_type(first[0]->val.type);
  501.     if (guesstype) {      /* must determine type */
  502.         if (!exmax || maxv == LONG_MAX) {
  503.             maxv = defaultsetsize-1;
  504.             if (ord_range(tp, NULL, &max2) && maxv > max2)
  505.                 maxv = max2;
  506.             exmax = makeexpr_long(maxv);
  507.         } else
  508.             exmax = copyexpr(exmax);
  509.         if (!ord_range(tp, NULL, &max2) || maxv != max2)
  510.             tp = makesubrangetype(tp, makeexpr_long(0), exmax);
  511.         type = makesettype(tp);
  512.     } else
  513. type = makesettype(type);
  514.     donecount = 0;
  515.     if (smallsetconst > 0) {
  516.         val.i = 0;
  517.         for (i = 0; i < num; i++) {
  518.             if (first[i]->kind == EK_CONST && first[i]->val.i < setbits &&
  519.                 (!last[i] || (last[i]->kind == EK_CONST &&
  520.                               last[i]->val.i >= 0 &&
  521.                               last[i]->val.i < setbits))) {
  522.                 if (last[i]) {
  523.                     for (j = first[i]->val.i; j <= last[i]->val.i; j++)
  524.                         val.i |= 1<<j;
  525.                 } else
  526.     val.i |= 1 << first[i]->val.i;
  527.                 doneflag[i] = 1;
  528.                 donecount++;
  529.             }
  530.         }
  531.     }
  532.     if (donecount) {
  533.         ex = makesmallsetconst(val.i, tp_smallset);
  534.     } else
  535.         ex = NULL;
  536.     if (type->kind == TK_SMALLSET) {
  537.         for (i = 0; i < num; i++) {
  538.             if (!doneflag[i]) {
  539.                 ex2 = makeexpr_bin(EK_LSH, type,
  540.    makeexpr_longcast(makeexpr_long(1), 1),
  541.    enum_to_int(first[i]));
  542.                 if (last[i]) {
  543.                     if (ord_range(type->indextype, NULL, &max2) && max2 == setbits-1)
  544.                         note("Range construction was implemented by a subtraction which may overflow [278]");
  545.                     ex2 = makeexpr_minus(makeexpr_bin(EK_LSH, type,
  546.                                                       makeexpr_longcast(makeexpr_long(1), 1),
  547.                                                       makeexpr_plus(enum_to_int(last[i]),
  548.                                                                     makeexpr_long(1))),
  549.                                          ex2);
  550.                 }
  551.                 if (ex)
  552.                     ex = makeexpr_bin(EK_BOR, type, makeexpr_longcast(ex, 1), ex2);
  553.                 else
  554.                     ex = ex2;
  555.             }
  556.         }
  557.     } else {
  558.         tvar = makestmttempvar(type, name_SET);
  559.         if (!ex) {
  560.             val.type = tp_smallset;
  561.     val.i = 0;
  562.     val.s = NULL;
  563.     ex = makeexpr_val(val);
  564. }
  565.         ex = makeexpr_bicall_2(setexpandname, type,
  566.                                makeexpr_var(tvar), makeexpr_arglong(ex, 1));
  567.         for (i = 0; i < num; i++) {
  568.             if (!doneflag[i]) {
  569.                 if (last[i])
  570.                     ex = makeexpr_bicall_3(setaddrangename, type,
  571.                                            ex, makeexpr_arglong(enum_to_int(first[i]), 0),
  572.                                                makeexpr_arglong(enum_to_int(last[i]), 0));
  573.                 else
  574.                     ex = makeexpr_bicall_2(setaddname, type,
  575.                                            ex, makeexpr_arglong(enum_to_int(first[i]), 0));
  576.             }
  577.         }
  578.     }
  579.     return ex;
  580. }
  581. Expr *p_funcarglist(ex, args, firstarg, ismacro)
  582. Expr *ex;
  583. Meaning *args;
  584. int firstarg, ismacro;
  585. {
  586.     Meaning *mp, *mp2, *arglist = args, *prevarg = NULL;
  587.     Expr *ex2;
  588.     int i, fi, fakenum = -1, castit, isconf, isnonpos = 0;
  589.     Type *tp, *tp2;
  590.     char *name;
  591.     castit = castargs;
  592.     if (castit < 0)
  593. castit = (prototypes == 0);
  594.     while (args) {
  595. if (isnonpos) {
  596.     while (curtok == TOK_COMMA)
  597. gettok();
  598.     if (curtok == TOK_RPAR) {
  599. args = arglist;
  600. i = firstarg;
  601. while (args) {
  602.     if (ex->nargs <= i)
  603. insertarg(&ex, ex->nargs, NULL);
  604.     if (!ex->args[i]) {
  605. if (args->constdefn)
  606.     ex->args[i] = copyexpr(args->constdefn);
  607. else {
  608.     warning(format_s("Missing value for parameter %s [291]",
  609.      args->name));
  610.     ex->args[i] = makeexpr_long(0);
  611. }
  612.     }
  613.     args = args->xnext;
  614.     i++;
  615. }
  616. break;
  617.     }
  618. }
  619. if (args->isreturn || args->fakeparam) {
  620.     if (args->fakeparam) {
  621. if (fakenum < 0)
  622.     fakenum = ex->nargs;
  623. if (args->constdefn)
  624.     insertarg(&ex, ex->nargs, copyexpr(args->constdefn));
  625. else
  626.     insertarg(&ex, ex->nargs, makeexpr_long(0));
  627.     }
  628.     args = args->xnext;     /* return value parameter */
  629.     continue;
  630. }
  631. if (curtok == TOK_RPAR) {
  632.     if (args->constdefn) {
  633. insertarg(&ex, ex->nargs, copyexpr(args->constdefn));
  634. args = args->xnext;
  635. continue;
  636.     } else {
  637. if (ex->kind == EK_FUNCTION) {
  638.     name = ((Meaning *)ex->val.i)->name;
  639.     ex->kind = EK_BICALL;
  640.     ex->val.s = stralloc(name);
  641. } else
  642.     name = "function";
  643. warning(format_s("Too few arguments for %s [292]", name));
  644. return ex;
  645.     }
  646. }
  647. if (curtok == TOK_COMMA) {
  648.     if (args->constdefn)
  649. insertarg(&ex, ex->nargs, copyexpr(args->constdefn));
  650.     else {
  651. warning(format_s("Missing parameter %s [293]", args->name));
  652. insertarg(&ex, ex->nargs, makeexpr_long(0));
  653.     }
  654.     gettok();
  655.     args = args->xnext;
  656.     continue;
  657. }
  658. p_mech_spec(0);
  659. if (curtok == TOK_IDENT) {
  660.     mp = arglist;
  661.     mp2 = NULL;
  662.     i = firstarg;
  663.     fi = -1;
  664.     while (mp && strcmp(curtokbuf, mp->sym->name)) {
  665. if (mp->fakeparam) {
  666.     if (fi < 0)
  667. fi = i;
  668. } else
  669.     fi = -1;
  670. i++;
  671. mp2 = mp;
  672. mp = mp->xnext;
  673.     }
  674.     if (mp &&
  675. (peeknextchar() == ':' || !curtokmeaning || isnonpos)) {
  676. gettok();
  677. wneedtok(TOK_ASSIGN);
  678. prevarg = mp2;
  679. args = mp;
  680. fakenum = fi;
  681. isnonpos = 1;
  682.     } else
  683. i = ex->nargs;
  684. } else
  685.     i = ex->nargs;
  686. while (ex->nargs <= i)
  687.     insertarg(&ex, ex->nargs, NULL);
  688. if (ex->args[i])
  689.     warning(format_s("Multiple values for parameter %s [294]",
  690.      args->name));
  691. tp = args->type;
  692. ex2 = p_expr(tp);
  693. if (args->kind == MK_VARPARAM)
  694.     tp = tp->basetype;
  695. tp2 = ex2->val.type;
  696. isconf = ((tp->kind == TK_ARRAY ||
  697.    tp->kind == TK_STRING) && tp->structdefd);
  698.         switch (args->kind) {
  699.             case MK_PARAM:
  700.         if (castit && tp->kind == TK_REAL &&
  701.     ex2->val.type->kind != TK_REAL)
  702.                     ex2 = makeexpr_cast(ex2, tp);
  703.                 else if (ord_type(tp)->kind == TK_INTEGER && !ismacro)
  704.                     ex2 = makeexpr_arglong(ex2, long_type(tp));
  705.                 else if (args->othername && args->rectype != tp &&
  706.                          tp->kind != TK_STRING && args->type == tp2)
  707.                     ex2 = makeexpr_addr(ex2);
  708.                 else
  709.                     ex2 = gentle_cast(ex2, tp);
  710. ex->args[i] = ex2;
  711.                 break;
  712.             case MK_VARPARAM:
  713.                 if (args->type == tp_strptr && args->anyvarflag) {
  714.     ex->args[i] = strmax_func(ex2);
  715.                     insertarg(&ex, ex->nargs-1, makeexpr_addr(ex2));
  716.     if (isnonpos)
  717. note("Non-positional conformant parameters may not work [279]");
  718.                 } else {                        /* regular VAR parameter */
  719.                     ex2 = makeexpr_addrf(ex2);
  720.                     if (args->anyvarflag ||
  721.                         (tp->kind == TK_POINTER && tp2->kind == TK_POINTER &&
  722.                          (tp == tp_anyptr || tp2 == tp_anyptr))) {
  723. if (!ismacro)
  724.     ex2 = makeexpr_cast(ex2, args->type);
  725.                     } else {
  726.                         if (tp2 != tp && !isconf &&
  727.     (tp2->kind != TK_STRING ||
  728.      tp->kind != TK_STRING))
  729.                             warning(format_s("Type mismatch in VAR parameter %s [295]",
  730.                                              args->name));
  731.                     }
  732.     ex->args[i] = ex2;
  733.                 }
  734.                 break;
  735.     default:
  736. intwarning("p_funcarglist",
  737.    format_s("Parameter type is %s [296]",
  738.     meaningkindname(args->kind)));
  739. break;
  740.         }
  741. if (isconf &&   /* conformant array or string */
  742.     (!prevarg || prevarg->type != args->type)) {
  743.     while (tp->kind == TK_ARRAY && tp->structdefd) {
  744. if (tp2->kind == TK_SMALLARRAY) {
  745.     warning("Trying to pass a small-array for a conformant array [297]");
  746.     /* this has a chance of working... */
  747.     ex->args[ex->nargs-1] =
  748. makeexpr_addr(ex->args[ex->nargs-1]);
  749. } else if (tp2->kind == TK_STRING) {
  750.     ex->args[fakenum++] =
  751. makeexpr_arglong(makeexpr_long(1), integer16 == 0);
  752.     ex->args[fakenum++] =
  753. makeexpr_arglong(strmax_func(ex->args[ex->nargs-1]),
  754.  integer16 == 0);
  755.     break;
  756.         } else if (tp2->kind != TK_ARRAY) {
  757.     warning("Type mismatch for conformant array [298]");
  758.     break;
  759. }
  760. ex->args[fakenum++] =
  761.     makeexpr_arglong(copyexpr(tp2->indextype->smin),
  762.      integer16 == 0);
  763. ex->args[fakenum++] =
  764.     makeexpr_arglong(copyexpr(tp2->indextype->smax),
  765.      integer16 == 0);
  766. tp = tp->basetype;
  767. tp2 = tp2->basetype;
  768.     }
  769.     if (tp->kind == TK_STRING && tp->structdefd) {
  770. ex->args[fakenum] =
  771.     makeexpr_arglong(strmax_func(ex->args[ex->nargs-1]),
  772.      integer16 == 0);
  773.     }
  774. }
  775. fakenum = -1;
  776. if (!isnonpos) {
  777.     prevarg = args;
  778.     args = args->xnext;
  779.     if (args) {
  780. if (curtok != TOK_RPAR && !wneedtok(TOK_COMMA))
  781.     skiptotoken2(TOK_RPAR, TOK_SEMI);
  782.     }
  783. }
  784.     }
  785.     if (curtok == TOK_COMMA) {
  786. if (ex->kind == EK_FUNCTION) {
  787.     name = ((Meaning *)ex->val.i)->name;
  788.     ex->kind = EK_BICALL;
  789.     ex->val.s = stralloc(name);
  790. } else
  791.     name = "function";
  792. warning(format_s("Too many arguments for %s [299]", name));
  793. while (curtok == TOK_COMMA) {
  794.     gettok();
  795.     insertarg(&ex, ex->nargs, p_expr(tp_integer));
  796. }
  797.     }
  798.     return ex;
  799. }
  800. Expr *replacemacargs(ex, fex)
  801. Expr *ex, *fex;
  802. {
  803.     int i;
  804.     Expr *ex2;
  805.     for (i = 0; i < ex->nargs; i++)
  806.         ex->args[i] = replacemacargs(ex->args[i], fex);
  807.     if (ex->kind == EK_MACARG) {
  808. if (ex->val.i <= fex->nargs) {
  809.     ex2 = copyexpr(fex->args[ex->val.i - 1]);
  810. } else {
  811.     ex2 = makeexpr_name("<meef>", tp_integer);
  812.     note("FuncMacro specified more arguments than call [280]");
  813. }
  814. freeexpr(ex);
  815. return ex2;
  816.     }
  817.     return resimplify(ex);
  818. }
  819. Expr *p_noarglist(ex, mp, args)
  820. Expr *ex;
  821. Meaning *mp, *args;
  822. {
  823.     while (args && args->constdefn) {
  824. insertarg(&ex, ex->nargs, copyexpr(args->constdefn));
  825. args = args->xnext;
  826.     }
  827.     if (args) {
  828. warning(format_s("Expected an argument list for %s [300]", mp->name));
  829. ex->kind = EK_BICALL;
  830. ex->val.s = stralloc(mp->name);
  831.     }
  832.     return ex;
  833. }
  834. void func_reference(func)
  835. Meaning *func;
  836. {
  837.     Meaning *mp;
  838.     if (func->ctx && func->ctx != curctx &&func->ctx->kind == MK_FUNCTION &&
  839. func->ctx->varstructflag && !curctx->ctx->varstructflag) {
  840. for (mp = curctx->ctx; mp != func->ctx; mp = mp->ctx)
  841.     mp->varstructflag = 1;
  842.     }
  843. }
  844. Expr *p_funccall(mp)
  845. Meaning *mp;
  846. {
  847.     Meaning *mp2, *tvar;
  848.     Expr *ex, *ex2;
  849.     int firstarg = 0;
  850.     func_reference(mp);
  851.     ex = makeexpr(EK_FUNCTION, 0);
  852.     ex->val.i = (long)mp;
  853.     ex->val.type = mp->type->basetype;
  854.     mp2 = mp->type->fbase;
  855.     if (mp2 && mp2->isreturn) {    /* pointer to buffer for return value */
  856.         tvar = makestmttempvar(ex->val.type->basetype,
  857.             (ex->val.type->basetype->kind == TK_STRING) ? name_STRING : name_TEMP);
  858.         insertarg(&ex, 0, makeexpr_addr(makeexpr_var(tvar)));
  859.         mp2 = mp2->xnext;
  860. firstarg++;
  861.     }
  862.     if (mp2 && curtok != TOK_LPAR) {
  863. ex = p_noarglist(ex, mp, mp2);
  864.     } else if (curtok == TOK_LPAR) {
  865. gettok();
  866.         ex = p_funcarglist(ex, mp2, firstarg, (mp->constdefn != NULL));
  867.         skipcloseparen();
  868.     }
  869.     if (mp->constdefn) {
  870.         ex2 = replacemacargs(copyexpr(mp->constdefn), ex);
  871. ex2 = gentle_cast(ex2, ex->val.type);
  872. ex2->val.type = ex->val.type;
  873.         freeexpr(ex);
  874.         return ex2;
  875.     }
  876.     return ex;
  877. }
  878. Expr *accumulate_strlit()
  879. {
  880.     char buf[256], ch, *cp, *cp2;
  881.     int len, i, danger = 0;
  882.     len = 0;
  883.     cp = buf;
  884.     for (;;) {
  885.         if (curtok == TOK_STRLIT) {
  886.             cp2 = curtokbuf;
  887.             i = curtokint;
  888.             while (--i >= 0) {
  889.                 if (++len <= 255) {
  890.                     ch = *cp++ = *cp2++;
  891.                     if (ch & 128)
  892.                         danger++;
  893.                 }
  894.             }
  895.         } else if (curtok == TOK_HAT) {    /* Turbo */
  896.             i = getchartok() & 0x1f;
  897.             if (++len <= 255)
  898.                 *cp++ = i;
  899. } else if (curtok == TOK_LPAR) {   /* VAX */
  900.     Value val;
  901.     do {
  902. gettok();
  903. val = p_constant(tp_integer);
  904. if (++len <= 255)
  905.     *cp++ = val.i;
  906.     } while (curtok == TOK_COMMA);
  907.     skipcloseparen();
  908.     continue;
  909.         } else
  910.             break;
  911.         gettok();
  912.     }
  913.     if (len > 255) {
  914.         warning("String literal too long [301]");
  915.         len = 255;
  916.     }
  917.     if (danger &&
  918.         !(unsignedchar == 1 ||
  919.           (unsignedchar != 0 && signedchars == 0)))
  920.         note(format_s("Character%s >= 128 encountered [281]", (danger > 1) ? "s" : ""));
  921.     return makeexpr_lstring(buf, len);
  922. }
  923. Expr *pascaltypecast(type, ex2)
  924. Type *type;
  925. Expr *ex2;
  926. {
  927.     if ((ex2->val.type->kind == TK_INTEGER ||
  928.  ex2->val.type->kind == TK_CHAR ||
  929.  ex2->val.type->kind == TK_BOOLEAN ||
  930.  ex2->val.type->kind == TK_ENUM ||
  931.  ex2->val.type->kind == TK_SUBR ||
  932.  ex2->val.type->kind == TK_REAL ||
  933.  ex2->val.type->kind == TK_POINTER ||
  934.  ex2->val.type->kind == TK_STRING) &&
  935. (type->kind == TK_INTEGER ||
  936.  type->kind == TK_CHAR ||
  937.  type->kind == TK_BOOLEAN ||
  938.  type->kind == TK_ENUM ||
  939.  type->kind == TK_SUBR ||
  940.  type->kind == TK_REAL ||
  941.  type->kind == TK_POINTER)) {
  942. if (type->kind == TK_POINTER || ex2->val.type->kind == TK_POINTER)
  943.     return makeexpr_un(EK_CAST, type, ex2);
  944. else
  945.     return makeexpr_un(EK_ACTCAST, type, ex2);
  946.     } else {
  947. return makeexpr_hat(makeexpr_cast(makeexpr_addr(ex2),
  948.   makepointertype(type)), 0);
  949.     }
  950. }
  951. Static Expr *p_factor(target)
  952. Type *target;
  953. {
  954.     Expr *ex, *ex2;
  955.     Type *type;
  956.     Meaning *mp, *mp2;
  957.     switch (curtok) {
  958.         case TOK_INTLIT:
  959.             ex = makeexpr_long(curtokint);
  960.             gettok();
  961.             return ex;
  962.         case TOK_HEXLIT:
  963.             ex = makeexpr_long(curtokint);
  964.             insertarg(&ex, 0, makeexpr_name("%#lx", tp_integer));
  965.             gettok();
  966.             return ex;
  967.         case TOK_OCTLIT:
  968.             ex = makeexpr_long(curtokint);
  969.             insertarg(&ex, 0, makeexpr_name("%#lo", tp_integer));
  970.             gettok();
  971.             return ex;
  972.         case TOK_MININT:
  973.     strcat(curtokbuf, ".0");
  974. /* fall through */
  975.         case TOK_REALLIT:
  976.             ex = makeexpr_real(curtokbuf);
  977.             gettok();
  978.             return ex;
  979.         case TOK_HAT:
  980.         case TOK_STRLIT:
  981.             ex = accumulate_strlit();
  982.             return ex;
  983.         case TOK_LPAR:
  984.             gettok();
  985.             ex = p_expr(target);
  986.             skipcloseparen();
  987.             return dots_n_hats(ex, target);
  988.         case TOK_NOT:
  989. case TOK_TWIDDLE:
  990.             gettok();
  991.             ex = p_factor(tp_integer);
  992.             if (ord_type(ex->val.type)->kind == TK_INTEGER)
  993.                 return makeexpr_un(EK_BNOT, tp_integer, ex);
  994.             else
  995.                 return makeexpr_not(ex);
  996.         case TOK_ADDR:
  997.             gettok();
  998.     if (curtok == TOK_ADDR) {
  999. gettok();
  1000. ex = p_factor(tp_proc);
  1001. if (ex->val.type->kind == TK_PROCPTR && ex->kind == EK_COMMA)
  1002.     return grabarg(grabarg(grabarg(ex, 0), 1), 0);
  1003. if (ex->val.type->kind != TK_CPROCPTR)
  1004.     warning("@@ allowed only for procedure pointers [302]");
  1005. return makeexpr_addrf(ex);
  1006.     }
  1007.             if (curtok == TOK_IDENT && 0 &&  /***/
  1008.                 curtokmeaning && (curtokmeaning->kind == MK_FUNCTION ||
  1009.                                   curtokmeaning->kind == MK_SPECIAL)) {
  1010.                 if (curtokmeaning->ctx == nullctx)
  1011.                     warning(format_s("Can't take address of predefined object %s [303]",
  1012.                                      curtokmeaning->name));
  1013.                 ex = makeexpr_name(curtokmeaning->name, tp_anyptr);
  1014.                 gettok();
  1015.             } else {
  1016. ex = p_factor(tp_proc);
  1017. if (ex->val.type->kind == TK_PROCPTR) {
  1018.   /*  ex = makeexpr_dotq(ex, "proc", tp_anyptr);  */
  1019. } else if (ex->val.type->kind == TK_CPROCPTR) {
  1020.     ex = makeexpr_cast(ex, tp_anyptr);
  1021. } else
  1022.     ex = makeexpr_addrf(ex);
  1023.             }
  1024.             return ex;
  1025.         case TOK_LBR:
  1026. case TOK_LBRACE:
  1027.             return p_setfactor(NULL);
  1028.         case TOK_NIL:
  1029.             gettok();
  1030.             return makeexpr_nil();
  1031. case TOK_IF:    /* nifty Pascal extension */
  1032.     gettok();
  1033.     ex = p_expr(tp_boolean);
  1034.     wneedtok(TOK_THEN);
  1035.     ex2 = p_expr(tp_integer);
  1036.     if (wneedtok(TOK_ELSE))
  1037. return makeexpr_cond(ex, ex2, p_factor(ex2->val.type));
  1038.     else
  1039. return makeexpr_cond(ex, ex2, makeexpr_long(0));
  1040.         case TOK_IDENT:
  1041.             mp = curtokmeaning;
  1042.             switch ((mp) ? mp->kind : MK_VAR) {
  1043.                 case MK_TYPE:
  1044.                     gettok();
  1045.                     type = mp->type;
  1046.                     switch (curtok) {
  1047.                         case TOK_LPAR:    /* Turbo type cast */
  1048.                             gettok();
  1049.                             ex2 = p_expr(type);
  1050.     ex = pascaltypecast(type, ex2);
  1051.                             skipcloseparen();
  1052.                             return dots_n_hats(ex, target);
  1053.                         case TOK_LBR:
  1054. case TOK_LBRACE:
  1055.                             switch (type->kind) {
  1056.                                 case TK_SET:
  1057.                                 case TK_SMALLSET:
  1058.                                     return p_setfactor(type->indextype);
  1059.                                 case TK_RECORD:
  1060.                                     return p_constrecord(type, 0);
  1061.                                 case TK_ARRAY:
  1062.                                 case TK_SMALLARRAY:
  1063.                                     return p_constarray(type, 0);
  1064.                                 case TK_STRING:
  1065.                                     return p_conststring(type, 0);
  1066.                                 default:
  1067.                                     warning("Bad type for constructor [304]");
  1068.     skipparens();
  1069.     return makeexpr_name(mp->name, mp->type);
  1070.                             }
  1071. default:
  1072.     wexpected("an expression");
  1073.     return makeexpr_name(mp->name, mp->type);
  1074.                     }
  1075.                 case MK_SPECIAL:
  1076.                     if (mp->handler && mp->isfunction &&
  1077. (curtok == TOK_LPAR || !target ||
  1078.  (target->kind != TK_PROCPTR &&
  1079.   target->kind != TK_CPROCPTR))) {
  1080.                         gettok();
  1081.                         if ((mp->sym->flags & LEAVEALONE) || mp->constdefn) {
  1082.                             ex = makeexpr_bicall_0(mp->name, tp_integer);
  1083.                             if (curtok == TOK_LPAR) {
  1084.                                 do {
  1085.                                     gettok();
  1086.                                     insertarg(&ex, ex->nargs, p_expr(NULL));
  1087.                                 } while (curtok == TOK_COMMA);
  1088.                                 skipcloseparen();
  1089.                             }
  1090.                             tryfuncmacro(&ex, mp);
  1091.     return ex;
  1092.                         }
  1093.                         ex = (*mp->handler)(mp);
  1094. if (!ex)
  1095.     ex = makeexpr_long(0);
  1096. return ex;
  1097.                     } else {
  1098. if (target->kind == TK_PROCPTR ||
  1099.     target->kind == TK_CPROCPTR)
  1100.     note("Using a built-in procedure as a procedure pointer [316]");
  1101.                         else
  1102.     symclass(curtoksym);
  1103.                         gettok();
  1104.                         return makeexpr_name(mp->name, tp_integer);
  1105.                     }
  1106.                 case MK_FUNCTION:
  1107.                     mp->refcount++;
  1108.                     need_forward_decl(mp);
  1109.     gettok();
  1110.                     if (mp->isfunction &&
  1111. (curtok == TOK_LPAR || !target ||
  1112.  (target->kind != TK_PROCPTR &&
  1113.   target->kind != TK_CPROCPTR))) {
  1114.                         ex = p_funccall(mp);
  1115.                         if (!mp->constdefn) {
  1116.                             if (mp->handler && !(mp->sym->flags & LEAVEALONE))
  1117.                                 ex = (*mp->handler)(ex);
  1118. }
  1119. if (mp->cbase->kind == MK_VARPARAM) {
  1120.     ex = makeexpr_hat(ex, 0);    /* returns pointer to structured result */
  1121.                         }
  1122.                         return dots_n_hats(ex, target);
  1123.                     } else {
  1124. if (mp->handler && !(mp->sym->flags & LEAVEALONE))
  1125.     note("Using a built-in procedure as a procedure pointer [316]");
  1126. if (target && target->kind == TK_CPROCPTR) {
  1127.     type = maketype(TK_CPROCPTR);
  1128.     type->basetype = mp->type;
  1129.     type->escale = 0;
  1130.     mp2 = makestmttempvar(type, name_TEMP);
  1131.     ex = makeexpr_comma(
  1132.                                     makeexpr_assign(
  1133.                                        makeexpr_var(mp2),
  1134.        makeexpr_name(mp->name, tp_text)),
  1135.     makeexpr_var(mp2));
  1136.     if (mp->ctx->kind == MK_FUNCTION)
  1137. warning("Procedure pointer to nested procedure [305]");
  1138. } else {
  1139.     type = maketype(TK_PROCPTR);
  1140.     type->basetype = mp->type;
  1141.     type->escale = 1;
  1142.     mp2 = makestmttempvar(type, name_TEMP);
  1143.     ex = makeexpr_comma(
  1144.                                     makeexpr_comma(
  1145.                                        makeexpr_assign(
  1146.                                           makeexpr_dotq(makeexpr_var(mp2),
  1147. "proc",
  1148. tp_anyptr),
  1149.   makeexpr_name(mp->name, tp_text)),
  1150.                                           /* handy pointer type */
  1151.        makeexpr_assign(
  1152.                                           makeexpr_dotq(makeexpr_var(mp2),
  1153. "link",
  1154. tp_anyptr),
  1155.           makeexpr_ctx(mp->ctx))),
  1156.     makeexpr_var(mp2));
  1157. }
  1158.                         return ex;
  1159.                     }
  1160.                 default:
  1161.                     return p_variable(target);
  1162.             }
  1163. default:
  1164.     wexpected("an expression");
  1165.     return makeexpr_long(0);
  1166.     
  1167.     }
  1168. }
  1169. Static Expr *p_powterm(target)
  1170. Type *target;
  1171. {
  1172.     Expr *ex = p_factor(target);
  1173.     Expr *ex2;
  1174.     int i, castit;
  1175.     long v;
  1176.     if (curtok == TOK_STARSTAR) {
  1177. gettok();
  1178. ex2 = p_powterm(target);
  1179. if (ex->val.type->kind == TK_REAL ||
  1180.     ex2->val.type->kind == TK_REAL) {
  1181.     if (checkconst(ex2, 2)) {
  1182. ex = makeexpr_sqr(ex, 0);
  1183.     } else if (checkconst(ex2, 3)) {
  1184. ex = makeexpr_sqr(ex, 1);
  1185.     } else {
  1186. castit = castargs >= 0 ? castargs : (prototypes == 0);
  1187. if (ex->val.type->kind != TK_REAL && castit)
  1188.     ex = makeexpr_cast(ex, tp_longreal);
  1189. if (ex2->val.type->kind != TK_REAL && castit)
  1190.     ex2 = makeexpr_cast(ex2, tp_longreal);
  1191. ex = makeexpr_bicall_2("pow", tp_longreal, ex, ex2);
  1192.     }
  1193. } else if (checkconst(ex, 2)) {
  1194.     freeexpr(ex);
  1195.     ex = makeexpr_bin(EK_LSH, tp_integer,
  1196.       makeexpr_longcast(makeexpr_long(1), 1), ex2);
  1197. } else if (checkconst(ex, 0) ||
  1198.    checkconst(ex, 1) ||
  1199.    checkconst(ex2, 1)) {
  1200.     freeexpr(ex2);
  1201. } else if (checkconst(ex2, 0)) {
  1202.     freeexpr(ex);
  1203.     freeexpr(ex2);
  1204.     ex = makeexpr_long(1);
  1205. } else if (isliteralconst(ex, NULL) == 2 &&
  1206.    isliteralconst(ex2, NULL) == 2 &&
  1207.    ex2->val.i > 0) {
  1208.     v = ex->val.i;
  1209.     i = ex2->val.i;
  1210.     while (--i > 0)
  1211. v *= ex->val.i;
  1212.     freeexpr(ex);
  1213.     freeexpr(ex2);
  1214.     ex = makeexpr_long(v);
  1215. } else if (checkconst(ex2, 2)) {
  1216.     ex = makeexpr_sqr(ex, 0);
  1217. } else if (checkconst(ex2, 3)) {
  1218.     ex = makeexpr_sqr(ex, 1);
  1219. } else {
  1220.     ex = makeexpr_bicall_2("ipow", tp_integer,
  1221.    makeexpr_arglong(ex, 1),
  1222.    makeexpr_arglong(ex2, 1));
  1223. }
  1224.     }
  1225.     return ex;
  1226. }
  1227. Static Expr *p_term(target)
  1228. Type *target;
  1229. {
  1230.     Expr *ex = p_powterm(target);
  1231.     Expr *ex2;
  1232.     Type *type;
  1233.     Meaning *tvar;
  1234.     int useshort;
  1235.     for (;;) {
  1236. checkkeyword(TOK_SHL);
  1237. checkkeyword(TOK_SHR);
  1238. checkkeyword(TOK_REM);
  1239.         switch (curtok) {
  1240.             case TOK_STAR:
  1241.                 gettok();
  1242.                 if (ex->val.type->kind == TK_SET ||
  1243.                     ex->val.type->kind == TK_SMALLSET) {
  1244.                     ex2 = p_powterm(ex->val.type);
  1245.                     type = mixsets(&ex, &ex2);
  1246.                     if (type->kind == TK_SMALLSET) {
  1247.                         ex = makeexpr_bin(EK_BAND, type, ex, ex2);
  1248.                     } else {
  1249.                         tvar = makestmttempvar(type, name_SET);
  1250.                         ex = makeexpr_bicall_3(setintname, type,
  1251.                                                makeexpr_var(tvar),
  1252.                                                ex, ex2);
  1253.                     }
  1254.                 } else
  1255.                     ex = makeexpr_times(ex, p_powterm(tp_integer));
  1256.                 break;
  1257.             case TOK_SLASH:
  1258.                 gettok();
  1259.                 if (ex->val.type->kind == TK_SET ||
  1260.                     ex->val.type->kind == TK_SMALLSET) {
  1261.                     ex2 = p_powterm(ex->val.type);
  1262.                     type = mixsets(&ex, &ex2);
  1263.                     if (type->kind == TK_SMALLSET) {
  1264.                         ex = makeexpr_bin(EK_BXOR, type, ex, ex2);
  1265.                     } else {
  1266.                         tvar = makestmttempvar(type, name_SET);
  1267.                         ex = makeexpr_bicall_3(setxorname, type,
  1268.                                                makeexpr_var(tvar),
  1269.                                                ex, ex2);
  1270.                     }
  1271. } else
  1272.     ex = makeexpr_divide(ex, p_powterm(tp_integer));
  1273.                 break;
  1274.             case TOK_DIV:
  1275.                 gettok();
  1276.                 ex = makeexpr_div(ex, p_powterm(tp_integer));
  1277.                 break;
  1278.             case TOK_REM:
  1279.                 gettok();
  1280.                 ex = makeexpr_rem(ex, p_powterm(tp_integer));
  1281.                 break;
  1282.             case TOK_MOD:
  1283.                 gettok();
  1284.                 ex = makeexpr_mod(ex, p_powterm(tp_integer));
  1285.                 break;
  1286.             case TOK_AND:
  1287.     case TOK_AMP:
  1288. useshort = (curtok == TOK_AMP);
  1289.                 gettok();
  1290.                 ex2 = p_powterm(tp_integer);
  1291.                 if (ord_type(ex->val.type)->kind == TK_INTEGER)
  1292.                     ex = makeexpr_bin(EK_BAND, ex->val.type, ex, ex2);
  1293.                 else if (partial_eval_flag || useshort ||
  1294.                          (shortopt && nosideeffects(ex2, 1)))
  1295.                     ex = makeexpr_and(ex, ex2);
  1296.                 else
  1297.                     ex = makeexpr_bin(EK_BAND, tp_boolean, ex, ex2);
  1298.                 break;
  1299.             case TOK_SHL:
  1300.                 gettok();
  1301.                 ex = makeexpr_bin(EK_LSH, ex->val.type, ex, p_powterm(tp_integer));
  1302.                 break;
  1303.             case TOK_SHR:
  1304.                 gettok();
  1305.                 ex = force_unsigned(ex);
  1306.                 ex = makeexpr_bin(EK_RSH, ex->val.type, ex, p_powterm(tp_integer));
  1307.                 break;
  1308.             default:
  1309.                 return ex;
  1310.         }
  1311.     }
  1312. }
  1313. Static Expr *p_sexpr(target)
  1314. Type *target;
  1315. {
  1316.     Expr *ex, *ex2;
  1317.     Type *type;
  1318.     Meaning *tvar;
  1319.     int useshort;
  1320.     switch (curtok) {
  1321.         case TOK_MINUS:
  1322.             gettok();
  1323.             if (curtok == TOK_MININT) {
  1324.                 gettok();
  1325.                 ex = makeexpr_long(MININT);
  1326. break;
  1327.             }
  1328.             ex = makeexpr_neg(p_term(target));
  1329.             break;
  1330.         case TOK_PLUS:
  1331.             gettok();
  1332.         /* fall through */
  1333.         default:
  1334.             ex = p_term(target);
  1335.             break;
  1336.     }
  1337.     if (curtok == TOK_PLUS &&
  1338.         (ex->val.type->kind == TK_STRING ||
  1339.          ord_type(ex->val.type)->kind == TK_CHAR ||
  1340.          ex->val.type->kind == TK_ARRAY)) {
  1341.         while (curtok == TOK_PLUS) {
  1342.             gettok();
  1343.             ex = makeexpr_concat(ex, p_term(NULL), 0);
  1344.         }
  1345.         return ex;
  1346.     } else {
  1347.         for (;;) {
  1348.     checkkeyword(TOK_XOR);
  1349.             switch (curtok) {
  1350.                 case TOK_PLUS:
  1351.                     gettok();
  1352.                     if (ex->val.type->kind == TK_SET ||
  1353.                         ex->val.type->kind == TK_SMALLSET) {
  1354.                         ex2 = p_term(ex->val.type);
  1355.                         type = mixsets(&ex, &ex2);
  1356.                         if (type->kind == TK_SMALLSET) {
  1357.                             ex = makeexpr_bin(EK_BOR, type, ex, ex2);
  1358.                         } else {
  1359.                             tvar = makestmttempvar(type, name_SET);
  1360.                             ex = makeexpr_bicall_3(setunionname, type,
  1361.                                                    makeexpr_var(tvar),
  1362.                                                    ex, ex2);
  1363.                         }
  1364.                     } else
  1365.                         ex = makeexpr_plus(ex, p_term(tp_integer));
  1366.                     break;
  1367.                 case TOK_MINUS:
  1368.                     gettok();
  1369.                     if (ex->val.type->kind == TK_SET ||
  1370.                         ex->val.type->kind == TK_SMALLSET) {
  1371.                         ex2 = p_term(tp_integer);
  1372.                         type = mixsets(&ex, &ex2);
  1373.                         if (type->kind == TK_SMALLSET) {
  1374.                             ex = makeexpr_bin(EK_BAND, type, ex,
  1375.                                               makeexpr_un(EK_BNOT, type, ex2));
  1376.                         } else {
  1377.                             tvar = makestmttempvar(type, name_SET);
  1378.                             ex = makeexpr_bicall_3(setdiffname, type,
  1379.                                                    makeexpr_var(tvar), ex, ex2);
  1380.                         }
  1381.                     } else
  1382.                         ex = makeexpr_minus(ex, p_term(tp_integer));
  1383.                     break;
  1384. case TOK_VBAR:
  1385.     if (modula2)
  1386. return ex;
  1387.     /* fall through */
  1388.                 case TOK_OR:
  1389.     useshort = (curtok == TOK_VBAR);
  1390.                     gettok();
  1391.                     ex2 = p_term(tp_integer);
  1392.                     if (ord_type(ex->val.type)->kind == TK_INTEGER)
  1393.                         ex = makeexpr_bin(EK_BOR, ex->val.type, ex, ex2);
  1394.                     else if (partial_eval_flag || useshort ||
  1395.                              (shortopt && nosideeffects(ex2, 1)))
  1396.                         ex = makeexpr_or(ex, ex2);
  1397.                     else
  1398.                         ex = makeexpr_bin(EK_BOR, tp_boolean, ex, ex2);
  1399.                     break;
  1400.                 case TOK_XOR:
  1401.                     gettok();
  1402.                     ex2 = p_term(tp_integer);
  1403.                     ex = makeexpr_bin(EK_BXOR, ex->val.type, ex, ex2);
  1404.                     break;
  1405.                 default:
  1406.                     return ex;
  1407.             }
  1408.         }
  1409.     }
  1410. }
  1411. Expr *p_expr(target)
  1412. Type *target;
  1413. {
  1414.     Expr *ex = p_sexpr(target);
  1415.     Expr *ex2, *ex3, *ex4;
  1416.     Type *type;
  1417.     Meaning *tvar;
  1418.     long mask, smin, smax;
  1419.     int i, j;
  1420.     switch (curtok) {
  1421.         case TOK_EQ:
  1422.             gettok();
  1423.             return makeexpr_rel(EK_EQ, ex, p_sexpr(ex->val.type));
  1424.         case TOK_NE:
  1425.             gettok();
  1426.             return makeexpr_rel(EK_NE, ex, p_sexpr(ex->val.type));
  1427.         case TOK_LT:
  1428.             gettok();
  1429.             return makeexpr_rel(EK_LT, ex, p_sexpr(ex->val.type));
  1430.         case TOK_GT:
  1431.             gettok();
  1432.             return makeexpr_rel(EK_GT, ex, p_sexpr(ex->val.type));
  1433.         case TOK_LE:
  1434.             gettok();
  1435.             return makeexpr_rel(EK_LE, ex, p_sexpr(ex->val.type));
  1436.         case TOK_GE:
  1437.             gettok();
  1438.             return makeexpr_rel(EK_GE, ex, p_sexpr(ex->val.type));
  1439.         case TOK_IN:
  1440.             gettok();
  1441.             ex2 = p_sexpr(tp_smallset);
  1442.             ex = gentle_cast(ex, ex2->val.type->indextype);
  1443.             if (ex2->val.type->kind == TK_SMALLSET) {
  1444.                 if (!ord_range(ex->val.type, &smin, &smax)) {
  1445.                     smin = -1;
  1446.                     smax = setbits;
  1447.                 }
  1448.                 if (!nosideeffects(ex, 0)) {
  1449.                     tvar = makestmttempvar(ex->val.type, name_TEMP);
  1450.                     ex3 = makeexpr_assign(makeexpr_var(tvar), ex);