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

📄 expr.c

📁 一个c compiler的source code
💻 C
📖 第 1 页 / 共 5 页
字号:
{
		switch (typ->type) {
			case bt_char:
					*node = makenode(en_cb,*node,0);
							break;
			case bt_unsignedchar:
					*node = makenode(en_cub,*node,0);
					break;
			case bt_enum:
			case bt_short:
	  			*node = makenode(en_cw,*node,0);
		  		break;
			case bt_unsignedshort:
  				*node = makenode(en_cuw,*node,0);
					break;
	  	case bt_long:
    			*node = makenode(en_cl,*node,0);
					break;
			case bt_unsigned:
					*node = makenode(en_cul,*node,0);
		  		break;
			case bt_float:
  				*node = makenode(en_cf,*node,0);
					break;
			case bt_double:
					*node = makenode(en_cd,*node,0);
					break;
			case bt_longdouble:
					*node = makenode(en_cld,*node,0);
					break;
			default:
					*node = makenode(en_cp,*node,0);
					break;
		}
	(*node)->cflags = typ->cflags;
}
TYP *gatherparms( ENODE **node)
/*
 * create a type tree and primary parameter list for a function
 *
 * At this point the parameter list is backwards from what codegen
 * needs!
 */
{
	ENODE *ep1 = 0,*ep2=0,**ep3 = &ep1;
	TABLE tbl;
	SYM **t = &tbl.head,*newt;
	TYP *tp;
	int ogc = goodcode;
	tbl.tail = tbl.head = 0;
	goodcode |= DF_FUNCPARMS;
	if (lastst == closepa) {
#ifdef CPLUSPLUS
		if (prm_cplusplus)
			tbl.head=tbl.tail=(SYM *)-1;
		else
#endif
			tbl.head=tbl.tail = 0;
	}
	else if (lastst == kw_void)
		tbl.head = tbl.tail = (SYM *)-1;
	else
	  while (lastst != closepa) {
			tp = exprnc(&ep2);
			if (!tp) {
				generror(ERR_EXPREXPECT,0,0);
				break;
			}
			ep2->cflags = tp->cflags;
			newt = xalloc(sizeof(SYM));
			newt->tp = tp;
			newt->next = 0;
			newt->name = 0;
			*t = newt;
			t = &newt->next;
			tbl.tail = newt;
			*ep3 = makenode(en_void,ep2,0);
			ep3 = &(*ep3)->v.p[1];
			if (lastst == comma)
				getsym();
		}
	needpunc(closepa,skm_closepa);
	tp = maketype(bt_func,0);
	tp->btp = &stdint;
	tp->lst = tbl;
	tp->bits = -1;
	tp->startbit = -1;
	tp->uflags = UF_DEFINED | UF_USED;
	goodcode = ogc;
	*node = ep1;
	return tp;
}
void checkparmconst(TYP *tp, TYP *tpi)
/*
 * Check the CONST flags for parameters
 */
{
	if (tpi->type != bt_pointer && tpi->type != bt_ref)
		return;
	while ((tp->type == bt_pointer || tp->type == bt_ref)&& !tp->val_flag && (!tpi || tpi->type == bt_pointer || tpi->type == bt_ref)) {
		if ((tp->cflags & DF_CONST) && (!tpi || !(tpi->cflags & DF_CONST)))
			generror(ERR_MODCONS,0,0);
		tp = tp->btp;
		tpi = tpi->btp;
	}
	if ((tp->cflags & DF_CONST) && (!tpi || !(tpi->cflags & DF_CONST)))
		generror(ERR_MODCONS,0,0);
}
void parmlist(ENODE **node, TYP *tpi, TYP *tp)
/*
 * take the primary type and node trees, the function argument expectations,
 * and check for type mismatch errors
 *
 * also reverse the primary node tree so the parms will be ready for
 * code generation
 */
{       ENODE    *ep1=0,*ep2=0,*ep3=*node;
				SYM *spi=tpi->lst.head,*sp=0;
				TYP *tp2;
				int matching = FALSE;
				if (tp)
					sp=tp->lst.head;
				if (tp && !sp)
					gensymerror(ERR_NOPROTO,tpi->sname);
				
					if (!prm_cplusplus && sp && sp != (SYM *)-1 && sp->tp->type != bt_ellipse)
							matching = TRUE;
					while (TRUE) {
							if (!spi || spi == (SYM *)-1){
								if (sp == (SYM *) -1)
									break;
								if (sp && sp->tp->type != bt_ellipse) 
									if (!sp->defalt) 
										genfuncerror(ERR_CALLLENSHORT,tpi->sname,0);
									else
										while (sp && sp != (SYM *)-1) {
											if (sp->tp->val_flag && (sp->tp->type == bt_struct || sp->tp->type == bt_union)) {
												ep1 = makenode(en_stackblock,sp->defalt,ep1);
												sp->defalt->size = sp->tp->size;
											}
											else
	    			    		   	ep1 = makenode(en_void,sp->defalt,ep1);
											sp = sp->next;
										}
								break;
							}
							else {
							ep2 = ep3->v.p[0];
							ep3 = ep3->v.p[1];
							if (matching) {
								if (!sp || sp == (SYM *)-1) {
									genfuncerror(ERR_CALLLENLONG,tpi->sname,0);
									break;
								}
								else {
									checkparmconst(spi->tp,sp->tp);
									if (!checktype(spi->tp,sp->tp))
								  	if (isscalar(sp->tp) && isscalar(spi->tp))
											promote_type(sp->tp,&ep2);
										else
											if (sp->tp->type == bt_pointer) {
												if (isintconst(ep2->nodetype)) {
													if (ep2->v.i != 0)
														generror(ERR_NONPORT,0,0);
												}
												else if (spi->tp->type != bt_pointer)
														genfuncerror(ERR_CALLMISMATCH,tpi->sname,sp->name);
						 					}
											else genfuncerror(ERR_CALLMISMATCH,tpi->sname,sp->name);
								}
							}
							}
							if (sp && sp->tp->type == bt_ref) {
								if (lvalue(ep2)) {
									while (castvalue(ep2))
										ep2 = ep2->v.p[0];
									ep2 = ep2->v.p[0];
								}
								else {
									ENODE *x;
									tp2 = sp->tp->btp;
									genfuncerror(ERR_TEMPUSED,tpi->sname,sp->name);
									ep2 = makenode(en_refassign,dummyvar(tp2->size,tp2),ep2);
								}
								}
							if (spi && spi != (SYM *) -1 && spi->tp->val_flag && (spi->tp->type == bt_struct || spi->tp->type == bt_union)) {
								ep1 = makenode(en_stackblock,ep2,ep1);
								ep2->size = sp->tp->size;
							}
							else
	        	   	ep1 = makenode(en_void,ep2,ep1);
							spi = spi->next;
 							if (sp && sp != (SYM *)-1) {
								sp = sp->next;
 								if (sp && sp->tp->type == bt_ellipse)
									matching = FALSE;
							}
					}
				if (tp)
					promote_type(tp->btp,&ep1);
				else
					promote_type(tpi->btp,&ep1);
				*node = ep1;
}

int floatrecurse(ENODE *node)
/*
 * Go through a node and see if it will be promoted to type FLOAT
 */
{
	if (!node)
		return 0;
	switch (node->nodetype) {
								case en_rcon:
								case en_lrcon:
								case en_fcon:
								case en_doubleref:
								case en_longdoubleref:
								case en_floatref:
								case en_cld:
								case en_cd:
								case en_cf:
												return 1;
                case en_labcon: case en_trapcall: 
                case en_nacon:  case en_autocon:  case en_autoreg: case en_nalabcon:
                case en_l_ref:  case en_tempref: case en_napccon: case en_absacon:
								case en_cl: case en_regref:
                case en_ul_ref:
								case en_cul:
								case en_cp:
                case en_icon:
								case en_lcon: case en_iucon: case en_lucon: case en_ccon:
								case en_bits:
                case en_ub_ref:
								case en_cub:
                case en_b_ref:
								case en_cb:
                case en_uw_ref:
								case en_cuw:
                case en_cw:
                case en_w_ref:
                case en_eq:     case en_ne:
                case en_lt:     case en_le:
                case en_gt:     case en_ge:
								case en_ugt: case en_uge: case en_ult: case en_ule:
                        return 0;
								case en_fcall: case en_pfcall:
								case en_fcallb: case en_pfcallb:
								case en_callblock:
												return(floatrecurse(node->v.p[1]));
                case en_not:    case en_compl:
                case en_uminus: 
                case en_ainc:   case en_adec:
								case en_moveblock: case en_stackblock:
                        return floatrecurse(node->v.p[0]);
								case en_refassign: case en_assign:
                case en_add:    case en_sub:
								case en_umul:		case en_udiv:	case en_umod: case en_pmul:
                case en_mul:    case en_div:
                case en_mod:    case en_and:
                case en_or:     case en_xor:
								case en_asalsh: case en_asarsh: case en_alsh: case en_arsh:
                case en_lsh:    case en_rsh:
                case en_land:   case en_lor:
                case en_asadd:  case en_assub:
                case en_asmul:  case en_asdiv:
                case en_asmod:  case en_asand:
								case en_asumod: case en_asudiv: case en_asumul:
                case en_asor:   case en_aslsh: case en_asxor:
                case en_asrsh:
                        return(floatrecurse(node->v.p[0]) || floatrecurse(node->v.p[1]));
                case en_void:   case en_cond:
                        return floatrecurse(node->v.p[1]);
	}
	return(0);
}
void floatcheck(ENODE *node)
/*
 * Error if node will be promoted to type float
 */
{
	if (floatrecurse(node))
		generror(ERR_INVFLOAT,0,0);
}
int     castbegin(int st)
/*
 *      return 1 if st in set of [ kw_char, kw_short, kw_long, kw_int,
 *      kw_float, kw_double, kw_struct, kw_union, kw_float, or is typedef ]
 */
{      
	SYM *sp;
	switch(st) {
		case kw_void:
		case kw_char: case kw_short: case kw_int: case kw_long:
		case kw_float: case kw_double:	
		case kw_struct:	case kw_union: case kw_signed:
		case kw_unsigned:	case kw_volatile:	case kw_const:
			return 1;
		default:
			if (st != id)
				return 0;
	} 
	nm = lastid;
	sp = gsearch(lastid);
	if (!sp)
		sp = search(lastid,&lsyms);
	if (sp && sp->storage_class == sc_type)
		return 1 ;
	return 0;
}

int tostring()
{
	short string[2048];
	int st = lastst;
	string[0] = 0;
	while (lastst == st) {
		if (st == lsconst) {
			if (pstrlen(string) +pstrlen(laststr) > 2040)
				generror(ERR_STRINGTOOBIG,0,0);
			else
				pstrcat(string,laststr);
		}
		else {
			if (strlen(string) +strlen(laststr) > 4090)
				generror(ERR_STRINGTOOBIG,0,0);
			else
				strcat(string,laststr);
		}
		getsym();
	}
	return(stringlit(string,st == lsconst));
}
TYP     *primary(ENODE **node)
/*
 *      primary will parse a primary expression and set the node pointer
 *      returning the type of the expression parsed. primary expressions
 *      are any of:
 *                      id
 *                      constant
 *                      string
 *                      ( expression )
 *                      primary++
 *                      primary--
 *                      primary[ expression ]
 *                      primary.id
 *                      primary->id
 *                      primary( parameter list )
 *											(* expression)( parameter list )
 *                      (typecast)primary
 *                      (typecast)(unary)
 */
{       ENODE    *pnode, *qnode, *rnode;
        SYM             *sp=0;
        TYP             *tptr,*tp1,*tp2;
				int flag = 0;
				int gcode,gdf;
				int isstring = FALSE;
        switch( lastst ) {
/* This trap thing should be in stmt.c */
						case kw__trap:    
									getsym();
									if (needpunc(openpa,0)) {
										long num = intexpr(0);
										if (num > 15 || num < 0)
											generror(ERR_INVTRAP,0,0);

⌨️ 快捷键说明

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