First cut of casts completed but not debugged

git-svn-id: http://picoc.googlecode.com/svn/trunk@338 21eae674-98b7-11dd-bd71-f92a316d2d60
This commit is contained in:
zik.saleeba 2009-10-10 17:59:55 +00:00
parent 7d135bbdd5
commit 8e735ef68f
4 changed files with 50 additions and 32 deletions

View file

@ -211,13 +211,6 @@ void ExpressionPushInt(struct ParseState *Parser, struct ExpressionStack **Stack
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
}
void ExpressionPushType(struct ParseState *Parser, struct ExpressionStack **StackTop, struct ValueType *TypeValue)
{
struct Value *ValueLoc = VariableAllocValueFromType(Parser, &TypeType, FALSE, NULL, FALSE);
ValueLoc->Val->Typ = TypeValue;
ExpressionStackPushValueNode(Parser, StackTop, ValueLoc);
}
#ifndef NO_FP
void ExpressionPushFP(struct ParseState *Parser, struct ExpressionStack **StackTop, double FPValue)
{
@ -227,8 +220,8 @@ void ExpressionPushFP(struct ParseState *Parser, struct ExpressionStack **StackT
}
#endif
/* assign to a pointer, leaving a value on the expression stack */
void ExpressionAssignToPointer(struct ParseState *Parser, struct Value *ToValue, struct Value *FromValue, const char *FuncName, int ParamNo)
/* assign to a pointer */
void ExpressionAssignToPointer(struct ParseState *Parser, struct Value *ToValue, struct Value *FromValue, const char *FuncName, int ParamNo, int AllowPointerCoercion)
{
struct ValueType *PointedToType = ToValue->Typ->FromType;
#ifndef NATIVE_POINTERS
@ -277,12 +270,19 @@ void ExpressionAssignToPointer(struct ParseState *Parser, struct Value *ToValue,
ToValue->Val->NativePointer = NULL;
#endif
}
#ifdef NATIVE_POINTERS
else if (AllowPointerCoercion && IS_NUMERIC_COERCIBLE(FromValue))
{
/* assign integer to native pointer */
ToValue->Val->NativePointer = COERCE_INTEGER(FromValue);
}
#endif
else
AssignFail(Parser, "%t from %t", ToValue->Typ, FromValue->Typ, 0, 0, FuncName, ParamNo);
}
/* assign any kind of value */
void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct Value *SourceValue, int Force, const char *FuncName, int ParamNo)
void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct Value *SourceValue, int Force, const char *FuncName, int ParamNo, int AllowPointerCoercion)
{
if (!DestValue->IsLValue && !Force)
AssignFail(Parser, "not an lvalue", NULL, NULL, 0, 0, FuncName, ParamNo);
@ -290,28 +290,28 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct
switch (DestValue->Typ->Base)
{
case TypeInt:
if (!IS_NUMERIC_COERCIBLE(SourceValue))
if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion))
AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo);
DestValue->Val->Integer = COERCE_INTEGER(SourceValue);
break;
case TypeChar:
if (!IS_NUMERIC_COERCIBLE(SourceValue))
if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion))
AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo);
DestValue->Val->Character = COERCE_INTEGER(SourceValue);
break;
#ifndef NO_FP
case TypeFP:
if (!IS_NUMERIC_COERCIBLE(SourceValue))
if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion))
AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo);
DestValue->Val->FP = COERCE_FP(SourceValue);
break;
#endif
case TypePointer:
ExpressionAssignToPointer(Parser, DestValue, SourceValue, FuncName, ParamNo);
ExpressionAssignToPointer(Parser, DestValue, SourceValue, FuncName, ParamNo, AllowPointerCoercion);
break;
case TypeArray:
@ -744,7 +744,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
{
/* assign a NULL pointer */
HeapUnpopStack(sizeof(struct Value)); /* XXX - possible bug if lvalue is a temp value and takes more than sizeof(struct Value) */
ExpressionAssign(Parser, BottomValue, TopValue, FALSE, NULL, 0);
ExpressionAssign(Parser, BottomValue, TopValue, FALSE, NULL, 0, FALSE);
ExpressionStackPushValueNode(Parser, StackTop, BottomValue);
}
else
@ -773,13 +773,14 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack *
{
/* assign a non-numeric type */
HeapUnpopStack(sizeof(struct Value)); /* XXX - possible bug if lvalue is a temp value and takes more than sizeof(struct Value) */
ExpressionAssign(Parser, BottomValue, TopValue, FALSE, NULL, 0);
ExpressionAssign(Parser, BottomValue, TopValue, FALSE, NULL, 0, FALSE);
ExpressionStackPushValueNode(Parser, StackTop, BottomValue);
}
else if (Op == TokenCast)
{
/* cast a value to a different type */
printf("do a cast\n");
/* cast a value to a different type */ /* XXX - possible bug if the destination type takes more than sizeof(struct Value) + sizeof(struct ValueType *) */
struct Value *ValueLoc = ExpressionStackPushValueByType(Parser, StackTop, BottomValue->Val->Typ);
ExpressionAssign(Parser, ValueLoc, TopValue, TRUE, NULL, 0, TRUE);
}
else
ProgramFail(Parser, "invalid operation");
@ -979,7 +980,9 @@ int ExpressionParse(struct ParseState *Parser, struct Value **Result)
Precedence = BracketPrecedence + OperatorPrecedence[(int)TokenCast].PrefixPrecedence;
ExpressionStackCollapse(Parser, &StackTop, Precedence);
ExpressionPushType(Parser, &StackTop, CastType);
CastTypeValue = VariableAllocValueFromType(Parser, &TypeType, FALSE, NULL, FALSE);
CastTypeValue->Val->Typ = CastType;
ExpressionStackPushValueNode(Parser, &StackTop, CastTypeValue);
ExpressionStackPushOperator(Parser, &StackTop, OrderInfix, TokenCast, Precedence);
}
else
@ -1179,7 +1182,7 @@ void ExpressionParseFunctionCall(struct ParseState *Parser, struct ExpressionSta
{
if (ArgCount < FuncValue->Val->FuncDef.NumParams)
{
ExpressionAssign(Parser, ParamArray[ArgCount], Param, TRUE, FuncName, ArgCount+1);
ExpressionAssign(Parser, ParamArray[ArgCount], Param, TRUE, FuncName, ArgCount+1, FALSE);
VariableStackPop(Parser, Param);
}
else

View file

@ -149,7 +149,7 @@ int ParseDeclaration(struct ParseState *Parser, enum LexToken Token)
if (Parser->Mode == RunModeRun)
{
ExpressionAssign(Parser, NewVariable, CValue, FALSE, NULL, 0);
ExpressionAssign(Parser, NewVariable, CValue, FALSE, NULL, 0, FALSE);
VariableStackPop(Parser, CValue);
}
}
@ -504,7 +504,7 @@ enum ParseResult ParseStatement(struct ParseState *Parser)
if (TopStackFrame->ReturnValue->Typ->Base != TypeVoid)
{
ExpressionAssign(Parser, TopStackFrame->ReturnValue, CValue, TRUE, NULL, 0);
ExpressionAssign(Parser, TopStackFrame->ReturnValue, CValue, TRUE, NULL, 0, FALSE);
VariableStackPop(Parser, CValue);
}

25
picoc.h
View file

@ -28,14 +28,27 @@
/* coercion of numeric types to other numeric types */
#ifndef NO_FP
#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) ? (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))
#define IS_FP(v) ((v)->Typ->Base == TypeFP)
#define FP_VAL(v) ((v)->Val->FP)
#else
#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 IS_FP(v) 0
#define FP_VAL(v) 0
#endif
#ifdef NATIVE_POINTERS
#define IS_POINTER_COERCIBLE(v, ap) ((ap) ? ((v)->Typ->Base == TypePointer) : 0)
#define POINTER_COERCE(v) ((int)(v)->Val->NativePointer)
#else
#define IS_POINTER_COERCIBLE(v, ap) 0
#define POINTER_COERCE(v) 0
#endif
#define IS_INTEGER_NUMERIC(v) ((v)->Typ->Base == TypeInt || (v)->Typ->Base == TypeChar)
#define IS_NUMERIC_COERCIBLE(v) (IS_INTEGER_NUMERIC(v) || IS_FP(v))
#define IS_NUMERIC_COERCIBLE_PLUS_POINTERS(v,ap) (IS_NUMERIC_COERCIBLE(v) || IS_POINTER_COERCIBLE(v,ap))
#define COERCE_INTEGER(v) (((v)->Typ->Base == TypeInt) ? (v)->Val->Integer : (((v)->Typ->Base == TypeChar) ? (int)(v)->Val->Character : (((v)->Typ->Base == TypePointer) ? POINTER_COERCE(v) : (int)FP_VAL(v))))
#define COERCE_FP(v) (((v)->Typ->Base == TypeFP) ? (v)->Val->FP : (((v)->Typ->Base == TypeInt) ? (double)(v)->Val->Integer : (((v)->Typ->Base == TypeChar) ? (double)(v)->Val->Character : POINTER_COERCE(v))))
struct Table;
@ -330,7 +343,7 @@ void ParserCopyPos(struct ParseState *To, struct ParseState *From);
/* expression.c */
int ExpressionParse(struct ParseState *Parser, struct Value **Result);
int ExpressionParseInt(struct ParseState *Parser);
void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct Value *SourceValue, int Force, const char *FuncName, int ParamNo);
void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct Value *SourceValue, int Force, const char *FuncName, int ParamNo, int AllowPointerCoercion);
/* type.c */
void TypeInit();

10
type.c
View file

@ -121,14 +121,16 @@ void TypeInit()
{
UberType.DerivedTypeList = NULL;
TypeAddBaseType(&IntType, TypeInt, sizeof(int));
#ifndef NO_FP
TypeAddBaseType(&FPType, TypeFP, sizeof(double));
#endif
TypeAddBaseType(&VoidType, TypeVoid, 0);
TypeAddBaseType(&TypeType, Type_Type, sizeof(struct ValueType *));
TypeAddBaseType(&FunctionType, TypeFunction, sizeof(int));
TypeAddBaseType(&MacroType, TypeMacro, sizeof(int));
TypeAddBaseType(&CharType, TypeChar, sizeof(char));
#ifndef NO_FP
TypeAddBaseType(&FPType, TypeFP, sizeof(double));
TypeAddBaseType(&TypeType, Type_Type, sizeof(double)); /* must be large enough to cast to a double */
#else
TypeAddBaseType(&TypeType, Type_Type, sizeof(struct ValueType *));
#endif
CharArrayType = TypeAdd(NULL, &CharType, TypeArray, 0, StrEmpty, sizeof(char));
#ifndef NATIVE_POINTERS
CharPtrType = TypeAdd(NULL, &CharType, TypePointer, 0, StrEmpty, sizeof(struct PointerValue));