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

📄 simp.c

📁 unix环境下实现的cmm语言编译器
💻 C
字号:
/*simp.c:进行常量合并和简化处理*/#include "cmm.h"#include <limits.h>static int addover(double x, double y, double min, double max);static int subover(double x, double y, double min, double max);static int mulover(double x, double y, double min, double max);static int addover(double x, double y, double min, double max);static int divover(double x, double y, double min, double max);#define xfoldcnst(TYPE,VAR,OP,RTYPE,FUNC,MIN,MAX)\	if(l->op == CNST+TYPE && r->op == CNST+TYPE\	&& FUNC((double)l->u.v.VAR,(double)r->u.v.VAR,\	(double)MIN,(double)MAX)) {\	p = tree(CNST+ttob(RTYPE), RTYPE,NULL,NULL);\	p->u.v.VAR = l->u.v.VAR OP r->u.v.VAR;\	return p;}#define commute(L,R) \	if(generic(R->op) == CNST && generic(L->op) != CNST)\	{ Tree t = R; R = L; L = t;}	#define identify(X,Y,TYPE,VAR,VAL) \	if(X->op == CNST+TYPE && X->u.v.VAR == VAL)\		return Y;#define cvtcnst(FTYPE, TYPE, EXPR)\	if(l->op == CNST+FTYPE) {\		p = tree(CNST+ttob(TYPE), TYPE, NULL,NULL);\		EXPR;\		return p;}#define xcvtcnst(FTYPE,TTYPE,VAR,MIN,MAX,EXPR) \	if (l->op == CNST+FTYPE) {\		if ( (VAR < MIN || VAR > MAX))\			warning("overflow in constant expression\n");\		if (VAR >= MIN && VAR <= MAX) {\			p = tree(CNST+ttob(TTYPE), TTYPE, NULL, NULL);\			EXPR;\			return p; } }#define cfoldcnst(FTYPE,VAR,OP,RTYPE)\		if(l->op == CNST+FTYPE && r->op == CNST+FTYPE) {\			p = tree(CNST+ttob(RTYPE), RTYPE, NULL, NULL);\			p->u.v.i = l->u.v.VAR OP r->u.v.VAR;\			return p;\		}#define foldaddp(L,R,RTYPE,VAR) \	if (L->op == CNST+P && R->op == CNST+RTYPE) {\		p = tree(CNST+P, ty, NULL, NULL);\		p->u.v.p = (char *)L->u.v.p + R->u.v.VAR;\		return p; }Tree constexpr(int tok){	Tree p;	p = expr(tok);	return p;}int intexpr(int tok){	int n = 0;	Tree p = constexpr(tok);	if(CNST == generic(p->op) && isarith(p->type))		n = p->u.v.i;	else		error("integer expression must be constant\n");	return n;}/*simplify对生成树进行常量合并*/Tree simplify(int op, Type ty, Tree l, Tree r){	Tree p;	DEBUG(fprint(2,"simplify begin\n"));	if(0 == optype(op))		op += ttob(ty);	switch(op) {	case ADD+I:		xfoldcnst(I,i,+,inttype,addover,INT_MIN,INT_MAX);		commute(r,l);		identify(r,l,I,i,0);		break;	case ADD+P:		foldaddp(l,r,I,i);		foldaddp(r,l,I,i);		commute(r, l);		identify(r, retype(l, ty),I,i,0);		break;	case CVC+I:		cvtcnst(C, inttype, p->u.v.i = 		(l->u.v.c&0200 ? (~0<<8):0)|(l->u.v.i &0377));		break;	case CVP+U:		cvtcnst(P, unsignedtype,p->u.v.u = (unsigned)l->u.v.p);		break;	case CVI+C:		xcvtcnst(I, chartype, l->u.v.i, SCHAR_MIN,SCHAR_MAX,		p->u.v.c = l->u.v.i);break;	case CVI+U:		cvtcnst(I,unsignedtype, p->u.v.u  = l->u.v.i); break; 	case CVU+P:		cvtcnst(I, voidptype, p->u.v.p = (void *)l->u.v.u);		break;	case NE+I:		cfoldcnst(I,i,!=,inttype);		break;	case NE+U:	case NE+P:		cfoldcnst(U,u,!=,inttype);		op = NE+I;		break;	case EQ+I:		cfoldcnst(I,i,==,inttype);		break;		case EQ+U:		cfoldcnst(U, u, ==, inttype);		op = EQ+I;		break;	case DIV+I:		identify(r,l,I,i,1);		xfoldcnst(I,i,/,inttype,divover,INT_MIN,INT_MAX);		break;	case GE+I:		cfoldcnst(I,i,>=,inttype);		break;	case GE+U:		cfoldcnst(U,u,>=,inttype);		op = GE+I;		break;			case GT+I:		cfoldcnst(I,i,>,inttype);		break;	case GT+U:		cfoldcnst(U,u,>,inttype);		op = GT+I;		break;			case LE+I:		cfoldcnst(I,i,<=,inttype);		break;	case LE+U:		cfoldcnst(U,u,<=,inttype);		op = LE+I;		break;	case LT+I:		cfoldcnst(I,i,<,inttype);		break;	case LT+U:		cfoldcnst(U,u,<=,inttype);		op=LT+I;		break;	case MOD+I:		if(CNST+I == r->op && 1 == r->u.v.i)			return consttree(0,inttype);		if(CNST+I == r->op && 0 == r->u.v.i)			break;		xfoldcnst(I,i,%,inttype,divover,INT_MIN,INT_MAX);		break;	case MUL+I:		commute(l,r);		if((CNST+I == l->op && 0 == l->u.v.i)		||(CNST+I == r->op && 0 == r->u.v.i))			return consttree(0,inttype);		identify(l,retype(r,ty),I,i,1);		xfoldcnst(I,i,*,inttype,mulover,INT_MIN,INT_MAX);		break;	case NEG+I:		if(CNST+I == l->op) {			if(INT_MIN == l->u.v.i)				warning("overflow in constant expression\n");			if(l->u.v.i != INT_MIN)				return consttree( -l->u.v.i, inttype);			}		if(NEG+I == l->op)			return l->kids[0];		break;	case NOT+I:		if(CNST+I == l->op) return  consttree(!l->u.v.i, inttype);		break;	case SUB+I:		xfoldcnst(I,i,-,inttype,subover,INT_MIN,INT_MAX);		identify(r,l,I,i,0);		break;	case SUB+P:		if( CNST+P == l->op && CNST+P == r->op)				return consttree((char *)l->u.v.p - (char *)r->u.v.p,inttype);		if( CNST+I == r->op)			return simplify(ADD+P, ty, l, consttree(-r->u.v.i,inttype));		break;	default:assert(0);break;	}	DEBUG(fprint(2,"simplify end\n"));	return tree(op, ty, l, r);}/*addover检查x与y的和是否溢出。*/int addover(double x, double y, double min, double max){	int cond = x == 0 || y == 0	|| (x < 0 && y < 0 && x >= min - y)	|| (x > 0 && y > 0 && x <= max - y)	|| (x < 0 && y > 0)	|| (x > 0 && y < 0);		if(!cond)		warning("overflow in constant expression\n");	return cond;}/*mulover检查x与y的积是否溢出。*/int mulover(double x, double y, double min, double max){	int cond = (x > -1 && x <= 1) || (y > -1 && y <= 1)	|| (x < 0 && y < 0 && -x <= max/-y)	|| (x < 0 && y > 0 && x >= min/y)	|| (x > 0 && y > 0 && x <= max/y)	|| (x > 0 && y < 0 && x >= min/y);	if(!cond)		warning("overflow in constant expression\n");	return cond;}/* div - return 1 if min <= x/y <= max, 0 otherwise */int divover(double x, double y, double min, double max){	int cond;	if (x < 0) x = -x;	if (y < 0) y = -y;	cond = y != 0 && (y > 1 || x <= max*y);	if (!cond && y != 0 )		warning("overflow in constant expression\n");	return cond;}int subover(double x, double y, double min, double max){	return addover(x, -y, min, max);}

⌨️ 快捷键说明

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