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

📄 expr.c

📁 c语言编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -