From 8e735ef68f7b3c2776760cbbea58cee307dfcd22 Mon Sep 17 00:00:00 2001 From: "zik.saleeba" Date: Sat, 10 Oct 2009 17:59:55 +0000 Subject: [PATCH] First cut of casts completed but not debugged git-svn-id: http://picoc.googlecode.com/svn/trunk@338 21eae674-98b7-11dd-bd71-f92a316d2d60 --- expression.c | 43 +++++++++++++++++++++++-------------------- parse.c | 4 ++-- picoc.h | 25 +++++++++++++++++++------ type.c | 10 ++++++---- 4 files changed, 50 insertions(+), 32 deletions(-) diff --git a/expression.c b/expression.c index d96af4d..4d5600e 100644 --- a/expression.c +++ b/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 diff --git a/parse.c b/parse.c index e9f861a..646b71c 100644 --- a/parse.c +++ b/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); } diff --git a/picoc.h b/picoc.h index 1fa94fa..82fa38d 100644 --- a/picoc.h +++ b/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(); diff --git a/type.c b/type.c index d069c31..9515826 100644 --- a/type.c +++ b/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));