⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 expr.c

📁 window下的c编译器。
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "c.h"

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 = (float)1.0;
static Tree expr2 ARGS((void));
static Tree expr3 ARGS((int));
static Tree nullcheck ARGS((Tree));
static Tree postfix ARGS((Tree));
static Tree unary ARGS((void));
static Tree primary ARGS((void));
static Type super ARGS((Type 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;
		Tree lhs = p;
		t = gettok();
		if (oper[op] == ASGN) {
			p = asgntree(ASGN, p, value(expr1(0)));
			if ((p->type->op == POINTER || generic(lhs->op) == INDIR)	&&
				p->kids[0] && p->kids[0]->u.sym) {
				Symbol sym;
				sym = p->kids[0]->u.sym;
				if (sym->scope == LOCAL &&
					(sym->sclass == AUTO || sym->sclass == REGISTER))
					sym->assigned = 1;
			}
		}
		else
			{
				expect('=');
				p = incr(op, p, expr1(0));
			}
	}
	if (tok)
		test(tok, stop);
	return p;
}
Tree incr(int op,Tree v,Tree e)
{
	if (v->kids[0] && v->kids[0]->u.sym) {
		v->kids[0]->u.sym->ref += 1.0;
		v->kids[0]->u.sym->lastuse = StatementCount;
	}

	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(StrTab[247],// <%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());
		p = condtree(p, l, r);
#if 0
		if (OptimizeFlag && p->op == COND &&
			p->kids[1] && p->kids[1]->op == RIGHT &&
			p->kids[1]->kids[0]->op == ASGNI && p->kids[1]->kids[1]->op == ASGNI) {
			/*
			Try to optimize the constructs of nested ?:
			a = (cond) ? (cond ? expr1 : expr2) : expr3;
			*/
			Tree tmp10 = p->kids[1]->kids[0];
			Tree tmp11 = p->kids[1]->kids[1];
//			printtree(tmp10,2);
//			printtree(tmp11,2);
			if (tmp10->kids[1] && tmp10->kids[1]->op == COND) {
				Tree tmp101 = tmp10->kids[1];
				if (tmp101->kids[1] && tmp101->kids[1]->op == RIGHT) {
					Tree tmp1010 = tmp101->kids[1]->kids[0];
					Tree tmp1011 = tmp101->kids[1]->kids[1];
					Symbol s1 = tmp10->kids[0]->u.sym;
					Symbol s2 = tmp11->kids[0]->u.sym;

					if (s1 == s2 && s1->temporary && s1->generated) {
						tmp1010->kids[0]->u.sym = tmp10->kids[0]->u.sym;
						tmp1011->kids[0]->u.sym = tmp11->kids[0]->u.sym;
						tmp101->u.sym = tmp10->kids[0]->u.sym;
						printf("toto\n");
					}
				}
			}
			else if (tmp11->kids[1] && tmp11->kids[1]->op == COND) {
				Tree tmp101 = tmp11->kids[1];
				if (tmp101->kids[1] && tmp101->kids[1]->op == RIGHT) {
					Tree tmp1010 = tmp101->kids[1]->kids[0];
					Tree tmp1011 = tmp101->kids[1]->kids[1];
					Symbol s1 = tmp10->kids[0]->u.sym;
					Symbol s2 = tmp11->kids[0]->u.sym;

					if (s1 == s2 && s1->temporary && s1->generated) {
						tmp1010->kids[0]->u.sym = tmp10->kids[0]->u.sym;
						tmp1011->kids[0]->u.sym = tmp11->kids[0]->u.sym;
						tmp101->u.sym = tmp10->kids[0]->u.sym;
						printf("toto *1*\n");
					}
				}
			}
		}
#endif
		if (events.points)
			if (p->op == COND) {
				Symbol t1 = p->u.sym;
				assert(p->kids[1]);
				assert(p->kids[1]->op == RIGHT);
				apply(events.points, &pts[0], &p->kids[1]->kids[0]);
				apply(events.points, &pts[1], &p->kids[1]->kids[1]);
				p = tree(COND, p->type, p->kids[0],
					tree(RIGHT, p->type,
						p->kids[1]->kids[0],
						p->kids[1]->kids[1]));
				p->u.sym = t1;
			}
	}
	return p;
}
Tree value(Tree p)
{
	int op = generic(rightkid(p)->op);

	if (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 (p->kids[0] &&
			p->kids[0]->op != (CNST+P) &&
			p->kids[0]->u.sym)
			p->kids[0]->u.sym->assigned = 1;
		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(StrTab[248], p->u.sym->name);// <invalid operand of unary &; `%s' is declared register\n>

						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)) {
							p = cast(p, promote(p->type));
							if (isunsigned(p->type)) {
								warning(StrTab[249]);// <unsigned operand of unary -\n>
								p = simplify(NEG, inttype, cast(p, inttype), NULL);
								p = cast(p, unsignedtype);
							} else
								p = simplify(NEG, p->type, p, NULL);
						} else
							typeerror(SUB, p, NULL); break;
	case '~':    t = gettok(); p = unary(); p = pointer(p);
						if (isint(p->type)
							|| (p->type == longlongtype || p->type == ulonglongtype)) {
							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 SIZEOF: t = gettok(); { Type ty;
					p = NULL;
					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 (isfunc(ty) || ty->size == 0)
						error(StrTab[250], ty);// <invalid type argument `%t' to `sizeof'\n>
					else if (p && rightkid(p)->op == FIELD)
						error(StrTab[251]);// <`sizeof' applied to a bit field\n>
					p = consttree(ty->size, unsignedtype); } 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;
			}
#if 0
			if (Xflag && isstruct(ty) && t == '{') {
				Symbol t1 = temporary(AUTO, ty, level);
				if (Aflag >= 2)
					warning(StrTab[252], ty);// <non-ANSI constructor for `%t'\n>
				p = tree(RIGHT, ty1, structexp(ty, t1), idtree(t1));
				break;
			}
#endif
			p = pointer(unary());
			pty = p->type;
			if (isenum(pty))
				pty = pty->type;
			if (isarith(pty) && isarith(ty)
			||  isptr(pty)   && isptr(ty))
				p = cast(p, ty);
			else if (isptr(pty) && isint(ty)
			||       isint(pty) && isptr(ty)) {
				if (Aflag >= 1 && ty->size < pty->size)
					warning(StrTab[253], p->type, ty);// <conversion from `%t' to `%t' is compiler dependent\n>

				p = cast(p, ty);
			} else if (ty != voidtype) {
				error(StrTab[254],// <cast from `%t' to `%t' is illegal\n>
					p->type, ty1);
				ty1 = inttype;
			}
			p = retype(p, ty1);
			if (generic(p->op) == INDIR)
				p = tree(RIGHT, ty, NULL, p);
		} 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 (q->op == (CNST+I) &&
						p->op != (CNST+P) &&
						p->type && p->type->op == ARRAY) {
						char *n;
						int bidx,d;
						if (p->u.sym && p->type->size) {
							n = p->u.sym->name;
							bidx = 1+q->u.v.i;
							assert(p->type->type);
							bidx *= p->type->type->size;
							d = p->type->type->size;
							if (d <= 0) d = 1;
							if (bidx > p->type->size)
								warning(StrTab[255],n,// <indexing array %s[%d] out of bounds (%d)\n>
									q->u.v.i,
									p->type->size/d);
						}
					}
					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(StrTab[256], p->type);// <found `%t' expected a function\n>
						ty = func(voidtype, NULL, 1);
					}
					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);
							p->u.sym = q->u.sym;
						}
					} else
						error(StrTab[257],// <left operand of . has incompatible type `%t'\n>
							p->type);
					t = gettok();
				} else
					error(StrTab[258]); break;// <field name expected\n>
		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(StrTab[259], p->type);// <left operand of -> has incompatible type `%t'\n>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -