1989-10-13 11:04:42 +00:00
|
|
|
/*
|
|
|
|
* (c) copyright 1989 by the Vrije Universiteit, Amsterdam, The Netherlands.
|
|
|
|
* See the copyright notice in the ACK home directory, in the file "Copyright".
|
|
|
|
*/
|
1994-06-27 08:03:14 +00:00
|
|
|
/* $Id$ */
|
1989-10-13 11:04:42 +00:00
|
|
|
/* 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 */
|
|
|
|
|
2017-11-10 03:22:13 +00:00
|
|
|
#include <assert.h>
|
2013-05-12 19:45:55 +00:00
|
|
|
#include "parameters.h"
|
1989-10-13 11:04:42 +00:00
|
|
|
#include <alloc.h>
|
|
|
|
#include <flt_arith.h>
|
2019-02-18 16:42:15 +00:00
|
|
|
#include "fltcstoper.h"
|
1989-10-13 11:04:42 +00:00
|
|
|
#include "arith.h"
|
|
|
|
#include "type.h"
|
|
|
|
#include "label.h"
|
|
|
|
#include "expr.h"
|
|
|
|
#include "sizes.h"
|
|
|
|
#include "Lpars.h"
|
2019-02-18 16:42:15 +00:00
|
|
|
#include "error.h"
|
1989-10-13 11:04:42 +00:00
|
|
|
|
|
|
|
extern int ResultKnown;
|
|
|
|
extern char *symbol2str();
|
|
|
|
|
2019-02-18 16:42:15 +00:00
|
|
|
void fltcstbin(register struct expr **expp, int oper, register struct expr *expr)
|
1989-10-13 11:04:42 +00:00
|
|
|
{
|
|
|
|
/* 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;
|
1989-11-08 16:52:34 +00:00
|
|
|
int cmpval = 0;
|
1989-10-13 11:04:42 +00:00
|
|
|
|
|
|
|
o1 = (*expp)->FL_ARITH;
|
|
|
|
o2 = expr->FL_ARITH;
|
|
|
|
|
2017-11-10 03:22:13 +00:00
|
|
|
assert(is_fp_cst(*expp) && is_fp_cst(expr));
|
1989-10-13 11:04:42 +00:00
|
|
|
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;
|
|
|
|
default:
|
1990-09-14 16:39:11 +00:00
|
|
|
/* in case of situations like a += 3.0; where a undefined */
|
|
|
|
flt_status = 0;
|
|
|
|
break;
|
1989-10-13 11:04:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (flt_status) {
|
|
|
|
case 0:
|
1990-09-14 16:39:11 +00:00
|
|
|
case FLT_UNFL: /* ignore underflow */
|
1989-10-13 11:04:42 +00:00
|
|
|
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 (compar) {
|
1989-10-19 14:53:25 +00:00
|
|
|
fill_int_expr(*expp, (arith)cmpval, INT);
|
1989-10-13 11:04:42 +00:00
|
|
|
} else {
|
|
|
|
(*expp)->FL_ARITH = o1;
|
|
|
|
}
|
|
|
|
(*expp)->ex_flags |= expr->ex_flags;
|
|
|
|
(*expp)->ex_flags &= ~EX_PARENS;
|
|
|
|
free_expression(expr);
|
|
|
|
}
|