📄 expr.c
字号:
#include "c.h"static char rcsid[] = "$Id: expr.c,v 1.1 2002/08/28 23:12:43 drh Exp $";static char prec[] = {#define xx(a,b,c,d,e,f,g) c,#define yy(a,b,c,d,e,f,g) c,#include "token.h"};static int oper[] = {#define xx(a,b,c,d,e,f,g) d,#define yy(a,b,c,d,e,f,g) d,#include "token.h"};float refinc = 1.0;static Tree expr2(void);static Tree expr3(int);static Tree nullcheck(Tree);static Tree postfix(Tree);static Tree unary(void);static Tree primary(void);static Type super(Type ty);static Type super(Type ty) { switch (ty->op) { case INT: if (ty->size < inttype->size) return inttype; break; case UNSIGNED: if (ty->size < unsignedtype->size) return unsignedtype; break; case POINTER: return unsignedptr; } return ty;}Tree expr(int tok) { static char stop[] = { IF, ID, '}', 0 }; Tree p = expr1(0); while (t == ',') { Tree q; t = gettok(); q = pointer(expr1(0)); p = tree(RIGHT, q->type, root(value(p)), q); } if (tok) test(tok, stop); return p;}Tree expr0(int tok) { return root(expr(tok));}Tree expr1(int tok) { static char stop[] = { IF, ID, 0 }; Tree p = expr2(); if (t == '=' || (prec[t] >= 6 && prec[t] <= 8) || (prec[t] >= 11 && prec[t] <= 13)) { int op = t; t = gettok(); if (oper[op] == ASGN) p = asgntree(ASGN, p, value(expr1(0))); else { expect('='); p = incr(op, p, expr1(0)); } } if (tok) test(tok, stop); return p;}Tree incr(int op, Tree v, Tree e) { return asgntree(ASGN, v, (*optree[op])(oper[op], v, e));}static Tree expr2(void) { Tree p = expr3(4); if (t == '?') { Tree l, r; Coordinate pts[2]; if (Aflag > 1 && isfunc(p->type)) warning("%s used in a conditional expression\n", funcname(p)); p = pointer(p); t = gettok(); pts[0] = src; l = pointer(expr(':')); pts[1] = src; r = pointer(expr2()); if (generic(p->op) != CNST && events.points) { apply(events.points, &pts[0], &l); apply(events.points, &pts[1], &r); } p = condtree(p, l, r); } return p;}Tree value(Tree p) { int op = generic(rightkid(p)->op); if (p->type != voidtype && (op==AND || op==OR || op==NOT || op==EQ || op==NE || op== LE || op==LT || op== GE || op==GT)) p = condtree(p, consttree(1, inttype), consttree(0, inttype)); return p;}static Tree expr3(int k) { int k1; Tree p = unary(); for (k1 = prec[t]; k1 >= k; k1--) while (prec[t] == k1 && *cp != '=') { Tree r; Coordinate pt; int op = t; t = gettok(); pt = src; p = pointer(p); if (op == ANDAND || op == OROR) { r = pointer(expr3(k1)); if (events.points) apply(events.points, &pt, &r); } else r = pointer(expr3(k1 + 1)); p = (*optree[op])(oper[op], p, r); } return p;}static Tree unary(void) { Tree p; switch (t) { case '*': t = gettok(); p = unary(); p = pointer(p); if (isptr(p->type) && (isfunc(p->type->type) || isarray(p->type->type))) p = retype(p, p->type->type); else { if (YYnull) p = nullcheck(p); p = rvalue(p); } break; case '&': t = gettok(); p = unary(); if (isarray(p->type) || isfunc(p->type)) p = retype(p, ptr(p->type)); else p = lvalue(p); if (isaddrop(p->op) && p->u.sym->sclass == REGISTER) error("invalid operand of unary &; `%s' is declared register\n", p->u.sym->name); else if (isaddrop(p->op)) p->u.sym->addressed = 1; break; case '+': t = gettok(); p = unary(); p = pointer(p); if (isarith(p->type)) p = cast(p, promote(p->type)); else typeerror(ADD, p, NULL); break; case '-': t = gettok(); p = unary(); p = pointer(p); if (isarith(p->type)) { Type ty = promote(p->type); p = cast(p, ty); if (isunsigned(ty)) { warning("unsigned operand of unary -\n"); p = simplify(ADD, ty, simplify(BCOM, ty, p, NULL), cnsttree(ty, 1UL)); } else p = simplify(NEG, ty, p, NULL); } else typeerror(SUB, p, NULL); break; case '~': t = gettok(); p = unary(); p = pointer(p); if (isint(p->type)) { Type ty = promote(p->type); p = simplify(BCOM, ty, cast(p, ty), NULL); } else typeerror(BCOM, p, NULL); break; case '!': t = gettok(); p = unary(); p = pointer(p); if (isscalar(p->type)) p = simplify(NOT, inttype, cond(p), NULL); else typeerror(NOT, p, NULL); break; case INCR: t = gettok(); p = unary(); p = incr(INCR, pointer(p), consttree(1, inttype)); break; case DECR: t = gettok(); p = unary(); p = incr(DECR, pointer(p), consttree(1, inttype)); break; case TYPECODE: case SIZEOF: { int op = t; Type ty; p = NULL; t = gettok(); if (t == '(') { t = gettok(); if (istypename(t, tsym)) { ty = typename(); expect(')'); } else { p = postfix(expr(')')); ty = p->type; } } else { p = unary(); ty = p->type; } assert(ty); if (op == TYPECODE) p = cnsttree(inttype, (long)ty->op); else { if (isfunc(ty) || ty->size == 0) error("invalid type argument `%t' to `sizeof'\n", ty); else if (p && rightkid(p)->op == FIELD) error("`sizeof' applied to a bit field\n"); p = cnsttree(unsignedlong, (unsigned long)ty->size); } } break; case '(': t = gettok(); if (istypename(t, tsym)) { Type ty, ty1 = typename(), pty; expect(')'); ty = unqual(ty1); if (isenum(ty)) { Type ty2 = ty->type; if (isconst(ty1)) ty2 = qual(CONST, ty2); if (isvolatile(ty1)) ty2 = qual(VOLATILE, ty2); ty1 = ty2; ty = ty->type; } p = pointer(unary()); pty = p->type; if (isenum(pty)) pty = pty->type; if (isarith(pty) && isarith(ty) || isptr(pty) && isptr(ty)) { explicitCast++; p = cast(p, ty); explicitCast--; } else if (isptr(pty) && isint(ty) || isint(pty) && isptr(ty)) { if (Aflag >= 1 && ty->size < pty->size) warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, ty); p = cast(p, ty); } else if (ty != voidtype) { error("cast from `%t' to `%t' is illegal\n", p->type, ty1); ty1 = inttype; } if (generic(p->op) == INDIR || ty->size == 0) p = tree(RIGHT, ty1, NULL, p); else p = retype(p, ty1); } else p = postfix(expr(')')); break; default: p = postfix(primary()); } return p;}static Tree postfix(Tree p) { for (;;) switch (t) { case INCR: p = tree(RIGHT, p->type, tree(RIGHT, p->type, p, incr(t, p, consttree(1, inttype))), p); t = gettok(); break; case DECR: p = tree(RIGHT, p->type, tree(RIGHT, p->type, p, incr(t, p, consttree(1, inttype))), p); t = gettok(); break; case '[': { Tree q; t = gettok(); q = expr(']'); if (YYnull) if (isptr(p->type)) p = nullcheck(p); else if (isptr(q->type)) q = nullcheck(q); p = (*optree['+'])(ADD, pointer(p), pointer(q)); if (isptr(p->type) && isarray(p->type->type)) p = retype(p, p->type->type); else p = rvalue(p); } break; case '(': { Type ty; Coordinate pt; p = pointer(p); if (isptr(p->type) && isfunc(p->type->type)) ty = p->type->type; else { error("found `%t' expected a function\n", p->type); ty = func(voidtype, NULL, 1); p = retype(p, ptr(ty)); } pt = src; t = gettok(); p = call(p, ty, pt); } break; case '.': t = gettok(); if (t == ID) { if (isstruct(p->type)) { Tree q = addrof(p); p = field(q, token); q = rightkid(q); if (isaddrop(q->op) && q->u.sym->temporary) p = tree(RIGHT, p->type, p, NULL); } else error("left operand of . has incompatible type `%t'\n", p->type); t = gettok(); } else error("field name expected\n"); break; case DEREF: t = gettok(); p = pointer(p); if (t == ID) { if (isptr(p->type) && isstruct(p->type->type)) { if (YYnull) p = nullcheck(p); p = field(p, token); } else error("left operand of -> has incompatible type `%t'\n", p->type); t = gettok(); } else error("field name expected\n"); break; default: return p; }}static Tree primary(void) { Tree p; assert(t != '('); switch (t) { case ICON: case FCON: p = tree(mkop(CNST,tsym->type), tsym->type, NULL, NULL); p->u.v = tsym->u.c.v; break; case SCON: if (ischar(tsym->type->type)) tsym->u.c.v.p = stringn(tsym->u.c.v.p, tsym->type->size); else tsym->u.c.v.p = memcpy(allocate((tsym->type->size/widechar->size)*sizeof (int), PERM), tsym->u.c.v.p, (tsym->type->size/widechar->size)*sizeof (int)); tsym = constant(tsym->type, tsym->u.c.v); if (tsym->u.c.loc == NULL) tsym->u.c.loc = genident(STATIC, tsym->type, GLOBAL); p = idtree(tsym->u.c.loc); break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -