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
This commit is contained in:
zik.saleeba 2009-10-25 11:54:34 +00:00
parent 8c7434424d
commit c6d483ee6f
5 changed files with 140 additions and 68 deletions

View file

@ -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
}
}

View file

@ -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);
}

23
picoc.h
View file

@ -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();

View file

@ -1,7 +1,7 @@
1
8
64
255
-1
1
14
16

27
type.c
View file

@ -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