corrected the treatment of the <<= and >>= operators
This commit is contained in:
parent
b9bce39f1e
commit
ecf5219493
3 changed files with 32 additions and 24 deletions
|
@ -324,6 +324,7 @@ ch7asgn(expp, oper, expr)
|
||||||
EVAL should however take care of evaluating (typeof (f op e))f
|
EVAL should however take care of evaluating (typeof (f op e))f
|
||||||
*/
|
*/
|
||||||
int fund = (*expp)->ex_type->tp_fund;
|
int fund = (*expp)->ex_type->tp_fund;
|
||||||
|
struct type *tp;
|
||||||
|
|
||||||
/* We expect an lvalue */
|
/* We expect an lvalue */
|
||||||
if (!(*expp)->ex_lvalue) {
|
if (!(*expp)->ex_lvalue) {
|
||||||
|
@ -333,6 +334,7 @@ ch7asgn(expp, oper, expr)
|
||||||
}
|
}
|
||||||
if (oper == '=') {
|
if (oper == '=') {
|
||||||
ch7cast(&expr, oper, (*expp)->ex_type);
|
ch7cast(&expr, oper, (*expp)->ex_type);
|
||||||
|
tp = expr->ex_type;
|
||||||
}
|
}
|
||||||
else { /* turn e into e' where typeof(e') = typeof (f op e) */
|
else { /* turn e into e' where typeof(e') = typeof (f op e) */
|
||||||
struct expr *extmp = intexpr((arith)0, INT);
|
struct expr *extmp = intexpr((arith)0, INT);
|
||||||
|
@ -341,13 +343,14 @@ ch7asgn(expp, oper, expr)
|
||||||
extmp->ex_lvalue = 1;
|
extmp->ex_lvalue = 1;
|
||||||
extmp->ex_type = (*expp)->ex_type;
|
extmp->ex_type = (*expp)->ex_type;
|
||||||
ch7bin(&extmp, oper, expr);
|
ch7bin(&extmp, oper, expr);
|
||||||
/* note that ch7bin creates a tree of the expression
|
/* Note that ch7bin creates a tree of the expression
|
||||||
((typeof (f op e))f op (typeof (f op e))e),
|
((typeof (f op e))f op (typeof (f op e))e),
|
||||||
where f ~ extmp and e ~ expr;
|
where f ~ extmp and e ~ expr.
|
||||||
we have to use (typeof (f op e))e
|
We want to use (typeof (f op e))e.
|
||||||
Ch7bin does not create a tree if both operands
|
Ch7bin does not create a tree if both operands
|
||||||
were illegal or constants!
|
were illegal or constants!
|
||||||
*/
|
*/
|
||||||
|
tp = extmp->ex_type; /* perform the arithmetic in type tp */
|
||||||
if (extmp->ex_class == Oper) {
|
if (extmp->ex_class == Oper) {
|
||||||
expr = extmp->OP_RIGHT;
|
expr = extmp->OP_RIGHT;
|
||||||
extmp->OP_RIGHT = NILEXPR;
|
extmp->OP_RIGHT = NILEXPR;
|
||||||
|
@ -356,13 +359,17 @@ ch7asgn(expp, oper, expr)
|
||||||
else
|
else
|
||||||
expr = extmp;
|
expr = extmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NOBITFIELD
|
#ifndef NOBITFIELD
|
||||||
if (fund == FIELD)
|
if (fund == FIELD)
|
||||||
*expp = new_oper((*expp)->ex_type->tp_up, *expp, oper, expr);
|
*expp = new_oper((*expp)->ex_type->tp_up, *expp, oper, expr);
|
||||||
else
|
else
|
||||||
#endif NOBITFIELD
|
|
||||||
*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
|
*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
|
||||||
(*expp)->OP_TYPE = expr->ex_type; /* for EVAL() */
|
#else NOBITFIELD
|
||||||
|
*expp = new_oper((*expp)->ex_type, *expp, oper, expr);
|
||||||
|
#endif NOBITFIELD
|
||||||
|
|
||||||
|
(*expp)->OP_TYPE = tp; /* for EVAL() */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Some interesting (?) questions answered.
|
/* Some interesting (?) questions answered.
|
||||||
|
|
|
@ -156,7 +156,8 @@ ch7bin(expp, oper, expr)
|
||||||
case RIGHTAB:
|
case RIGHTAB:
|
||||||
opnd2integral(expp, oper);
|
opnd2integral(expp, oper);
|
||||||
opnd2integral(&expr, oper);
|
opnd2integral(&expr, oper);
|
||||||
ch7cast(&expr, oper, int_type); /* leftop should be int */
|
fund = arithbalance(expp, oper, &expr); /* ch. 7.5 */
|
||||||
|
ch7cast(&expr, oper, int_type); /* cvt. rightop to int */
|
||||||
non_commutative_binop(expp, oper, expr);
|
non_commutative_binop(expp, oper, expr);
|
||||||
break;
|
break;
|
||||||
case '<':
|
case '<':
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
#include "atw.h"
|
#include "atw.h"
|
||||||
|
|
||||||
#define CRASH() crash("EVAL: CRASH at line %u", __LINE__)
|
#define CRASH() crash("EVAL: CRASH at line %u", __LINE__)
|
||||||
#define roundup(n) ((n) < word_size ? word_size : (n))
|
#define toword(n) ((n) < word_size ? word_size : (n))
|
||||||
|
|
||||||
char *symbol2str();
|
char *symbol2str();
|
||||||
char *long2str();
|
char *long2str();
|
||||||
|
@ -374,6 +374,10 @@ EVAL(expr, val, code, true_label, false_label)
|
||||||
case ANDAB:
|
case ANDAB:
|
||||||
case XORAB:
|
case XORAB:
|
||||||
case ORAB:
|
case ORAB:
|
||||||
|
{
|
||||||
|
arith old_offset;
|
||||||
|
arith tmpvar = tmp_pointer_var(&old_offset);
|
||||||
|
|
||||||
#ifndef NOBITFIELD
|
#ifndef NOBITFIELD
|
||||||
if (leftop->ex_type->tp_fund == FIELD) {
|
if (leftop->ex_type->tp_fund == FIELD) {
|
||||||
eval_field(expr, code);
|
eval_field(expr, code);
|
||||||
|
@ -381,34 +385,29 @@ EVAL(expr, val, code, true_label, false_label)
|
||||||
}
|
}
|
||||||
#endif NOBITFIELD
|
#endif NOBITFIELD
|
||||||
if (leftop->ex_class != Value) {
|
if (leftop->ex_class != Value) {
|
||||||
arith old_offset;
|
|
||||||
arith tmpvar = tmp_pointer_var(&old_offset);
|
|
||||||
|
|
||||||
EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL);
|
EVAL(leftop, LVAL, TRUE, NO_LABEL, NO_LABEL);
|
||||||
C_lal(tmpvar);
|
C_lal(tmpvar);
|
||||||
C_sti(pointer_size);
|
C_sti(pointer_size);
|
||||||
C_lal(tmpvar);
|
C_lal(tmpvar);
|
||||||
C_loi(pointer_size);
|
C_loi(pointer_size);
|
||||||
C_loi(leftop->ex_type->tp_size);
|
C_loi(leftop->ex_type->tp_size);
|
||||||
conversion(leftop->ex_type, tp);
|
}
|
||||||
EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL);
|
else {
|
||||||
assop(tp, oper);
|
load_val(leftop, RVAL);
|
||||||
conversion(tp, leftop->ex_type);
|
}
|
||||||
if (gencode)
|
conversion(leftop->ex_type, tp);
|
||||||
C_dup(roundup(leftop->ex_type->tp_size));
|
EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL);
|
||||||
|
assop(tp, oper);
|
||||||
|
conversion(tp, leftop->ex_type);
|
||||||
|
if (gencode)
|
||||||
|
C_dup(toword(leftop->ex_type->tp_size));
|
||||||
|
if (leftop->ex_class != Value) {
|
||||||
C_lal(tmpvar);
|
C_lal(tmpvar);
|
||||||
C_loi(pointer_size);
|
C_loi(pointer_size);
|
||||||
C_sti(leftop->ex_type->tp_size);
|
C_sti(leftop->ex_type->tp_size);
|
||||||
free_tmp_var(old_offset);
|
free_tmp_var(old_offset);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
load_val(leftop, RVAL);
|
|
||||||
conversion(leftop->ex_type, tp);
|
|
||||||
EVAL(rightop, RVAL, TRUE, NO_LABEL, NO_LABEL);
|
|
||||||
assop(tp, oper);
|
|
||||||
conversion(tp, leftop->ex_type);
|
|
||||||
if (gencode)
|
|
||||||
C_dup(roundup(leftop->ex_type->tp_size));
|
|
||||||
store_val(
|
store_val(
|
||||||
&(leftop->ex_object.ex_value),
|
&(leftop->ex_object.ex_value),
|
||||||
leftop->ex_type
|
leftop->ex_type
|
||||||
|
@ -417,6 +416,7 @@ EVAL(expr, val, code, true_label, false_label)
|
||||||
if (gencode)
|
if (gencode)
|
||||||
conversion(leftop->ex_type, expr->ex_type);
|
conversion(leftop->ex_type, expr->ex_type);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case '(':
|
case '(':
|
||||||
{
|
{
|
||||||
register struct expr *expr;
|
register struct expr *expr;
|
||||||
|
|
Loading…
Reference in a new issue