fltcstoper.c addded to Repository
This commit is contained in:
		
							parent
							
								
									257b4847bf
								
							
						
					
					
						commit
						fd259c398c
					
				
					 9 changed files with 128 additions and 39 deletions
				
			
		| 
						 | 
				
			
			@ -18,9 +18,9 @@ blocks.c
 | 
			
		|||
cem.1
 | 
			
		||||
cem.c
 | 
			
		||||
cemcom.1
 | 
			
		||||
ch7.c
 | 
			
		||||
ch7bin.c
 | 
			
		||||
ch7mon.c
 | 
			
		||||
ch3.c
 | 
			
		||||
ch3bin.c
 | 
			
		||||
ch3mon.c
 | 
			
		||||
char.tab
 | 
			
		||||
class.h
 | 
			
		||||
code.c
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +45,7 @@ expression.g
 | 
			
		|||
field.c
 | 
			
		||||
field.str
 | 
			
		||||
file_info.h
 | 
			
		||||
fltcstoper.c
 | 
			
		||||
idf.c
 | 
			
		||||
idf.str
 | 
			
		||||
init.c
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -158,7 +158,9 @@ firstline:
 | 
			
		|||
	case STSKIP:		/* just skip the skip characters	*/
 | 
			
		||||
		goto again;
 | 
			
		||||
	case STGARB:		/* garbage character			*/
 | 
			
		||||
#ifndef NOPP
 | 
			
		||||
garbage:
 | 
			
		||||
#endif
 | 
			
		||||
		if (040 < ch && ch < 0177)
 | 
			
		||||
			lexerror("garbage char %c", ch);
 | 
			
		||||
		else
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,8 +3,8 @@
 | 
			
		|||
 | 
			
		||||
# Machine and environ dependent definitions
 | 
			
		||||
EMHOME = ../../..
 | 
			
		||||
CC = cc
 | 
			
		||||
CC = $(EMHOME)/bin/fcc
 | 
			
		||||
CC = cc
 | 
			
		||||
CFLOW = cflow
 | 
			
		||||
MKDEP = $(EMHOME)/bin/mkdep
 | 
			
		||||
PRID = $(EMHOME)/bin/prid
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ GENOPTIONS = -vvvx
 | 
			
		|||
# Special #defines during compilation
 | 
			
		||||
PROF = #-pg
 | 
			
		||||
CDEFS =	$(EM_INCLUDES) $(LIB_INCLUDES)
 | 
			
		||||
CFLAGS = $(CDEFS) $(COPTIONS) $(PROF) #-O
 | 
			
		||||
CFLAGS = $(CDEFS) $(COPTIONS) $(PROF) -O
 | 
			
		||||
LDFLAGS = -i $(PROF)
 | 
			
		||||
 | 
			
		||||
# Grammar files and their objects
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -256,6 +256,7 @@ ch3bin(expp, oper, expr)
 | 
			
		|||
#endif	LINT
 | 
			
		||||
			*expp = (*expp)->VL_VALUE ?
 | 
			
		||||
				expr->OP_LEFT : expr->OP_RIGHT;
 | 
			
		||||
			(*expp)->ex_flags |= EX_ILVALUE;
 | 
			
		||||
		}
 | 
			
		||||
		else {
 | 
			
		||||
			*expp = new_oper(expr->ex_type, *expp, oper, expr);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -97,30 +97,6 @@ rank_of(oper)
 | 
			
		|||
	/*NOTREACHED*/
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
rank_of_expression(ex)
 | 
			
		||||
	register struct expr *ex;
 | 
			
		||||
{
 | 
			
		||||
	/*	Returns the rank of the top node in the expression.
 | 
			
		||||
	*/
 | 
			
		||||
	if (!ex || (ex->ex_flags & EX_PARENS) || ex->ex_class != Oper)
 | 
			
		||||
		return 0;
 | 
			
		||||
	return rank_of(ex->OP_OPER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
check_conditional(expr, oper, pos_descr)
 | 
			
		||||
	register struct expr *expr;
 | 
			
		||||
	char *pos_descr;
 | 
			
		||||
{
 | 
			
		||||
	/*	Since the grammar is LR and the parser is LL, this kludge
 | 
			
		||||
		here checks if there was a syntax error caused by
 | 
			
		||||
		the priorities in an expression.
 | 
			
		||||
	*/
 | 
			
		||||
	if (rank_of_expression(expr) >= rank_of(oper))
 | 
			
		||||
		expr_error(expr, "%s %s",
 | 
			
		||||
			symbol2str(expr->OP_OPER), pos_descr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dot2expr(expp)
 | 
			
		||||
	struct expr **expp;
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -242,12 +242,8 @@ conditional_expression(struct expr **expp;)
 | 
			
		|||
			else ResultKnown = OldResultKnown;
 | 
			
		||||
		  }
 | 
			
		||||
		}
 | 
			
		||||
		/* should be: conditional_expression(&e2)
 | 
			
		||||
		 * but that wouldn't work  with 0 ? 0 : i = 0
 | 
			
		||||
		 */
 | 
			
		||||
		assignment_expression(&e2)
 | 
			
		||||
		conditional_expression(&e2)
 | 
			
		||||
		{	
 | 
			
		||||
			check_conditional(e2, '=', "not allowed after :");
 | 
			
		||||
			ResultKnown = OldResultKnown;
 | 
			
		||||
			ch3bin(&e1, ':', e2);
 | 
			
		||||
			opnd2test(expp, '?');
 | 
			
		||||
| 
						 | 
				
			
			@ -263,7 +259,7 @@ assignment_expression(struct expr **expp;)
 | 
			
		|||
	}
 | 
			
		||||
:
 | 
			
		||||
	conditional_expression(expp)
 | 
			
		||||
	[%prefer	/* (rank_of(DOT) <= maxrank) for any asgnop */
 | 
			
		||||
	[
 | 
			
		||||
		asgnop(&oper)
 | 
			
		||||
		assignment_expression(&e1)
 | 
			
		||||
		{ch3asgn(expp, oper, e1);}
 | 
			
		||||
| 
						 | 
				
			
			@ -339,7 +335,6 @@ constant(struct expr **expp;) :
 | 
			
		|||
/* 3.4 */
 | 
			
		||||
constant_expression (struct expr **expp;) :
 | 
			
		||||
	conditional_expression(expp)
 | 
			
		||||
			    /* was: assignment_expression(expp) */
 | 
			
		||||
	{ chk_cst_expr(expp); }
 | 
			
		||||
;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,6 +29,7 @@
 | 
			
		|||
 | 
			
		||||
arith NewLocal();		/* util.c	*/
 | 
			
		||||
char *symbol2str();		/* symbol2str.c	*/
 | 
			
		||||
extern arith full_mask[];	/* cstoper.c	*/
 | 
			
		||||
 | 
			
		||||
/*	Eval_field() evaluates expressions involving bit fields.
 | 
			
		||||
	The various instructions are not yet optimised in the expression
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +74,7 @@ eval_field(expr, code)
 | 
			
		|||
			C_slu(asize);
 | 
			
		||||
		else
 | 
			
		||||
			C_sli(asize);
 | 
			
		||||
		C_loc(~((fd->fd_mask << fd->fd_shift) | (~0 << (8 * asize))));
 | 
			
		||||
		C_loc(~((fd->fd_mask << fd->fd_shift) | ~full_mask[asize]));
 | 
			
		||||
		if (leftop->ex_depth == 0)	{	/* simple case	*/
 | 
			
		||||
			load_val(leftop, RVAL);
 | 
			
		||||
			C_and(asize);
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +144,7 @@ eval_field(expr, code)
 | 
			
		|||
			C_slu(asize);
 | 
			
		||||
		else
 | 
			
		||||
			C_sli(asize);
 | 
			
		||||
		C_loc(~((fd->fd_mask << fd->fd_shift) | (~0 << (8 * asize))));
 | 
			
		||||
		C_loc(~((fd->fd_mask << fd->fd_shift) | ~full_mask[asize]));
 | 
			
		||||
		if (leftop->ex_depth == 0)	{
 | 
			
		||||
			load_val(leftop, RVAL);
 | 
			
		||||
			C_and(asize);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										113
									
								
								lang/cem/cemcom.ansi/fltcstoper.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								lang/cem/cemcom.ansi/fltcstoper.c
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,113 @@
 | 
			
		|||
/*
 | 
			
		||||
 * (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
 | 
			
		||||
 * See the copyright notice in the ACK home directory, in the file "Copyright".
 | 
			
		||||
 */
 | 
			
		||||
/* $Header$ */
 | 
			
		||||
/*	C O N S T A N T   E X P R E S S I O N   H A N D L I N G		*/
 | 
			
		||||
/*	  F O R   F L O A T I N G   P O I N T   N U M B E R S		*/
 | 
			
		||||
 | 
			
		||||
#include	"debug.h"
 | 
			
		||||
#include	"assert.h"
 | 
			
		||||
#include	<alloc.h>
 | 
			
		||||
#include	"target_sizes.h"
 | 
			
		||||
#include	"idf.h"
 | 
			
		||||
#include	<flt_arith.h>
 | 
			
		||||
#include	"arith.h"
 | 
			
		||||
#include	"type.h"
 | 
			
		||||
#include	"label.h"
 | 
			
		||||
#include	"expr.h"
 | 
			
		||||
#include	"sizes.h"
 | 
			
		||||
#include	"Lpars.h"
 | 
			
		||||
 | 
			
		||||
extern int ResultKnown;
 | 
			
		||||
extern char *symbol2str();
 | 
			
		||||
 | 
			
		||||
fltcstbin(expp, oper, expr)
 | 
			
		||||
	register struct expr **expp, *expr;
 | 
			
		||||
{
 | 
			
		||||
	/*	The operation oper is performed on the constant
 | 
			
		||||
		expressions *expp(ld) and expr(ct), and the result restored in
 | 
			
		||||
		*expp.
 | 
			
		||||
	*/
 | 
			
		||||
	flt_arith o1, o2;
 | 
			
		||||
	int compar = 0;
 | 
			
		||||
	arith cmpval;
 | 
			
		||||
 | 
			
		||||
	o1 = (*expp)->FL_ARITH;
 | 
			
		||||
	o2 = expr->FL_ARITH;
 | 
			
		||||
 | 
			
		||||
	ASSERT(is_fp_cst(*expp) && is_fp_cst(expr));
 | 
			
		||||
	switch (oper)	{
 | 
			
		||||
	case '*':
 | 
			
		||||
		flt_mul(&o1, &o2, &o1);
 | 
			
		||||
		break;
 | 
			
		||||
	case '/':
 | 
			
		||||
		flt_div(&o1, &o2, &o1);
 | 
			
		||||
		break;
 | 
			
		||||
	case '+':
 | 
			
		||||
		flt_add(&o1, &o2, &o1);
 | 
			
		||||
		break;
 | 
			
		||||
	case '-':
 | 
			
		||||
		flt_sub(&o1, &o2, &o1);
 | 
			
		||||
		break;
 | 
			
		||||
	case '<':
 | 
			
		||||
	case '>':
 | 
			
		||||
	case LESSEQ:
 | 
			
		||||
	case GREATEREQ:
 | 
			
		||||
	case EQUAL:
 | 
			
		||||
	case NOTEQUAL:
 | 
			
		||||
		compar++;
 | 
			
		||||
		cmpval = flt_cmp(&o1, &o2);
 | 
			
		||||
		switch(oper) {
 | 
			
		||||
		case '<':	cmpval = (cmpval < 0);	break;
 | 
			
		||||
		case '>':	cmpval = (cmpval > 0);	break;
 | 
			
		||||
		case LESSEQ:	cmpval = (cmpval <= 0);	break;
 | 
			
		||||
		case GREATEREQ:	cmpval = (cmpval >= 0);	break;
 | 
			
		||||
		case EQUAL:	cmpval = (cmpval == 0);	break;
 | 
			
		||||
		case NOTEQUAL:	cmpval = (cmpval != 0);	break;
 | 
			
		||||
		}
 | 
			
		||||
		break;
 | 
			
		||||
	case '%':
 | 
			
		||||
	case LEFT:
 | 
			
		||||
	case RIGHT:
 | 
			
		||||
	case '&':
 | 
			
		||||
	case '|':
 | 
			
		||||
	case '^':
 | 
			
		||||
		/*
 | 
			
		||||
		expr_error(*expp, "floating operand for %s", symbol2str(oper));
 | 
			
		||||
		break;
 | 
			
		||||
		*/
 | 
			
		||||
	default:
 | 
			
		||||
		crash("(fltcstoper) bad operator %s", symbol2str(oper));
 | 
			
		||||
		/*NOTREACHED*/
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	switch (flt_status) {
 | 
			
		||||
		case 0:
 | 
			
		||||
		case FLT_UNFL:
 | 
			
		||||
			break;
 | 
			
		||||
		case FLT_OVFL:
 | 
			
		||||
			if (!ResultKnown)
 | 
			
		||||
			    expr_warning(expr,"floating point overflow on %s"
 | 
			
		||||
					, symbol2str(oper));
 | 
			
		||||
			break;
 | 
			
		||||
		case FLT_DIV0:
 | 
			
		||||
			if (!ResultKnown)
 | 
			
		||||
				expr_error(expr,"division by 0.0");
 | 
			
		||||
			else
 | 
			
		||||
				expr_warning(expr,"division by 0.0");
 | 
			
		||||
			break;
 | 
			
		||||
		default:	/* there can't be another status */
 | 
			
		||||
			crash("(fltcstoper) bad status");
 | 
			
		||||
	}
 | 
			
		||||
	if ((*expp)->FL_VALUE) free((*expp)->FL_VALUE);
 | 
			
		||||
	(*expp)->FL_VALUE = 0;
 | 
			
		||||
	if (compar) {
 | 
			
		||||
		fill_int_expr(*expp, cmpval, INT);
 | 
			
		||||
	} else {
 | 
			
		||||
		(*expp)->FL_ARITH = o1;
 | 
			
		||||
	}
 | 
			
		||||
	(*expp)->ex_flags |= expr->ex_flags;
 | 
			
		||||
	(*expp)->ex_flags &= ~EX_PARENS;
 | 
			
		||||
	free_expression(expr);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -58,7 +58,7 @@ promoted_type(tp)
 | 
			
		|||
struct type *tp;
 | 
			
		||||
{
 | 
			
		||||
	if (tp->tp_fund == CHAR || tp->tp_fund == SHORT) {
 | 
			
		||||
		if (tp->tp_unsigned == UNSIGNED && tp->tp_size == int_size)
 | 
			
		||||
		if (tp->tp_unsigned && tp->tp_size == int_size)
 | 
			
		||||
			return uint_type;
 | 
			
		||||
		else return int_type;
 | 
			
		||||
	} else if (tp->tp_fund == FLOAT)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue