#include "c.h"

static char rcsid[] = "$Id: expr.c 355 2007-02-18 22:08:49Z drh $";

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;
	case ID:   if (tsym == NULL)
		   	{
				Symbol p = install(token, &identifiers, level, PERM);
				p->src = src;
				if (getchr() == '(') {
					Symbol q = lookup(token, externals);
					p->type = func(inttype, NULL, 1);
					p->sclass = EXTERN;
					if (Aflag >= 1)
						warning("missing prototype\n");
					if (q && !eqtype(q->type, p->type, 1))
						warning("implicit declaration of `%s' does not match previous declaration at %w\n", q->name, &q->src);

					if (q == NULL) {
						q = install(p->name, &externals, GLOBAL, PERM);
						q->type = p->type;
						q->sclass = EXTERN;
						q->src = src;
						(*IR->defsymbol)(q);
					}
					p->u.alias = q;
				} else {
					error("undeclared identifier `%s'\n", p->name);
					p->sclass = AUTO;
					p->type = inttype;
					if (p->scope == GLOBAL)
						(*IR->defsymbol)(p);
					else
						addlocal(p);
				}
				t = gettok();
				if (xref)
					use(p, src);
				return idtree(p);
			}
		   if (xref)
		   	use(tsym, src);
		   if (tsym->sclass == ENUM)
		   	p = consttree(tsym->u.value, inttype);
		   else {
		   	if (tsym->sclass == TYPEDEF)
		   		error("illegal use of type name `%s'\n", tsym->name);
		   	p = idtree(tsym);
		   } break;
	case FIRSTARG:
		if (level > PARAM && cfunc && cfunc->u.f.callee[0])
			p = idtree(cfunc->u.f.callee[0]);
		else {
			error("illegal use of `%k'\n", FIRSTARG);
			p = cnsttree(inttype, 0L);
		}
		break;
	default:
		error("illegal expression\n");
			p = cnsttree(inttype, 0L);
	}
	t = gettok();
	return p;
}
Tree idtree(Symbol p) {
	int op;
	Tree e;
	Type ty = p->type ? unqual(p->type) : voidptype;

	if (p->scope == GLOBAL || p->sclass == STATIC)
		op = ADDRG;
	else if (p->scope == PARAM) {
		op = ADDRF;
		if (isstruct(p->type) && !IR->wants_argb)
			{
				e = tree(mkop(op,voidptype), ptr(ptr(p->type)), NULL, NULL);
				e->u.sym = p;
				return rvalue(rvalue(e));
			}
	} else if (p->sclass == EXTERN) {
		assert(p->u.alias);
		p = p->u.alias;
		op = ADDRG;
	} else
		op = ADDRL;
	p->ref += refinc;
	if (isarray(ty))
		e = tree(mkop(op,voidptype), p->type,      NULL, NULL);
	else if (isfunc(ty))
		e = tree(mkop(op,funcptype), p->type,      NULL, NULL);
	else
		e = tree(mkop(op,voidptype), ptr(p->type), NULL, NULL);
	e->u.sym = p;
	if (isptr(e->type))
		e = rvalue(e);
	return e;
}

Tree rvalue(Tree p) {
	Type ty = deref(p->type);

	ty = unqual(ty);
	return tree(mkop(INDIR,ty), ty, p, NULL);
}
Tree lvalue(Tree p) {
	if (generic(p->op) != INDIR) {
		error("lvalue required\n");
		return value(p);
	} else if (unqual(p->type) == voidtype)
		warning("`%t' used as an lvalue\n", p->type);
	return p->kids[0];
}
Tree retype(Tree p, Type ty) {
	Tree q;

	if (p->type == ty)
		return p;
	q = tree(p->op, ty, p->kids[0], p->kids[1]);
	q->node = p->node;
	q->u = p->u;
	return q;
}
Tree rightkid(Tree p) {
	while (p && p->op == RIGHT)
		if (p->kids[1])
			p = p->kids[1];
		else if (p->kids[0])
			p = p->kids[0];
		else
			assert(0);
	assert(p);
	return p;
}
int hascall(Tree p) {
	if (p == 0)
		return 0;
	if (generic(p->op) == CALL || (IR->mulops_calls &&
	  (p->op == DIV+I || p->op == MOD+I || p->op == MUL+I
	|| p->op == DIV+U || p->op == MOD+U || p->op == MUL+U)))
		return 1;
	return hascall(p->kids[0]) || hascall(p->kids[1]);
}
Type binary(Type xty, Type yty) {
#define xx(t) if (xty == t || yty == t) return t
	xx(longdouble);
	xx(doubletype);
	xx(floattype);
	xx(unsignedlonglong);
	xx(longlong);
	xx(unsignedlong);
	if (xty == longtype     && yty == unsignedtype
	||  xty == unsignedtype && yty == longtype)
		if (longtype->size > unsignedtype->size)
			return longtype;
		else
			return unsignedlong;
	xx(longtype);
	xx(unsignedtype);
	return inttype;
#undef xx
}
Tree pointer(Tree p) {
	if (isarray(p->type))
		/* assert(p->op != RIGHT || p->u.sym == NULL), */
		p = retype(p, atop(p->type));
	else if (isfunc(p->type))
		p = retype(p, ptr(p->type));
	return p;
}
Tree cond(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)
		return p;
	p = pointer(p);
	return (*optree[NEQ])(NE, p, consttree(0, inttype));
}
Tree cast(Tree p, Type type) {
	Type src, dst;

	p = value(p);
	if (p->type == type)
		return p;
	dst = unqual(type);
	src = unqual(p->type);
	if (src->op != dst->op || src->size != dst->size) {
		switch (src->op) {
		case INT:
			if (src->size < inttype->size)
				p = simplify(CVI, inttype, p, NULL);
			break;
		case UNSIGNED:
			if (src->size < inttype->size)
				p = simplify(CVU, inttype, p, NULL);
			else if (src->size < unsignedtype->size)
				p = simplify(CVU, unsignedtype, p, NULL);
			break;
		case ENUM:
			p = retype(p, inttype);
			break;
		case POINTER:
			if (isint(dst) && src->size > dst->size)
				warning("conversion from `%t' to `%t' is undefined\n", p->type, type);
			p = simplify(CVP, super(src), p, NULL);
			break;
		case FLOAT:
			break;
		default: assert(0);
		}
		{
			src = unqual(p->type);
			dst = super(dst);
			if (src->op != dst->op)
				switch (src->op) {
				case INT:
					p = simplify(CVI, dst, p, NULL);
					break;
				case UNSIGNED:
					if (isfloat(dst)) {
						Type ssrc = signedint(src);
						Tree two = cnsttree(longdouble, (long double)2.0);
						p = (*optree['+'])(ADD,
							(*optree['*'])(MUL,
								two,
								simplify(CVU, ssrc,
									simplify(RSH, src,
										p, consttree(1, inttype)), NULL)),
							simplify(CVU, ssrc,
								simplify(BAND, src,
									p, consttree(1, unsignedtype)), NULL));
					} else
						p = simplify(CVU, dst, p, NULL);
					break;
				case FLOAT:
					if (isunsigned(dst)) {
						Type sdst = signedint(dst);
						Tree c = cast(cnsttree(longdouble, (long double)sdst->u.sym->u.limits.max.i + 1), src);
						p = condtree(
							simplify(GE, src, p, c),
							(*optree['+'])(ADD,
								cast(cast(simplify(SUB, src, p, c), sdst), dst),
								cast(cnsttree(unsignedlong, (unsigned long)sdst->u.sym->u.limits.max.i + 1), dst)),
							simplify(CVF, sdst, p, NULL));
					} else
						p = simplify(CVF, dst, p, NULL);
					break;
				default: assert(0);
				}
			dst = unqual(type);
		}
	}
	src = unqual(p->type);
	switch (src->op) {
	case INT:
		if (src->op != dst->op || src->size != dst->size)
			p = simplify(CVI, dst, p, NULL);
		break;
	case UNSIGNED:
		if (src->op != dst->op || src->size != dst->size)
			p = simplify(CVU, dst, p, NULL);
		break;
	case FLOAT:
		if (src->op != dst->op || src->size != dst->size)
			p = simplify(CVF, dst, p, NULL);
		break;
	case POINTER:
		if (src->op != dst->op)
			p = simplify(CVP, dst, p, NULL);
		else {
			if (isfunc(src->type) && !isfunc(dst->type)
			|| !isfunc(src->type) &&  isfunc(dst->type))
				warning("conversion from `%t' to `%t' is compiler dependent\n", p->type, type);

			if (src->size != dst->size)
				p = simplify(CVP, dst, p, NULL);
		}
		break;
	default: assert(0);
	}
	return retype(p, type);
}
Tree field(Tree p, const char *name) {
	Field q;
	Type ty1, ty = p->type;

	if (isptr(ty))
		ty = deref(ty);
	ty1 = ty;
	ty = unqual(ty);
	if ((q = fieldref(name, ty)) != NULL) {
		if (isarray(q->type)) {
			ty = q->type->type;
			if (isconst(ty1) && !isconst(ty))
				ty = qual(CONST, ty);
			if (isvolatile(ty1) && !isvolatile(ty))
				ty = qual(VOLATILE, ty);
			ty = array(ty, q->type->size/ty->size, q->type->align);
		} else {
			ty = q->type;
			if (isconst(ty1) && !isconst(ty))
				ty = qual(CONST, ty);
			if (isvolatile(ty1) && !isvolatile(ty))
				ty = qual(VOLATILE, ty);
			ty = ptr(ty);
		}
		if (YYcheck && !isaddrop(p->op) && q->offset > 0)	/* omit */
			p = nullcall(ty, YYcheck, p, consttree(q->offset, inttype));	/* omit */
		else					/* omit */
		p = simplify(ADD+P, ty, p, consttree(q->offset, signedptr));

		if (q->lsb) {
			p = tree(FIELD, ty->type, rvalue(p), NULL);
			p->u.field = q;
		} else if (!isarray(q->type))
			p = rvalue(p);

	} else {
		error("unknown field `%s' of `%t'\n", name, ty);
		p = rvalue(retype(p, ptr(inttype)));
	}
	return p;
}
/* funcname - return name of function f or a function' */
char *funcname(Tree f) {
	if (isaddrop(f->op))
		return stringf("`%s'", f->u.sym->name);
	return "a function";
}
static Tree nullcheck(Tree p) {
	if (!needconst && YYnull && isptr(p->type)) {
		p = value(p);
		if (strcmp(YYnull->name, "_YYnull") == 0) {
			Symbol t1 = temporary(REGISTER, voidptype);
			p = tree(RIGHT, p->type,
				tree(OR, voidtype,
					cond(asgn(t1, cast(p, voidptype))),
					vcall(YYnull, voidtype,	(file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno)		, NULL)),
				idtree(t1));
		}

		else
			p = nullcall(p->type, YYnull, p, cnsttree(inttype, 0L));

	}
	return p;
}
Tree nullcall(Type pty, Symbol f, Tree p, Tree e) {
	Type ty;

	if (isarray(pty))
		return retype(nullcall(atop(pty), f, p, e), pty);
	ty = unqual(unqual(p->type)->type);
	return vcall(f, pty,
		p, e,
		cnsttree(inttype, (long)ty->size),
		cnsttree(inttype, (long)ty->align),
		(file && *file ? pointer(idtree(mkstr(file)->u.c.loc)) : cnsttree(voidptype, NULL)), cnsttree(inttype, (long)lineno)		, NULL);
}
