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:
parent
7d135bbdd5
commit
8e735ef68f
43
expression.c
43
expression.c
|
@ -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
|
||||
|
|
4
parse.c
4
parse.c
|
@ -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
25
picoc.h
|
@ -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
10
type.c
|
@ -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));
|
||||
|
|
Loading…
Reference in a new issue