- value *val ;
-
- /* create a new value */
- val = newValue();
- val->type = val->etype = newCharLink();
- val->type->class = SPECIFIER ;
- SPEC_NOUN(val->type) = V_INT ; /* type is int */
- SPEC_SCLS(val->type) = S_LITERAL;/* will remain literal */
-
- switch (ctype)
- {
- case '<' :
- SPEC_CVAL(val->type).v_int = floatFromVal(lval) < floatFromVal(rval);
- break ;
-
- case '>' :
- SPEC_CVAL(val->type).v_int = floatFromVal(lval) > floatFromVal(rval);
- break ;
-
- case LE_OP :
- SPEC_CVAL(val->type).v_int = floatFromVal(lval) <= floatFromVal(rval);
- break ;
-
- case GE_OP :
- SPEC_CVAL(val->type).v_int = floatFromVal(lval) >= floatFromVal(rval);
- break ;
-
- case EQ_OP :
- SPEC_CVAL(val->type).v_int = floatFromVal(lval) == floatFromVal(rval);
- break ;
+ value *val;
+
+ /* create a new value */
+ val = newValue ();
+ val->type = val->etype = newCharLink ();
+ val->type->class = SPECIFIER;
+ SPEC_NOUN (val->type) = V_CHAR; /* type is char */
+ SPEC_USIGN (val->type) = 1;
+ SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */
+
+ switch (ctype)
+ {
+ case '<':
+ SPEC_CVAL (val->type).v_int = floatFromVal (lval) < floatFromVal (rval);
+ break;
+
+ case '>':
+ SPEC_CVAL (val->type).v_int = floatFromVal (lval) > floatFromVal (rval);
+ break;
+
+ case LE_OP:
+ SPEC_CVAL (val->type).v_int = floatFromVal (lval) <= floatFromVal (rval);
+ break;
+
+ case GE_OP:
+ SPEC_CVAL (val->type).v_int = floatFromVal (lval) >= floatFromVal (rval);
+ break;
+
+ case EQ_OP:
+ if (SPEC_NOUN(lval->type) == V_FLOAT ||
+ SPEC_NOUN(rval->type) == V_FLOAT)
+ {
+ SPEC_CVAL (val->type).v_int = floatFromVal (lval) == floatFromVal (rval);
+ }
+ else
+ {
+ /* integrals: ignore signedness */
+ TYPE_UDWORD l, r;
+
+ l = (TYPE_UDWORD) floatFromVal (lval);
+ r = (TYPE_UDWORD) floatFromVal (rval);
+ /* In order to correctly compare 'signed int' and 'unsigned int' it's
+ neccessary to strip them to 16 bit.
+ Literals are reduced to their cheapest type, therefore left and
+ right might have different types. It's neccessary to find a
+ common type: int (used for char too) or long */
+ if (!IS_LONG (lval->etype) &&
+ !IS_LONG (rval->etype))
+ {
+ r = (TYPE_UWORD) r;
+ l = (TYPE_UWORD) l;
+ }
+ SPEC_CVAL (val->type).v_int = l == r;
+ }
+ break;
+ case NE_OP:
+ if (SPEC_NOUN(lval->type) == V_FLOAT ||
+ SPEC_NOUN(rval->type) == V_FLOAT)
+ {
+ SPEC_CVAL (val->type).v_int = floatFromVal (lval) != floatFromVal (rval);
+ }
+ else
+ {
+ /* integrals: ignore signedness */
+ TYPE_UDWORD l, r;
+
+ l = (TYPE_UDWORD) floatFromVal (lval);
+ r = (TYPE_UDWORD) floatFromVal (rval);
+ /* In order to correctly compare 'signed int' and 'unsigned int' it's
+ neccessary to strip them to 16 bit.
+ Literals are reduced to their cheapest type, therefore left and
+ right might have different types. It's neccessary to find a
+ common type: int (used for char too) or long */
+ if (!IS_LONG (lval->etype) &&
+ !IS_LONG (rval->etype))
+ {
+ r = (TYPE_UWORD) r;
+ l = (TYPE_UWORD) l;
+ }
+ SPEC_CVAL (val->type).v_int = l != r;
+ }
+ break;