v21i069: Pascal to C translator, Part24/32

Rich Salz rsalz at uunet.uu.net
Thu Mar 29 23:49:01 AEST 1990


Submitted-by: Dave Gillespie <daveg at csvax.caltech.edu>
Posting-number: Volume 21, Issue 69
Archive-name: p2c/part24

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 24 (of 32)."
# Contents:  src/pexpr.c.2
# Wrapped by rsalz at litchi.bbn.com on Mon Mar 26 14:29:47 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/pexpr.c.2' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/pexpr.c.2'\"
else
echo shar: Extracting \"'src/pexpr.c.2'\" \(48796 characters\)
sed "s/^X//" >'src/pexpr.c.2' <<'END_OF_FILE'
X                    ex = makeexpr_var(tvar);
X                } else
X                    ex3 = NULL;
X                ex4 = copyexpr(ex);
X                if (ex->kind == EK_CONST && smallsetconst)
X                    ex = makesmallsetconst(1<<ex->val.i, ex2->val.type);
X                else
X                    ex = makeexpr_bin(EK_LSH, ex2->val.type,
X                                      makeexpr_longcast(makeexpr_long(1), 1),
X                                      enum_to_int(ex));
X                ex = makeexpr_rel(EK_NE, makeexpr_bin(EK_BAND, tp_integer, ex, ex2),
X                                         makeexpr_long(0));
X                if (*name_SETBITS ||
X                    ((ex4->kind == EK_CONST) ? ((unsigned long)ex4->val.i >= setbits)
X                                             : !(0 <= smin && smax < setbits))) {
X                    ex = makeexpr_and(makeexpr_range(enum_to_int(ex4),
X                                                     makeexpr_long(0),
X                                                     makeexpr_setbits(), 0),
X                                      ex);
X                } else
X                    freeexpr(ex4);
X                ex = makeexpr_comma(ex3, ex);
X                return ex;
X            } else {
X                ex3 = ex2;
X                while (ex3->kind == EK_BICALL &&
X                       (!strcmp(ex3->val.s, setaddname) ||
X                        !strcmp(ex3->val.s, setaddrangename)))
X                    ex3 = ex3->args[0];
X                if (ex3->kind == EK_BICALL && !strcmp(ex3->val.s, setexpandname) &&
X                    (tvar = istempvar(ex3->args[0])) != NULL && 
X                    isconstexpr(ex3->args[1], &mask)) {
X                    canceltempvar(tvar);
X                    if (!nosideeffects(ex, 0)) {
X                        tvar = makestmttempvar(ex->val.type, name_TEMP);
X                        ex3 = makeexpr_assign(makeexpr_var(tvar), ex);
X                        ex = makeexpr_var(tvar);
X                    } else
X                        ex3 = NULL;
X                    type = ord_type(ex2->val.type->indextype);
X                    ex4 = NULL;
X                    i = 0;
X                    while (i < setbits) {
X                        if (mask & (1<<i++)) {
X                            if (i+1 < setbits && (mask & (2<<i))) {
X                                for (j = i; j < setbits && (mask & (1<<j)); j++) ;
X                                ex4 = makeexpr_or(ex4,
X                                        makeexpr_range(copyexpr(ex),
X                                                       makeexpr_val(make_ord(type, i-1)),
X                                                       makeexpr_val(make_ord(type, j-1)), 1));
X                                i = j;
X                            } else {
X                                ex4 = makeexpr_or(ex4,
X                                        makeexpr_rel(EK_EQ, copyexpr(ex),
X                                                            makeexpr_val(make_ord(type, i-1))));
X                            }
X                        }
X                    }
X                    mask = 0;
X                    for (;;) {
X                        if (!strcmp(ex2->val.s, setaddrangename)) {
X                            if (checkconst(ex2->args[1], 'a') &&
X                                checkconst(ex2->args[2], 'z')) {
X                                mask |= 0x1;
X                            } else if (checkconst(ex2->args[1], 'A') &&
X                                       checkconst(ex2->args[2], 'Z')) {
X                                mask |= 0x2;
X                            } else if (checkconst(ex2->args[1], '0') &&
X                                       checkconst(ex2->args[2], '9')) {
X                                mask |= 0x4;
X                            } else {
X                                ex4 = makeexpr_or(ex4,
X                                        makeexpr_range(copyexpr(ex), ex2->args[1], ex2->args[2], 1));
X                            }
X                        } else if (!strcmp(ex2->val.s, setaddname)) {
X                            ex4 = makeexpr_or(ex4,
X                                    makeexpr_rel(EK_EQ, copyexpr(ex), ex2->args[1]));
X                        } else
X                            break;
X                        ex2 = ex2->args[0];
X                    }
X                    /* do these now so that EK_OR optimizations will work: */
X                    if (mask & 0x1)
X                        ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
X                                                              makeexpr_char('a'),
X                                                              makeexpr_char('z'), 1));
X                    if (mask & 0x2)
X                        ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
X                                                              makeexpr_char('A'),
X                                                              makeexpr_char('Z'), 1));
X                    if (mask & 0x4)
X                        ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
X                                                              makeexpr_char('0'),
X                                                              makeexpr_char('9'), 1));
X                    freeexpr(ex);
X                    return makeexpr_comma(ex3, ex4);
X                }
X                return makeexpr_bicall_2(setinname, tp_boolean,
X                                         makeexpr_arglong(ex, 0), ex2);
X            }
X
X	default:
X	    return ex;
X    }
X}
X
X
X
X
X
X
X
X/* Parse a C expression; used by VarMacro, etc. */
X
XType *nametotype(name)
Xchar *name;
X{
X    if (!strcicmp(name, "malloc") ||
X	!strcicmp(name, mallocname)) {
X	return tp_anyptr;
X    }
X    return tp_integer;
X}
X
X
Xint istypespec()
X{
X    switch (curtok) {
X
X        case TOK_CONST:
X            return 1;
X
X        case TOK_IDENT:
X            return !strcmp(curtokcase, "volatile") ||
X                   !strcmp(curtokcase, "void") ||
X                   !strcmp(curtokcase, "char") ||
X                   !strcmp(curtokcase, "short") ||
X                   !strcmp(curtokcase, "int") ||
X                   !strcmp(curtokcase, "long") ||
X                   !strcmp(curtokcase, "float") ||
X                   !strcmp(curtokcase, "double") ||
X                   !strcmp(curtokcase, "signed") ||
X                   !strcmp(curtokcase, "unsigned") ||
X                   !strcmp(curtokcase, "struct") ||
X                   !strcmp(curtokcase, "union") ||
X                   !strcmp(curtokcase, "class") ||
X                   !strcmp(curtokcase, "enum") ||
X                   !strcmp(curtokcase, "typedef") ||
X                   (curtokmeaning &&
X                    curtokmeaning->kind == MK_TYPE);
X
X        default:
X            return 0;
X    }
X}
X
X
X
XExpr *pc_parentype(cp)
Xchar *cp;
X{
X    Expr *ex;
X
X    if (curtok == TOK_IDENT &&
X         curtokmeaning &&
X         curtokmeaning->kind == MK_TYPE) {
X        ex = makeexpr_type(curtokmeaning->type);
X        gettok();
X        skipcloseparen();
X    } else if (curtok == TOK_IDENT && !strcmp(curtokcase, "typedef")) {
X        ex = makeexpr_name(getparenstr(inbufptr), tp_integer);
X        gettok();
X    } else {
X        ex = makeexpr_name(getparenstr(cp), tp_integer);
X        gettok();
X    }
X    return ex;
X}
X
X
X
X
XExpr *pc_expr2();
X
XExpr *pc_factor()
X{
X    Expr *ex;
X    char *cp;
X    Strlist *sl;
X    int i;
X
X    switch (curtok) {
X
X        case TOK_BANG:
X            gettok();
X            return makeexpr_not(pc_expr2(14));
X
X        case TOK_TWIDDLE:
X            gettok();
X            return makeexpr_un(EK_BNOT, tp_integer, pc_expr2(14));
X
X        case TOK_PLPL:
X            gettok();
X            ex = pc_expr2(14);
X            return makeexpr_assign(ex, makeexpr_plus(copyexpr(ex), makeexpr_long(1)));
X
X        case TOK_MIMI:
X            gettok();
X            ex = pc_expr2(14);
X            return makeexpr_assign(ex, makeexpr_minus(copyexpr(ex), makeexpr_long(1)));
X
X        case TOK_STAR:
X            gettok();
X            ex = pc_expr2(14);
X            if (ex->val.type->kind != TK_POINTER)
X                ex->val.type = makepointertype(ex->val.type);
X            return makeexpr_hat(ex, 0);
X
X        case TOK_AMP:
X            gettok();
X            return makeexpr_addr(pc_expr2(14));
X
X        case TOK_PLUS:
X            gettok();
X            return pc_expr2(14);
X
X        case TOK_MINUS:
X            gettok();
X            return makeexpr_neg(pc_expr2(14));
X
X        case TOK_LPAR:
X            cp = inbufptr;
X            gettok();
X            if (istypespec()) {
X                ex = pc_parentype(cp);
X                return makeexpr_bin(EK_LITCAST, tp_integer, ex, pc_expr2(14));
X            }
X            ex = pc_expr();
X            skipcloseparen();
X            return ex;
X
X        case TOK_IDENT:
X            if (!strcmp(curtokcase, "sizeof")) {
X                gettok();
X                if (curtok != TOK_LPAR)
X                    return makeexpr_sizeof(pc_expr2(14), 1);
X                cp = inbufptr;
X                gettok();
X                if (istypespec()) {
X                    ex = makeexpr_sizeof(pc_parentype(cp), 1);
X                } else {
X                    ex = makeexpr_sizeof(pc_expr(), 1);
X                    skipcloseparen();
X                }
X                return ex;
X            }
X            if (curtoksym->flags & FMACREC) {
X                ex = makeexpr(EK_MACARG, 0);
X                ex->val.type = tp_integer;
X                ex->val.i = 0;
X                for (sl = funcmacroargs, i = 1; sl; sl = sl->next, i++) {
X                    if (sl->value == (long)curtoksym) {
X                        ex->val.i = i;
X                        break;
X                    }
X                }
X            } else
X                ex = makeexpr_name(curtokcase, nametotype(curtokcase));
X            gettok();
X            return ex;
X
X        case TOK_INTLIT:
X            ex = makeexpr_long(curtokint);
X            if (curtokbuf[strlen(curtokbuf)-1] == 'L')
X                ex = makeexpr_longcast(ex, 1);
X            gettok();
X            return ex;
X
X        case TOK_HEXLIT:
X            ex = makeexpr_long(curtokint);
X            insertarg(&ex, 0, makeexpr_name("%#lx", tp_integer));
X            if (curtokbuf[strlen(curtokbuf)-1] == 'L')
X                ex = makeexpr_longcast(ex, 1);
X            gettok();
X            return ex;
X
X        case TOK_OCTLIT:
X            ex = makeexpr_long(curtokint);
X            insertarg(&ex, 0, makeexpr_name("%#lo", tp_integer));
X            if (curtokbuf[strlen(curtokbuf)-1] == 'L')
X                ex = makeexpr_longcast(ex, 1);
X            gettok();
X            return ex;
X
X        case TOK_REALLIT:
X            ex = makeexpr_real(curtokbuf);
X            gettok();
X            return ex;
X
X        case TOK_STRLIT:
X            ex = makeexpr_lstring(curtokbuf, curtokint);
X            gettok();
X            return ex;
X
X        case TOK_CHARLIT:
X            ex = makeexpr_char(curtokint);
X            gettok();
X            return ex;
X
X        default:
X	    wexpected("a C expression");
X	    return makeexpr_long(0);
X    }
X}
X
X
X
X
X#define pc_prec(pr)  if (prec > (pr)) return ex; gettok();
X
XExpr *pc_expr2(prec)
Xint prec;
X{
X    Expr *ex, *ex2;
X    int i;
X
X    ex = pc_factor();
X    for (;;) {
X        switch (curtok) {
X
X            case TOK_COMMA:
X                pc_prec(1);
X                ex = makeexpr_comma(ex, pc_expr2(2));
X                break;
X
X            case TOK_EQ:
X                pc_prec(2);
X                ex = makeexpr_assign(ex, pc_expr2(2));
X                break;
X
X            case TOK_QM:
X                pc_prec(3);
X                ex2 = pc_expr();
X                if (wneedtok(TOK_COLON))
X		    ex = makeexpr_cond(ex, ex2, pc_expr2(3));
X		else
X		    ex = makeexpr_cond(ex, ex2, makeexpr_long(0));
X                break;
X
X            case TOK_OROR:
X                pc_prec(4);
X                ex = makeexpr_or(ex, pc_expr2(5));
X                break;
X
X            case TOK_ANDAND:
X                pc_prec(5);
X                ex = makeexpr_and(ex, pc_expr2(6));
X                break;
X
X            case TOK_VBAR:
X                pc_prec(6);
X                ex = makeexpr_bin(EK_BOR, tp_integer, ex, pc_expr2(7));
X                break;
X
X            case TOK_HAT:
X                pc_prec(7);
X                ex = makeexpr_bin(EK_BXOR, tp_integer, ex, pc_expr2(8));
X                break;
X
X            case TOK_AMP:
X                pc_prec(8);
X                ex = makeexpr_bin(EK_BAND, tp_integer, ex, pc_expr2(9));
X                break;
X
X            case TOK_EQEQ:
X                pc_prec(9);
X                ex = makeexpr_rel(EK_EQ, ex, pc_expr2(10));
X                break;
X
X            case TOK_BANGEQ:
X                pc_prec(9);
X                ex = makeexpr_rel(EK_NE, ex, pc_expr2(10));
X                break;
X
X            case TOK_LT:
X                pc_prec(10);
X                ex = makeexpr_rel(EK_LT, ex, pc_expr2(11));
X                break;
X
X            case TOK_LE:
X                pc_prec(10);
X                ex = makeexpr_rel(EK_LE, ex, pc_expr2(11));
X                break;
X
X            case TOK_GT:
X                pc_prec(10);
X                ex = makeexpr_rel(EK_GT, ex, pc_expr2(11));
X                break;
X
X            case TOK_GE:
X                pc_prec(10);
X                ex = makeexpr_rel(EK_GE, ex, pc_expr2(11));
X                break;
X
X            case TOK_LTLT:
X                pc_prec(11);
X                ex = makeexpr_bin(EK_LSH, tp_integer, ex, pc_expr2(12));
X                break;
X
X            case TOK_GTGT:
X                pc_prec(11);
X                ex = makeexpr_bin(EK_RSH, tp_integer, ex, pc_expr2(12));
X                break;
X
X            case TOK_PLUS:
X                pc_prec(12);
X                ex = makeexpr_plus(ex, pc_expr2(13));
X                break;
X
X            case TOK_MINUS:
X                pc_prec(12);
X                ex = makeexpr_minus(ex, pc_expr2(13));
X                break;
X
X            case TOK_STAR:
X                pc_prec(13);
X                ex = makeexpr_times(ex, pc_expr2(14));
X                break;
X
X            case TOK_SLASH:
X                pc_prec(13);
X                ex = makeexpr_div(ex, pc_expr2(14));
X                break;
X
X            case TOK_PERC:
X                pc_prec(13);
X                ex = makeexpr_mod(ex, pc_expr2(14));
X                break;
X
X            case TOK_PLPL:
X                pc_prec(15);
X                ex = makeexpr_un(EK_POSTINC, tp_integer, ex);
X                break;
X
X            case TOK_MIMI:
X                pc_prec(15);
X                ex = makeexpr_un(EK_POSTDEC, tp_integer, ex);
X                break;
X
X            case TOK_LPAR:
X                pc_prec(16);
X                if (ex->kind == EK_NAME) {
X                    ex->kind = EK_BICALL;
X                } else {
X                    ex = makeexpr_un(EK_SPCALL, tp_integer, ex);
X                }
X                while (curtok != TOK_RPAR) {
X                    insertarg(&ex, ex->nargs, pc_expr2(2));
X                    if (curtok != TOK_RPAR)
X                        if (!wneedtok(TOK_COMMA))
X			    skiptotoken2(TOK_RPAR, TOK_SEMI);
X                }
X                gettok();
X                break;
X
X            case TOK_LBR:
X                pc_prec(16);
X                ex = makeexpr_index(ex, pc_expr(), NULL);
X                if (!wneedtok(TOK_RBR))
X		    skippasttoken(TOK_RBR);
X                break;
X
X            case TOK_ARROW:
X                pc_prec(16);
X                if (!wexpecttok(TOK_IDENT))
X		    break;
X                if (ex->val.type->kind != TK_POINTER)
X                    ex->val.type = makepointertype(ex->val.type);
X                ex = makeexpr_dotq(makeexpr_hat(ex, 0),
X                                   curtokcase, tp_integer);
X                gettok();
X                break;
X
X            case TOK_DOT:
X                pc_prec(16);
X                if (!wexpecttok(TOK_IDENT))
X		    break;
X                ex = makeexpr_dotq(ex, curtokcase, tp_integer);
X                gettok();
X                break;
X
X	    case TOK_COLONCOLON:
X		if (prec > 16)
X		    return ex;
X		i = C_lex;
X		C_lex = 0;
X		gettok();
X		if (curtok == TOK_IDENT &&
X		    curtokmeaning && curtokmeaning->kind == MK_TYPE) {
X		    ex->val.type = curtokmeaning->type;
X		} else if (curtok == TOK_LPAR) {
X		    gettok();
X		    ex->val.type = p_type(NULL);
X		    if (!wexpecttok(TOK_RPAR))
X			skiptotoken(TOK_RPAR);
X		} else
X		    wexpected("a type name");
X		C_lex = i;
X		gettok();
X		break;
X
X            default:
X                return ex;
X        }
X    }
X}
X
X
X
X
XExpr *pc_expr()
X{
X    return pc_expr2(0);
X}
X
X
X
XExpr *pc_expr_str(buf)
Xchar *buf;
X{
X    Strlist *defsl, *sl;
X    Expr *ex;
X
X    defsl = NULL;
X    sl = strlist_append(&defsl, buf);
X    C_lex++;
X    push_input_strlist(defsl, buf);
X    ex = pc_expr();
X    if (curtok != TOK_EOF)
X        warning(format_s("Junk (%s) at end of C expression [306]",
X			 tok_name(curtok)));
X    pop_input();
X    C_lex--;
X    strlist_empty(&defsl);
X    return ex;
X}
X
X
X
X
X
X
X/* Simplify an expression */
X
XExpr *fixexpr(ex, env)
XExpr *ex;
Xint env;
X{
X    Expr *ex2, *ex3, **ep;
X    Type *type, *type2;
X    Meaning *mp;
X    char *cp;
X    char sbuf[5];
X    int i;
X    Value val;
X
X    if (!ex)
X        return NULL;
X    switch (ex->kind) {
X
X        case EK_BICALL:
X            ex2 = fix_bicall(ex, env);
X            if (ex2) {
X                ex = ex2;
X                break;
X            }
X            cp = ex->val.s;
X            if (!strcmp(cp, "strlen")) {
X                if (ex->args[0]->kind == EK_BICALL &&
X                    !strcmp(ex->args[0]->val.s, "sprintf") &&
X                    sprintf_value == 0) {     /* does sprintf return char count? */
X                    ex = grabarg(ex, 0);
X                    strchange(&ex->val.s, "*sprintf");
X                    ex = fixexpr(ex, env);
X                } else {
X                    ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
X                }
X            } else if (!strcmp(cp, name_SETIO)) {
X                ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
X            } else if (!strcmp(cp, "~~SETIO")) {
X                ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
X                ex = makeexpr_cond(ex->args[0],
X                                   makeexpr_long(0),
X                                   makeexpr_bicall_1(name_ESCIO, tp_int, ex->args[1]));
X            } else if (!strcmp(cp, name_CHKIO)) {
X                ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
X                ex->args[2] = fixexpr(ex->args[2], env);
X                ex->args[3] = fixexpr(ex->args[3], env);
X            } else if (!strcmp(cp, "~~CHKIO")) {
X                ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
X                ex->args[2] = fixexpr(ex->args[2], env);
X                ex->args[3] = fixexpr(ex->args[3], env);
X                ex2 = makeexpr_bicall_1(name_ESCIO, tp_int, ex->args[1]);
X                if (ord_type(ex->args[3]->val.type)->kind != TK_INTEGER)
X                    ex2 = makeexpr_cast(ex2, ex->args[3]->val.type);
X                ex = makeexpr_cond(ex->args[0], ex->args[2], ex2);
X            } else if (!strcmp(cp, "assert")) {
X                ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
X            } else {
X                for (i = 0; i < ex->nargs; i++)
X                    ex->args[i] = fixexpr(ex->args[i], ENV_EXPR);
X		ex = cleansprintf(ex);
X                if (!strcmp(cp, "sprintf")) {
X                    if (checkstring(ex->args[1], "%s")) {
X                        delfreearg(&ex, 1);
X                        strchange(&ex->val.s, "strcpy");
X                        ex = fixexpr(ex, env);
X                    } else if (sprintf_value != 1 && env != ENV_STMT) {
X                        if (*sprintfname) {
X                            strchange(&ex->val.s, format_s("*%s", sprintfname));
X                        } else {
X                            strchange(&ex->val.s, "*sprintf");
X                            ex = makeexpr_comma(ex, copyexpr(ex->args[0]));
X                        }
X                    }
X                } else if (!strcmp(cp, "strcpy")) {
X                    if (env == ENV_STMT &&
X                         ex->args[1]->kind == EK_BICALL &&
X                         !strcmp(ex->args[1]->val.s, "strcpy") &&
X                         nosideeffects(ex->args[1]->args[0], 1)) {
X                        ex2 = ex->args[1];
X                        ex->args[1] = copyexpr(ex2->args[0]);
X                        ex = makeexpr_comma(ex2, ex);
X                    }
X                } else if (!strcmp(cp, "memcpy")) {
X                    strchange(&ex->val.s, format_s("*%s", memcpyname));
X                    if (!strcmp(memcpyname, "*bcopy")) {
X                        swapexprs(ex->args[0], ex->args[1]);
X                        if (env != ENV_STMT)
X                            ex = makeexpr_comma(ex, copyexpr(ex->args[1]));
X                    }
X		} else if (!strcmp(cp, setunionname) &&
X			   (ex3 = singlevar(ex->args[0])) != NULL &&
X			   ((i=1, exprsame(ex->args[0], ex->args[i], 0)) ||
X			    (i=2, exprsame(ex->args[0], ex->args[i], 0))) &&
X			   !exproccurs(ex3, ex->args[3-i])) {
X		    ep = &ex->args[3-i];
X		    while ((ex2 = *ep)->kind == EK_BICALL &&
X			   (!strcmp(ex2->val.s, setaddname) ||
X			    !strcmp(ex2->val.s, setaddrangename)))
X			ep = &ex2->args[0];
X		    if (ex2->kind == EK_BICALL &&
X			!strcmp(ex2->val.s, setexpandname) &&
X			checkconst(ex2->args[1], 0) &&
X			(mp = istempvar(ex2->args[0])) != NULL) {
X			if (ex2 == ex->args[3-i]) {
X			    ex = grabarg(ex, i);
X			} else {
X			    freeexpr(ex2);
X			    *ep = ex->args[i];
X			    ex = ex->args[3-i];
X			}
X		    }
X		} else if (!strcmp(cp, setdiffname) && *setremname &&
X			   (ex3 = singlevar(ex->args[0])) != NULL &&
X			   exprsame(ex->args[0], ex->args[1], 0) &&
X			   !exproccurs(ex3, ex->args[2])) {
X		    ep = &ex->args[2];
X		    while ((ex2 = *ep)->kind == EK_BICALL &&
X			   !strcmp(ex2->val.s, setaddname))
X			ep = &ex2->args[0];
X		    if (ex2->kind == EK_BICALL &&
X			!strcmp(ex2->val.s, setexpandname) &&
X			checkconst(ex2->args[1], 0) &&
X			(mp = istempvar(ex2->args[0])) != NULL) {
X			if (ex2 == ex->args[2]) {
X			    ex = grabarg(ex, 1);
X			} else {
X			    ex2 = ex->args[2];
X			    while (ex2->kind == EK_BICALL &&
X				   !strcmp(ex2->val.s, setaddname)) {
X				strchange(&ex2->val.s, setremname);
X				ex2 = ex2->args[0];
X			    }
X			    freeexpr(ex2);
X			    *ep = ex->args[1];
X			    ex = ex->args[2];
X			}
X		    }
X                } else if (!strcmp(cp, setexpandname) && env == ENV_STMT &&
X                           checkconst(ex->args[1], 0)) {
X                    ex = makeexpr_assign(makeexpr_hat(ex->args[0], 0),
X                                         ex->args[1]);
X                } else if (!strcmp(cp, getbitsname)) {
X		    type = ex->args[0]->val.type;
X		    if (type->kind == TK_POINTER)
X			type = type->basetype;
X                    sbuf[0] = (type->issigned) ? 'S' : 'U';
X                    sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
X                    sbuf[2] = 0;
X                    if (sbuf[1] == 'S' &&
X                        type->smax->val.type == tp_boolean) {
X                        ex = makeexpr_rel(EK_NE,
X                                          makeexpr_bin(EK_BAND, tp_integer,
X                                                       ex->args[0],
X                                                       makeexpr_bin(EK_LSH, tp_integer,
X                                                                    makeexpr_longcast(makeexpr_long(1),
X                                                                                      type->basetype
X                                                                                            == tp_unsigned),
X                                                                    ex->args[1])),
X                                          makeexpr_long(0));
X                        ex = fixexpr(ex, env);
X                    } else
X                        strchange(&ex->val.s, format_s(cp, sbuf));
X                } else if (!strcmp(cp, putbitsname)) {
X		    type = ex->args[0]->val.type;
X		    if (type->kind == TK_POINTER)
X			type = type->basetype;
X                    sbuf[0] = (type->issigned) ? 'S' : 'U';
X                    sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
X                    sbuf[2] = 0;
X                    if (sbuf[1] == 'S' &&
X                        type->smax->val.type == tp_boolean) {
X                        ex = makeexpr_assign(ex->args[0],
X                                             makeexpr_bin(EK_BOR, tp_integer,
X                                                          copyexpr(ex->args[0]),
X                                                          makeexpr_bin(EK_LSH, tp_integer,
X                                                                       makeexpr_longcast(ex->args[2],
X                                                                                         type->basetype
X                                                                                               == tp_unsigned),
X                                                                       ex->args[1])));
X                    } else
X                        strchange(&ex->val.s, format_s(cp, sbuf));
X                } else if (!strcmp(cp, storebitsname)) {
X		    type = ex->args[0]->val.type;
X		    if (type->kind == TK_POINTER)
X			type = type->basetype;
X                    sbuf[0] = (type->issigned) ? 'S' : 'U';
X                    sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
X                    sbuf[2] = 0;
X                    strchange(&ex->val.s, format_s(cp, sbuf));
X                } else if (!strcmp(cp, clrbitsname)) {
X		    type = ex->args[0]->val.type;
X		    if (type->kind == TK_POINTER)
X			type = type->basetype;
X                    sbuf[0] = (type->kind == TK_ARRAY) ? 'B' : 'S';
X                    sbuf[1] = 0;
X                    if (sbuf[0] == 'S' &&
X                        type->smax->val.type == tp_boolean) {
X                        ex = makeexpr_assign(ex->args[0],
X                                             makeexpr_bin(EK_BAND, tp_integer,
X                                                   copyexpr(ex->args[0]),
X                                                   makeexpr_un(EK_BNOT, tp_integer,
X                                                          makeexpr_bin(EK_LSH, tp_integer,
X                                                                       makeexpr_longcast(makeexpr_long(1),
X                                                                                         type->basetype
X                                                                                               == tp_unsigned),
X                                                                       ex->args[1]))));
X                    } else
X                        strchange(&ex->val.s, format_s(cp, sbuf));
X                } else if (!strcmp(cp, "fopen")) {
X		    if (which_lang == LANG_HP &&
X			ex->args[0]->kind == EK_CONST &&
X			ex->args[0]->val.type->kind == TK_STRING &&
X			ex->args[0]->val.i >= 1 &&
X			ex->args[0]->val.i <= 2 &&
X			isdigit(ex->args[0]->val.s[0]) &&
X			(ex->args[0]->val.i == 1 ||
X			 isdigit(ex->args[0]->val.s[1]))) {
X			strchange(&ex->val.s, "fdopen");
X			ex->args[0] = makeexpr_long(atoi(ex->args[0]->val.s));
X		    }
X		}
X            }
X            break;
X
X        case EK_NOT:
X            ex = makeexpr_not(fixexpr(grabarg(ex, 0), ENV_BOOL));
X            break;
X
X        case EK_AND:
X        case EK_OR:
X            for (i = 0; i < ex->nargs; i++)
X                ex->args[i] = fixexpr(ex->args[i], ENV_BOOL);
X            break;
X
X        case EK_EQ:
X        case EK_NE:
X            ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
X            ex->args[1] = fixexpr(ex->args[1], ENV_EXPR);
X            if (checkconst(ex->args[1], 0) && env == ENV_BOOL &&
X                ord_type(ex->args[1]->val.type)->kind != TK_ENUM &&
X                (implicitzero > 0 ||
X                 (implicitzero < 0 && ex->args[0]->kind == EK_BICALL &&
X                                      boolean_bicall(ex->args[0]->val.s)))) {
X                if (ex->kind == EK_EQ)
X                    ex = makeexpr_not(grabarg(ex, 0));
X                else {
X                    ex = grabarg(ex, 0);
X                    ex->val.type = tp_boolean;
X                }
X            }
X            break;
X
X        case EK_COND:
X            ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
X#if 0
X            val = eval_expr(ex->args[0]);
X#else
X	    val = ex->args[0]->val;
X	    if (ex->args[0]->kind != EK_CONST)
X		val.type = NULL;
X#endif
X            if (val.type == tp_boolean) {
X                ex = grabarg(ex, (val.i) ? 1 : 2);
X                ex = fixexpr(ex, env);
X            } else {
X                ex->args[1] = fixexpr(ex->args[1], env);
X                ex->args[2] = fixexpr(ex->args[2], env);
X            }
X            break;
X
X        case EK_COMMA:
X            for (i = 0; i < ex->nargs-1; ) {
X                ex->args[i] = fixexpr(ex->args[i], ENV_STMT);
X                if (nosideeffects(ex->args[i], 1))
X                    delfreearg(&ex, i);
X                else
X                    i++;
X            }
X            ex->args[ex->nargs-1] = fixexpr(ex->args[ex->nargs-1], env);
X            if (ex->nargs == 1)
X                ex = grabarg(ex, 0);
X            break;
X
X        case EK_CHECKNIL:
X            ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
X            if (ex->nargs == 2) {
X                ex->args[1] = fixexpr(ex->args[1], ENV_EXPR);
X                ex2 = makeexpr_assign(copyexpr(ex->args[1]), ex->args[0]);
X                ex3 = ex->args[1];
X            } else {
X                ex2 = copyexpr(ex->args[0]);
X                ex3 = ex->args[0];
X            }
X            type = ex->args[0]->val.type;
X            type2 = ex->val.type;
X            ex = makeexpr_cond(makeexpr_rel(EK_NE, ex2, makeexpr_nil()),
X                               ex3,
X                               makeexpr_cast(makeexpr_bicall_0(name_NILCHECK,
X                                                               tp_int),
X                                             type));
X            ex->val.type = type2;
X            ex = fixexpr(ex, env);
X            break;
X
X        case EK_CAST:
X        case EK_ACTCAST:
X            if (env == ENV_STMT) {
X                ex = fixexpr(grabarg(ex, 0), ENV_STMT);
X            } else {
X                ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
X            }
X            break;
X
X        default:
X            for (i = 0; i < ex->nargs; i++)
X                ex->args[i] = fixexpr(ex->args[i], ENV_EXPR);
X            break;
X    }
X    return fix_expression(ex, env);
X}
X
X
X
X
X
X
X
X
X/* Output an expression */
X
X
X#define bitOp(k)  ((k)==EK_BAND || (k)==EK_BOR || (k)==EK_BXOR)
X
X#define shfOp(k)  ((k)==EK_LSH || (k)==EK_RSH)
X
X#define logOp(k)  ((k)==EK_AND || (k)==EK_OR)
X
X#define relOp(k)  ((k)==EK_EQ || (k)==EK_LT || (k)==EK_GT ||    \
X		   (k)==EK_NE || (k)==EK_GE || (k)==EK_LE)
X
X#define mathOp(k) ((k)==EK_PLUS || (k)==EK_TIMES || (k)==EK_NEG ||   \
X		   (k)==EK_DIV || (k)==EK_DIVIDE || (k)==EK_MOD)
X
X#define divOp(k)  ((k)==EK_DIV || (k)==EK_DIVIDE)
X
X
XStatic int incompat(ex, num, prec)
XExpr *ex;
Xint num, prec;
X{
X    Expr *subex = ex->args[num];
X
X    if (extraparens == 0)
X	return prec;
X    if (ex->kind == subex->kind) {
X	if (logOp(ex->kind) || bitOp(ex->kind) ||
X	    (divOp(ex->kind) && num == 0))
X	    return -99;   /* not even invisible parens */
X	else if (extraparens != 2)
X	    return prec;
X    }
X    if (extraparens == 2)
X	return 15;
X    if (divOp(ex->kind) && num == 0 &&
X	(subex->kind == EK_TIMES || divOp(subex->kind)))
X	return -99;
X    if (bitOp(ex->kind) || shfOp(ex->kind))
X	return 15;
X    if (relOp(ex->kind) && relOp(subex->kind))
X	return 15;
X    if ((relOp(ex->kind) || logOp(ex->kind)) && bitOp(subex->kind))
X	return 15;
X    if (ex->kind == EK_COMMA)
X	return 15;
X    if (ex->kind == EK_ASSIGN && relOp(subex->kind))
X	return 15;
X    if (extraparens != 1)
X	return prec;
X    if (ex->kind == EK_ASSIGN)
X	return prec;
X    if (relOp(ex->kind) && mathOp(subex->kind))
X	return prec;
X    return 15;
X}
X
X
X
X
X#define EXTRASPACE() if (spaceexprs == 1) output(" ")
X#define NICESPACE()  if (spaceexprs != 0) output(" ")
X
X#define setprec(p) \
X    if ((subprec=(p)) <= prec) { \
X        parens = 1; output("("); \
X    }
X
X#define setprec2(p) \
X    if ((subprec=(p)) <= prec) { \
X        parens = 1; output("("); \
X    } else if (prec != -99) { \
X        parens = 2; output((breakparens == 1) ? "\010" : "\003"); \
X    }
X
X#define setprec3(p) \
X    if ((subprec=(p)) <= prec) { \
X         parens = 1; output("("); \
X    } else if (prec != -99) { \
X         parens = 2; output((prec > 2 && breakparens != 0) ? "\010" \
X			                                   : "\003"); \
X    }
X
X
XStatic void outop3(breakbefore, name)
Xint breakbefore;
Xchar *name;
X{
X    if (breakbefore & BRK_LEFT) {
X	output("\002");
X	if (breakbefore & BRK_RPREF)
X	    output("\013");
X    }
X    output(name);
X    if (breakbefore & BRK_HANG)
X	output("\015");
X    if (breakbefore & BRK_RIGHT) {
X	output("\002");
X	if (breakbefore & BRK_LPREF)
X	    output("\013");
X    }
X}
X
X#define outop(name) do { \
X    NICESPACE(); outop3(breakflag, name); NICESPACE(); \
X} while (0)
X
X#define outop2(name) do { \
X    EXTRASPACE(); outop3(breakflag, name); EXTRASPACE(); \
X} while (0)
X
X#define checkbreak(code) do { \
X    breakflag=(code); \
X    if ((prec != -99) && (breakflag & BRK_ALLNONE)) output("\007"); \
X} while (0)
X
X
XStatic void out_ctx(ctx, address)
XMeaning *ctx;
Xint address;
X{
X    Meaning *ctx2;
X    int breakflag = breakbeforedot;
X
X    if (ctx->kind == MK_FUNCTION && ctx->varstructflag) {
X        if (curctx != ctx) {
X	    if (address && curctx->ctx && curctx->ctx != ctx) {
X		output("\003");
X		if (breakflag & BRK_ALLNONE)
X		    output("\007");
X	    }
X            output(format_s(name_LINK, curctx->ctx->name));
X            ctx2 = curctx->ctx;
X            while (ctx2 && ctx2 != ctx) {
X                outop2("->");
X                output(format_s(name_LINK, ctx2->ctx->name));
X                ctx2 = ctx2->ctx;
X            }
X            if (ctx2 != ctx)
X                intwarning("out_ctx",
X                           format_s("variable from %s not present in context path [307]",
X                                     ctx->name));
X	    if (address && curctx->ctx && curctx->ctx != ctx)
X		output("\004");
X            if (!address)
X                outop2("->");
X        } else {
X            if (address) {
X                output("&");
X		EXTRASPACE();
X	    }
X            output(format_s(name_VARS, curctx->name));
X            if (!address) {
X                outop2(".");
X	    }
X        }
X    } else {
X        if (address)
X            output("NULL");
X    }
X}
X
X
X
Xvoid out_var(mp, prec)
XMeaning *mp;
Xint prec;
X{
X    switch (mp->kind) {
X
X        case MK_CONST:
X            output(mp->name);
X            return;
X
X        case MK_VAR:
X        case MK_VARREF:
X        case MK_VARMAC:
X        case MK_PARAM:
X        case MK_VARPARAM:
X            if (mp->varstructflag) {
X		output("\003");
X                out_ctx(mp->ctx, 0);
X		output(mp->name);
X		output("\004");
X	    } else
X		output(mp->name);
X            return;
X
X	default:
X	    if (mp->name)
X		output(mp->name);
X	    else
X		intwarning("out_var", "mp->sym == NULL [308]");
X	    return;
X    }
X}
X
X
X
XStatic int scanfield(variants, unions, lev, mp, field)
XMeaning **variants, *mp, *field;
Xshort *unions;
Xint lev;
X{
X    int i, num, breakflag;
X    Value v;
X
X    unions[lev] = (mp && mp->kind == MK_VARIANT);
X    while (mp && mp->kind == MK_FIELD) {
X        if (mp == field) {
X            for (i = 0; i < lev; i++) {
X		v = variants[i]->val;    /* sidestep a Sun 386i compiler bug */
X                num = ord_value(v);
X		breakflag = breakbeforedot;
X                if (!unions[i]) {
X                    output(format_s(name_UNION, ""));
X		    outop2(".");
X                }
X                if (variants[i]->ctx->cnext ||
X                    variants[i]->ctx->kind != MK_FIELD) {
X                    output(format_s(name_VARIANT, variantfieldname(num)));
X		    outop2(".");
X                }
X            }
X            output(mp->name);
X            return 1;
X        }
X        mp = mp->cnext;
X    }
X    while (mp && mp->kind == MK_VARIANT) {
X        variants[lev] = mp;
X        if (scanfield(variants, unions, lev+1, mp->ctx, field))
X            return 1;
X        mp = mp->cnext;
X    }
X    return 0;
X}
X
X
Xvoid out_field(mp)
XMeaning *mp;
X{
X    Meaning *variants[50];
X    short unions[51];
X
X    if (!scanfield(variants, unions, 0, mp->rectype->fbase, mp))
X        intwarning("out_field", "field name not in tree [309]");
X    else if (mp->warnifused) {
X        if (mp->rectype->meaning)
X            note(format_ss("Reference to field %s of record %s [282]", 
X                           mp->name, mp->rectype->meaning->name));
X        else
X            note(format_s("Reference to field %s [282]", mp->name));
X    }
X}
X
X
X
X
XStatic void wrexpr(ex, prec)
XExpr *ex;
Xint prec;
X{
X    short parens = 0;
X    int subprec, i, j, minusflag, breakflag = 0;
X    int saveindent;
X    Expr *ex2, *ex3;
X    char *cp;
X    Meaning *mp;
X    Symbol *sp;
X
X    if (debug>2) { fprintf(outf,"wrexpr{"); dumpexpr(ex); fprintf(outf,", %d}\n", prec); }
X    switch (ex->kind) {
X
X        case EK_VAR:
X            mp = (Meaning *)ex->val.i;
X            if (mp->warnifused)
X                note(format_s("Reference to %s [283]", mp->name));
X            out_var(mp, prec);
X            break;
X
X        case EK_NAME:
X            output(ex->val.s);
X            break;
X
X        case EK_MACARG:
X            output("<meef>");
X            intwarning("wrexpr", "Stray EK_MACARG encountered [310]");
X            break;
X
X        case EK_CTX:
X            out_ctx((Meaning *)ex->val.i, 1);
X            break;
X
X        case EK_CONST:
X            if (ex->nargs > 0)
X                cp = value_name(ex->val, ex->args[0]->val.s, 0);
X            else
X                cp = value_name(ex->val, NULL, 0);
X            if (*cp == '-')
X                setprec(14);
X            output(cp);
X            break;
X
X        case EK_LONGCONST:
X            if (ex->nargs > 0)
X                cp = value_name(ex->val, ex->args[0]->val.s, 1);
X            else
X                cp = value_name(ex->val, NULL, 1);
X            if (*cp == '-')
X                setprec(14);
X            output(cp);
X            break;
X
X        case EK_STRUCTCONST:
X            ex3 = NULL;
X            for (i = 0; i < ex->nargs; i++) {
X                ex2 = ex->args[i];
X                if (ex2->kind == EK_STRUCTOF) {
X                    j = ex2->val.i;
X                    ex2 = ex2->args[0];
X                } else
X                    j = 1;
X                if (ex2->kind == EK_VAR) {
X                    mp = (Meaning *)ex2->val.i;
X                    if (mp->kind == MK_CONST &&
X                        (mp->val.type->kind == TK_RECORD ||
X                         mp->val.type->kind == TK_ARRAY)) {
X                        if (foldconsts != 1)
X                            note(format_s("Expanding constant %s into another constant [284]",
X                                          mp->name));
X                        ex2 = (Expr *)mp->val.i;
X                    }
X                }
X                while (--j >= 0) {
X                    if (ex3) {
X                        if (ex3->kind == EK_STRUCTCONST ||
X                            ex2->kind == EK_STRUCTCONST)
X                            output(",\n");
X                        else
X                            output(",\001 ");
X                    }
X                    if (ex2->kind == EK_STRUCTCONST) {
X                        output("{ \005");
X			saveindent = outindent;
X			moreindent(extrainitindent);
X                        out_expr(ex2);
X                        outindent = saveindent;
X                        output(" }");
X                    } else
X                        out_expr(ex2);
X                    ex3 = ex2;
X                }
X            }
X            break;
X
X        case EK_FUNCTION:
X            mp = (Meaning *)ex->val.i;
X	    sp = findsymbol_opt(mp->name);
X	    if ((sp && (sp->flags & WARNLIBR)) || mp->warnifused)
X                note(format_s("Called procedure %s [285]", mp->name));
X            output(mp->name);
X            output("(\002");
X	    j = sp ? (sp->flags & FUNCBREAK) : 0;
X	    if (j == FALLBREAK)
X		output("\007");
X            for (i = 0; i < ex->nargs; i++) {
X		if ((j == FSPCARG1 && i == 1) ||
X		    (j == FSPCARG2 && i == 2) ||
X		    (j == FSPCARG3 && i == 3))
X		    output(",\011 ");
X                else if (i > 0)
X                    output(",\002 ");
X                out_expr(ex->args[i]);
X            }
X            if (mp->ctx->kind == MK_FUNCTION && mp->ctx->varstructflag) {
X                if (i > 0)
X                    output(",\002 ");
X                out_ctx(mp->ctx, 1);
X            }
X            output(")");
X            break;
X
X        case EK_BICALL:
X            cp = ex->val.s;
X            while (*cp == '*')
X                cp++;
X	    sp = findsymbol_opt(cp);
X	    if (sp && (sp->flags & WARNLIBR))
X                note(format_s("Called library procedure %s [286]", cp));
X            output(cp);
X            output("(\002");
X	    j = sp ? (sp->flags & FUNCBREAK) : 0;
X	    if (j == FALLBREAK)
X		output("\007");
X            for (i = 0; i < ex->nargs; i++) {
X		if ((j == FSPCARG1 && i == 1) ||
X		    (j == FSPCARG2 && i == 2) ||
X		    (j == FSPCARG3 && i == 3))
X		    output(",\011 ");
X                else if (i > 0)
X                    output(",\002 ");
X                out_expr(ex->args[i]);
X            }
X            output(")");
X            break;
X
X        case EK_SPCALL:
X            setprec(16);
X            if (starfunctions) {
X                output("(\002*");
X                wrexpr(ex->args[0], 13);
X                output(")");
X            } else
X                wrexpr(ex->args[0], subprec-1);
X            output("(\002");
X            for (i = 1; i < ex->nargs; i++) {
X                if (i > 1)
X                    output(",\002 ");
X                out_expr(ex->args[i]);
X            }
X            output(")");
X            break;
X
X        case EK_INDEX:
X            setprec(16);
X            wrexpr(ex->args[0], subprec-1);
X	    if (lookback(1) == ']')
X		output("\001");
X            output("[");
X            out_expr(ex->args[1]);
X            output("]");
X            break;
X
X        case EK_DOT:
X            setprec2(16);
X	    checkbreak(breakbeforedot);
X            if (ex->args[0]->kind == EK_HAT) {
X                wrexpr(ex->args[0]->args[0], subprec-1);
X                outop2("->");
X            } else if (ex->args[0]->kind == EK_CTX) {
X                out_ctx((Meaning *)ex->args[0]->val.i, 0);
X            } else {
X                wrexpr(ex->args[0], subprec-1);
X                outop2(".");
X            }
X            if (ex->val.i)
X                out_field((Meaning *)ex->val.i);
X            else
X                output(ex->val.s);
X            break;
X
X        case EK_POSTINC:
X	    if (prec == 0 && !postincrement) {
X		setprec(14);
X		output("++");
X		EXTRASPACE();
X		wrexpr(ex->args[0], subprec);
X	    } else {
X		setprec(15);
X		wrexpr(ex->args[0], subprec);
X		EXTRASPACE();
X		output("++");
X	    }
X            break;
X
X        case EK_POSTDEC:
X	    if (prec == 0 && !postincrement) {
X		setprec(14);
X		output("--");
X		EXTRASPACE();
X		wrexpr(ex->args[0], subprec);
X	    } else {
X		setprec(15);
X		wrexpr(ex->args[0], subprec);
X		EXTRASPACE();
X		output("--");
X	    }
X            break;
X
X        case EK_HAT:
X            setprec(14);
X	    if (lookback_prn(1) == '/')
X		output(" ");
X            output("*");
X            EXTRASPACE();
X            wrexpr(ex->args[0], subprec-1);
X            break;
X
X        case EK_ADDR:
X            setprec(14);
X	    if (lookback_prn(1) == '&')
X		output(" ");
X            output("&");
X            EXTRASPACE();
X            wrexpr(ex->args[0], subprec-1);
X            break;
X
X        case EK_NEG:
X            setprec(14);
X            output("-");
X            EXTRASPACE();
X            if (ex->args[0]->kind == EK_TIMES)
X                wrexpr(ex->args[0], 12);
X            else
X                wrexpr(ex->args[0], subprec-1);
X            break;
X
X        case EK_NOT:
X            setprec(14);
X            output("!");
X            EXTRASPACE();
X            wrexpr(ex->args[0], subprec-1);
X            break;
X
X        case EK_BNOT:
X            setprec(14);
X            output("~");
X            EXTRASPACE();
X            wrexpr(ex->args[0], subprec-1);
X            break;
X
X        case EK_CAST:
X        case EK_ACTCAST:
X            if (similartypes(ex->val.type, ex->args[0]->val.type)) {
X                wrexpr(ex->args[0], prec);
X            } else if (ord_type(ex->args[0]->val.type)->kind == TK_ENUM &&
X                       ex->val.type == tp_int && !useenum) {
X                wrexpr(ex->args[0], prec);
X            } else {
X                setprec2(14);
X                output("(");
X                out_type(ex->val.type, 0);
X                output(")\002");
X                EXTRASPACE();
X                if (extraparens != 0)
X                    wrexpr(ex->args[0], 15);
X                else
X                    wrexpr(ex->args[0], subprec-1);
X            }
X            break;
X
X        case EK_LITCAST:
X            setprec2(14);
X            output("(");
X            out_expr(ex->args[0]);
X            output(")\002");
X            EXTRASPACE();
X            if (extraparens != 0)
X                wrexpr(ex->args[1], 15);
X            else
X                wrexpr(ex->args[1], subprec-1);
X            break;
X
X        case EK_SIZEOF:
X            setprec(14);
X            output("sizeof(");
X	    out_expr(ex->args[0]);
X            output(")");
X            break;
X
X	case EK_TYPENAME:
X	    out_type(ex->val.type, 1);
X	    break;
X
X        case EK_TIMES:
X	    setprec2(13);
X	    checkbreak(breakbeforearith);
X            ex2 = copyexpr(ex);
X            if (expr_looks_neg(ex2->args[ex2->nargs-1])) {
X                ex2->args[0] = makeexpr_neg(ex2->args[0]);
X                ex2->args[ex2->nargs-1] = makeexpr_neg(ex2->args[ex2->nargs-1]);
X            }
X            wrexpr(ex2->args[0], incompat(ex2, 0, subprec-1));
X            for (i = 1; i < ex2->nargs; i++) {
X                outop("*");
X                wrexpr(ex2->args[i], incompat(ex2, i, subprec));
X            }
X            freeexpr(ex2);
X            break;
X
X        case EK_DIV:
X        case EK_DIVIDE:
X            setprec2(13);
X	    checkbreak(breakbeforearith);
X	    wrexpr(ex->args[0], incompat(ex, 0, subprec-1));
X            outop("/");
X            wrexpr(ex->args[1], incompat(ex, 1, subprec));
X            break;
X
X        case EK_MOD:
X            setprec2(13);
X	    checkbreak(breakbeforearith);
X            wrexpr(ex->args[0], incompat(ex, 0, subprec-1));
X            outop("%");
X            wrexpr(ex->args[1], incompat(ex, 1, subprec));
X            break;
X
X        case EK_PLUS:
X            setprec2(12);
X	    checkbreak(breakbeforearith);
X            ex2 = copyexpr(ex);
X            minusflag = 0;
X            if (expr_looks_neg(ex2->args[0])) {
X                j = 1;
X                while (j < ex2->nargs && expr_looks_neg(ex2->args[j])) j++;
X                if (j < ex2->nargs)
X                    swapexprs(ex2->args[0], ex2->args[j]);
X            } else if (ex2->val.i && ex2->nargs == 2) {   /* this was originally "a-b" */
X                if (isliteralconst(ex2->args[1], NULL) != 2) {
X                    if (expr_neg_cost(ex2->args[1]) <= 0) {
X                        minusflag = 1;
X                    } else if (expr_neg_cost(ex2->args[0]) <= 0) {
X                        swapexprs(ex2->args[0], ex2->args[1]);
X                        if (isliteralconst(ex2->args[0], NULL) != 2)
X                            minusflag = 1;
X                    }
X                }
X            }
X            wrexpr(ex2->args[0], incompat(ex, 0, subprec));
X            for (i = 1; i < ex2->nargs; i++) {
X                if (expr_looks_neg(ex2->args[i]) || minusflag) {
X                    outop("-");
X                    ex2->args[i] = makeexpr_neg(ex2->args[i]);
X                } else
X                    outop("+");
X                wrexpr(ex2->args[i], incompat(ex, i, subprec));
X            }
X            freeexpr(ex2);
X            break;
X
X        case EK_LSH:
X            setprec3(11);
X	    checkbreak(breakbeforearith);
X            wrexpr(ex->args[0], incompat(ex, 0, subprec));
X            outop("<<");
X            wrexpr(ex->args[1], incompat(ex, 1, subprec));
X            break;
X
X        case EK_RSH:
X            setprec3(11);
X	    checkbreak(breakbeforearith);
X	    wrexpr(ex->args[0], incompat(ex, 0, subprec));
X            outop(">>");
X            wrexpr(ex->args[1], incompat(ex, 1, subprec));
X            break;
X
X        case EK_LT:
X            setprec2(10);
X	    checkbreak(breakbeforerel);
X            wrexpr(ex->args[0], incompat(ex, 0, subprec));
X            outop("<");
X            wrexpr(ex->args[1], incompat(ex, 0, subprec));
X            break;
X
X        case EK_GT:
END_OF_FILE
if test 48796 -ne `wc -c <'src/pexpr.c.2'`; then
    echo shar: \"'src/pexpr.c.2'\" unpacked with wrong size!
fi
# end of 'src/pexpr.c.2'
fi
echo shar: End of archive 24 \(of 32\).
cp /dev/null ark24isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 32 archives.
    echo "Now see PACKNOTES and the README"
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.



More information about the Comp.sources.unix mailing list