/* given a parent type, get a matching derived type and make one if necessary. * Identifier should be registered with the shared string table. */ struct ValueType *TypeGetMatching(struct ParseState *Parser, struct ValueType *ParentType, enum BaseType Base, int ArraySize, const char *Identifier, int AllowDuplicates) { int Sizeof; int AlignBytes; struct ValueType *ThisType = ParentType->DerivedTypeList; while (ThisType != NULL && (ThisType->Base != Base || ThisType->ArraySize != ArraySize || ThisType->Identifier != Identifier)) ThisType = ThisType->Next; if (ThisType != NULL) { if (AllowDuplicates) return ThisType; else ProgramFail(Parser, "tipo de dato '%s' ya existe", Identifier); } switch (Base) { case TypePointer: Sizeof = sizeof(void *); AlignBytes = PointerAlignBytes; break; case TypeArray: Sizeof = ArraySize * ParentType->Sizeof; AlignBytes = ParentType->AlignBytes; break; case TypeEnum: Sizeof = sizeof(int); AlignBytes = IntAlignBytes; break; default: Sizeof = 0; AlignBytes = 0; break; /* structs and unions will get bigger when we add members to them */ } return TypeAdd(Parser, ParentType, Base, ArraySize, Identifier, Sizeof, AlignBytes); }
/* initialise the type system */ void TypeInit(Picoc *pc){ struct IntAlign { char x; int y; } ia; struct ShortAlign { char x; short y; } sa; struct CharAlign { char x; char y; } ca; struct LongAlign { char x; long y; } la; struct Int128Align{char x; __m128i y;} i128a; #ifndef NO_FP struct DoubleAlign { char x; double y; } da; struct LongDoubleAlign { char x; long double y; } lda; #endif struct PointerAlign { char x; void *y; } pa; IntAlignBytes = (char *)&ia.y - &ia.x; PointerAlignBytes = (char *)&pa.y - &pa.x; pc->UberType.DerivedTypeList = NULL; TypeAddBaseType(pc, &pc->IntType, TypeInt, sizeof(int), IntAlignBytes); TypeAddBaseType(pc, &pc->ShortType, TypeShort, sizeof(short), (char *)&sa.y - &sa.x); TypeAddBaseType(pc, &pc->CharType, TypeChar, sizeof(char), (char *)&ca.y - &ca.x); TypeAddBaseType(pc, &pc->LongType, TypeLong, sizeof(long), (char *)&la.y - &la.x); TypeAddBaseType(pc, &pc->Int128Type, TypeInt128, sizeof(__m128), (char *)&i128a.y - &i128a.x); TypeAddBaseType(pc, &pc->UnsignedIntType, TypeUnsignedInt, sizeof(unsigned int), IntAlignBytes); TypeAddBaseType(pc, &pc->UnsignedShortType, TypeUnsignedShort, sizeof(unsigned short), (char *)&sa.y - &sa.x); TypeAddBaseType(pc, &pc->UnsignedLongType, TypeUnsignedLong, sizeof(unsigned long), (char *)&la.y - &la.x); TypeAddBaseType(pc, &pc->UnsignedCharType, TypeUnsignedChar, sizeof(unsigned char), (char *)&ca.y - &ca.x); TypeAddBaseType(pc, &pc->VoidType, TypeVoid, 0, 1); TypeAddBaseType(pc, &pc->FunctionType, TypeFunction, sizeof(int), IntAlignBytes); TypeAddBaseType(pc, &pc->MacroType, TypeMacro, sizeof(int), IntAlignBytes); TypeAddBaseType(pc, &pc->GotoLabelType, TypeGotoLabel, 0, 1); #ifndef NO_FP TypeAddBaseType(pc, &pc->FP32Type, TypeFP32, sizeof(float), (char *)&la.y - &la.x); TypeAddBaseType(pc, &pc->FP64Type, TypeFP64, sizeof(double), (char *)&da.y - &da.x); TypeAddBaseType(pc, &pc->FP128Type, TypeFP128, sizeof(long double), (char *)&lda.y - &lda.x); TypeAddBaseType(pc, &pc->TypeType, Type_Type, sizeof(long double ), (char *)&lda.y - &lda.x); /* must be large enough to cast to a double */ #else TypeAddBaseType(pc, &pc->TypeType, Type_Type, sizeof(struct ValueType *), PointerAlignBytes); #endif pc->CharArrayType = TypeAdd(pc, NULL, &pc->CharType, TypeArray, 0, pc->StrEmpty, sizeof(char), (char *)&ca.y - &ca.x); pc->CharPtrType = TypeAdd(pc, NULL, &pc->CharType, TypePointer, 0, pc->StrEmpty, sizeof(void *), PointerAlignBytes); pc->CharPtrPtrType = TypeAdd(pc, NULL, pc->CharPtrType, TypePointer, 0, pc->StrEmpty, sizeof(void *), PointerAlignBytes); pc->VoidPtrType = TypeAdd(pc, NULL, &pc->VoidType, TypePointer, 0, pc->StrEmpty, sizeof(void *), PointerAlignBytes); }
/* initialise the type system */ void TypeInit() { struct IntAlign { char x; int y; } ia; struct ShortAlign { char x; short y; } sa; struct CharAlign { char x; char y; } ca; struct LongAlign { char x; long y; } la; #ifndef NO_FP struct DoubleAlign { char x; double y; } da; #endif struct PointerAlign { char x; void *y; } pa; IntAlignBytes = (char *)&ia.y - &ia.x; PointerAlignBytes = (char *)&pa.y - &pa.x; UberType.DerivedTypeList = NULL; TypeAddBaseType(&IntType, TypeInt, sizeof(int), IntAlignBytes); TypeAddBaseType(&ShortType, TypeShort, sizeof(short), (char *)&sa.y - &sa.x); TypeAddBaseType(&CharType, TypeChar, sizeof(unsigned char), (char *)&ca.y - &ca.x); TypeAddBaseType(&LongType, TypeLong, sizeof(long), (char *)&la.y - &la.x); TypeAddBaseType(&UnsignedIntType, TypeUnsignedInt, sizeof(unsigned int), IntAlignBytes); TypeAddBaseType(&UnsignedShortType, TypeUnsignedShort, sizeof(unsigned short), (char *)&sa.y - &sa.x); TypeAddBaseType(&UnsignedLongType, TypeUnsignedLong, sizeof(unsigned long), (char *)&la.y - &la.x); TypeAddBaseType(&VoidType, TypeVoid, 0, 1); TypeAddBaseType(&FunctionType, TypeFunction, sizeof(int), IntAlignBytes); TypeAddBaseType(&MacroType, TypeMacro, sizeof(int), IntAlignBytes); TypeAddBaseType(&GotoLabelType, TypeGotoLabel, 0, 1); #ifndef NO_FP TypeAddBaseType(&FPType, TypeFP, sizeof(double), (char *)&da.y - &da.x); TypeAddBaseType(&TypeType, Type_Type, sizeof(double), (char *)&da.y - &da.x); /* must be large enough to cast to a double */ #else TypeAddBaseType(&TypeType, Type_Type, sizeof(struct ValueType *), PointerAlignBytes); #endif CharArrayType = TypeAdd(NULL, &CharType, TypeArray, 0, StrEmpty, sizeof(char), (char *)&ca.y - &ca.x); CharPtrType = TypeAdd(NULL, &CharType, TypePointer, 0, StrEmpty, sizeof(void *), PointerAlignBytes); CharPtrPtrType = TypeAdd(NULL, CharPtrType, TypePointer, 0, StrEmpty, sizeof(void *), PointerAlignBytes); VoidPtrType = TypeAdd(NULL, &VoidType, TypePointer, 0, StrEmpty, sizeof(void *), PointerAlignBytes); }