newer version

This commit is contained in:
ceriel 1986-04-07 22:15:08 +00:00
parent f2b68c8261
commit 3de71150a6
2 changed files with 105 additions and 60 deletions

View file

@ -1,4 +1,4 @@
/* 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 */ /* 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 */
static char *RcsId = "$Header$"; static char *RcsId = "$Header$";
@ -14,33 +14,66 @@ static char *RcsId = "$Header$";
long mach_long_sign; /* sign bit of the machine long */ long mach_long_sign; /* sign bit of the machine long */
int mach_long_size; /* size of long on this machine == sizeof(long) */ int mach_long_size; /* size of long on this machine == sizeof(long) */
long full_mask[MAXSIZE];/* full_mask[1] == 0XFF, full_mask[2] == 0XFFFF, .. */ long full_mask[MAXSIZE];/* full_mask[1] == 0xFF, full_mask[2] == 0xFFFF, .. */
arith max_int; /* maximum integer on target machine */ arith max_int; /* maximum integer on target machine */
arith max_unsigned; /* maximum unsigned on target machine */ arith max_unsigned; /* maximum unsigned on target machine */
arith max_longint; /* maximum longint on target machine */ arith max_longint; /* maximum longint on target machine */
#if 0 cstunary(expp, oper)
register struct node *expp;
{
/* The unary operation oper is performed on the constant
expression expp, and the result restored in expp.
*/
arith o1 = expp->nd_INT;
switch(oper) {
case '+':
return;
case '-':
o1 = -o1;
break;
case NOT:
o1 = !o1;
break;
default:
assert(0);
}
expp->nd_INT = o1;
cut_size(expp);
}
cstbin(expp, oper, expr) cstbin(expp, oper, expr)
struct expr **expp, *expr; register struct node *expp, *expr;
{ {
/* The operation oper is performed on the constant /* The binary operation oper is performed on the constant
expressions *expp(ld) and expr(ct), and the result restored in expressions expp and expr, and the result restored in
*expp. expp.
*/ */
arith o1 = (*expp)->VL_VALUE; arith o1 = expp->nd_INT;
arith o2 = expr->VL_VALUE; arith o2 = expr->nd_INT;
int uns = (*expp)->ex_type->tp_unsigned; int uns = expp->nd_type != int_type;
ASSERT(is_ld_cst(*expp) && is_cp_cst(expr)); assert(expp->nd_class == Value && expr->nd_class == Value);
switch (oper) { switch (oper) {
case IN:
/* ??? */
return;
case '*': case '*':
if (expp->nd_type->tp_fund == SET) {
/* ??? */
return;
}
o1 *= o2; o1 *= o2;
break; break;
case '/': case '/':
assert(expp->nd_type->tp_fund == SET);
/* ??? */
return;
case DIV:
if (o2 == 0) { if (o2 == 0) {
expr_error(expr, "division by 0"); node_error(expr, "division by 0");
break; return;
} }
if (uns) { if (uns) {
/* this is more of a problem than you might /* this is more of a problem than you might
@ -74,10 +107,10 @@ cstbin(expp, oper, expr)
else else
o1 /= o2; o1 /= o2;
break; break;
case '%': case MOD:
if (o2 == 0) { if (o2 == 0) {
expr_error(expr, "modulo by 0"); node_error(expr, "modulo by 0");
break; return;
} }
if (uns) { if (uns) {
if (o2 & mach_long_sign) {/* o2 > max_long */ if (o2 & mach_long_sign) {/* o2 > max_long */
@ -104,24 +137,18 @@ cstbin(expp, oper, expr)
o1 %= o2; o1 %= o2;
break; break;
case '+': case '+':
if (expp->nd_type->tp_fund == SET) {
/* ??? */
return;
}
o1 += o2; o1 += o2;
break; break;
case '-': case '-':
o1 -= o2; if (expp->nd_type->tp_fund == SET) {
break; /* ??? */
case LEFT: return;
o1 <<= o2;
break;
case RIGHT:
if (o2 == 0)
break;
if (uns) {
o1 >>= 1;
o1 & = ~mach_long_sign;
o1 >>= (o2-1);
} }
else o1 -= o2;
o1 >>= o2;
break; break;
case '<': case '<':
if (uns) { if (uns) {
@ -143,7 +170,11 @@ cstbin(expp, oper, expr)
else else
o1 = o1 > o2; o1 = o1 > o2;
break; break;
case LESSEQ: case LESSEQUAL:
if (expp->nd_type->tp_fund == SET) {
/* ??? */
return;
}
if (uns) { if (uns) {
o1 = (o1 & mach_long_sign ? o1 = (o1 & mach_long_sign ?
(o2 & mach_long_sign ? o1 <= o2 : 0) : (o2 & mach_long_sign ? o1 <= o2 : 0) :
@ -153,7 +184,11 @@ cstbin(expp, oper, expr)
else else
o1 = o1 <= o2; o1 = o1 <= o2;
break; break;
case GREATEREQ: case GREATEREQUAL:
if (expp->nd_type->tp_fund == SET) {
/* ??? */
return;
}
if (uns) { if (uns) {
o1 = (o1 & mach_long_sign ? o1 = (o1 & mach_long_sign ?
(o2 & mach_long_sign ? o1 >= o2 : 1) : (o2 & mach_long_sign ? o1 >= o2 : 1) :
@ -163,59 +198,64 @@ cstbin(expp, oper, expr)
else else
o1 = o1 >= o2; o1 = o1 >= o2;
break; break;
case EQUAL: case '=':
if (expp->nd_type->tp_fund == SET) {
/* ??? */
return;
}
o1 = o1 == o2; o1 = o1 == o2;
break; break;
case NOTEQUAL: case '#':
if (expp->nd_type->tp_fund == SET) {
/* ??? */
return;
}
o1 = o1 != o2; o1 = o1 != o2;
break; break;
case '&': case AND:
o1 &= o2; o1 = o1 && o2;
break; break;
case '|': case OR:
o1 |= o2; o1 = o1 || o2;
break;
case '^':
o1 ^= o2;
break; break;
default:
assert(0);
} }
(*expp)->VL_VALUE = o1; expp->nd_INT = o1;
cut_size(*expp); cut_size(expp);
(*expp)->ex_flags |= expr->ex_flags;
(*expp)->ex_flags &= ~EX_PARENS;
} }
cut_size(expr) cut_size(expr)
struct expr *expr; register struct node *expr;
{ {
/* The constant value of the expression expr is made to /* The constant value of the expression expr is made to
conform to the size of the type of the expression. conform to the size of the type of the expression.
*/ */
arith o1 = expr->VL_VALUE; arith o1 = expr->nd_INT;
int uns = expr->ex_type->tp_unsigned; int uns = expr->nd_type == card_type || expr->nd_type == intorcard_type;
int size = (int) expr->ex_type->tp_size; int size = expr->nd_type->tp_size;
ASSERT(expr->ex_class == Value); assert(expr->nd_class == Value);
if (uns) { if (uns) {
if (o1 & ~full_mask[size]) if (o1 & ~full_mask[size]) {
expr_warning(expr, node_warning(expr,
"overflow in unsigned constant expression"); "overflow in constant expression");
}
o1 &= full_mask[size]; o1 &= full_mask[size];
} }
else { else {
int nbits = (int) (mach_long_size - size) * 8; int nbits = (int) (mach_long_size - size) * 8;
long remainder = o1 & ~full_mask[size]; long remainder = o1 & ~full_mask[size];
if (remainder != 0 && remainder != ~full_mask[size]) if (remainder != 0 && remainder != ~full_mask[size]) {
expr_warning(expr, "overflow in constant expression"); node_warning(expr, "overflow in constant expression");
o1 <<= nbits; /* ??? */ }
o1 <<= nbits;
o1 >>= nbits; o1 >>= nbits;
} }
expr->VL_VALUE = o1; expr->nd_INT = o1;
} }
# endif
init_cst() init_cst()
{ {
int i = 0; int i = 0;

View file

@ -13,7 +13,12 @@ struct node {
#define Call 4 /* cast or procedure - or function call */ #define Call 4 /* cast or procedure - or function call */
#define Link 5 #define Link 5
struct type *nd_type; /* type of this node */ struct type *nd_type; /* type of this node */
struct token nd_token; union {
struct token ndu_token;
char *ndu_set; /* Pointer to a set constant */
} nd_val;
#define nd_token nd_val.ndu_token
#define nd_set nd_val.ndu_set
#define nd_symb nd_token.tk_symb #define nd_symb nd_token.tk_symb
#define nd_lineno nd_token.tk_lineno #define nd_lineno nd_token.tk_lineno
#define nd_filename nd_token.tk_filename #define nd_filename nd_token.tk_filename