Added type coercion to floating point from numeric types in parameters.

git-svn-id: http://picoc.googlecode.com/svn/trunk@295 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-05-27 05:03:48 +00:00
parent 83d6b9a6d3
commit 4949ad046a
3 changed files with 19 additions and 15 deletions

View file

@ -194,7 +194,7 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct
else else
{ {
NextArg = (struct Value *)((void *)NextArg + sizeof(struct Value) + TypeStackSizeValue(NextArg)); NextArg = (struct Value *)((void *)NextArg + sizeof(struct Value) + TypeStackSizeValue(NextArg));
if (NextArg->Typ != FormatType && !(FormatType == &IntType && IS_INTEGER_COERCIBLE(NextArg))) if (NextArg->Typ != FormatType && !(FormatType == &IntType && IS_NUMERIC_COERCIBLE(NextArg)))
PrintStr("XXX", Stream); /* bad type for format */ PrintStr("XXX", Stream); /* bad type for format */
else else
{ {

View file

@ -344,7 +344,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack
} }
else else
#endif #endif
if (IS_INTEGER_COERCIBLE(TopValue)) if (IS_NUMERIC_COERCIBLE(TopValue))
{ {
/* integer prefix arithmetic */ /* integer prefix arithmetic */
int ResultInt = 0; int ResultInt = 0;
@ -424,7 +424,7 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack
} }
debugf("ExpressionPostfixOperator()\n"); debugf("ExpressionPostfixOperator()\n");
if (IS_INTEGER_COERCIBLE(TopValue)) if (IS_NUMERIC_COERCIBLE(TopValue))
{ {
int ResultInt = 0; int ResultInt = 0;
int TopInt = COERCE_INTEGER(TopValue); int TopInt = COERCE_INTEGER(TopValue);
@ -520,7 +520,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
if (BottomValue->Typ->Base != TypeArray) if (BottomValue->Typ->Base != TypeArray)
ProgramFail(Parser, "this %t is not an array", BottomValue->Typ); ProgramFail(Parser, "this %t is not an array", BottomValue->Typ);
if (!IS_INTEGER_COERCIBLE(TopValue)) if (!IS_NUMERIC_COERCIBLE(TopValue))
ProgramFail(Parser, "array index must be an integer"); ProgramFail(Parser, "array index must be an integer");
ArrayIndex = COERCE_INTEGER(TopValue); ArrayIndex = COERCE_INTEGER(TopValue);
@ -534,8 +534,8 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
} }
#ifndef NO_FP #ifndef NO_FP
else if ( (TopValue->Typ == &FPType && BottomValue->Typ == &FPType) || else if ( (TopValue->Typ == &FPType && BottomValue->Typ == &FPType) ||
(TopValue->Typ == &FPType && IS_INTEGER_COERCIBLE(BottomValue)) || (TopValue->Typ == &FPType && IS_NUMERIC_COERCIBLE(BottomValue)) ||
(IS_INTEGER_COERCIBLE(TopValue) && BottomValue->Typ == &FPType) ) (IS_NUMERIC_COERCIBLE(TopValue) && BottomValue->Typ == &FPType) )
{ {
/* floating point infix arithmetic */ /* floating point infix arithmetic */
int ResultIsInt = FALSE; int ResultIsInt = FALSE;
@ -569,7 +569,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
ExpressionPushFP(Parser, StackTop, ResultFP); ExpressionPushFP(Parser, StackTop, ResultFP);
} }
#endif #endif
else if (IS_INTEGER_COERCIBLE(TopValue) && IS_INTEGER_COERCIBLE(BottomValue)) else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue))
{ {
/* integer operation */ /* integer operation */
int TopInt = COERCE_INTEGER(TopValue); int TopInt = COERCE_INTEGER(TopValue);
@ -616,7 +616,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
ExpressionPushInt(Parser, StackTop, ResultInt); ExpressionPushInt(Parser, StackTop, ResultInt);
} }
else if (BottomValue->Typ->Base == TypePointer && IS_INTEGER_COERCIBLE(TopValue)) else if (BottomValue->Typ->Base == TypePointer && IS_NUMERIC_COERCIBLE(TopValue))
{ {
/* pointer/integer infix arithmetic */ /* pointer/integer infix arithmetic */
int TopInt = COERCE_INTEGER(TopValue); int TopInt = COERCE_INTEGER(TopValue);
@ -1090,12 +1090,15 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
if (FuncValue->Val->FuncDef.ParamType[ArgCount] != Param->Typ) if (FuncValue->Val->FuncDef.ParamType[ArgCount] != Param->Typ)
{ {
/* parameter is the wrong type - can we coerce it to being the type we want? */ /* parameter is the wrong type - can we coerce it to being the type we want? */
if (FuncValue->Val->FuncDef.ParamType[ArgCount] == &IntType && IS_INTEGER_COERCIBLE(Param)) if (FuncValue->Val->FuncDef.ParamType[ArgCount] == &IntType && IS_NUMERIC_COERCIBLE(Param))
Param->Val->Integer = COERCE_INTEGER(Param); /* cast to int */ Param->Val->Integer = COERCE_INTEGER(Param); /* cast to int */
else if (FuncValue->Val->FuncDef.ParamType[ArgCount] == &CharType && IS_INTEGER_COERCIBLE(Param)) else if (FuncValue->Val->FuncDef.ParamType[ArgCount] == &CharType && IS_NUMERIC_COERCIBLE(Param))
Param->Val->Character = COERCE_INTEGER(Param); /* cast to char */ Param->Val->Character = COERCE_INTEGER(Param); /* cast to char */
#ifndef NO_FP
else if (FuncValue->Val->FuncDef.ParamType[ArgCount] == &FPType && IS_NUMERIC_COERCIBLE(Param))
Param->Val->FP = COERCE_FP(Param); /* cast to floating point */
#endif
else else
ProgramFail(Parser, "parameter %d to %s() is %t instead of %t", ArgCount+1, FuncName, Param->Typ, FuncValue->Val->FuncDef.ParamType[ArgCount]); ProgramFail(Parser, "parameter %d to %s() is %t instead of %t", ArgCount+1, FuncName, Param->Typ, FuncValue->Val->FuncDef.ParamType[ArgCount]);
@ -1164,7 +1167,7 @@ int ExpressionParseInt(struct ParseState *Parser)
if (Parser->Mode == RunModeRun) if (Parser->Mode == RunModeRun)
{ {
if (!IS_INTEGER_COERCIBLE(Val)) if (!IS_NUMERIC_COERCIBLE(Val))
ProgramFail(Parser, "integer value expected instead of %t", Val->Typ); ProgramFail(Parser, "integer value expected instead of %t", Val->Typ);
Result = COERCE_INTEGER(Val); Result = COERCE_INTEGER(Val);

View file

@ -28,10 +28,11 @@
/* coercion of numeric types to other numeric types */ /* coercion of numeric types to other numeric types */
#ifndef NO_FP #ifndef NO_FP
#define IS_INTEGER_COERCIBLE(v) ((v)->Typ->Base == TypeInt || (v)->Typ->Base == TypeFP || (v)->Typ->Base == TypeChar) #define IS_NUMERIC_COERCIBLE(v) ((v)->Typ->Base == TypeInt || (v)->Typ->Base == TypeFP || (v)->Typ->Base == TypeChar)
#define COERCE_INTEGER(v) (((v)->Typ->Base == TypeInt) ? (int)(v)->Val->Integer : (((v)->Typ->Base == TypeChar) ? (int)(v)->Val->Character : (v)->Val->FP)) #define COERCE_INTEGER(v) (((v)->Typ->Base == TypeInt) ? (v)->Val->Integer : (((v)->Typ->Base == TypeChar) ? (int)(v)->Val->Character : (int)(v)->Val->FP))
#define COERCE_FP(v) (((v)->Typ->Base == TypeInt) ? (double)(v)->Val->Integer : (((v)->Typ->Base == TypeChar) ? (double)(v)->Val->Character : (v)->Val->FP))
#else #else
#define IS_INTEGER_COERCIBLE(v) ((v)->Typ->Base == TypeInt || (v)->Typ->Base == TypeChar) #define IS_NUMERIC_COERCIBLE(v) ((v)->Typ->Base == TypeInt || (v)->Typ->Base == TypeChar)
#define COERCE_INTEGER(v) (((v)->Typ->Base == TypeChar) ? (int)(v)->Val->Character : (v)->Val->Integer) #define COERCE_INTEGER(v) (((v)->Typ->Base == TypeChar) ? (int)(v)->Val->Character : (v)->Val->Integer)
#endif #endif