fbconst.c

来自「c编译器实现」· C语言 代码 · 共 212 行

C
212
字号
/* *  FBCC - A simple C compiler. *  *  Copyright (c) 1996 Fabrice Bellard * *  Contact addresses: *  mail: Fabrice Bellard, 451 chemin du mas de Matour, 34790 Grabels, France *  email: bellard@email.enst.fr *  url: http://www.enst.fr/~bellard * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* * Propagation des constantes dans les expressions */#include <stdlib.h>#include <stdio.h>#include "fbcc.h"/* * On ne g鑢e ici que le minimum */LIST *Expr_CEval(LIST *e);int Expr_IsConst(LIST *e){	 return hd_tag(tl(e)) == EXPR_INT;}int Expr_ConstVal(LIST *e){	 return hd_int(tl(tl(e)));}LIST *Expr_ConstInteger1(LIST *type,int val){	 return mk_list(type,mk_tag(EXPR_INT,mk_int(val,NULL)));}LIST *Expr_CBinary(LIST *expr){	 int op,val1,val2,val;	 LIST *ec1,*ec2,*type;	 	 ec1=hd_list(tl(tl(expr)));	 ec2=hd_list(tl(tl(tl(expr))));	 op=hd_tag(tl(expr));	 type=list_dup(hd_list(expr));	 	 ec1=Expr_CEval(ec1);	 ec2=Expr_CEval(ec2);	 	 if (op != EXPR_ASSIGN && Expr_IsConst(ec1) && Expr_IsConst(ec2) ) {			val1=Expr_ConstVal(ec1);			val2=Expr_ConstVal(ec2);			switch(op) {			 case EXPR_ADD:				 val=val1+val2;				 break;			 case EXPR_SUB:				 val=val1-val2;				 break;			 case EXPR_MUL:				 if (hd_tag(type)==TYPE_UINT) val=(unsigned int)val1*(unsigned int)val2;				 else val=val1*val2;				 break;			 case EXPR_DIV:				 if (val2==0) Error("Divison par z閞o");				 if (hd_tag(type)==TYPE_UINT) val=(unsigned int)val1/(unsigned int)val2;				 else val=val1*val2;				 break;				 /* jamais atteint !*/			 default:				 val=0;			}			list_free(ec1);			list_free(ec2);			return Expr_ConstInteger1(type,val);	 } else {			return mk_list(type,mk_tag(op,mk_list(ec1,mk_list(ec2,NULL))));	 }}LIST *Expr_CUnary(LIST *expr){	 int op,val1,val;	 LIST *ec1,*type;	 	 ec1=hd_list(tl(tl(expr)));	 op=hd_tag(tl(expr));	 type=list_dup(hd_list(expr));	  	 ec1=Expr_CEval(ec1);	 if (op != EXPR_INDIR && Expr_IsConst(ec1)) {			val1=Expr_ConstVal(ec1);			switch (op) {			 case EXPR_NEG:				 val=-val1;				 break;			 default:				 /* jamais atteint !*/				 val=0;			}			list_free(ec1);			return Expr_ConstInteger1(type,val);	 } else {			return mk_list(type,mk_tag(op,mk_list(ec1,NULL)));	 }}LIST *Expr_CCast(LIST *expr){	 int val;	 LIST *ec1,*type;	 	 ec1=hd_list(tl(tl(expr)));	 type=list_dup(hd_list(expr));	 ec1=Expr_CEval(ec1);	 if (Expr_IsConst(ec1)) {			val=Expr_ConstVal(ec1);			switch(hd_tag(type)) {			 case TYPE_CHAR:				 val=(char)val;				 break;			 case TYPE_UCHAR:				 val=(unsigned char)val;				 break;			 case TYPE_SHORT:				 val=(short)val;				 break;			 case TYPE_USHORT:				 val=(unsigned short)val;				 break;			}			list_free(ec1);			return Expr_ConstInteger1(type,val);	 } else {			return mk_list(type,mk_tag(EXPR_CAST,mk_list(ec1,NULL)));	 }}/* * On retourne une expression dupliqu閑 avec la propagation des constantes * effectu閑 */LIST *Expr_CEval(LIST *expr){	 int op;	 	 op=hd_tag(tl(expr));	 switch(op) {		case EXPR_CAST:			return Expr_CCast(expr);		case EXPR_NEG:		case EXPR_INDIR:			return Expr_CUnary(expr);		case EXPR_ADD:		case EXPR_MUL:		case EXPR_SUB:		case EXPR_DIV:		case EXPR_ASSIGN:			return Expr_CBinary(expr);		default:			return list_dup(expr);	 }}/* * On propage les constantes et on efface l'expression d'origine */LIST *Expr_ConstEval(LIST *expr){	 LIST *res;/*	 printf("avant=");  List_Print(expr); printf("\n");  */	 	 res=Expr_CEval(expr); 	 list_free(expr);/*   printf("apr鑣=");  List_Print(res); printf("\n"); */	 return res;}

⌨️ 快捷键说明

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