From c6d483ee6f67edbc706bc18bad73896df6548796 Mon Sep 17 00:00:00 2001 From: "zik.saleeba" Date: Sun, 25 Oct 2009 11:54:34 +0000 Subject: [PATCH] Unsigned types now exist. They're probably not handled quite correctly in expressions yet though. git-svn-id: http://picoc.googlecode.com/svn/trunk@345 21eae674-98b7-11dd-bd71-f92a316d2d60 --- clibrary.c | 41 +++++----- expression.c | 115 ++++++++++++++++++++-------- picoc.h | 23 +++--- tests/26_character_constants.expect | 2 +- type.c | 27 +++++-- 5 files changed, 140 insertions(+), 68 deletions(-) diff --git a/clibrary.c b/clibrary.c index d45ce6a..8337453 100644 --- a/clibrary.c +++ b/clibrary.c @@ -157,21 +157,24 @@ void PrintType(struct ValueType *Typ, struct OutputStream *Stream) { switch (Typ->Base) { - case TypeVoid: PrintStr("void", Stream); break; - case TypeInt: PrintStr("int", Stream); break; - case TypeShort: PrintStr("short", Stream); break; - case TypeChar: PrintStr("char", Stream); break; + case TypeVoid: PrintStr("void", Stream); break; + case TypeInt: PrintStr("int", Stream); break; + case TypeShort: PrintStr("short", Stream); break; + case TypeChar: PrintStr("char", Stream); break; + case TypeUnsignedInt: PrintStr("unsigned int", Stream); break; + case TypeUnsignedShort: PrintStr("unsigned short", Stream); break; + case TypeUnsignedChar: PrintStr("unsigned char", Stream); break; #ifndef NO_FP - case TypeFP: PrintStr("double", Stream); break; + case TypeFP: PrintStr("double", Stream); break; #endif - case TypeFunction: PrintStr("function", Stream); break; - case TypeMacro: PrintStr("macro", Stream); break; - case TypePointer: if (Typ->FromType) PrintType(Typ->FromType, Stream); PrintCh('*', Stream); break; - case TypeArray: PrintType(Typ->FromType, Stream); PrintCh('[', Stream); if (Typ->ArraySize != 0) PrintInt(Typ->ArraySize, 0, FALSE, FALSE, Stream); PrintCh(']', Stream); break; - case TypeStruct: PrintStr("struct ", Stream); PrintStr(Typ->Identifier, Stream); break; - case TypeUnion: PrintStr("union ", Stream); PrintStr(Typ->Identifier, Stream); break; - case TypeEnum: PrintStr("enum ", Stream); PrintStr(Typ->Identifier, Stream); break; - case Type_Type: PrintStr("type ", Stream); break; + case TypeFunction: PrintStr("function", Stream); break; + case TypeMacro: PrintStr("macro", Stream); break; + case TypePointer: if (Typ->FromType) PrintType(Typ->FromType, Stream); PrintCh('*', Stream); break; + case TypeArray: PrintType(Typ->FromType, Stream); PrintCh('[', Stream); if (Typ->ArraySize != 0) PrintInt(Typ->ArraySize, 0, FALSE, FALSE, Stream); PrintCh(']', Stream); break; + case TypeStruct: PrintStr("struct ", Stream); PrintStr(Typ->Identifier, Stream); break; + case TypeUnion: PrintStr("union ", Stream); PrintStr(Typ->Identifier, Stream); break; + case TypeEnum: PrintStr("enum ", Stream); PrintStr(Typ->Identifier, Stream); break; + case Type_Type: PrintStr("type ", Stream); break; } } @@ -273,13 +276,13 @@ void GenericPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct PrintStr(Str, Stream); break; } - case 'd': PrintInt(COERCE_INTEGER(NextArg), FieldWidth, ZeroPad, LeftJustify, Stream); break; - case 'u': PrintUnsigned((unsigned int)COERCE_INTEGER(NextArg), 10, FieldWidth, ZeroPad, LeftJustify, Stream); break; - case 'x': PrintUnsigned((unsigned int)COERCE_INTEGER(NextArg), 16, FieldWidth, ZeroPad, LeftJustify, Stream); break; - case 'b': PrintUnsigned((unsigned int)COERCE_INTEGER(NextArg), 2, FieldWidth, ZeroPad, LeftJustify, Stream); break; - case 'c': PrintCh(COERCE_INTEGER(NextArg), Stream); break; + case 'd': PrintInt(ExpressionCoerceInteger(NextArg), FieldWidth, ZeroPad, LeftJustify, Stream); break; + case 'u': PrintUnsigned((unsigned int)ExpressionCoerceInteger(NextArg), 10, FieldWidth, ZeroPad, LeftJustify, Stream); break; + case 'x': PrintUnsigned((unsigned int)ExpressionCoerceInteger(NextArg), 16, FieldWidth, ZeroPad, LeftJustify, Stream); break; + case 'b': PrintUnsigned((unsigned int)ExpressionCoerceInteger(NextArg), 2, FieldWidth, ZeroPad, LeftJustify, Stream); break; + case 'c': PrintCh(ExpressionCoerceInteger(NextArg), Stream); break; #ifndef NO_FP - case 'f': PrintFP(COERCE_FP(NextArg), Stream); break; + case 'f': PrintFP(ExpressionCoerceFP(NextArg), Stream); break; #endif } } diff --git a/expression.c b/expression.c index 523981f..dd2ca3f 100644 --- a/expression.c +++ b/expression.c @@ -127,6 +127,69 @@ void ExpressionStackShow(struct ExpressionStack *StackTop) } #endif +int ExpressionCoerceInteger(struct Value *Val) +{ + switch (Val->Typ->Base) + { + case TypeInt: return (int)Val->Val->Integer; + case TypeChar: return (int)Val->Val->Character; + case TypeShort: return (int)Val->Val->ShortInteger; + case TypeUnsignedInt: return (int)Val->Val->UnsignedInteger; + case TypeUnsignedChar: return (int)Val->Val->UnsignedCharacter; + case TypeUnsignedShort: return (int)Val->Val->UnsignedShortInteger; + case TypePointer: +#ifdef NATIVE_POINTERS + return (int)Val->Val->NativePointer; +#else + return 0; +#endif +#ifndef NO_FP + case TypeFP: return (int)Val->Val->FP; +#endif + default: return 0; + } +} + +unsigned int ExpressionCoerceUnsignedInteger(struct Value *Val) +{ + switch (Val->Typ->Base) + { + case TypeInt: return (unsigned int)Val->Val->Integer; + case TypeChar: return (unsigned int)Val->Val->Character; + case TypeShort: return (unsigned int)Val->Val->ShortInteger; + case TypeUnsignedInt: return (unsigned int)Val->Val->UnsignedInteger; + case TypeUnsignedChar: return (unsigned int)Val->Val->UnsignedCharacter; + case TypeUnsignedShort: return (unsigned int)Val->Val->UnsignedShortInteger; + case TypePointer: +#ifdef NATIVE_POINTERS + return (unsigned int)Val->Val->NativePointer; +#else + return 0; +#endif +#ifndef NO_FP + case TypeFP: return (unsigned int)Val->Val->FP; +#endif + default: return 0; + } +} + +#ifdef NATIVE_POINTERS +double ExpressionCoerceFP(struct Value *Val) +{ + switch (Val->Typ->Base) + { + case TypeInt: return (double)Val->Val->Integer; + case TypeChar: return (double)Val->Val->Character; + case TypeShort: return (double)Val->Val->ShortInteger; + case TypeUnsignedInt: return (double)Val->Val->UnsignedInteger; + case TypeUnsignedChar: return (double)Val->Val->UnsignedCharacter; + case TypeUnsignedShort: return (double)Val->Val->UnsignedShortInteger; + case TypeFP: return (double)Val->Val->FP; + default: return 0; + } +} +#endif + /* assign an integer value */ int ExpressionAssignInt(struct ParseState *Parser, struct Value *DestValue, int FromInt, int After) { @@ -262,7 +325,7 @@ void ExpressionAssignToPointer(struct ParseState *Parser, struct Value *ToValue, ToValue->Val->NativePointer = VariableDereferencePointer(Parser, FromValue, NULL, NULL, NULL, NULL); #endif } - else if (IS_NUMERIC_COERCIBLE(FromValue) && COERCE_INTEGER(FromValue) == 0) + else if (IS_NUMERIC_COERCIBLE(FromValue) && ExpressionCoerceInteger(FromValue) == 0) { /* null pointer assignment */ #ifndef NATIVE_POINTERS @@ -276,7 +339,7 @@ void ExpressionAssignToPointer(struct ParseState *Parser, struct Value *ToValue, else if (AllowPointerCoercion && IS_NUMERIC_COERCIBLE(FromValue)) { /* assign integer to native pointer */ - ToValue->Val->NativePointer = (void *)COERCE_INTEGER(FromValue); + ToValue->Val->NativePointer = (void *)ExpressionCoerceUnsignedInteger(FromValue); } #endif else @@ -289,34 +352,24 @@ void ExpressionAssign(struct ParseState *Parser, struct Value *DestValue, struct if (!DestValue->IsLValue && !Force) AssignFail(Parser, "not an lvalue", NULL, NULL, 0, 0, FuncName, ParamNo); + if (IS_NUMERIC_COERCIBLE(DestValue) && !IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion)) + AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo); + switch (DestValue->Typ->Base) { - case TypeInt: - 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 TypeInt: DestValue->Val->Integer = ExpressionCoerceInteger(SourceValue); break; + case TypeShort: DestValue->Val->ShortInteger = ExpressionCoerceInteger(SourceValue); break; + case TypeChar: DestValue->Val->Character = ExpressionCoerceInteger(SourceValue); break; + case TypeUnsignedInt: DestValue->Val->UnsignedInteger = ExpressionCoerceUnsignedInteger(SourceValue); break; + case TypeUnsignedShort: DestValue->Val->UnsignedShortInteger = ExpressionCoerceUnsignedInteger(SourceValue); break; + case TypeUnsignedChar: DestValue->Val->UnsignedCharacter = ExpressionCoerceUnsignedInteger(SourceValue); break; - case TypeShort: - if (!IS_NUMERIC_COERCIBLE_PLUS_POINTERS(SourceValue, AllowPointerCoercion)) - AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo); - - DestValue->Val->ShortInteger = COERCE_INTEGER(SourceValue); - break; - - case TypeChar: - 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_PLUS_POINTERS(SourceValue, AllowPointerCoercion)) AssignFail(Parser, "%t from %t", DestValue->Typ, SourceValue->Typ, 0, 0, FuncName, ParamNo); - DestValue->Val->FP = COERCE_FP(SourceValue); + DestValue->Val->FP = ExpressionCoerceFP(SourceValue); break; #endif case TypePointer: @@ -434,7 +487,7 @@ void ExpressionPrefixOperator(struct ParseState *Parser, struct ExpressionStack { /* integer prefix arithmetic */ int ResultInt = 0; - int TopInt = COERCE_INTEGER(TopValue); + int TopInt = ExpressionCoerceInteger(TopValue); switch (Op) { case TokenPlus: ResultInt = TopInt; break; @@ -513,7 +566,7 @@ void ExpressionPostfixOperator(struct ParseState *Parser, struct ExpressionStack if (IS_NUMERIC_COERCIBLE(TopValue)) { int ResultInt = 0; - int TopInt = COERCE_INTEGER(TopValue); + int TopInt = ExpressionCoerceInteger(TopValue); switch (Op) { case TokenIncrement: ResultInt = ExpressionAssignInt(Parser, TopValue, TopInt+1, TRUE); break; @@ -609,7 +662,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * if (!IS_NUMERIC_COERCIBLE(TopValue)) ProgramFail(Parser, "array index must be an integer"); - ArrayIndex = COERCE_INTEGER(TopValue); + ArrayIndex = ExpressionCoerceInteger(TopValue); #ifndef NATIVE_POINTERS if (ArrayIndex < 0 || ArrayIndex >= BottomValue->Val->Array.Size) ProgramFail(Parser, "illegal array index %d [0..%d]", ArrayIndex, BottomValue->Val->Array.Size-1); @@ -627,8 +680,8 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * /* floating point infix arithmetic */ int ResultIsInt = FALSE; double ResultFP = 0.0; - double TopFP = (TopValue->Typ == &FPType) ? TopValue->Val->FP : (double)COERCE_INTEGER(TopValue); - double BottomFP = (BottomValue->Typ == &FPType) ? BottomValue->Val->FP : (double)COERCE_INTEGER(BottomValue); + double TopFP = (TopValue->Typ == &FPType) ? TopValue->Val->FP : (double)ExpressionCoerceInteger(TopValue); + double BottomFP = (BottomValue->Typ == &FPType) ? BottomValue->Val->FP : (double)ExpressionCoerceInteger(BottomValue); switch (Op) { @@ -659,8 +712,8 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * else if (IS_NUMERIC_COERCIBLE(TopValue) && IS_NUMERIC_COERCIBLE(BottomValue)) { /* integer operation */ - int TopInt = COERCE_INTEGER(TopValue); - int BottomInt = COERCE_INTEGER(BottomValue); + int TopInt = ExpressionCoerceInteger(TopValue); + int BottomInt = ExpressionCoerceInteger(BottomValue); switch (Op) { case TokenAssign: ResultInt = ExpressionAssignInt(Parser, BottomValue, TopInt, FALSE); break; @@ -706,7 +759,7 @@ void ExpressionInfixOperator(struct ParseState *Parser, struct ExpressionStack * else if (BottomValue->Typ->Base == TypePointer && IS_NUMERIC_COERCIBLE(TopValue)) { /* pointer/integer infix arithmetic */ - int TopInt = COERCE_INTEGER(TopValue); + int TopInt = ExpressionCoerceInteger(TopValue); if (Op == TokenEqual || Op == TokenNotEqual) { @@ -1292,7 +1345,7 @@ int ExpressionParseInt(struct ParseState *Parser) if (!IS_NUMERIC_COERCIBLE(Val)) ProgramFail(Parser, "integer value expected instead of %t", Val->Typ); - Result = COERCE_INTEGER(Val); + Result = ExpressionCoerceInteger(Val); VariableStackPop(Parser, Val); } diff --git a/picoc.h b/picoc.h index a6bad68..0215d13 100644 --- a/picoc.h +++ b/picoc.h @@ -47,14 +47,6 @@ #define IS_INTEGER_NUMERIC(v) ((v)->Typ->Base == TypeInt || (v)->Typ->Base == TypeChar || (v)->Typ->Base == TypeShort) #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 == TypeShort) ? (int)(v)->Val->ShortInteger : \ - (((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 : \ - (((v)->Typ->Base == TypeShort) ? (double)(v)->Val->ShortInteger : POINTER_COERCE(v))))) struct Table; @@ -128,10 +120,13 @@ enum BaseType TypeVoid, /* no type */ TypeInt, /* integer */ TypeShort, /* short integer */ + TypeChar, /* a single character */ + TypeUnsignedInt, /* unsigned integer */ + TypeUnsignedShort, /* unsigned short integer */ + TypeUnsignedChar, /* a single unsigned character */ #ifndef NO_FP TypeFP, /* floating point */ #endif - TypeChar, /* a single character */ TypeFunction, /* a function */ TypeMacro, /* a macro */ TypePointer, /* a pointer */ @@ -187,9 +182,12 @@ struct PointerValue union AnyValue { - unsigned char Character; + char Character; short ShortInteger; int Integer; + unsigned char UnsignedCharacter; + unsigned short UnsignedShortInteger; + unsigned int UnsignedInteger; char *Identifier; struct ArrayValue Array; struct ParseState Parser; @@ -357,6 +355,11 @@ void ParserCopyPos(struct ParseState *To, struct ParseState *From); 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, int AllowPointerCoercion); +int ExpressionCoerceInteger(struct Value *Val); +unsigned int ExpressionCoerceUnsignedInteger(struct Value *Val); +#ifndef NO_FP +double ExpressionCoerceFP(struct Value *Val); +#endif /* type.c */ void TypeInit(); diff --git a/tests/26_character_constants.expect b/tests/26_character_constants.expect index a4fdf01..c34b6b0 100644 --- a/tests/26_character_constants.expect +++ b/tests/26_character_constants.expect @@ -1,7 +1,7 @@ 1 8 64 -255 +-1 1 14 16 diff --git a/type.c b/type.c index 585edde..1e3c4af 100644 --- a/type.c +++ b/type.c @@ -5,6 +5,9 @@ struct ValueType UberType; struct ValueType IntType; struct ValueType ShortType; struct ValueType CharType; +struct ValueType UnsignedIntType; +struct ValueType UnsignedShortType; +struct ValueType UnsignedCharType; #ifndef NO_FP struct ValueType FPType; #endif @@ -134,6 +137,9 @@ void TypeInit() TypeAddBaseType(&IntType, TypeInt, sizeof(int)); TypeAddBaseType(&ShortType, TypeShort, sizeof(short)); TypeAddBaseType(&CharType, TypeChar, sizeof(char)); + TypeAddBaseType(&UnsignedIntType, TypeUnsignedInt, sizeof(unsigned int)); + TypeAddBaseType(&UnsignedShortType, TypeUnsignedShort, sizeof(unsigned short)); + TypeAddBaseType(&UnsignedCharType, TypeUnsignedChar, sizeof(unsigned char)); TypeAddBaseType(&VoidType, TypeVoid, 0); TypeAddBaseType(&FunctionType, TypeFunction, sizeof(int)); TypeAddBaseType(&MacroType, TypeMacro, sizeof(int)); @@ -309,15 +315,22 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ) { struct ParseState Before = *Parser; enum LexToken Token = LexGetToken(Parser, NULL, TRUE); + int Unsigned = FALSE; *Typ = NULL; - /* just ignore signed/unsigned for now */ + /* handle signed/unsigned with no trailing type */ if (Token == TokenSignedType || Token == TokenUnsignedType) { - Token = LexGetToken(Parser, NULL, FALSE); - if (Token != TokenIntType && Token != TokenLongType && Token != TokenShortType && Token != TokenCharType) + enum LexToken FollowToken = LexGetToken(Parser, NULL, FALSE); + Unsigned = (Token == TokenUnsignedType); + + if (FollowToken != TokenIntType && FollowToken != TokenLongType && FollowToken != TokenShortType && FollowToken != TokenCharType) { - *Typ = &IntType; + if (Token == TokenUnsignedType) + *Typ = &UnsignedIntType; + else + *Typ = &IntType; + return TRUE; } @@ -326,9 +339,9 @@ int TypeParseFront(struct ParseState *Parser, struct ValueType **Typ) switch (Token) { - case TokenIntType: case TokenLongType: case TokenSignedType: case TokenUnsignedType: *Typ = &IntType; break; - case TokenShortType: *Typ = &ShortType; break; - case TokenCharType: *Typ = &CharType; break; + case TokenIntType: case TokenLongType: case TokenSignedType: case TokenUnsignedType: *Typ = Unsigned ? &UnsignedIntType : &IntType; break; + case TokenShortType: *Typ = Unsigned ? &UnsignedShortType : &ShortType; break; + case TokenCharType: *Typ = Unsigned ? &UnsignedCharType : &CharType; break; #ifndef NO_FP case TokenFloatType: case TokenDoubleType: *Typ = &FPType; break; #endif