1
0
mirror of https://github.com/cc65/cc65.git synced 2024-06-18 07:29:36 +00:00

Merge branch 'master' into fptest

# Conflicts:
#	src/cc65/expr.c
#	src/cc65/scanner.c
This commit is contained in:
mrdudz 2023-08-25 22:47:32 +02:00
commit 92d9e4fcd7
4 changed files with 68 additions and 11 deletions

View File

@ -807,6 +807,9 @@ and the one defined by the ISO standard:
<itemize>
<item> The datatypes "float" and "double" are not available.
Floating point constants may be used, though they will have to be
converted and stored into integer values.
Floating point arithmetic expressions are not supported.
<p>
<item> C Functions may pass and return structs (or unions) by value, but only
of 1, 2 or 4 byte sizes.

View File

@ -1913,6 +1913,7 @@ static void UnaryOp (ExprDesc* Expr)
/* Get the expression */
hie10 (Expr);
#if 0
/* We can only handle integer types */
if (!IsClassInt (Expr->Type)
&& !IsClassFloat (Expr->Type) /* FIXME: float */
@ -1949,9 +1950,48 @@ static void UnaryOp (ExprDesc* Expr)
/* Limit the calculated value to the range of its type */
LimitExprValue (Expr, 1);
#else
/* Check for a constant numeric expression */
if (ED_IsConstAbs (Expr)) {
if (IsClassFloat (Expr->Type)) {
switch (Tok) {
case TOK_MINUS: Expr->V.FVal = FP_D_Sub(FP_D_Make(0.0),Expr->V.FVal); break;
case TOK_PLUS: break;
case TOK_COMP: Error ("Unary ~ operator not valid for floating point constant"); break;
default: Internal ("Unexpected token: %d", Tok);
}
} else {
if (!IsClassInt (Expr->Type)) {
Error ("Constant argument must have integer or float type");
ED_MakeConstAbsInt (Expr, 1);
}
/* Value is numeric */
switch (Tok) {
case TOK_MINUS: Expr->IVal = -Expr->IVal; break;
case TOK_PLUS: break;
case TOK_COMP: Expr->IVal = ~Expr->IVal; break;
default: Internal ("Unexpected token: %d", Tok);
}
/* Adjust the type of the expression */
Expr->Type = IntPromotion (Expr->Type);
/* Limit the calculated value to the range of its type */
LimitExprValue (Expr, 1);
}
#endif
} else {
unsigned Flags;
#if 0
/* If not constant, we can only handle integer types */
if (!IsClassInt (Expr->Type)) {
Error ("Non-constant argument must have integer type");
ED_MakeConstAbsInt (Expr, 1);
}
#endif
/* Value is not constant */
LoadExpr (CF_NONE, Expr);

View File

@ -712,23 +712,21 @@ static void NumericConst (void)
/* Check for a fractional part and read it */
if (SB_Peek (&Src) == '.') {
Double Scale;
Double Scale, ScaleDigit;
/* Skip the dot */
SB_Skip (&Src);
/* Read fractional digits */
Scale = FP_D_Make (10.0);
ScaleDigit = FP_D_Div (FP_D_Make (1.0), FP_D_FromInt (Base));
Scale = ScaleDigit;
while (IsXDigit (SB_Peek (&Src)) && (DigitVal = HexVal (SB_Peek (&Src))) < Base) {
/* Get the value of this digit */
Double FracVal = FP_D_FromInt(0);
if (DigitVal != 0) {
FracVal = FP_D_Div (FP_D_FromInt (DigitVal), Scale);
}
Double FracVal = FP_D_Mul (FP_D_FromInt (DigitVal), Scale);
/* Add it to the float value */
FVal = FP_D_Add (FVal, FracVal);
/* Scale base */
Scale = FP_D_Mul (Scale, FP_D_FromInt (Base));
/* Adjust Scale for next digit */
Scale = FP_D_Mul (Scale, ScaleDigit);
/* Skip the digit */
SB_Skip (&Src);
}
@ -740,12 +738,15 @@ static void NumericConst (void)
unsigned Digits;
unsigned Exp;
int Sign;
/* Skip the exponent notifier */
SB_Skip (&Src);
/* Read an optional sign */
Sign = 0;
if (SB_Peek (&Src) == '-') {
Sign = 1;
SB_Skip (&Src);
} else if (SB_Peek (&Src) == '+') {
SB_Skip (&Src);
@ -775,9 +776,11 @@ static void NumericConst (void)
Warning ("Floating constant exponent is too large");
}
/* Scale the exponent and adjust the value accordingly */
/* Scale the exponent and adjust the value accordingly.
** Decimal exponents are base 10, hexadecimal exponents are base 2 (C99).
*/
if (Exp) {
FVal = FP_D_Mul (FVal, FP_D_Make (pow (10, Exp)));
FVal = FP_D_Mul (FVal, FP_D_Make (pow ((Base == 16) ? 2.0 : 10.0, (Sign ? -1.0 : 1.0) * Exp)));
}
}

View File

@ -151,6 +151,17 @@ static void DoConversion (ExprDesc* Expr, const Type* NewType, int Explicit)
}
/* FIXME: float --- end of new code */
/* If this is a floating point constant, convert to integer,
** and warn if precision is discarded.
*/
if (IsClassFloat (OldType) && IsClassInt (NewType)) {
long IVal = (long)Expr->V.FVal.V;
if ((Expr->V.FVal.V != FP_D_FromInt(IVal).V) && !Explicit) {
Warning ("Floating point constant (%f) converted to integer loses precision (%ld)",Expr->V.FVal.V,IVal);
}
Expr->IVal = IVal;
}
/* Check if the new datatype will have a smaller range. If it
** has a larger range, things are OK, since the value is
** internally already represented by a long.