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

编译器/解释器

开发平台:

C/C++

  1.                     ex = makeexpr_var(tvar);
  2.                 } else
  3.                     ex3 = NULL;
  4.                 ex4 = copyexpr(ex);
  5.                 if (ex->kind == EK_CONST && smallsetconst)
  6.                     ex = makesmallsetconst(1<<ex->val.i, ex2->val.type);
  7.                 else
  8.                     ex = makeexpr_bin(EK_LSH, ex2->val.type,
  9.                                       makeexpr_longcast(makeexpr_long(1), 1),
  10.                                       enum_to_int(ex));
  11.                 ex = makeexpr_rel(EK_NE, makeexpr_bin(EK_BAND, tp_integer, ex, ex2),
  12.                                          makeexpr_long(0));
  13.                 if (*name_SETBITS ||
  14.                     ((ex4->kind == EK_CONST) ? ((unsigned long)ex4->val.i >= setbits)
  15.                                              : !(0 <= smin && smax < setbits))) {
  16.                     ex = makeexpr_and(makeexpr_range(enum_to_int(ex4),
  17.                                                      makeexpr_long(0),
  18.                                                      makeexpr_setbits(), 0),
  19.                                       ex);
  20.                 } else
  21.                     freeexpr(ex4);
  22.                 ex = makeexpr_comma(ex3, ex);
  23.                 return ex;
  24.             } else {
  25.                 ex3 = ex2;
  26.                 while (ex3->kind == EK_BICALL &&
  27.                        (!strcmp(ex3->val.s, setaddname) ||
  28.                         !strcmp(ex3->val.s, setaddrangename)))
  29.                     ex3 = ex3->args[0];
  30.                 if (ex3->kind == EK_BICALL && !strcmp(ex3->val.s, setexpandname) &&
  31.                     (tvar = istempvar(ex3->args[0])) != NULL && 
  32.                     isconstexpr(ex3->args[1], &mask)) {
  33.                     canceltempvar(tvar);
  34.                     if (!nosideeffects(ex, 0)) {
  35.                         tvar = makestmttempvar(ex->val.type, name_TEMP);
  36.                         ex3 = makeexpr_assign(makeexpr_var(tvar), ex);
  37.                         ex = makeexpr_var(tvar);
  38.                     } else
  39.                         ex3 = NULL;
  40.                     type = ord_type(ex2->val.type->indextype);
  41.                     ex4 = NULL;
  42.                     i = 0;
  43.                     while (i < setbits) {
  44.                         if (mask & (1<<i++)) {
  45.                             if (i+1 < setbits && (mask & (2<<i))) {
  46.                                 for (j = i; j < setbits && (mask & (1<<j)); j++) ;
  47.                                 ex4 = makeexpr_or(ex4,
  48.                                         makeexpr_range(copyexpr(ex),
  49.                                                        makeexpr_val(make_ord(type, i-1)),
  50.                                                        makeexpr_val(make_ord(type, j-1)), 1));
  51.                                 i = j;
  52.                             } else {
  53.                                 ex4 = makeexpr_or(ex4,
  54.                                         makeexpr_rel(EK_EQ, copyexpr(ex),
  55.                                                             makeexpr_val(make_ord(type, i-1))));
  56.                             }
  57.                         }
  58.                     }
  59.                     mask = 0;
  60.                     for (;;) {
  61.                         if (!strcmp(ex2->val.s, setaddrangename)) {
  62.                             if (checkconst(ex2->args[1], 'a') &&
  63.                                 checkconst(ex2->args[2], 'z')) {
  64.                                 mask |= 0x1;
  65.                             } else if (checkconst(ex2->args[1], 'A') &&
  66.                                        checkconst(ex2->args[2], 'Z')) {
  67.                                 mask |= 0x2;
  68.                             } else if (checkconst(ex2->args[1], '0') &&
  69.                                        checkconst(ex2->args[2], '9')) {
  70.                                 mask |= 0x4;
  71.                             } else {
  72.                                 ex4 = makeexpr_or(ex4,
  73.                                         makeexpr_range(copyexpr(ex), ex2->args[1], ex2->args[2], 1));
  74.                             }
  75.                         } else if (!strcmp(ex2->val.s, setaddname)) {
  76.                             ex4 = makeexpr_or(ex4,
  77.                                     makeexpr_rel(EK_EQ, copyexpr(ex), ex2->args[1]));
  78.                         } else
  79.                             break;
  80.                         ex2 = ex2->args[0];
  81.                     }
  82.                     /* do these now so that EK_OR optimizations will work: */
  83.                     if (mask & 0x1)
  84.                         ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
  85.                                                               makeexpr_char('a'),
  86.                                                               makeexpr_char('z'), 1));
  87.                     if (mask & 0x2)
  88.                         ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
  89.                                                               makeexpr_char('A'),
  90.                                                               makeexpr_char('Z'), 1));
  91.                     if (mask & 0x4)
  92.                         ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
  93.                                                               makeexpr_char('0'),
  94.                                                               makeexpr_char('9'), 1));
  95.                     freeexpr(ex);
  96.                     return makeexpr_comma(ex3, ex4);
  97.                 }
  98.                 return makeexpr_bicall_2(setinname, tp_boolean,
  99.                                          makeexpr_arglong(ex, 0), ex2);
  100.             }
  101. default:
  102.     return ex;
  103.     }
  104. }
  105. /* Parse a C expression; used by VarMacro, etc. */
  106. Type *nametotype(name)
  107. char *name;
  108. {
  109.     if (!strcicmp(name, "malloc") ||
  110. !strcicmp(name, mallocname)) {
  111. return tp_anyptr;
  112.     }
  113.     return tp_integer;
  114. }
  115. int istypespec()
  116. {
  117.     switch (curtok) {
  118.         case TOK_CONST:
  119.             return 1;
  120.         case TOK_IDENT:
  121.             return !strcmp(curtokcase, "volatile") ||
  122.                    !strcmp(curtokcase, "void") ||
  123.                    !strcmp(curtokcase, "char") ||
  124.                    !strcmp(curtokcase, "short") ||
  125.                    !strcmp(curtokcase, "int") ||
  126.                    !strcmp(curtokcase, "long") ||
  127.                    !strcmp(curtokcase, "float") ||
  128.                    !strcmp(curtokcase, "double") ||
  129.                    !strcmp(curtokcase, "signed") ||
  130.                    !strcmp(curtokcase, "unsigned") ||
  131.                    !strcmp(curtokcase, "struct") ||
  132.                    !strcmp(curtokcase, "union") ||
  133.                    !strcmp(curtokcase, "class") ||
  134.                    !strcmp(curtokcase, "enum") ||
  135.                    !strcmp(curtokcase, "typedef") ||
  136.                    (curtokmeaning &&
  137.                     curtokmeaning->kind == MK_TYPE);
  138.         default:
  139.             return 0;
  140.     }
  141. }
  142. Expr *pc_parentype(cp)
  143. char *cp;
  144. {
  145.     Expr *ex;
  146.     if (curtok == TOK_IDENT &&
  147.          curtokmeaning &&
  148.          curtokmeaning->kind == MK_TYPE) {
  149.         ex = makeexpr_type(curtokmeaning->type);
  150.         gettok();
  151.         skipcloseparen();
  152.     } else if (curtok == TOK_IDENT && !strcmp(curtokcase, "typedef")) {
  153.         ex = makeexpr_name(getparenstr(inbufptr), tp_integer);
  154.         gettok();
  155.     } else {
  156.         ex = makeexpr_name(getparenstr(cp), tp_integer);
  157.         gettok();
  158.     }
  159.     return ex;
  160. }
  161. Expr *pc_expr2();
  162. Expr *pc_factor()
  163. {
  164.     Expr *ex;
  165.     char *cp;
  166.     Strlist *sl;
  167.     int i;
  168.     switch (curtok) {
  169.         case TOK_BANG:
  170.             gettok();
  171.             return makeexpr_not(pc_expr2(14));
  172.         case TOK_TWIDDLE:
  173.             gettok();
  174.             return makeexpr_un(EK_BNOT, tp_integer, pc_expr2(14));
  175.         case TOK_PLPL:
  176.             gettok();
  177.             ex = pc_expr2(14);
  178.             return makeexpr_assign(ex, makeexpr_plus(copyexpr(ex), makeexpr_long(1)));
  179.         case TOK_MIMI:
  180.             gettok();
  181.             ex = pc_expr2(14);
  182.             return makeexpr_assign(ex, makeexpr_minus(copyexpr(ex), makeexpr_long(1)));
  183.         case TOK_STAR:
  184.             gettok();
  185.             ex = pc_expr2(14);
  186.             if (ex->val.type->kind != TK_POINTER)
  187.                 ex->val.type = makepointertype(ex->val.type);
  188.             return makeexpr_hat(ex, 0);
  189.         case TOK_AMP:
  190.             gettok();
  191.             return makeexpr_addr(pc_expr2(14));
  192.         case TOK_PLUS:
  193.             gettok();
  194.             return pc_expr2(14);
  195.         case TOK_MINUS:
  196.             gettok();
  197.             return makeexpr_neg(pc_expr2(14));
  198.         case TOK_LPAR:
  199.             cp = inbufptr;
  200.             gettok();
  201.             if (istypespec()) {
  202.                 ex = pc_parentype(cp);
  203.                 return makeexpr_bin(EK_LITCAST, tp_integer, ex, pc_expr2(14));
  204.             }
  205.             ex = pc_expr();
  206.             skipcloseparen();
  207.             return ex;
  208.         case TOK_IDENT:
  209.             if (!strcmp(curtokcase, "sizeof")) {
  210.                 gettok();
  211.                 if (curtok != TOK_LPAR)
  212.                     return makeexpr_sizeof(pc_expr2(14), 1);
  213.                 cp = inbufptr;
  214.                 gettok();
  215.                 if (istypespec()) {
  216.                     ex = makeexpr_sizeof(pc_parentype(cp), 1);
  217.                 } else {
  218.                     ex = makeexpr_sizeof(pc_expr(), 1);
  219.                     skipcloseparen();
  220.                 }
  221.                 return ex;
  222.             }
  223.             if (curtoksym->flags & FMACREC) {
  224.                 ex = makeexpr(EK_MACARG, 0);
  225.                 ex->val.type = tp_integer;
  226.                 ex->val.i = 0;
  227.                 for (sl = funcmacroargs, i = 1; sl; sl = sl->next, i++) {
  228.                     if (sl->value == (long)curtoksym) {
  229.                         ex->val.i = i;
  230.                         break;
  231.                     }
  232.                 }
  233.             } else
  234.                 ex = makeexpr_name(curtokcase, nametotype(curtokcase));
  235.             gettok();
  236.             return ex;
  237.         case TOK_INTLIT:
  238.             ex = makeexpr_long(curtokint);
  239.             if (curtokbuf[strlen(curtokbuf)-1] == 'L')
  240.                 ex = makeexpr_longcast(ex, 1);
  241.             gettok();
  242.             return ex;
  243.         case TOK_HEXLIT:
  244.             ex = makeexpr_long(curtokint);
  245.             insertarg(&ex, 0, makeexpr_name("%#lx", tp_integer));
  246.             if (curtokbuf[strlen(curtokbuf)-1] == 'L')
  247.                 ex = makeexpr_longcast(ex, 1);
  248.             gettok();
  249.             return ex;
  250.         case TOK_OCTLIT:
  251.             ex = makeexpr_long(curtokint);
  252.             insertarg(&ex, 0, makeexpr_name("%#lo", tp_integer));
  253.             if (curtokbuf[strlen(curtokbuf)-1] == 'L')
  254.                 ex = makeexpr_longcast(ex, 1);
  255.             gettok();
  256.             return ex;
  257.         case TOK_REALLIT:
  258.             ex = makeexpr_real(curtokbuf);
  259.             gettok();
  260.             return ex;
  261.         case TOK_STRLIT:
  262.             ex = makeexpr_lstring(curtokbuf, curtokint);
  263.             gettok();
  264.             return ex;
  265.         case TOK_CHARLIT:
  266.             ex = makeexpr_char(curtokint);
  267.             gettok();
  268.             return ex;
  269.         default:
  270.     wexpected("a C expression");
  271.     return makeexpr_long(0);
  272.     }
  273. }
  274. #define pc_prec(pr)  if (prec > (pr)) return ex; gettok();
  275. Expr *pc_expr2(prec)
  276. int prec;
  277. {
  278.     Expr *ex, *ex2;
  279.     int i;
  280.     ex = pc_factor();
  281.     for (;;) {
  282.         switch (curtok) {
  283.             case TOK_COMMA:
  284.                 pc_prec(1);
  285.                 ex = makeexpr_comma(ex, pc_expr2(2));
  286.                 break;
  287.             case TOK_EQ:
  288.                 pc_prec(2);
  289.                 ex = makeexpr_assign(ex, pc_expr2(2));
  290.                 break;
  291.             case TOK_QM:
  292.                 pc_prec(3);
  293.                 ex2 = pc_expr();
  294.                 if (wneedtok(TOK_COLON))
  295.     ex = makeexpr_cond(ex, ex2, pc_expr2(3));
  296. else
  297.     ex = makeexpr_cond(ex, ex2, makeexpr_long(0));
  298.                 break;
  299.             case TOK_OROR:
  300.                 pc_prec(4);
  301.                 ex = makeexpr_or(ex, pc_expr2(5));
  302.                 break;
  303.             case TOK_ANDAND:
  304.                 pc_prec(5);
  305.                 ex = makeexpr_and(ex, pc_expr2(6));
  306.                 break;
  307.             case TOK_VBAR:
  308.                 pc_prec(6);
  309.                 ex = makeexpr_bin(EK_BOR, tp_integer, ex, pc_expr2(7));
  310.                 break;
  311.             case TOK_HAT:
  312.                 pc_prec(7);
  313.                 ex = makeexpr_bin(EK_BXOR, tp_integer, ex, pc_expr2(8));
  314.                 break;
  315.             case TOK_AMP:
  316.                 pc_prec(8);
  317.                 ex = makeexpr_bin(EK_BAND, tp_integer, ex, pc_expr2(9));
  318.                 break;
  319.             case TOK_EQEQ:
  320.                 pc_prec(9);
  321.                 ex = makeexpr_rel(EK_EQ, ex, pc_expr2(10));
  322.                 break;
  323.             case TOK_BANGEQ:
  324.                 pc_prec(9);
  325.                 ex = makeexpr_rel(EK_NE, ex, pc_expr2(10));
  326.                 break;
  327.             case TOK_LT:
  328.                 pc_prec(10);
  329.                 ex = makeexpr_rel(EK_LT, ex, pc_expr2(11));
  330.                 break;
  331.             case TOK_LE:
  332.                 pc_prec(10);
  333.                 ex = makeexpr_rel(EK_LE, ex, pc_expr2(11));
  334.                 break;
  335.             case TOK_GT:
  336.                 pc_prec(10);
  337.                 ex = makeexpr_rel(EK_GT, ex, pc_expr2(11));
  338.                 break;
  339.             case TOK_GE:
  340.                 pc_prec(10);
  341.                 ex = makeexpr_rel(EK_GE, ex, pc_expr2(11));
  342.                 break;
  343.             case TOK_LTLT:
  344.                 pc_prec(11);
  345.                 ex = makeexpr_bin(EK_LSH, tp_integer, ex, pc_expr2(12));
  346.                 break;
  347.             case TOK_GTGT:
  348.                 pc_prec(11);
  349.                 ex = makeexpr_bin(EK_RSH, tp_integer, ex, pc_expr2(12));
  350.                 break;
  351.             case TOK_PLUS:
  352.                 pc_prec(12);
  353.                 ex = makeexpr_plus(ex, pc_expr2(13));
  354.                 break;
  355.             case TOK_MINUS:
  356.                 pc_prec(12);
  357.                 ex = makeexpr_minus(ex, pc_expr2(13));
  358.                 break;
  359.             case TOK_STAR:
  360.                 pc_prec(13);
  361.                 ex = makeexpr_times(ex, pc_expr2(14));
  362.                 break;
  363.             case TOK_SLASH:
  364.                 pc_prec(13);
  365.                 ex = makeexpr_div(ex, pc_expr2(14));
  366.                 break;
  367.             case TOK_PERC:
  368.                 pc_prec(13);
  369.                 ex = makeexpr_mod(ex, pc_expr2(14));
  370.                 break;
  371.             case TOK_PLPL:
  372.                 pc_prec(15);
  373.                 ex = makeexpr_un(EK_POSTINC, tp_integer, ex);
  374.                 break;
  375.             case TOK_MIMI:
  376.                 pc_prec(15);
  377.                 ex = makeexpr_un(EK_POSTDEC, tp_integer, ex);
  378.                 break;
  379.             case TOK_LPAR:
  380.                 pc_prec(16);
  381.                 if (ex->kind == EK_NAME) {
  382.                     ex->kind = EK_BICALL;
  383.                 } else {
  384.                     ex = makeexpr_un(EK_SPCALL, tp_integer, ex);
  385.                 }
  386.                 while (curtok != TOK_RPAR) {
  387.                     insertarg(&ex, ex->nargs, pc_expr2(2));
  388.                     if (curtok != TOK_RPAR)
  389.                         if (!wneedtok(TOK_COMMA))
  390.     skiptotoken2(TOK_RPAR, TOK_SEMI);
  391.                 }
  392.                 gettok();
  393.                 break;
  394.             case TOK_LBR:
  395.                 pc_prec(16);
  396.                 ex = makeexpr_index(ex, pc_expr(), NULL);
  397.                 if (!wneedtok(TOK_RBR))
  398.     skippasttoken(TOK_RBR);
  399.                 break;
  400.             case TOK_ARROW:
  401.                 pc_prec(16);
  402.                 if (!wexpecttok(TOK_IDENT))
  403.     break;
  404.                 if (ex->val.type->kind != TK_POINTER)
  405.                     ex->val.type = makepointertype(ex->val.type);
  406.                 ex = makeexpr_dotq(makeexpr_hat(ex, 0),
  407.                                    curtokcase, tp_integer);
  408.                 gettok();
  409.                 break;
  410.             case TOK_DOT:
  411.                 pc_prec(16);
  412.                 if (!wexpecttok(TOK_IDENT))
  413.     break;
  414.                 ex = makeexpr_dotq(ex, curtokcase, tp_integer);
  415.                 gettok();
  416.                 break;
  417.     case TOK_COLONCOLON:
  418. if (prec > 16)
  419.     return ex;
  420. i = C_lex;
  421. C_lex = 0;
  422. gettok();
  423. if (curtok == TOK_IDENT &&
  424.     curtokmeaning && curtokmeaning->kind == MK_TYPE) {
  425.     ex->val.type = curtokmeaning->type;
  426. } else if (curtok == TOK_LPAR) {
  427.     gettok();
  428.     ex->val.type = p_type(NULL);
  429.     if (!wexpecttok(TOK_RPAR))
  430. skiptotoken(TOK_RPAR);
  431. } else
  432.     wexpected("a type name");
  433. C_lex = i;
  434. gettok();
  435. break;
  436.             default:
  437.                 return ex;
  438.         }
  439.     }
  440. }
  441. Expr *pc_expr()
  442. {
  443.     return pc_expr2(0);
  444. }
  445. Expr *pc_expr_str(buf)
  446. char *buf;
  447. {
  448.     Strlist *defsl, *sl;
  449.     Expr *ex;
  450.     defsl = NULL;
  451.     sl = strlist_append(&defsl, buf);
  452.     C_lex++;
  453.     push_input_strlist(defsl, buf);
  454.     ex = pc_expr();
  455.     if (curtok != TOK_EOF)
  456.         warning(format_s("Junk (%s) at end of C expression [306]",
  457.  tok_name(curtok)));
  458.     pop_input();
  459.     C_lex--;
  460.     strlist_empty(&defsl);
  461.     return ex;
  462. }
  463. /* Simplify an expression */
  464. Expr *fixexpr(ex, env)
  465. Expr *ex;
  466. int env;
  467. {
  468.     Expr *ex2, *ex3, **ep;
  469.     Type *type, *type2;
  470.     Meaning *mp;
  471.     char *cp;
  472.     char sbuf[5];
  473.     int i;
  474.     Value val;
  475.     if (!ex)
  476.         return NULL;
  477.     switch (ex->kind) {
  478.         case EK_BICALL:
  479.             ex2 = fix_bicall(ex, env);
  480.             if (ex2) {
  481.                 ex = ex2;
  482.                 break;
  483.             }
  484.             cp = ex->val.s;
  485.             if (!strcmp(cp, "strlen")) {
  486.                 if (ex->args[0]->kind == EK_BICALL &&
  487.                     !strcmp(ex->args[0]->val.s, "sprintf") &&
  488.                     sprintf_value == 0) {     /* does sprintf return char count? */
  489.                     ex = grabarg(ex, 0);
  490.                     strchange(&ex->val.s, "*sprintf");
  491.                     ex = fixexpr(ex, env);
  492.                 } else {
  493.                     ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
  494.                 }
  495.             } else if (!strcmp(cp, name_SETIO)) {
  496.                 ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  497.             } else if (!strcmp(cp, "~~SETIO")) {
  498.                 ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  499.                 ex = makeexpr_cond(ex->args[0],
  500.                                    makeexpr_long(0),
  501.                                    makeexpr_bicall_1(name_ESCIO, tp_int, ex->args[1]));
  502.             } else if (!strcmp(cp, name_CHKIO)) {
  503.                 ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  504.                 ex->args[2] = fixexpr(ex->args[2], env);
  505.                 ex->args[3] = fixexpr(ex->args[3], env);
  506.             } else if (!strcmp(cp, "~~CHKIO")) {
  507.                 ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  508.                 ex->args[2] = fixexpr(ex->args[2], env);
  509.                 ex->args[3] = fixexpr(ex->args[3], env);
  510.                 ex2 = makeexpr_bicall_1(name_ESCIO, tp_int, ex->args[1]);
  511.                 if (ord_type(ex->args[3]->val.type)->kind != TK_INTEGER)
  512.                     ex2 = makeexpr_cast(ex2, ex->args[3]->val.type);
  513.                 ex = makeexpr_cond(ex->args[0], ex->args[2], ex2);
  514.             } else if (!strcmp(cp, "assert")) {
  515.                 ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  516.             } else {
  517.                 for (i = 0; i < ex->nargs; i++)
  518.                     ex->args[i] = fixexpr(ex->args[i], ENV_EXPR);
  519. ex = cleansprintf(ex);
  520.                 if (!strcmp(cp, "sprintf")) {
  521.                     if (checkstring(ex->args[1], "%s")) {
  522.                         delfreearg(&ex, 1);
  523.                         strchange(&ex->val.s, "strcpy");
  524.                         ex = fixexpr(ex, env);
  525.                     } else if (sprintf_value != 1 && env != ENV_STMT) {
  526.                         if (*sprintfname) {
  527.                             strchange(&ex->val.s, format_s("*%s", sprintfname));
  528.                         } else {
  529.                             strchange(&ex->val.s, "*sprintf");
  530.                             ex = makeexpr_comma(ex, copyexpr(ex->args[0]));
  531.                         }
  532.                     }
  533.                 } else if (!strcmp(cp, "strcpy")) {
  534.                     if (env == ENV_STMT &&
  535.                          ex->args[1]->kind == EK_BICALL &&
  536.                          !strcmp(ex->args[1]->val.s, "strcpy") &&
  537.                          nosideeffects(ex->args[1]->args[0], 1)) {
  538.                         ex2 = ex->args[1];
  539.                         ex->args[1] = copyexpr(ex2->args[0]);
  540.                         ex = makeexpr_comma(ex2, ex);
  541.                     }
  542.                 } else if (!strcmp(cp, "memcpy")) {
  543.                     strchange(&ex->val.s, format_s("*%s", memcpyname));
  544.                     if (!strcmp(memcpyname, "*bcopy")) {
  545.                         swapexprs(ex->args[0], ex->args[1]);
  546.                         if (env != ENV_STMT)
  547.                             ex = makeexpr_comma(ex, copyexpr(ex->args[1]));
  548.                     }
  549. } else if (!strcmp(cp, setunionname) &&
  550.    (ex3 = singlevar(ex->args[0])) != NULL &&
  551.    ((i=1, exprsame(ex->args[0], ex->args[i], 0)) ||
  552.     (i=2, exprsame(ex->args[0], ex->args[i], 0))) &&
  553.    !exproccurs(ex3, ex->args[3-i])) {
  554.     ep = &ex->args[3-i];
  555.     while ((ex2 = *ep)->kind == EK_BICALL &&
  556.    (!strcmp(ex2->val.s, setaddname) ||
  557.     !strcmp(ex2->val.s, setaddrangename)))
  558. ep = &ex2->args[0];
  559.     if (ex2->kind == EK_BICALL &&
  560. !strcmp(ex2->val.s, setexpandname) &&
  561. checkconst(ex2->args[1], 0) &&
  562. (mp = istempvar(ex2->args[0])) != NULL) {
  563. if (ex2 == ex->args[3-i]) {
  564.     ex = grabarg(ex, i);
  565. } else {
  566.     freeexpr(ex2);
  567.     *ep = ex->args[i];
  568.     ex = ex->args[3-i];
  569. }
  570.     }
  571. } else if (!strcmp(cp, setdiffname) && *setremname &&
  572.    (ex3 = singlevar(ex->args[0])) != NULL &&
  573.    exprsame(ex->args[0], ex->args[1], 0) &&
  574.    !exproccurs(ex3, ex->args[2])) {
  575.     ep = &ex->args[2];
  576.     while ((ex2 = *ep)->kind == EK_BICALL &&
  577.    !strcmp(ex2->val.s, setaddname))
  578. ep = &ex2->args[0];
  579.     if (ex2->kind == EK_BICALL &&
  580. !strcmp(ex2->val.s, setexpandname) &&
  581. checkconst(ex2->args[1], 0) &&
  582. (mp = istempvar(ex2->args[0])) != NULL) {
  583. if (ex2 == ex->args[2]) {
  584.     ex = grabarg(ex, 1);
  585. } else {
  586.     ex2 = ex->args[2];
  587.     while (ex2->kind == EK_BICALL &&
  588.    !strcmp(ex2->val.s, setaddname)) {
  589. strchange(&ex2->val.s, setremname);
  590. ex2 = ex2->args[0];
  591.     }
  592.     freeexpr(ex2);
  593.     *ep = ex->args[1];
  594.     ex = ex->args[2];
  595. }
  596.     }
  597.                 } else if (!strcmp(cp, setexpandname) && env == ENV_STMT &&
  598.                            checkconst(ex->args[1], 0)) {
  599.                     ex = makeexpr_assign(makeexpr_hat(ex->args[0], 0),
  600.                                          ex->args[1]);
  601.                 } else if (!strcmp(cp, getbitsname)) {
  602.     type = ex->args[0]->val.type;
  603.     if (type->kind == TK_POINTER)
  604. type = type->basetype;
  605.                     sbuf[0] = (type->issigned) ? 'S' : 'U';
  606.                     sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
  607.                     sbuf[2] = 0;
  608.                     if (sbuf[1] == 'S' &&
  609.                         type->smax->val.type == tp_boolean) {
  610.                         ex = makeexpr_rel(EK_NE,
  611.                                           makeexpr_bin(EK_BAND, tp_integer,
  612.                                                        ex->args[0],
  613.                                                        makeexpr_bin(EK_LSH, tp_integer,
  614.                                                                     makeexpr_longcast(makeexpr_long(1),
  615.                                                                                       type->basetype
  616.                                                                                             == tp_unsigned),
  617.                                                                     ex->args[1])),
  618.                                           makeexpr_long(0));
  619.                         ex = fixexpr(ex, env);
  620.                     } else
  621.                         strchange(&ex->val.s, format_s(cp, sbuf));
  622.                 } else if (!strcmp(cp, putbitsname)) {
  623.     type = ex->args[0]->val.type;
  624.     if (type->kind == TK_POINTER)
  625. type = type->basetype;
  626.                     sbuf[0] = (type->issigned) ? 'S' : 'U';
  627.                     sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
  628.                     sbuf[2] = 0;
  629.                     if (sbuf[1] == 'S' &&
  630.                         type->smax->val.type == tp_boolean) {
  631.                         ex = makeexpr_assign(ex->args[0],
  632.                                              makeexpr_bin(EK_BOR, tp_integer,
  633.                                                           copyexpr(ex->args[0]),
  634.                                                           makeexpr_bin(EK_LSH, tp_integer,
  635.                                                                        makeexpr_longcast(ex->args[2],
  636.                                                                                          type->basetype
  637.                                                                                                == tp_unsigned),
  638.                                                                        ex->args[1])));
  639.                     } else
  640.                         strchange(&ex->val.s, format_s(cp, sbuf));
  641.                 } else if (!strcmp(cp, storebitsname)) {
  642.     type = ex->args[0]->val.type;
  643.     if (type->kind == TK_POINTER)
  644. type = type->basetype;
  645.                     sbuf[0] = (type->issigned) ? 'S' : 'U';
  646.                     sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
  647.                     sbuf[2] = 0;
  648.                     strchange(&ex->val.s, format_s(cp, sbuf));
  649.                 } else if (!strcmp(cp, clrbitsname)) {
  650.     type = ex->args[0]->val.type;
  651.     if (type->kind == TK_POINTER)
  652. type = type->basetype;
  653.                     sbuf[0] = (type->kind == TK_ARRAY) ? 'B' : 'S';
  654.                     sbuf[1] = 0;
  655.                     if (sbuf[0] == 'S' &&
  656.                         type->smax->val.type == tp_boolean) {
  657.                         ex = makeexpr_assign(ex->args[0],
  658.                                              makeexpr_bin(EK_BAND, tp_integer,
  659.                                                    copyexpr(ex->args[0]),
  660.                                                    makeexpr_un(EK_BNOT, tp_integer,
  661.                                                           makeexpr_bin(EK_LSH, tp_integer,
  662.                                                                        makeexpr_longcast(makeexpr_long(1),
  663.                                                                                          type->basetype
  664.                                                                                                == tp_unsigned),
  665.                                                                        ex->args[1]))));
  666.                     } else
  667.                         strchange(&ex->val.s, format_s(cp, sbuf));
  668.                 } else if (!strcmp(cp, "fopen")) {
  669.     if (which_lang == LANG_HP &&
  670. ex->args[0]->kind == EK_CONST &&
  671. ex->args[0]->val.type->kind == TK_STRING &&
  672. ex->args[0]->val.i >= 1 &&
  673. ex->args[0]->val.i <= 2 &&
  674. isdigit(ex->args[0]->val.s[0]) &&
  675. (ex->args[0]->val.i == 1 ||
  676.  isdigit(ex->args[0]->val.s[1]))) {
  677. strchange(&ex->val.s, "fdopen");
  678. ex->args[0] = makeexpr_long(atoi(ex->args[0]->val.s));
  679.     }
  680. }
  681.             }
  682.             break;
  683.         case EK_NOT:
  684.             ex = makeexpr_not(fixexpr(grabarg(ex, 0), ENV_BOOL));
  685.             break;
  686.         case EK_AND:
  687.         case EK_OR:
  688.             for (i = 0; i < ex->nargs; i++)
  689.                 ex->args[i] = fixexpr(ex->args[i], ENV_BOOL);
  690.             break;
  691.         case EK_EQ:
  692.         case EK_NE:
  693.             ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
  694.             ex->args[1] = fixexpr(ex->args[1], ENV_EXPR);
  695.             if (checkconst(ex->args[1], 0) && env == ENV_BOOL &&
  696.                 ord_type(ex->args[1]->val.type)->kind != TK_ENUM &&
  697.                 (implicitzero > 0 ||
  698.                  (implicitzero < 0 && ex->args[0]->kind == EK_BICALL &&
  699.                                       boolean_bicall(ex->args[0]->val.s)))) {
  700.                 if (ex->kind == EK_EQ)
  701.                     ex = makeexpr_not(grabarg(ex, 0));
  702.                 else {
  703.                     ex = grabarg(ex, 0);
  704.                     ex->val.type = tp_boolean;
  705.                 }
  706.             }
  707.             break;
  708.         case EK_COND:
  709.             ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
  710. #if 0
  711.             val = eval_expr(ex->args[0]);
  712. #else
  713.     val = ex->args[0]->val;
  714.     if (ex->args[0]->kind != EK_CONST)
  715. val.type = NULL;
  716. #endif
  717.             if (val.type == tp_boolean) {
  718.                 ex = grabarg(ex, (val.i) ? 1 : 2);
  719.                 ex = fixexpr(ex, env);
  720.             } else {
  721.                 ex->args[1] = fixexpr(ex->args[1], env);
  722.                 ex->args[2] = fixexpr(ex->args[2], env);
  723.             }
  724.             break;
  725.         case EK_COMMA:
  726.             for (i = 0; i < ex->nargs-1; ) {
  727.                 ex->args[i] = fixexpr(ex->args[i], ENV_STMT);
  728.                 if (nosideeffects(ex->args[i], 1))
  729.                     delfreearg(&ex, i);
  730.                 else
  731.                     i++;
  732.             }
  733.             ex->args[ex->nargs-1] = fixexpr(ex->args[ex->nargs-1], env);
  734.             if (ex->nargs == 1)
  735.                 ex = grabarg(ex, 0);
  736.             break;
  737.         case EK_CHECKNIL:
  738.             ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
  739.             if (ex->nargs == 2) {
  740.                 ex->args[1] = fixexpr(ex->args[1], ENV_EXPR);
  741.                 ex2 = makeexpr_assign(copyexpr(ex->args[1]), ex->args[0]);
  742.                 ex3 = ex->args[1];
  743.             } else {
  744.                 ex2 = copyexpr(ex->args[0]);
  745.                 ex3 = ex->args[0];
  746.             }
  747.             type = ex->args[0]->val.type;
  748.             type2 = ex->val.type;
  749.             ex = makeexpr_cond(makeexpr_rel(EK_NE, ex2, makeexpr_nil()),
  750.                                ex3,
  751.                                makeexpr_cast(makeexpr_bicall_0(name_NILCHECK,
  752.                                                                tp_int),
  753.                                              type));
  754.             ex->val.type = type2;
  755.             ex = fixexpr(ex, env);
  756.             break;
  757.         case EK_CAST:
  758.         case EK_ACTCAST:
  759.             if (env == ENV_STMT) {
  760.                 ex = fixexpr(grabarg(ex, 0), ENV_STMT);
  761.             } else {
  762.                 ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
  763.             }
  764.             break;
  765.         default:
  766.             for (i = 0; i < ex->nargs; i++)
  767.                 ex->args[i] = fixexpr(ex->args[i], ENV_EXPR);
  768.             break;
  769.     }
  770.     return fix_expression(ex, env);
  771. }
  772. /* Output an expression */
  773. #define bitOp(k)  ((k)==EK_BAND || (k)==EK_BOR || (k)==EK_BXOR)
  774. #define shfOp(k)  ((k)==EK_LSH || (k)==EK_RSH)
  775. #define logOp(k)  ((k)==EK_AND || (k)==EK_OR)
  776. #define relOp(k)  ((k)==EK_EQ || (k)==EK_LT || (k)==EK_GT ||    
  777.    (k)==EK_NE || (k)==EK_GE || (k)==EK_LE)
  778. #define mathOp(k) ((k)==EK_PLUS || (k)==EK_TIMES || (k)==EK_NEG ||   
  779.    (k)==EK_DIV || (k)==EK_DIVIDE || (k)==EK_MOD)
  780. #define divOp(k)  ((k)==EK_DIV || (k)==EK_DIVIDE)
  781. Static int incompat(ex, num, prec)
  782. Expr *ex;
  783. int num, prec;
  784. {
  785.     Expr *subex = ex->args[num];
  786.     if (extraparens == 0)
  787. return prec;
  788.     if (ex->kind == subex->kind) {
  789. if (logOp(ex->kind) || bitOp(ex->kind) ||
  790.     (divOp(ex->kind) && num == 0))
  791.     return -99;   /* not even invisible parens */
  792. else if (extraparens != 2)
  793.     return prec;
  794.     }
  795.     if (extraparens == 2)
  796. return 15;
  797.     if (divOp(ex->kind) && num == 0 &&
  798. (subex->kind == EK_TIMES || divOp(subex->kind)))
  799. return -99;
  800.     if (bitOp(ex->kind) || shfOp(ex->kind))
  801. return 15;
  802.     if (relOp(ex->kind) && relOp(subex->kind))
  803. return 15;
  804.     if ((relOp(ex->kind) || logOp(ex->kind)) && bitOp(subex->kind))
  805. return 15;
  806.     if (ex->kind == EK_COMMA)
  807. return 15;
  808.     if (ex->kind == EK_ASSIGN && relOp(subex->kind))
  809. return 15;
  810.     if (extraparens != 1)
  811. return prec;
  812.     if (ex->kind == EK_ASSIGN)
  813. return prec;
  814.     if (relOp(ex->kind) && mathOp(subex->kind))
  815. return prec;
  816.     return 15;
  817. }
  818. #define EXTRASPACE() if (spaceexprs == 1) output(" ")
  819. #define NICESPACE()  if (spaceexprs != 0) output(" ")
  820. #define setprec(p) 
  821.     if ((subprec=(p)) <= prec) { 
  822.         parens = 1; output("("); 
  823.     }
  824. #define setprec2(p) 
  825.     if ((subprec=(p)) <= prec) { 
  826.         parens = 1; output("("); 
  827.     } else if (prec != -99) { 
  828.         parens = 2; output((breakparens == 1) ? "10" : "03"); 
  829.     }
  830. #define setprec3(p) 
  831.     if ((subprec=(p)) <= prec) { 
  832.          parens = 1; output("("); 
  833.     } else if (prec != -99) { 
  834.          parens = 2; output((prec > 2 && breakparens != 0) ? "10" 
  835.                                    : "03"); 
  836.     }
  837. Static void outop3(breakbefore, name)
  838. int breakbefore;
  839. char *name;
  840. {
  841.     if (breakbefore & BRK_LEFT) {
  842. output("02");
  843. if (breakbefore & BRK_RPREF)
  844.     output("13");
  845.     }
  846.     output(name);
  847.     if (breakbefore & BRK_HANG)
  848. output("15");
  849.     if (breakbefore & BRK_RIGHT) {
  850. output("02");
  851. if (breakbefore & BRK_LPREF)
  852.     output("13");
  853.     }
  854. }
  855. #define outop(name) do { 
  856.     NICESPACE(); outop3(breakflag, name); NICESPACE(); 
  857. } while (0)
  858. #define outop2(name) do { 
  859.     EXTRASPACE(); outop3(breakflag, name); EXTRASPACE(); 
  860. } while (0)
  861. #define checkbreak(code) do { 
  862.     breakflag=(code); 
  863.     if ((prec != -99) && (breakflag & BRK_ALLNONE)) output("07"); 
  864. } while (0)
  865. Static void out_ctx(ctx, address)
  866. Meaning *ctx;
  867. int address;
  868. {
  869.     Meaning *ctx2;
  870.     int breakflag = breakbeforedot;
  871.     if (ctx->kind == MK_FUNCTION && ctx->varstructflag) {
  872.         if (curctx != ctx) {
  873.     if (address && curctx->ctx && curctx->ctx != ctx) {
  874. output("03");
  875. if (breakflag & BRK_ALLNONE)
  876.     output("07");
  877.     }
  878.             output(format_s(name_LINK, curctx->ctx->name));
  879.             ctx2 = curctx->ctx;
  880.             while (ctx2 && ctx2 != ctx) {
  881.                 outop2("->");
  882.                 output(format_s(name_LINK, ctx2->ctx->name));
  883.                 ctx2 = ctx2->ctx;
  884.             }
  885.             if (ctx2 != ctx)
  886.                 intwarning("out_ctx",
  887.                            format_s("variable from %s not present in context path [307]",
  888.                                      ctx->name));
  889.     if (address && curctx->ctx && curctx->ctx != ctx)
  890. output("04");
  891.             if (!address)
  892.                 outop2("->");
  893.         } else {
  894.             if (address) {
  895.                 output("&");
  896. EXTRASPACE();
  897.     }
  898.             output(format_s(name_VARS, curctx->name));
  899.             if (!address) {
  900.                 outop2(".");
  901.     }
  902.         }
  903.     } else {
  904.         if (address)
  905.             output("NULL");
  906.     }
  907. }
  908. void out_var(mp, prec)
  909. Meaning *mp;
  910. int prec;
  911. {
  912.     switch (mp->kind) {
  913.         case MK_CONST:
  914.             output(mp->name);
  915.             return;
  916.         case MK_VAR:
  917.         case MK_VARREF:
  918.         case MK_VARMAC:
  919.         case MK_PARAM:
  920.         case MK_VARPARAM:
  921.             if (mp->varstructflag) {
  922. output("03");
  923.                 out_ctx(mp->ctx, 0);
  924. output(mp->name);
  925. output("04");
  926.     } else
  927. output(mp->name);
  928.             return;
  929. default:
  930.     if (mp->name)
  931. output(mp->name);
  932.     else
  933. intwarning("out_var", "mp->sym == NULL [308]");
  934.     return;
  935.     }
  936. }
  937. Static int scanfield(variants, unions, lev, mp, field)
  938. Meaning **variants, *mp, *field;
  939. short *unions;
  940. int lev;
  941. {
  942.     int i, num, breakflag;
  943.     Value v;
  944.     unions[lev] = (mp && mp->kind == MK_VARIANT);
  945.     while (mp && mp->kind == MK_FIELD) {
  946.         if (mp == field) {
  947.             for (i = 0; i < lev; i++) {
  948. v = variants[i]->val;    /* sidestep a Sun 386i compiler bug */
  949.                 num = ord_value(v);
  950. breakflag = breakbeforedot;
  951.                 if (!unions[i]) {
  952.                     output(format_s(name_UNION, ""));
  953.     outop2(".");
  954.                 }
  955.                 if (variants[i]->ctx->cnext ||
  956.                     variants[i]->ctx->kind != MK_FIELD) {
  957.                     output(format_s(name_VARIANT, variantfieldname(num)));
  958.     outop2(".");
  959.                 }
  960.             }
  961.             output(mp->name);
  962.             return 1;
  963.         }
  964.         mp = mp->cnext;
  965.     }
  966.     while (mp && mp->kind == MK_VARIANT) {
  967.         variants[lev] = mp;
  968.         if (scanfield(variants, unions, lev+1, mp->ctx, field))
  969.             return 1;
  970.         mp = mp->cnext;
  971.     }
  972.     return 0;
  973. }
  974. void out_field(mp)
  975. Meaning *mp;
  976. {
  977.     Meaning *variants[50];
  978.     short unions[51];
  979.     if (!scanfield(variants, unions, 0, mp->rectype->fbase, mp))
  980.         intwarning("out_field", "field name not in tree [309]");
  981.     else if (mp->warnifused) {
  982.         if (mp->rectype->meaning)
  983.             note(format_ss("Reference to field %s of record %s [282]", 
  984.                            mp->name, mp->rectype->meaning->name));
  985.         else
  986.             note(format_s("Reference to field %s [282]", mp->name));
  987.     }
  988. }
  989. Static void wrexpr(ex, prec)
  990. Expr *ex;
  991. int prec;
  992. {
  993.     short parens = 0;
  994.     int subprec, i, j, minusflag, breakflag = 0;
  995.     int saveindent;
  996.     Expr *ex2, *ex3;
  997.     char *cp;
  998.     Meaning *mp;
  999.     Symbol *sp;
  1000.     if (debug>2) { fprintf(outf,"wrexpr{"); dumpexpr(ex); fprintf(outf,", %d}n", prec); }
  1001.     switch (ex->kind) {
  1002.         case EK_VAR:
  1003.             mp = (Meaning *)ex->val.i;
  1004.             if (mp->warnifused)
  1005.                 note(format_s("Reference to %s [283]", mp->name));
  1006.             out_var(mp, prec);
  1007.             break;
  1008.         case EK_NAME:
  1009.             output(ex->val.s);
  1010.             break;
  1011.         case EK_MACARG:
  1012.             output("<meef>");
  1013.             intwarning("wrexpr", "Stray EK_MACARG encountered [310]");
  1014.             break;
  1015.         case EK_CTX:
  1016.             out_ctx((Meaning *)ex->val.i, 1);
  1017.             break;
  1018.         case EK_CONST:
  1019.             if (ex->nargs > 0)
  1020.                 cp = value_name(ex->val, ex->args[0]->val.s, 0);
  1021.             else
  1022.                 cp = value_name(ex->val, NULL, 0);
  1023.             if (*cp == '-')
  1024.                 setprec(14);
  1025.             output(cp);
  1026.             break;
  1027.         case EK_LONGCONST:
  1028.             if (ex->nargs > 0)
  1029.                 cp = value_name(ex->val, ex->args[0]->val.s, 1);
  1030.             else
  1031.                 cp = value_name(ex->val, NULL, 1);
  1032.             if (*cp == '-')
  1033.                 setprec(14);
  1034.             output(cp);
  1035.             break;
  1036.         case EK_STRUCTCONST:
  1037.             ex3 = NULL;
  1038.             for (i = 0; i < ex->nargs; i++) {
  1039.                 ex2 = ex->args[i];
  1040.                 if (ex2->kind == EK_STRUCTOF) {
  1041.                     j = ex2->val.i;
  1042.                     ex2 = ex2->args[0];
  1043.                 } else
  1044.                     j = 1;
  1045.                 if (ex2->kind == EK_VAR) {
  1046.                     mp = (Meaning *)ex2->val.i;
  1047.                     if (mp->kind == MK_CONST &&
  1048.                         (mp->val.type->kind == TK_RECORD ||
  1049.                          mp->val.type->kind == TK_ARRAY)) {
  1050.                         if (foldconsts != 1)
  1051.                             note(format_s("Expanding constant %s into another constant [284]",
  1052.                                           mp->name));
  1053.                         ex2 = (Expr *)mp->val.i;
  1054.                     }
  1055.                 }
  1056.                 while (--j >= 0) {
  1057.                     if (ex3) {
  1058.                         if (ex3->kind == EK_STRUCTCONST ||
  1059.                             ex2->kind == EK_STRUCTCONST)
  1060.                             output(",n");
  1061.                         else
  1062.                             output(",01 ");
  1063.                     }
  1064.                     if (ex2->kind == EK_STRUCTCONST) {
  1065.                         output("{ 05");
  1066. saveindent = outindent;
  1067. moreindent(extrainitindent);
  1068.                         out_expr(ex2);
  1069.                         outindent = saveindent;
  1070.                         output(" }");
  1071.                     } else
  1072.                         out_expr(ex2);
  1073.                     ex3 = ex2;
  1074.                 }
  1075.             }
  1076.             break;
  1077.         case EK_FUNCTION:
  1078.             mp = (Meaning *)ex->val.i;
  1079.     sp = findsymbol_opt(mp->name);
  1080.     if ((sp && (sp->flags & WARNLIBR)) || mp->warnifused)
  1081.                 note(format_s("Called procedure %s [285]", mp->name));
  1082.             output(mp->name);
  1083.             output("(02");
  1084.     j = sp ? (sp->flags & FUNCBREAK) : 0;
  1085.     if (j == FALLBREAK)
  1086. output("07");
  1087.             for (i = 0; i < ex->nargs; i++) {
  1088. if ((j == FSPCARG1 && i == 1) ||
  1089.     (j == FSPCARG2 && i == 2) ||
  1090.     (j == FSPCARG3 && i == 3))
  1091.     output(",11 ");
  1092.                 else if (i > 0)
  1093.                     output(",02 ");
  1094.                 out_expr(ex->args[i]);
  1095.             }
  1096.             if (mp->ctx->kind == MK_FUNCTION && mp->ctx->varstructflag) {
  1097.                 if (i > 0)
  1098.                     output(",02 ");
  1099.                 out_ctx(mp->ctx, 1);
  1100.             }
  1101.             output(")");
  1102.             break;
  1103.         case EK_BICALL:
  1104.             cp = ex->val.s;
  1105.             while (*cp == '*')
  1106.                 cp++;
  1107.     sp = findsymbol_opt(cp);
  1108.     if (sp && (sp->flags & WARNLIBR))
  1109.                 note(format_s("Called library procedure %s [286]", cp));
  1110.             output(cp);
  1111.             output("(02");
  1112.     j = sp ? (sp->flags & FUNCBREAK) : 0;
  1113.     if (j == FALLBREAK)
  1114. output("07");
  1115.             for (i = 0; i < ex->nargs; i++) {
  1116. if ((j == FSPCARG1 && i == 1) ||
  1117.     (j == FSPCARG2 && i == 2) ||
  1118.     (j == FSPCARG3 && i == 3))
  1119.     output(",11 ");
  1120.                 else if (i > 0)
  1121.                     output(",02 ");
  1122.                 out_expr(ex->args[i]);
  1123.             }
  1124.             output(")");
  1125.             break;
  1126.         case EK_SPCALL:
  1127.             setprec(16);
  1128.             if (starfunctions) {
  1129.                 output("(02*");
  1130.                 wrexpr(ex->args[0], 13);
  1131.                 output(")");
  1132.             } else
  1133.                 wrexpr(ex->args[0], subprec-1);
  1134.             output("(02");
  1135.             for (i = 1; i < ex->nargs; i++) {
  1136.                 if (i > 1)
  1137.                     output(",02 ");
  1138.                 out_expr(ex->args[i]);
  1139.             }
  1140.             output(")");
  1141.             break;
  1142.         case EK_INDEX:
  1143.             setprec(16);
  1144.             wrexpr(ex->args[0], subprec-1);
  1145.     if (lookback(1) == ']')
  1146. output("01");
  1147.             output("[");
  1148.             out_expr(ex->args[1]);
  1149.             output("]");
  1150.             break;
  1151.         case EK_DOT:
  1152.             setprec2(16);
  1153.     checkbreak(breakbeforedot);
  1154.             if (ex->args[0]->kind == EK_HAT) {
  1155.                 wrexpr(ex->args[0]->args[0], subprec-1);
  1156.                 outop2("->");
  1157.             } else if (ex->args[0]->kind == EK_CTX) {
  1158.                 out_ctx((Meaning *)ex->args[0]->val.i, 0);
  1159.             } else {
  1160.                 wrexpr(ex->args[0], subprec-1);
  1161.                 outop2(".");
  1162.             }
  1163.             if (ex->val.i)
  1164.                 out_field((Meaning *)ex->val.i);
  1165.             else
  1166.                 output(ex->val.s);
  1167.             break;
  1168.         case EK_POSTINC:
  1169.     if (prec == 0 && !postincrement) {
  1170. setprec(14);
  1171. output("++");
  1172. EXTRASPACE();
  1173. wrexpr(ex->args[0], subprec);
  1174.     } else {
  1175. setprec(15);
  1176. wrexpr(ex->args[0], subprec);
  1177. EXTRASPACE();
  1178. output("++");
  1179.     }
  1180.             break;
  1181.         case EK_POSTDEC:
  1182.     if (prec == 0 && !postincrement) {
  1183. setprec(14);
  1184. output("--");
  1185. EXTRASPACE();
  1186. wrexpr(ex->args[0], subprec);
  1187.     } else {
  1188. setprec(15);
  1189. wrexpr(ex->args[0], subprec);
  1190. EXTRASPACE();
  1191. output("--");
  1192.     }
  1193.             break;
  1194.         case EK_HAT:
  1195.             setprec(14);
  1196.     if (lookback_prn(1) == '/')
  1197. output(" ");
  1198.             output("*");
  1199.             EXTRASPACE();
  1200.             wrexpr(ex->args[0], subprec-1);
  1201.             break;
  1202.         case EK_ADDR:
  1203.             setprec(14);
  1204.     if (lookback_prn(1) == '&')
  1205. output(" ");
  1206.             output("&");
  1207.             EXTRASPACE();
  1208.             wrexpr(ex->args[0], subprec-1);
  1209.             break;
  1210.         case EK_NEG:
  1211.             setprec(14);
  1212.             output("-");
  1213.             EXTRASPACE();
  1214.             if (ex->args[0]->kind == EK_TIMES)
  1215.                 wrexpr(ex->args[0], 12);
  1216.             else
  1217.                 wrexpr(ex->args[0], subprec-1);
  1218.             break;
  1219.         case EK_NOT:
  1220.             setprec(14);
  1221.             output("!");
  1222.             EXTRASPACE();
  1223.             wrexpr(ex->args[0], subprec-1);
  1224.             break;
  1225.         case EK_BNOT:
  1226.             setprec(14);
  1227.             output("~");
  1228.             EXTRASPACE();
  1229.             wrexpr(ex->args[0], subprec-1);
  1230.             break;
  1231.         case EK_CAST:
  1232.         case EK_ACTCAST:
  1233.             if (similartypes(ex->val.type, ex->args[0]->val.type)) {
  1234.                 wrexpr(ex->args[0], prec);
  1235.             } else if (ord_type(ex->args[0]->val.type)->kind == TK_ENUM &&
  1236.                        ex->val.type == tp_int && !useenum) {
  1237.                 wrexpr(ex->args[0], prec);
  1238.             } else {
  1239.                 setprec2(14);
  1240.                 output("(");
  1241.                 out_type(ex->val.type, 0);
  1242.                 output(")02");
  1243.                 EXTRASPACE();
  1244.                 if (extraparens != 0)
  1245.                     wrexpr(ex->args[0], 15);
  1246.                 else
  1247.                     wrexpr(ex->args[0], subprec-1);
  1248.             }
  1249.             break;
  1250.         case EK_LITCAST:
  1251.             setprec2(14);
  1252.             output("(");
  1253.             out_expr(ex->args[0]);
  1254.             output(")02");
  1255.             EXTRASPACE();
  1256.             if (extraparens != 0)
  1257.                 wrexpr(ex->args[1], 15);
  1258.             else
  1259.                 wrexpr(ex->args[1], subprec-1);
  1260.             break;
  1261.         case EK_SIZEOF:
  1262.             setprec(14);
  1263.             output("sizeof(");
  1264.     out_expr(ex->args[0]);
  1265.             output(")");
  1266.             break;
  1267. case EK_TYPENAME:
  1268.     out_type(ex->val.type, 1);
  1269.     break;
  1270.         case EK_TIMES:
  1271.     setprec2(13);
  1272.     checkbreak(breakbeforearith);
  1273.             ex2 = copyexpr(ex);
  1274.             if (expr_looks_neg(ex2->args[ex2->nargs-1])) {
  1275.                 ex2->args[0] = makeexpr_neg(ex2->args[0]);
  1276.                 ex2->args[ex2->nargs-1] = makeexpr_neg(ex2->args[ex2->nargs-1]);
  1277.             }
  1278.             wrexpr(ex2->args[0], incompat(ex2, 0, subprec-1));
  1279.             for (i = 1; i < ex2->nargs; i++) {
  1280.                 outop("*");
  1281.                 wrexpr(ex2->args[i], incompat(ex2, i, subprec));
  1282.             }
  1283.             freeexpr(ex2);
  1284.             break;
  1285.         case EK_DIV:
  1286.         case EK_DIVIDE:
  1287.             setprec2(13);
  1288.     checkbreak(breakbeforearith);
  1289.     wrexpr(ex->args[0], incompat(ex, 0, subprec-1));
  1290.             outop("/");
  1291.             wrexpr(ex->args[1], incompat(ex, 1, subprec));
  1292.             break;
  1293.         case EK_MOD:
  1294.             setprec2(13);
  1295.     checkbreak(breakbeforearith);
  1296.             wrexpr(ex->args[0], incompat(ex, 0, subprec-1));
  1297.             outop("%");
  1298.             wrexpr(ex->args[1], incompat(ex, 1, subprec));
  1299.             break;
  1300.         case EK_PLUS:
  1301.             setprec2(12);
  1302.     checkbreak(breakbeforearith);
  1303.             ex2 = copyexpr(ex);
  1304.             minusflag = 0;
  1305.             if (expr_looks_neg(ex2->args[0])) {
  1306.                 j = 1;
  1307.                 while (j < ex2->nargs && expr_looks_neg(ex2->args[j])) j++;
  1308.                 if (j < ex2->nargs)
  1309.                     swapexprs(ex2->args[0], ex2->args[j]);
  1310.             } else if (ex2->val.i && ex2->nargs == 2) {   /* this was originally "a-b" */
  1311.                 if (isliteralconst(ex2->args[1], NULL) != 2) {
  1312.                     if (expr_neg_cost(ex2->args[1]) <= 0) {
  1313.                         minusflag = 1;
  1314.                     } else if (expr_neg_cost(ex2->args[0]) <= 0) {
  1315.                         swapexprs(ex2->args[0], ex2->args[1]);
  1316.                         if (isliteralconst(ex2->args[0], NULL) != 2)
  1317.                             minusflag = 1;
  1318.                     }
  1319.                 }
  1320.             }
  1321.             wrexpr(ex2->args[0], incompat(ex, 0, subprec));
  1322.             for (i = 1; i < ex2->nargs; i++) {
  1323.                 if (expr_looks_neg(ex2->args[i]) || minusflag) {
  1324.                     outop("-");
  1325.                     ex2->args[i] = makeexpr_neg(ex2->args[i]);
  1326.                 } else
  1327.                     outop("+");
  1328.                 wrexpr(ex2->args[i], incompat(ex, i, subprec));
  1329.             }
  1330.             freeexpr(ex2);
  1331.             break;
  1332.         case EK_LSH:
  1333.             setprec3(11);
  1334.     checkbreak(breakbeforearith);
  1335.             wrexpr(ex->args[0], incompat(ex, 0, subprec));
  1336.             outop("<<");
  1337.             wrexpr(ex->args[1], incompat(ex, 1, subprec));
  1338.             break;
  1339.         case EK_RSH:
  1340.             setprec3(11);
  1341.     checkbreak(breakbeforearith);
  1342.     wrexpr(ex->args[0], incompat(ex, 0, subprec));
  1343.             outop(">>");
  1344.             wrexpr(ex->args[1], incompat(ex, 1, subprec));
  1345.             break;
  1346.         case EK_LT:
  1347.             setprec2(10);
  1348.     checkbreak(breakbeforerel);
  1349.             wrexpr(ex->args[0], incompat(ex, 0, subprec));
  1350.             outop("<");
  1351.             wrexpr(ex->args[1], incompat(ex, 0, subprec));
  1352.             break;
  1353.         case EK_GT: