pexpr.c.2
上传用户:upcnvip
上传日期:2007-01-06
资源大小:474k
文件大小:48k
- ex = makeexpr_var(tvar);
- } else
- ex3 = NULL;
- ex4 = copyexpr(ex);
- if (ex->kind == EK_CONST && smallsetconst)
- ex = makesmallsetconst(1<<ex->val.i, ex2->val.type);
- else
- ex = makeexpr_bin(EK_LSH, ex2->val.type,
- makeexpr_longcast(makeexpr_long(1), 1),
- enum_to_int(ex));
- ex = makeexpr_rel(EK_NE, makeexpr_bin(EK_BAND, tp_integer, ex, ex2),
- makeexpr_long(0));
- if (*name_SETBITS ||
- ((ex4->kind == EK_CONST) ? ((unsigned long)ex4->val.i >= setbits)
- : !(0 <= smin && smax < setbits))) {
- ex = makeexpr_and(makeexpr_range(enum_to_int(ex4),
- makeexpr_long(0),
- makeexpr_setbits(), 0),
- ex);
- } else
- freeexpr(ex4);
- ex = makeexpr_comma(ex3, ex);
- return ex;
- } else {
- ex3 = ex2;
- while (ex3->kind == EK_BICALL &&
- (!strcmp(ex3->val.s, setaddname) ||
- !strcmp(ex3->val.s, setaddrangename)))
- ex3 = ex3->args[0];
- if (ex3->kind == EK_BICALL && !strcmp(ex3->val.s, setexpandname) &&
- (tvar = istempvar(ex3->args[0])) != NULL &&
- isconstexpr(ex3->args[1], &mask)) {
- canceltempvar(tvar);
- if (!nosideeffects(ex, 0)) {
- tvar = makestmttempvar(ex->val.type, name_TEMP);
- ex3 = makeexpr_assign(makeexpr_var(tvar), ex);
- ex = makeexpr_var(tvar);
- } else
- ex3 = NULL;
- type = ord_type(ex2->val.type->indextype);
- ex4 = NULL;
- i = 0;
- while (i < setbits) {
- if (mask & (1<<i++)) {
- if (i+1 < setbits && (mask & (2<<i))) {
- for (j = i; j < setbits && (mask & (1<<j)); j++) ;
- ex4 = makeexpr_or(ex4,
- makeexpr_range(copyexpr(ex),
- makeexpr_val(make_ord(type, i-1)),
- makeexpr_val(make_ord(type, j-1)), 1));
- i = j;
- } else {
- ex4 = makeexpr_or(ex4,
- makeexpr_rel(EK_EQ, copyexpr(ex),
- makeexpr_val(make_ord(type, i-1))));
- }
- }
- }
- mask = 0;
- for (;;) {
- if (!strcmp(ex2->val.s, setaddrangename)) {
- if (checkconst(ex2->args[1], 'a') &&
- checkconst(ex2->args[2], 'z')) {
- mask |= 0x1;
- } else if (checkconst(ex2->args[1], 'A') &&
- checkconst(ex2->args[2], 'Z')) {
- mask |= 0x2;
- } else if (checkconst(ex2->args[1], '0') &&
- checkconst(ex2->args[2], '9')) {
- mask |= 0x4;
- } else {
- ex4 = makeexpr_or(ex4,
- makeexpr_range(copyexpr(ex), ex2->args[1], ex2->args[2], 1));
- }
- } else if (!strcmp(ex2->val.s, setaddname)) {
- ex4 = makeexpr_or(ex4,
- makeexpr_rel(EK_EQ, copyexpr(ex), ex2->args[1]));
- } else
- break;
- ex2 = ex2->args[0];
- }
- /* do these now so that EK_OR optimizations will work: */
- if (mask & 0x1)
- ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
- makeexpr_char('a'),
- makeexpr_char('z'), 1));
- if (mask & 0x2)
- ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
- makeexpr_char('A'),
- makeexpr_char('Z'), 1));
- if (mask & 0x4)
- ex4 = makeexpr_or(ex4, makeexpr_range(copyexpr(ex),
- makeexpr_char('0'),
- makeexpr_char('9'), 1));
- freeexpr(ex);
- return makeexpr_comma(ex3, ex4);
- }
- return makeexpr_bicall_2(setinname, tp_boolean,
- makeexpr_arglong(ex, 0), ex2);
- }
- default:
- return ex;
- }
- }
- /* Parse a C expression; used by VarMacro, etc. */
- Type *nametotype(name)
- char *name;
- {
- if (!strcicmp(name, "malloc") ||
- !strcicmp(name, mallocname)) {
- return tp_anyptr;
- }
- return tp_integer;
- }
- int istypespec()
- {
- switch (curtok) {
- case TOK_CONST:
- return 1;
- case TOK_IDENT:
- return !strcmp(curtokcase, "volatile") ||
- !strcmp(curtokcase, "void") ||
- !strcmp(curtokcase, "char") ||
- !strcmp(curtokcase, "short") ||
- !strcmp(curtokcase, "int") ||
- !strcmp(curtokcase, "long") ||
- !strcmp(curtokcase, "float") ||
- !strcmp(curtokcase, "double") ||
- !strcmp(curtokcase, "signed") ||
- !strcmp(curtokcase, "unsigned") ||
- !strcmp(curtokcase, "struct") ||
- !strcmp(curtokcase, "union") ||
- !strcmp(curtokcase, "class") ||
- !strcmp(curtokcase, "enum") ||
- !strcmp(curtokcase, "typedef") ||
- (curtokmeaning &&
- curtokmeaning->kind == MK_TYPE);
- default:
- return 0;
- }
- }
- Expr *pc_parentype(cp)
- char *cp;
- {
- Expr *ex;
- if (curtok == TOK_IDENT &&
- curtokmeaning &&
- curtokmeaning->kind == MK_TYPE) {
- ex = makeexpr_type(curtokmeaning->type);
- gettok();
- skipcloseparen();
- } else if (curtok == TOK_IDENT && !strcmp(curtokcase, "typedef")) {
- ex = makeexpr_name(getparenstr(inbufptr), tp_integer);
- gettok();
- } else {
- ex = makeexpr_name(getparenstr(cp), tp_integer);
- gettok();
- }
- return ex;
- }
- Expr *pc_expr2();
- Expr *pc_factor()
- {
- Expr *ex;
- char *cp;
- Strlist *sl;
- int i;
- switch (curtok) {
- case TOK_BANG:
- gettok();
- return makeexpr_not(pc_expr2(14));
- case TOK_TWIDDLE:
- gettok();
- return makeexpr_un(EK_BNOT, tp_integer, pc_expr2(14));
- case TOK_PLPL:
- gettok();
- ex = pc_expr2(14);
- return makeexpr_assign(ex, makeexpr_plus(copyexpr(ex), makeexpr_long(1)));
- case TOK_MIMI:
- gettok();
- ex = pc_expr2(14);
- return makeexpr_assign(ex, makeexpr_minus(copyexpr(ex), makeexpr_long(1)));
- case TOK_STAR:
- gettok();
- ex = pc_expr2(14);
- if (ex->val.type->kind != TK_POINTER)
- ex->val.type = makepointertype(ex->val.type);
- return makeexpr_hat(ex, 0);
- case TOK_AMP:
- gettok();
- return makeexpr_addr(pc_expr2(14));
- case TOK_PLUS:
- gettok();
- return pc_expr2(14);
- case TOK_MINUS:
- gettok();
- return makeexpr_neg(pc_expr2(14));
- case TOK_LPAR:
- cp = inbufptr;
- gettok();
- if (istypespec()) {
- ex = pc_parentype(cp);
- return makeexpr_bin(EK_LITCAST, tp_integer, ex, pc_expr2(14));
- }
- ex = pc_expr();
- skipcloseparen();
- return ex;
- case TOK_IDENT:
- if (!strcmp(curtokcase, "sizeof")) {
- gettok();
- if (curtok != TOK_LPAR)
- return makeexpr_sizeof(pc_expr2(14), 1);
- cp = inbufptr;
- gettok();
- if (istypespec()) {
- ex = makeexpr_sizeof(pc_parentype(cp), 1);
- } else {
- ex = makeexpr_sizeof(pc_expr(), 1);
- skipcloseparen();
- }
- return ex;
- }
- if (curtoksym->flags & FMACREC) {
- ex = makeexpr(EK_MACARG, 0);
- ex->val.type = tp_integer;
- ex->val.i = 0;
- for (sl = funcmacroargs, i = 1; sl; sl = sl->next, i++) {
- if (sl->value == (long)curtoksym) {
- ex->val.i = i;
- break;
- }
- }
- } else
- ex = makeexpr_name(curtokcase, nametotype(curtokcase));
- gettok();
- return ex;
- case TOK_INTLIT:
- ex = makeexpr_long(curtokint);
- if (curtokbuf[strlen(curtokbuf)-1] == 'L')
- ex = makeexpr_longcast(ex, 1);
- gettok();
- return ex;
- case TOK_HEXLIT:
- ex = makeexpr_long(curtokint);
- insertarg(&ex, 0, makeexpr_name("%#lx", tp_integer));
- if (curtokbuf[strlen(curtokbuf)-1] == 'L')
- ex = makeexpr_longcast(ex, 1);
- gettok();
- return ex;
- case TOK_OCTLIT:
- ex = makeexpr_long(curtokint);
- insertarg(&ex, 0, makeexpr_name("%#lo", tp_integer));
- if (curtokbuf[strlen(curtokbuf)-1] == 'L')
- ex = makeexpr_longcast(ex, 1);
- gettok();
- return ex;
- case TOK_REALLIT:
- ex = makeexpr_real(curtokbuf);
- gettok();
- return ex;
- case TOK_STRLIT:
- ex = makeexpr_lstring(curtokbuf, curtokint);
- gettok();
- return ex;
- case TOK_CHARLIT:
- ex = makeexpr_char(curtokint);
- gettok();
- return ex;
- default:
- wexpected("a C expression");
- return makeexpr_long(0);
- }
- }
- #define pc_prec(pr) if (prec > (pr)) return ex; gettok();
- Expr *pc_expr2(prec)
- int prec;
- {
- Expr *ex, *ex2;
- int i;
- ex = pc_factor();
- for (;;) {
- switch (curtok) {
- case TOK_COMMA:
- pc_prec(1);
- ex = makeexpr_comma(ex, pc_expr2(2));
- break;
- case TOK_EQ:
- pc_prec(2);
- ex = makeexpr_assign(ex, pc_expr2(2));
- break;
- case TOK_QM:
- pc_prec(3);
- ex2 = pc_expr();
- if (wneedtok(TOK_COLON))
- ex = makeexpr_cond(ex, ex2, pc_expr2(3));
- else
- ex = makeexpr_cond(ex, ex2, makeexpr_long(0));
- break;
- case TOK_OROR:
- pc_prec(4);
- ex = makeexpr_or(ex, pc_expr2(5));
- break;
- case TOK_ANDAND:
- pc_prec(5);
- ex = makeexpr_and(ex, pc_expr2(6));
- break;
- case TOK_VBAR:
- pc_prec(6);
- ex = makeexpr_bin(EK_BOR, tp_integer, ex, pc_expr2(7));
- break;
- case TOK_HAT:
- pc_prec(7);
- ex = makeexpr_bin(EK_BXOR, tp_integer, ex, pc_expr2(8));
- break;
- case TOK_AMP:
- pc_prec(8);
- ex = makeexpr_bin(EK_BAND, tp_integer, ex, pc_expr2(9));
- break;
- case TOK_EQEQ:
- pc_prec(9);
- ex = makeexpr_rel(EK_EQ, ex, pc_expr2(10));
- break;
- case TOK_BANGEQ:
- pc_prec(9);
- ex = makeexpr_rel(EK_NE, ex, pc_expr2(10));
- break;
- case TOK_LT:
- pc_prec(10);
- ex = makeexpr_rel(EK_LT, ex, pc_expr2(11));
- break;
- case TOK_LE:
- pc_prec(10);
- ex = makeexpr_rel(EK_LE, ex, pc_expr2(11));
- break;
- case TOK_GT:
- pc_prec(10);
- ex = makeexpr_rel(EK_GT, ex, pc_expr2(11));
- break;
- case TOK_GE:
- pc_prec(10);
- ex = makeexpr_rel(EK_GE, ex, pc_expr2(11));
- break;
- case TOK_LTLT:
- pc_prec(11);
- ex = makeexpr_bin(EK_LSH, tp_integer, ex, pc_expr2(12));
- break;
- case TOK_GTGT:
- pc_prec(11);
- ex = makeexpr_bin(EK_RSH, tp_integer, ex, pc_expr2(12));
- break;
- case TOK_PLUS:
- pc_prec(12);
- ex = makeexpr_plus(ex, pc_expr2(13));
- break;
- case TOK_MINUS:
- pc_prec(12);
- ex = makeexpr_minus(ex, pc_expr2(13));
- break;
- case TOK_STAR:
- pc_prec(13);
- ex = makeexpr_times(ex, pc_expr2(14));
- break;
- case TOK_SLASH:
- pc_prec(13);
- ex = makeexpr_div(ex, pc_expr2(14));
- break;
- case TOK_PERC:
- pc_prec(13);
- ex = makeexpr_mod(ex, pc_expr2(14));
- break;
- case TOK_PLPL:
- pc_prec(15);
- ex = makeexpr_un(EK_POSTINC, tp_integer, ex);
- break;
- case TOK_MIMI:
- pc_prec(15);
- ex = makeexpr_un(EK_POSTDEC, tp_integer, ex);
- break;
- case TOK_LPAR:
- pc_prec(16);
- if (ex->kind == EK_NAME) {
- ex->kind = EK_BICALL;
- } else {
- ex = makeexpr_un(EK_SPCALL, tp_integer, ex);
- }
- while (curtok != TOK_RPAR) {
- insertarg(&ex, ex->nargs, pc_expr2(2));
- if (curtok != TOK_RPAR)
- if (!wneedtok(TOK_COMMA))
- skiptotoken2(TOK_RPAR, TOK_SEMI);
- }
- gettok();
- break;
- case TOK_LBR:
- pc_prec(16);
- ex = makeexpr_index(ex, pc_expr(), NULL);
- if (!wneedtok(TOK_RBR))
- skippasttoken(TOK_RBR);
- break;
- case TOK_ARROW:
- pc_prec(16);
- if (!wexpecttok(TOK_IDENT))
- break;
- if (ex->val.type->kind != TK_POINTER)
- ex->val.type = makepointertype(ex->val.type);
- ex = makeexpr_dotq(makeexpr_hat(ex, 0),
- curtokcase, tp_integer);
- gettok();
- break;
- case TOK_DOT:
- pc_prec(16);
- if (!wexpecttok(TOK_IDENT))
- break;
- ex = makeexpr_dotq(ex, curtokcase, tp_integer);
- gettok();
- break;
- case TOK_COLONCOLON:
- if (prec > 16)
- return ex;
- i = C_lex;
- C_lex = 0;
- gettok();
- if (curtok == TOK_IDENT &&
- curtokmeaning && curtokmeaning->kind == MK_TYPE) {
- ex->val.type = curtokmeaning->type;
- } else if (curtok == TOK_LPAR) {
- gettok();
- ex->val.type = p_type(NULL);
- if (!wexpecttok(TOK_RPAR))
- skiptotoken(TOK_RPAR);
- } else
- wexpected("a type name");
- C_lex = i;
- gettok();
- break;
- default:
- return ex;
- }
- }
- }
- Expr *pc_expr()
- {
- return pc_expr2(0);
- }
- Expr *pc_expr_str(buf)
- char *buf;
- {
- Strlist *defsl, *sl;
- Expr *ex;
- defsl = NULL;
- sl = strlist_append(&defsl, buf);
- C_lex++;
- push_input_strlist(defsl, buf);
- ex = pc_expr();
- if (curtok != TOK_EOF)
- warning(format_s("Junk (%s) at end of C expression [306]",
- tok_name(curtok)));
- pop_input();
- C_lex--;
- strlist_empty(&defsl);
- return ex;
- }
- /* Simplify an expression */
- Expr *fixexpr(ex, env)
- Expr *ex;
- int env;
- {
- Expr *ex2, *ex3, **ep;
- Type *type, *type2;
- Meaning *mp;
- char *cp;
- char sbuf[5];
- int i;
- Value val;
- if (!ex)
- return NULL;
- switch (ex->kind) {
- case EK_BICALL:
- ex2 = fix_bicall(ex, env);
- if (ex2) {
- ex = ex2;
- break;
- }
- cp = ex->val.s;
- if (!strcmp(cp, "strlen")) {
- if (ex->args[0]->kind == EK_BICALL &&
- !strcmp(ex->args[0]->val.s, "sprintf") &&
- sprintf_value == 0) { /* does sprintf return char count? */
- ex = grabarg(ex, 0);
- strchange(&ex->val.s, "*sprintf");
- ex = fixexpr(ex, env);
- } else {
- ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
- }
- } else if (!strcmp(cp, name_SETIO)) {
- ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
- } else if (!strcmp(cp, "~~SETIO")) {
- ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
- ex = makeexpr_cond(ex->args[0],
- makeexpr_long(0),
- makeexpr_bicall_1(name_ESCIO, tp_int, ex->args[1]));
- } else if (!strcmp(cp, name_CHKIO)) {
- ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
- ex->args[2] = fixexpr(ex->args[2], env);
- ex->args[3] = fixexpr(ex->args[3], env);
- } else if (!strcmp(cp, "~~CHKIO")) {
- ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
- ex->args[2] = fixexpr(ex->args[2], env);
- ex->args[3] = fixexpr(ex->args[3], env);
- ex2 = makeexpr_bicall_1(name_ESCIO, tp_int, ex->args[1]);
- if (ord_type(ex->args[3]->val.type)->kind != TK_INTEGER)
- ex2 = makeexpr_cast(ex2, ex->args[3]->val.type);
- ex = makeexpr_cond(ex->args[0], ex->args[2], ex2);
- } else if (!strcmp(cp, "assert")) {
- ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
- } else {
- for (i = 0; i < ex->nargs; i++)
- ex->args[i] = fixexpr(ex->args[i], ENV_EXPR);
- ex = cleansprintf(ex);
- if (!strcmp(cp, "sprintf")) {
- if (checkstring(ex->args[1], "%s")) {
- delfreearg(&ex, 1);
- strchange(&ex->val.s, "strcpy");
- ex = fixexpr(ex, env);
- } else if (sprintf_value != 1 && env != ENV_STMT) {
- if (*sprintfname) {
- strchange(&ex->val.s, format_s("*%s", sprintfname));
- } else {
- strchange(&ex->val.s, "*sprintf");
- ex = makeexpr_comma(ex, copyexpr(ex->args[0]));
- }
- }
- } else if (!strcmp(cp, "strcpy")) {
- if (env == ENV_STMT &&
- ex->args[1]->kind == EK_BICALL &&
- !strcmp(ex->args[1]->val.s, "strcpy") &&
- nosideeffects(ex->args[1]->args[0], 1)) {
- ex2 = ex->args[1];
- ex->args[1] = copyexpr(ex2->args[0]);
- ex = makeexpr_comma(ex2, ex);
- }
- } else if (!strcmp(cp, "memcpy")) {
- strchange(&ex->val.s, format_s("*%s", memcpyname));
- if (!strcmp(memcpyname, "*bcopy")) {
- swapexprs(ex->args[0], ex->args[1]);
- if (env != ENV_STMT)
- ex = makeexpr_comma(ex, copyexpr(ex->args[1]));
- }
- } else if (!strcmp(cp, setunionname) &&
- (ex3 = singlevar(ex->args[0])) != NULL &&
- ((i=1, exprsame(ex->args[0], ex->args[i], 0)) ||
- (i=2, exprsame(ex->args[0], ex->args[i], 0))) &&
- !exproccurs(ex3, ex->args[3-i])) {
- ep = &ex->args[3-i];
- while ((ex2 = *ep)->kind == EK_BICALL &&
- (!strcmp(ex2->val.s, setaddname) ||
- !strcmp(ex2->val.s, setaddrangename)))
- ep = &ex2->args[0];
- if (ex2->kind == EK_BICALL &&
- !strcmp(ex2->val.s, setexpandname) &&
- checkconst(ex2->args[1], 0) &&
- (mp = istempvar(ex2->args[0])) != NULL) {
- if (ex2 == ex->args[3-i]) {
- ex = grabarg(ex, i);
- } else {
- freeexpr(ex2);
- *ep = ex->args[i];
- ex = ex->args[3-i];
- }
- }
- } else if (!strcmp(cp, setdiffname) && *setremname &&
- (ex3 = singlevar(ex->args[0])) != NULL &&
- exprsame(ex->args[0], ex->args[1], 0) &&
- !exproccurs(ex3, ex->args[2])) {
- ep = &ex->args[2];
- while ((ex2 = *ep)->kind == EK_BICALL &&
- !strcmp(ex2->val.s, setaddname))
- ep = &ex2->args[0];
- if (ex2->kind == EK_BICALL &&
- !strcmp(ex2->val.s, setexpandname) &&
- checkconst(ex2->args[1], 0) &&
- (mp = istempvar(ex2->args[0])) != NULL) {
- if (ex2 == ex->args[2]) {
- ex = grabarg(ex, 1);
- } else {
- ex2 = ex->args[2];
- while (ex2->kind == EK_BICALL &&
- !strcmp(ex2->val.s, setaddname)) {
- strchange(&ex2->val.s, setremname);
- ex2 = ex2->args[0];
- }
- freeexpr(ex2);
- *ep = ex->args[1];
- ex = ex->args[2];
- }
- }
- } else if (!strcmp(cp, setexpandname) && env == ENV_STMT &&
- checkconst(ex->args[1], 0)) {
- ex = makeexpr_assign(makeexpr_hat(ex->args[0], 0),
- ex->args[1]);
- } else if (!strcmp(cp, getbitsname)) {
- type = ex->args[0]->val.type;
- if (type->kind == TK_POINTER)
- type = type->basetype;
- sbuf[0] = (type->issigned) ? 'S' : 'U';
- sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
- sbuf[2] = 0;
- if (sbuf[1] == 'S' &&
- type->smax->val.type == tp_boolean) {
- ex = makeexpr_rel(EK_NE,
- makeexpr_bin(EK_BAND, tp_integer,
- ex->args[0],
- makeexpr_bin(EK_LSH, tp_integer,
- makeexpr_longcast(makeexpr_long(1),
- type->basetype
- == tp_unsigned),
- ex->args[1])),
- makeexpr_long(0));
- ex = fixexpr(ex, env);
- } else
- strchange(&ex->val.s, format_s(cp, sbuf));
- } else if (!strcmp(cp, putbitsname)) {
- type = ex->args[0]->val.type;
- if (type->kind == TK_POINTER)
- type = type->basetype;
- sbuf[0] = (type->issigned) ? 'S' : 'U';
- sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
- sbuf[2] = 0;
- if (sbuf[1] == 'S' &&
- type->smax->val.type == tp_boolean) {
- ex = makeexpr_assign(ex->args[0],
- makeexpr_bin(EK_BOR, tp_integer,
- copyexpr(ex->args[0]),
- makeexpr_bin(EK_LSH, tp_integer,
- makeexpr_longcast(ex->args[2],
- type->basetype
- == tp_unsigned),
- ex->args[1])));
- } else
- strchange(&ex->val.s, format_s(cp, sbuf));
- } else if (!strcmp(cp, storebitsname)) {
- type = ex->args[0]->val.type;
- if (type->kind == TK_POINTER)
- type = type->basetype;
- sbuf[0] = (type->issigned) ? 'S' : 'U';
- sbuf[1] = (type->kind == TK_ARRAY) ? 'B' : 'S';
- sbuf[2] = 0;
- strchange(&ex->val.s, format_s(cp, sbuf));
- } else if (!strcmp(cp, clrbitsname)) {
- type = ex->args[0]->val.type;
- if (type->kind == TK_POINTER)
- type = type->basetype;
- sbuf[0] = (type->kind == TK_ARRAY) ? 'B' : 'S';
- sbuf[1] = 0;
- if (sbuf[0] == 'S' &&
- type->smax->val.type == tp_boolean) {
- ex = makeexpr_assign(ex->args[0],
- makeexpr_bin(EK_BAND, tp_integer,
- copyexpr(ex->args[0]),
- makeexpr_un(EK_BNOT, tp_integer,
- makeexpr_bin(EK_LSH, tp_integer,
- makeexpr_longcast(makeexpr_long(1),
- type->basetype
- == tp_unsigned),
- ex->args[1]))));
- } else
- strchange(&ex->val.s, format_s(cp, sbuf));
- } else if (!strcmp(cp, "fopen")) {
- if (which_lang == LANG_HP &&
- ex->args[0]->kind == EK_CONST &&
- ex->args[0]->val.type->kind == TK_STRING &&
- ex->args[0]->val.i >= 1 &&
- ex->args[0]->val.i <= 2 &&
- isdigit(ex->args[0]->val.s[0]) &&
- (ex->args[0]->val.i == 1 ||
- isdigit(ex->args[0]->val.s[1]))) {
- strchange(&ex->val.s, "fdopen");
- ex->args[0] = makeexpr_long(atoi(ex->args[0]->val.s));
- }
- }
- }
- break;
- case EK_NOT:
- ex = makeexpr_not(fixexpr(grabarg(ex, 0), ENV_BOOL));
- break;
- case EK_AND:
- case EK_OR:
- for (i = 0; i < ex->nargs; i++)
- ex->args[i] = fixexpr(ex->args[i], ENV_BOOL);
- break;
- case EK_EQ:
- case EK_NE:
- ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
- ex->args[1] = fixexpr(ex->args[1], ENV_EXPR);
- if (checkconst(ex->args[1], 0) && env == ENV_BOOL &&
- ord_type(ex->args[1]->val.type)->kind != TK_ENUM &&
- (implicitzero > 0 ||
- (implicitzero < 0 && ex->args[0]->kind == EK_BICALL &&
- boolean_bicall(ex->args[0]->val.s)))) {
- if (ex->kind == EK_EQ)
- ex = makeexpr_not(grabarg(ex, 0));
- else {
- ex = grabarg(ex, 0);
- ex->val.type = tp_boolean;
- }
- }
- break;
- case EK_COND:
- ex->args[0] = fixexpr(ex->args[0], ENV_BOOL);
- #if 0
- val = eval_expr(ex->args[0]);
- #else
- val = ex->args[0]->val;
- if (ex->args[0]->kind != EK_CONST)
- val.type = NULL;
- #endif
- if (val.type == tp_boolean) {
- ex = grabarg(ex, (val.i) ? 1 : 2);
- ex = fixexpr(ex, env);
- } else {
- ex->args[1] = fixexpr(ex->args[1], env);
- ex->args[2] = fixexpr(ex->args[2], env);
- }
- break;
- case EK_COMMA:
- for (i = 0; i < ex->nargs-1; ) {
- ex->args[i] = fixexpr(ex->args[i], ENV_STMT);
- if (nosideeffects(ex->args[i], 1))
- delfreearg(&ex, i);
- else
- i++;
- }
- ex->args[ex->nargs-1] = fixexpr(ex->args[ex->nargs-1], env);
- if (ex->nargs == 1)
- ex = grabarg(ex, 0);
- break;
- case EK_CHECKNIL:
- ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
- if (ex->nargs == 2) {
- ex->args[1] = fixexpr(ex->args[1], ENV_EXPR);
- ex2 = makeexpr_assign(copyexpr(ex->args[1]), ex->args[0]);
- ex3 = ex->args[1];
- } else {
- ex2 = copyexpr(ex->args[0]);
- ex3 = ex->args[0];
- }
- type = ex->args[0]->val.type;
- type2 = ex->val.type;
- ex = makeexpr_cond(makeexpr_rel(EK_NE, ex2, makeexpr_nil()),
- ex3,
- makeexpr_cast(makeexpr_bicall_0(name_NILCHECK,
- tp_int),
- type));
- ex->val.type = type2;
- ex = fixexpr(ex, env);
- break;
- case EK_CAST:
- case EK_ACTCAST:
- if (env == ENV_STMT) {
- ex = fixexpr(grabarg(ex, 0), ENV_STMT);
- } else {
- ex->args[0] = fixexpr(ex->args[0], ENV_EXPR);
- }
- break;
- default:
- for (i = 0; i < ex->nargs; i++)
- ex->args[i] = fixexpr(ex->args[i], ENV_EXPR);
- break;
- }
- return fix_expression(ex, env);
- }
- /* Output an expression */
- #define bitOp(k) ((k)==EK_BAND || (k)==EK_BOR || (k)==EK_BXOR)
- #define shfOp(k) ((k)==EK_LSH || (k)==EK_RSH)
- #define logOp(k) ((k)==EK_AND || (k)==EK_OR)
- #define relOp(k) ((k)==EK_EQ || (k)==EK_LT || (k)==EK_GT ||
- (k)==EK_NE || (k)==EK_GE || (k)==EK_LE)
- #define mathOp(k) ((k)==EK_PLUS || (k)==EK_TIMES || (k)==EK_NEG ||
- (k)==EK_DIV || (k)==EK_DIVIDE || (k)==EK_MOD)
- #define divOp(k) ((k)==EK_DIV || (k)==EK_DIVIDE)
- Static int incompat(ex, num, prec)
- Expr *ex;
- int num, prec;
- {
- Expr *subex = ex->args[num];
- if (extraparens == 0)
- return prec;
- if (ex->kind == subex->kind) {
- if (logOp(ex->kind) || bitOp(ex->kind) ||
- (divOp(ex->kind) && num == 0))
- return -99; /* not even invisible parens */
- else if (extraparens != 2)
- return prec;
- }
- if (extraparens == 2)
- return 15;
- if (divOp(ex->kind) && num == 0 &&
- (subex->kind == EK_TIMES || divOp(subex->kind)))
- return -99;
- if (bitOp(ex->kind) || shfOp(ex->kind))
- return 15;
- if (relOp(ex->kind) && relOp(subex->kind))
- return 15;
- if ((relOp(ex->kind) || logOp(ex->kind)) && bitOp(subex->kind))
- return 15;
- if (ex->kind == EK_COMMA)
- return 15;
- if (ex->kind == EK_ASSIGN && relOp(subex->kind))
- return 15;
- if (extraparens != 1)
- return prec;
- if (ex->kind == EK_ASSIGN)
- return prec;
- if (relOp(ex->kind) && mathOp(subex->kind))
- return prec;
- return 15;
- }
- #define EXTRASPACE() if (spaceexprs == 1) output(" ")
- #define NICESPACE() if (spaceexprs != 0) output(" ")
- #define setprec(p)
- if ((subprec=(p)) <= prec) {
- parens = 1; output("(");
- }
- #define setprec2(p)
- if ((subprec=(p)) <= prec) {
- parens = 1; output("(");
- } else if (prec != -99) {
- parens = 2; output((breakparens == 1) ? "