mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-10 23:01:50 +00:00
- first stage of simplifying the type system.
Let's use inline checkers in PType instead of constantly having to do clumsy IsKindOf checks etc. Once complete this also means that the types can be taken out of the class hierarchy, freeing up some common names.
This commit is contained in:
parent
522ce59be2
commit
b2d944974e
16 changed files with 153 additions and 138 deletions
|
@ -205,7 +205,6 @@ void PClass::StaticInit ()
|
|||
{
|
||||
atterm (StaticShutdown);
|
||||
|
||||
StaticBootstrap();
|
||||
Namespaces.GlobalNamespace = Namespaces.NewNamespace(0);
|
||||
|
||||
FAutoSegIterator probe(CRegHead, CRegTail);
|
||||
|
@ -265,6 +264,7 @@ void PClass::StaticShutdown ()
|
|||
ClassDataAllocator.FreeAllBlocks();
|
||||
AllClasses.Clear();
|
||||
PClassActor::AllActorClasses.Clear();
|
||||
ClassMap.Clear();
|
||||
|
||||
FAutoSegIterator probe(CRegHead, CRegTail);
|
||||
|
||||
|
@ -276,16 +276,6 @@ void PClass::StaticShutdown ()
|
|||
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClass :: StaticBootstrap STATIC
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void PClass::StaticBootstrap()
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClass Constructor
|
||||
|
@ -363,7 +353,6 @@ void ClassReg::SetupClass(PClass *cls)
|
|||
cls->Size = SizeOf;
|
||||
cls->Pointers = Pointers;
|
||||
cls->ConstructNative = ConstructNative;
|
||||
//cls->mDescriptiveName.Format("Class<%s>", cls->TypeName.GetChars());
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -52,7 +52,6 @@ public:
|
|||
|
||||
static void StaticInit();
|
||||
static void StaticShutdown();
|
||||
static void StaticBootstrap();
|
||||
|
||||
// Per-class information -------------------------------------
|
||||
PClass *ParentClass = nullptr; // the class this class derives from
|
||||
|
|
|
@ -75,12 +75,12 @@ cycle_t ActionCycles;
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
class PActorInfo : public PBasicType
|
||||
class PActorInfo : public PCompoundType
|
||||
{
|
||||
DECLARE_CLASS(PActorInfo, PBasicType);
|
||||
DECLARE_CLASS(PActorInfo, PCompoundType);
|
||||
public:
|
||||
PActorInfo()
|
||||
:PBasicType(sizeof(FActorInfo), alignof(FActorInfo))
|
||||
:PCompoundType(sizeof(FActorInfo), alignof(FActorInfo))
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -424,7 +424,7 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
|
|||
}
|
||||
params.Push(f.GetIndex());
|
||||
}
|
||||
else if (args[i]->IsKindOf(RUNTIME_CLASS(PInt)))
|
||||
else if (args[i]->isIntCompatible())
|
||||
{
|
||||
char *endp;
|
||||
int v = (int)strtoll(sc.String, &endp, 0);
|
||||
|
@ -441,7 +441,7 @@ static void ParseListMenuBody(FScanner &sc, DListMenuDescriptor *desc)
|
|||
if (args[i] == TypeBool) v = !!v;
|
||||
params.Push(v);
|
||||
}
|
||||
else if (args[i]->IsKindOf(RUNTIME_CLASS(PFloat)))
|
||||
else if (args[i]->isFloat())
|
||||
{
|
||||
char *endp;
|
||||
double v = strtod(sc.String, &endp);
|
||||
|
@ -775,7 +775,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc)
|
|||
{
|
||||
params.Push(V_GetColor(nullptr, sc));
|
||||
}
|
||||
else if (args[i]->IsKindOf(RUNTIME_CLASS(PInt)))
|
||||
else if (args[i]->isIntCompatible())
|
||||
{
|
||||
char *endp;
|
||||
int v = (int)strtoll(sc.String, &endp, 0);
|
||||
|
@ -794,7 +794,7 @@ static void ParseOptionMenuBody(FScanner &sc, DOptionMenuDescriptor *desc)
|
|||
if (args[i] == TypeBool) v = !!v;
|
||||
params.Push(v);
|
||||
}
|
||||
else if (args[i]->IsKindOf(RUNTIME_CLASS(PFloat)))
|
||||
else if (args[i]->isFloat())
|
||||
{
|
||||
char *endp;
|
||||
double v = strtod(sc.String, &endp);
|
||||
|
|
|
@ -5040,12 +5040,11 @@ bool GetVarAddrType(AActor *self, FName varname, int index, void *&addr, PType *
|
|||
return false;
|
||||
}
|
||||
addr = baddr;
|
||||
// We don't want Int subclasses like Name or Color to be accessible,
|
||||
// but we do want to support Float subclasses like Fixed.
|
||||
if (!type->IsA(RUNTIME_CLASS(PInt)) && !type->IsKindOf(RUNTIME_CLASS(PFloat)))
|
||||
// We don't want Int subclasses like Name or Color to be accessible here.
|
||||
if (!type->isInt() && !type->isFloat())
|
||||
{
|
||||
// For reading, we also support Name and String types.
|
||||
if (readonly && (type->IsA(RUNTIME_CLASS(PName)) || type->IsA(RUNTIME_CLASS(PString))))
|
||||
if (readonly && (type == TypeName || type == TypeString))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -5061,7 +5060,7 @@ static void SetUserVariable(AActor *self, FName varname, int index, int value)
|
|||
|
||||
if (GetVarAddrType(self, varname, index, addr, type, false))
|
||||
{
|
||||
if (!type->IsKindOf(RUNTIME_CLASS(PFloat)))
|
||||
if (!type->isFloat())
|
||||
{
|
||||
type->SetValue(addr, value);
|
||||
}
|
||||
|
@ -5079,15 +5078,15 @@ static int GetUserVariable(AActor *self, FName varname, int index)
|
|||
|
||||
if (GetVarAddrType(self, varname, index, addr, type, true))
|
||||
{
|
||||
if (type->IsKindOf(RUNTIME_CLASS(PFloat)))
|
||||
if (type->isFloat())
|
||||
{
|
||||
return DoubleToACS(type->GetValueFloat(addr));
|
||||
}
|
||||
else if (type->IsA(RUNTIME_CLASS(PName)))
|
||||
else if (type == TypeName)
|
||||
{
|
||||
return GlobalACSStrings.AddString(FName(ENamedName(type->GetValueInt(addr))).GetChars());
|
||||
}
|
||||
else if (type->IsA(RUNTIME_CLASS(PString)))
|
||||
else if (type == TypeString)
|
||||
{
|
||||
return GlobalACSStrings.AddString(*(FString *)addr);
|
||||
}
|
||||
|
|
|
@ -4753,7 +4753,7 @@ static PField *GetVar(DObject *self, FName varname)
|
|||
{
|
||||
PField *var = dyn_cast<PField>(self->GetClass()->FindSymbol(varname, true));
|
||||
|
||||
if (var == NULL || (var->Flags & (VARF_Native | VARF_Private | VARF_Protected | VARF_Static)) || !var->Type->IsKindOf(RUNTIME_CLASS(PBasicType)))
|
||||
if (var == NULL || (var->Flags & (VARF_Native | VARF_Private | VARF_Protected | VARF_Static)) || !var->Type->isScalar())
|
||||
{
|
||||
Printf("%s is not a user variable in class %s\n", varname.GetChars(),
|
||||
self->GetClass()->TypeName.GetChars());
|
||||
|
@ -4803,8 +4803,7 @@ static PField *GetArrayVar(DObject *self, FName varname, int pos)
|
|||
PField *var = dyn_cast<PField>(self->GetClass()->FindSymbol(varname, true));
|
||||
|
||||
if (var == NULL || (var->Flags & (VARF_Native | VARF_Private | VARF_Protected | VARF_Static)) ||
|
||||
!var->Type->IsKindOf(RUNTIME_CLASS(PArray)) ||
|
||||
!static_cast<PArray *>(var->Type)->ElementType->IsKindOf(RUNTIME_CLASS(PBasicType)))
|
||||
!var->Type->IsKindOf(RUNTIME_CLASS(PArray)) || !static_cast<PArray *>(var->Type)->ElementType->isScalar())
|
||||
{
|
||||
Printf("%s is not a user array in class %s\n", varname.GetChars(),
|
||||
self->GetClass()->TypeName.GetChars());
|
||||
|
|
|
@ -1621,7 +1621,7 @@ static void SetMapThingUserData(AActor *actor, unsigned udi)
|
|||
|
||||
udi++;
|
||||
|
||||
if (var == NULL || (var->Flags & (VARF_Native|VARF_Private|VARF_Protected|VARF_Static)) || !var->Type->IsKindOf(RUNTIME_CLASS(PBasicType)))
|
||||
if (var == NULL || (var->Flags & (VARF_Native|VARF_Private|VARF_Protected|VARF_Static)) || !var->Type->isScalar())
|
||||
{
|
||||
DPrintf(DMSG_WARNING, "%s is not a user variable in class %s\n", varname.GetChars(),
|
||||
actor->GetClass()->TypeName.GetChars());
|
||||
|
|
|
@ -207,7 +207,7 @@ static PContainerType *FindContainerType(FName name, FCompileContext &ctx)
|
|||
if (sym && sym->IsKindOf(RUNTIME_CLASS(PSymbolType)))
|
||||
{
|
||||
auto type = static_cast<PSymbolType*>(sym);
|
||||
return dyn_cast<PContainerType>(type->Type);
|
||||
return type->Type->toContainer();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -292,10 +292,10 @@ static PSymbol *FindBuiltinFunction(FName funcname, VMNativeFunction::NativeCall
|
|||
|
||||
static bool AreCompatiblePointerTypes(PType *dest, PType *source, bool forcompare = false)
|
||||
{
|
||||
if (dest->IsKindOf(RUNTIME_CLASS(PPointer)) && source->IsKindOf(RUNTIME_CLASS(PPointer)))
|
||||
if (dest->isPointer() && source->isPointer())
|
||||
{
|
||||
auto fromtype = static_cast<PPointer *>(source);
|
||||
auto totype = static_cast<PPointer *>(dest);
|
||||
auto fromtype = source->toPointer();
|
||||
auto totype = dest->toPointer();
|
||||
// null pointers can be assigned to everything, everything can be assigned to void pointers.
|
||||
if (fromtype == nullptr || totype == TypeVoidPtr) return true;
|
||||
// when comparing const-ness does not matter.
|
||||
|
@ -557,11 +557,11 @@ FxExpression *FxConstant::MakeConstant(PSymbol *sym, const FScriptPosition &pos)
|
|||
PSymbolConstNumeric *csym = dyn_cast<PSymbolConstNumeric>(sym);
|
||||
if (csym != nullptr)
|
||||
{
|
||||
if (csym->ValueType->IsA(RUNTIME_CLASS(PInt)))
|
||||
if (csym->ValueType->isInt())
|
||||
{
|
||||
x = new FxConstant(csym->Value, pos);
|
||||
}
|
||||
else if (csym->ValueType->IsA(RUNTIME_CLASS(PFloat)))
|
||||
else if (csym->ValueType->isFloat())
|
||||
{
|
||||
x = new FxConstant(csym->Float, pos);
|
||||
}
|
||||
|
@ -1356,7 +1356,7 @@ FxExpression *FxColorCast::Resolve(FCompileContext &ctx)
|
|||
CHECKRESOLVED();
|
||||
SAFE_RESOLVE(basex, ctx);
|
||||
|
||||
if (basex->ValueType == TypeColor || basex->ValueType->GetClass() == RUNTIME_CLASS(PInt))
|
||||
if (basex->ValueType == TypeColor || basex->ValueType->isInt())
|
||||
{
|
||||
FxExpression *x = basex;
|
||||
x->ValueType = TypeColor;
|
||||
|
@ -1445,7 +1445,7 @@ FxExpression *FxSoundCast::Resolve(FCompileContext &ctx)
|
|||
CHECKRESOLVED();
|
||||
SAFE_RESOLVE(basex, ctx);
|
||||
|
||||
if (basex->ValueType == TypeSound || basex->ValueType->GetClass() == RUNTIME_CLASS(PInt))
|
||||
if (basex->ValueType == TypeSound || basex->ValueType->isInt())
|
||||
{
|
||||
FxExpression *x = basex;
|
||||
x->ValueType = TypeSound;
|
||||
|
@ -1617,7 +1617,7 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
|
|||
// don't go through the entire list if the types are the same.
|
||||
goto basereturn;
|
||||
}
|
||||
else if (basex->ValueType == TypeNullPtr && (ValueType == TypeState || ValueType->IsKindOf(RUNTIME_CLASS(PPointer))))
|
||||
else if (basex->ValueType == TypeNullPtr && ValueType->isPointer())
|
||||
{
|
||||
goto basereturn;
|
||||
}
|
||||
|
@ -1629,7 +1629,7 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
|
|||
delete this;
|
||||
return x;
|
||||
}
|
||||
else if (ValueType->IsA(RUNTIME_CLASS(PInt)))
|
||||
else if (ValueType->isInt())
|
||||
{
|
||||
// This is only for casting to actual ints. Subtypes representing an int will be handled elsewhere.
|
||||
FxExpression *x = new FxIntCast(basex, NoWarn, Explicit);
|
||||
|
@ -1773,7 +1773,7 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
|
|||
if (fromtype->IsDescendantOf(totype)) goto basereturn;
|
||||
}
|
||||
}
|
||||
else if (basex->IsNativeStruct() && ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && static_cast<PPointer*>(ValueType)->PointedType == basex->ValueType)
|
||||
else if (basex->IsNativeStruct() && ValueType->isRealPointer() && ValueType->toPointer()->PointedType == basex->ValueType)
|
||||
{
|
||||
bool writable;
|
||||
basex->RequestAddress(ctx, &writable);
|
||||
|
@ -2494,7 +2494,7 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx)
|
|||
}
|
||||
// Both types are the same so this is ok.
|
||||
}
|
||||
else if (Right->IsNativeStruct() && Base->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && static_cast<PPointer*>(Base->ValueType)->PointedType == Right->ValueType)
|
||||
else if (Right->IsNativeStruct() && Base->ValueType->isRealPointer() && Base->ValueType->toPointer()->PointedType == Right->ValueType)
|
||||
{
|
||||
// allow conversion of native structs to pointers of the same type. This is necessary to assign elements from global arrays like players, sectors, etc. to local pointers.
|
||||
// For all other types this is not needed. Structs are not assignable and classes can only exist as references.
|
||||
|
@ -3649,12 +3649,12 @@ FxExpression *FxCompareEq::Resolve(FCompileContext& ctx)
|
|||
goto error;
|
||||
}
|
||||
}
|
||||
else if (left->IsPointer() && static_cast<PPointer*>(left->ValueType)->PointedType == right->ValueType)
|
||||
else if (left->IsPointer() && left->ValueType->toPointer()->PointedType == right->ValueType)
|
||||
{
|
||||
bool writable;
|
||||
if (!right->RequestAddress(ctx, &writable)) goto error;
|
||||
}
|
||||
else if (right->IsPointer() && static_cast<PPointer*>(right->ValueType)->PointedType == left->ValueType)
|
||||
else if (right->IsPointer() && right->ValueType->toPointer()->PointedType == left->ValueType)
|
||||
{
|
||||
bool writable;
|
||||
if (!left->RequestAddress(ctx, &writable)) goto error;
|
||||
|
@ -4684,7 +4684,7 @@ FxExpression *FxDynamicCast::Resolve(FCompileContext& ctx)
|
|||
{
|
||||
CHECKRESOLVED();
|
||||
SAFE_RESOLVE(expr, ctx);
|
||||
bool constflag = expr->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && static_cast<PPointer *>(expr->ValueType)->IsConst;
|
||||
bool constflag = expr->ValueType->isPointer() && expr->ValueType->toPointer()->IsConst;
|
||||
if (constflag)
|
||||
{
|
||||
// readonly pointers are normally only used for class defaults which lack type information to be cast properly, so we have to error out here.
|
||||
|
@ -6342,7 +6342,7 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx)
|
|||
auto sn = static_cast<PSymbolConstNumeric*>(sym);
|
||||
|
||||
VMValue vmv;
|
||||
if (sn->ValueType->IsKindOf(RUNTIME_CLASS(PInt))) vmv = sn->Value;
|
||||
if (sn->ValueType->isIntCompatible()) vmv = sn->Value;
|
||||
else vmv = sn->Float;
|
||||
auto x = new FxConstant(sn->ValueType, vmv, ScriptPosition);
|
||||
delete this;
|
||||
|
@ -6393,10 +6393,10 @@ FxExpression *FxMemberIdentifier::Resolve(FCompileContext& ctx)
|
|||
{
|
||||
Object->ValueType = TypeColorStruct;
|
||||
}
|
||||
if (Object->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)))
|
||||
if (Object->ValueType->isRealPointer())
|
||||
{
|
||||
auto ptype = static_cast<PPointer *>(Object->ValueType)->PointedType;
|
||||
if (ptype->IsKindOf(RUNTIME_CLASS(PContainerType)))
|
||||
auto ptype = Object->ValueType->toPointer()->PointedType;
|
||||
if (ptype->isContainer())
|
||||
{
|
||||
auto ret = ResolveMember(ctx, ctx.Class, Object, static_cast<PContainerType *>(ptype));
|
||||
delete this;
|
||||
|
@ -6603,8 +6603,8 @@ FxExpression *FxClassDefaults::Resolve(FCompileContext& ctx)
|
|||
{
|
||||
CHECKRESOLVED();
|
||||
SAFE_RESOLVE(obj, ctx);
|
||||
assert(obj->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)));
|
||||
ValueType = NewPointer(static_cast<PPointer*>(obj->ValueType)->PointedType, true);
|
||||
assert(obj->ValueType->isRealPointer());
|
||||
ValueType = NewPointer(obj->ValueType->toPointer()->PointedType, true);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -6938,7 +6938,7 @@ bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable)
|
|||
{
|
||||
// [ZZ] original check.
|
||||
bool bWritable = (AddressWritable && !ctx.CheckWritable(membervar->Flags) &&
|
||||
(!classx->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) || !static_cast<PPointer*>(classx->ValueType)->IsConst));
|
||||
(!classx->ValueType->isPointer() || !classx->ValueType->toPointer()->IsConst));
|
||||
// [ZZ] implement write barrier between different scopes
|
||||
if (bWritable)
|
||||
{
|
||||
|
@ -7018,10 +7018,10 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
|
|||
return x->Resolve(ctx);
|
||||
}
|
||||
|
||||
if (classx->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)))
|
||||
if (classx->ValueType->isPointer())
|
||||
{
|
||||
PPointer *ptrtype = dyn_cast<PPointer>(classx->ValueType);
|
||||
if (ptrtype == nullptr || !ptrtype->PointedType->IsKindOf(RUNTIME_CLASS(PContainerType)))
|
||||
PPointer *ptrtype = classx->ValueType->toPointer();
|
||||
if (ptrtype == nullptr || !ptrtype->PointedType->isContainer())
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Member variable requires a struct or class object");
|
||||
delete this;
|
||||
|
@ -7241,7 +7241,7 @@ FxExpression *FxArrayElement::Resolve(FCompileContext &ctx)
|
|||
if (arraytype == nullptr)
|
||||
{
|
||||
// Check if we got a pointer to an array. Some native data structures (like the line list in sectors) use this.
|
||||
PPointer *ptype = dyn_cast<PPointer>(Array->ValueType);
|
||||
PPointer *ptype = Array->ValueType->toPointer();
|
||||
if (ptype == nullptr || !ptype->PointedType->IsKindOf(RUNTIME_CLASS(PArray)))
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "'[]' can only be used with arrays.");
|
||||
|
@ -7316,7 +7316,7 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
|
|||
|
||||
if (arrayispointer)
|
||||
{
|
||||
arraytype = static_cast<PArray*>(static_cast<PPointer*>(Array->ValueType)->PointedType);
|
||||
arraytype = static_cast<PArray*>(Array->ValueType->toPointer()->PointedType);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -8150,7 +8150,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
member->membervar = newfield;
|
||||
}
|
||||
}
|
||||
else if (a->IsPointer() && Self->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)))
|
||||
else if (a->IsPointer() && Self->ValueType->isPointer())
|
||||
{
|
||||
// the only case which must be checked up front is for pointer arrays receiving a new element.
|
||||
// Since there is only one native backing class it uses a neutral void pointer as its argument,
|
||||
|
@ -8178,7 +8178,7 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
if (!Self->IsResizableArray())
|
||||
{
|
||||
auto atype = Self->ValueType;
|
||||
if (Self->ValueType->IsKindOf(RUNTIME_CLASS(PPointer))) atype = static_cast<PPointer*>(ValueType)->PointedType;
|
||||
if (Self->ValueType->isPointer()) atype = ValueType->toPointer()->PointedType;
|
||||
auto size = static_cast<PArray*>(atype)->ElementCount;
|
||||
auto x = new FxConstant(size, ScriptPosition);
|
||||
delete this;
|
||||
|
@ -8222,10 +8222,11 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
return x->Resolve(ctx);
|
||||
}
|
||||
|
||||
if (Self->ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && !Self->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
|
||||
if (Self->ValueType->isRealPointer())
|
||||
{
|
||||
auto ptype = static_cast<PPointer *>(Self->ValueType)->PointedType;
|
||||
if (ptype->IsKindOf(RUNTIME_CLASS(PContainerType)))
|
||||
auto ptype = Self->ValueType->toPointer()->PointedType;
|
||||
cls = ptype->toContainer();
|
||||
if (cls != nullptr)
|
||||
{
|
||||
if (ptype->IsKindOf(RUNTIME_CLASS(PClassType)) && MethodName == NAME_GetClass)
|
||||
{
|
||||
|
@ -8238,9 +8239,6 @@ FxExpression *FxMemberFunctionCall::Resolve(FCompileContext& ctx)
|
|||
auto x = new FxGetClass(Self);
|
||||
return x->Resolve(ctx);
|
||||
}
|
||||
|
||||
|
||||
cls = static_cast<PContainerType *>(ptype);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -8759,7 +8757,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
|
|||
// If this is a reference argument, the pointer type must be undone because the code below expects the pointed type as value type.
|
||||
if (argflags[i + k + implicit] & VARF_Ref)
|
||||
{
|
||||
assert(ntype->IsKindOf(RUNTIME_CLASS(PPointer)));
|
||||
assert(ntype->isPointer());
|
||||
ntype = TypeNullPtr; // the default of a reference type can only be a null pointer
|
||||
}
|
||||
if (ntype->GetRegCount() == 1)
|
||||
|
@ -8822,7 +8820,7 @@ FxExpression *FxVMFunctionCall::Resolve(FCompileContext& ctx)
|
|||
ArgList[i] = ArgList[i]->Resolve(ctx); // nust be resolved before the address is requested.
|
||||
if (ArgList[i] != nullptr && ArgList[i]->ValueType != TypeNullPtr)
|
||||
{
|
||||
if (type == ArgList[i]->ValueType && type->IsA(RUNTIME_CLASS(PPointer)) && static_cast<PPointer*>(type)->PointedType->IsA(RUNTIME_CLASS(PStruct)))
|
||||
if (type == ArgList[i]->ValueType && type->isRealPointer() && type->toPointer()->PointedType->IsA(RUNTIME_CLASS(PStruct)))
|
||||
{
|
||||
// trying to pass a struct reference as a struct reference. This must preserve the type.
|
||||
}
|
||||
|
@ -8937,7 +8935,7 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
|
|||
|
||||
if (innerside == FScopeBarrier::Side_Virtual)
|
||||
{
|
||||
auto selfside = FScopeBarrier::SideFromObjectFlags(static_cast<PPointer*>(Self->ValueType)->PointedType->ObjectFlags);
|
||||
auto selfside = FScopeBarrier::SideFromObjectFlags(Self->ValueType->toPointer()->PointedType->ObjectFlags);
|
||||
|
||||
int outerside = FScopeBarrier::SideFromFlags(CallingFunction->Variants[0].Flags);
|
||||
if (outerside == FScopeBarrier::Side_Virtual)
|
||||
|
@ -9300,7 +9298,7 @@ FxExpression *FxGetClass::Resolve(FCompileContext &ctx)
|
|||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
ValueType = NewClassPointer(static_cast<PClassType*>(static_cast<PPointer*>(Self->ValueType)->PointedType)->Descriptor);
|
||||
ValueType = NewClassPointer(static_cast<PClassType*>(Self->ValueType->toPointer()->PointedType)->Descriptor);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -330,14 +330,14 @@ public:
|
|||
virtual bool CheckReturn() { return false; }
|
||||
virtual int GetBitValue() { return -1; }
|
||||
bool IsNumeric() const { return ValueType->isNumeric(); }
|
||||
bool IsFloat() const { return ValueType->GetRegType() == REGT_FLOAT && ValueType->GetRegCount() == 1; }
|
||||
bool IsInteger() const { return ValueType->isNumeric() && (ValueType->GetRegType() == REGT_INT); }
|
||||
bool IsPointer() const { return ValueType->GetRegType() == REGT_POINTER; }
|
||||
bool IsFloat() const { return ValueType->isFloat(); }
|
||||
bool IsInteger() const { return ValueType->isNumeric() && ValueType->isIntCompatible(); }
|
||||
bool IsPointer() const { return ValueType->isPointer(); }
|
||||
bool IsVector() const { return ValueType == TypeVector2 || ValueType == TypeVector3; };
|
||||
bool IsBoolCompat() const { return ValueType->GetRegCount() == 1 && (ValueType->GetRegType() == REGT_INT || ValueType->GetRegType() == REGT_FLOAT || ValueType->GetRegType() == REGT_POINTER); }
|
||||
bool IsBoolCompat() const { return ValueType->isScalar(); }
|
||||
bool IsObject() const { return ValueType->IsKindOf(RUNTIME_CLASS(PObjectPointer)); }
|
||||
bool IsArray() const { return ValueType->IsKindOf(RUNTIME_CLASS(PArray)) || (ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && static_cast<PPointer*>(ValueType)->PointedType->IsKindOf(RUNTIME_CLASS(PArray))); }
|
||||
bool IsResizableArray() const { return (ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && static_cast<PPointer*>(ValueType)->PointedType->IsKindOf(RUNTIME_CLASS(PStaticArray))); } // can only exist in pointer form.
|
||||
bool IsArray() const { return ValueType->IsKindOf(RUNTIME_CLASS(PArray)) || (ValueType->isPointer() && ValueType->toPointer()->PointedType->IsKindOf(RUNTIME_CLASS(PArray))); }
|
||||
bool IsResizableArray() const { return (ValueType->isPointer() && ValueType->toPointer()->PointedType->IsKindOf(RUNTIME_CLASS(PStaticArray))); } // can only exist in pointer form.
|
||||
bool IsDynamicArray() const { return (ValueType->IsKindOf(RUNTIME_CLASS(PDynArray))); }
|
||||
bool IsNativeStruct() const { return (ValueType->IsA(RUNTIME_CLASS(PStruct)) && static_cast<PStruct*>(ValueType)->isNative); }
|
||||
|
||||
|
|
|
@ -866,17 +866,17 @@ static void DispatchScriptProperty(FScanner &sc, PProperty *prop, AActor *defaul
|
|||
if (sc.CheckNumber()) *(int*)addr = sc.Number;
|
||||
else *(PalEntry*)addr = V_GetColor(nullptr, sc);
|
||||
}
|
||||
else if (f->Type->IsKindOf(RUNTIME_CLASS(PInt)))
|
||||
else if (f->Type->isIntCompatible())
|
||||
{
|
||||
sc.MustGetNumber();
|
||||
static_cast<PInt*>(f->Type)->SetValue(addr, sc.Number);
|
||||
}
|
||||
else if (f->Type->IsKindOf(RUNTIME_CLASS(PFloat)))
|
||||
else if (f->Type->isFloat())
|
||||
{
|
||||
sc.MustGetFloat();
|
||||
static_cast<PFloat*>(f->Type)->SetValue(addr, sc.Float);
|
||||
}
|
||||
else if (f->Type->IsKindOf(RUNTIME_CLASS(PString)))
|
||||
else if (f->Type == TypeString)
|
||||
{
|
||||
sc.MustGetString();
|
||||
*(FString*)addr = strbin1(sc.String);
|
||||
|
|
|
@ -104,9 +104,9 @@ unsigned PFunction::AddVariant(PPrototype *proto, TArray<uint32_t> &argflags, TA
|
|||
if (flags & VARF_Method)
|
||||
{
|
||||
assert(proto->ArgumentTypes.Size() > 0);
|
||||
auto selftypeptr = dyn_cast<PPointer>(proto->ArgumentTypes[0]);
|
||||
auto selftypeptr = proto->ArgumentTypes[0]->toPointer();
|
||||
assert(selftypeptr != nullptr);
|
||||
variant.SelfClass = dyn_cast<PContainerType>(selftypeptr->PointedType);
|
||||
variant.SelfClass = selftypeptr->PointedType->toContainer();
|
||||
assert(variant.SelfClass != nullptr);
|
||||
}
|
||||
else
|
||||
|
@ -155,7 +155,7 @@ PField::PField(FName name, PType *type, uint32_t flags, size_t offset, int bitva
|
|||
unsigned val = bitvalue;
|
||||
while ((val >>= 1)) BitValue++;
|
||||
|
||||
if (type->IsA(RUNTIME_CLASS(PInt)) && unsigned(BitValue) < 8u * type->Size)
|
||||
if (type->isInt() && unsigned(BitValue) < 8u * type->Size)
|
||||
{
|
||||
// map to the single bytes in the actual variable. The internal bit instructions operate on 8 bit values.
|
||||
#ifndef __BIG_ENDIAN__
|
||||
|
@ -582,7 +582,7 @@ void RemoveUnusedSymbols()
|
|||
{
|
||||
for (PType *ty = TypeTable.TypeHash[i]; ty != nullptr; ty = ty->HashNext)
|
||||
{
|
||||
if (ty->IsKindOf(RUNTIME_CLASS(PContainerType)))
|
||||
if (ty->isContainer())
|
||||
{
|
||||
auto it = ty->Symbols.GetIterator();
|
||||
PSymbolTable::MapType::Pair *pair;
|
||||
|
|
|
@ -377,16 +377,6 @@ void PType::StaticInit()
|
|||
|
||||
IMPLEMENT_CLASS(PBasicType, true, false)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PBasicType Default Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
PBasicType::PBasicType()
|
||||
{
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PBasicType Parameterized Constructor
|
||||
|
@ -397,12 +387,25 @@ PBasicType::PBasicType(unsigned int size, unsigned int align)
|
|||
: PType(size, align)
|
||||
{
|
||||
mDescriptiveName = "BasicType";
|
||||
Flags |= TYPE_Scalar;
|
||||
}
|
||||
|
||||
/* PCompoundType **********************************************************/
|
||||
|
||||
IMPLEMENT_CLASS(PCompoundType, true, false)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PBasicType Parameterized Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
PCompoundType::PCompoundType(unsigned int size, unsigned int align)
|
||||
: PType(size, align)
|
||||
{
|
||||
mDescriptiveName = "CompoundType";
|
||||
}
|
||||
|
||||
/* PContainerType *************************************************************/
|
||||
|
||||
IMPLEMENT_CLASS(PContainerType, true, false)
|
||||
|
@ -462,6 +465,7 @@ PInt::PInt(unsigned int size, bool unsign, bool compatible)
|
|||
: PBasicType(size, size), Unsigned(unsign), IntCompatible(compatible)
|
||||
{
|
||||
mDescriptiveName.Format("%cInt%d", unsign? 'U':'S', size);
|
||||
Flags |= TYPE_Int;
|
||||
|
||||
MemberOnly = (size < 4);
|
||||
if (!unsign)
|
||||
|
@ -713,26 +717,13 @@ PBool::PBool()
|
|||
{
|
||||
mDescriptiveName = "Bool";
|
||||
MemberOnly = false;
|
||||
Flags |= TYPE_IntNotInt;
|
||||
}
|
||||
|
||||
/* PFloat *****************************************************************/
|
||||
|
||||
IMPLEMENT_CLASS(PFloat, false, false)
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PFloat Default Constructor
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
PFloat::PFloat()
|
||||
: PBasicType(8, 8)
|
||||
{
|
||||
mDescriptiveName = "Float";
|
||||
SetDoubleSymbols();
|
||||
SetOps();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PFloat Parameterized Constructor
|
||||
|
@ -743,6 +734,7 @@ PFloat::PFloat(unsigned int size)
|
|||
: PBasicType(size, size)
|
||||
{
|
||||
mDescriptiveName.Format("Float%d", size);
|
||||
Flags |= TYPE_Float;
|
||||
if (size == 8)
|
||||
{
|
||||
#ifdef __i386__
|
||||
|
@ -1085,6 +1077,7 @@ PName::PName()
|
|||
: PInt(sizeof(FName), true, false)
|
||||
{
|
||||
mDescriptiveName = "Name";
|
||||
Flags |= TYPE_IntNotInt;
|
||||
assert(sizeof(FName) == alignof(FName));
|
||||
}
|
||||
|
||||
|
@ -1134,6 +1127,7 @@ IMPLEMENT_CLASS(PSpriteID, false, false)
|
|||
PSpriteID::PSpriteID()
|
||||
: PInt(sizeof(int), true, true)
|
||||
{
|
||||
Flags |= TYPE_IntNotInt;
|
||||
mDescriptiveName = "SpriteID";
|
||||
}
|
||||
|
||||
|
@ -1177,6 +1171,7 @@ PTextureID::PTextureID()
|
|||
: PInt(sizeof(FTextureID), true, false)
|
||||
{
|
||||
mDescriptiveName = "TextureID";
|
||||
Flags |= TYPE_IntNotInt;
|
||||
assert(sizeof(FTextureID) == alignof(FTextureID));
|
||||
}
|
||||
|
||||
|
@ -1220,6 +1215,7 @@ PSound::PSound()
|
|||
: PInt(sizeof(FSoundID), true)
|
||||
{
|
||||
mDescriptiveName = "Sound";
|
||||
Flags |= TYPE_IntNotInt;
|
||||
assert(sizeof(FSoundID) == alignof(FSoundID));
|
||||
}
|
||||
|
||||
|
@ -1270,6 +1266,7 @@ PColor::PColor()
|
|||
: PInt(sizeof(PalEntry), true)
|
||||
{
|
||||
mDescriptiveName = "Color";
|
||||
Flags |= TYPE_IntNotInt;
|
||||
assert(sizeof(PalEntry) == alignof(PalEntry));
|
||||
}
|
||||
|
||||
|
@ -1286,6 +1283,7 @@ IMPLEMENT_CLASS(PStateLabel, false, false)
|
|||
PStateLabel::PStateLabel()
|
||||
: PInt(sizeof(int), false, false)
|
||||
{
|
||||
Flags |= TYPE_IntNotInt;
|
||||
mDescriptiveName = "StateLabel";
|
||||
}
|
||||
|
||||
|
@ -1307,6 +1305,7 @@ PPointer::PPointer()
|
|||
storeOp = OP_SP;
|
||||
moveOp = OP_MOVEA;
|
||||
RegType = REGT_POINTER;
|
||||
Flags |= TYPE_Pointer;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1332,6 +1331,7 @@ PPointer::PPointer(PType *pointsat, bool isconst)
|
|||
storeOp = OP_SP;
|
||||
moveOp = OP_MOVEA;
|
||||
RegType = REGT_POINTER;
|
||||
Flags |= TYPE_Pointer;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -61,6 +61,21 @@ enum
|
|||
// Map * *
|
||||
// Prototype *+ *+
|
||||
|
||||
enum ETypeFlags
|
||||
{
|
||||
TYPE_Scalar = 1,
|
||||
TYPE_Container = 2,
|
||||
TYPE_Int = 4,
|
||||
TYPE_IntNotInt = 8, // catch-all for subtypes that are not being checked by type directly.
|
||||
TYPE_Float = 16,
|
||||
TYPE_Pointer = 32,
|
||||
|
||||
TYPE_IntCompatible = TYPE_Int | TYPE_IntNotInt, // must be the combination of all flags that are subtypes of int and can be cast to an int.
|
||||
};
|
||||
|
||||
class PContainerType;
|
||||
class PPointer;
|
||||
|
||||
struct ZCC_ExprConstant;
|
||||
class PType : public PTypeBase
|
||||
{
|
||||
|
@ -71,6 +86,7 @@ public:
|
|||
PClass *TypeTableType; // The type to use for hashing into the type table
|
||||
unsigned int Size; // this type's size
|
||||
unsigned int Align; // this type's preferred alignment
|
||||
unsigned int Flags = 0; // What is this type?
|
||||
PType *HashNext; // next type in this type table
|
||||
PSymbolTable Symbols;
|
||||
bool MemberOnly = false; // type may only be used as a struct/class member but not as a local variable or function argument.
|
||||
|
@ -160,6 +176,17 @@ public:
|
|||
const char *DescriptiveName() const;
|
||||
|
||||
static void StaticInit();
|
||||
|
||||
bool isScalar() const { return !!(Flags & TYPE_Scalar); }
|
||||
bool isContainer() const { return !!(Flags & TYPE_Container); }
|
||||
bool isInt() const { return (Flags & TYPE_IntCompatible) == TYPE_Int; }
|
||||
bool isIntCompatible() const { return !!(Flags & TYPE_IntCompatible); }
|
||||
bool isFloat() const { return !!(Flags & TYPE_Float); }
|
||||
bool isPointer() const { return !!(Flags & TYPE_Pointer); }
|
||||
bool isRealPointer() const { return !!(Flags & TYPE_Pointer); } // This excludes class pointers which use their PointedType differently
|
||||
|
||||
PContainerType *toContainer() { return isContainer() ? (PContainerType*)this : nullptr; }
|
||||
PPointer *toPointer() { return isPointer() ? (PPointer*)this : nullptr; }
|
||||
};
|
||||
|
||||
// Not-really-a-type types --------------------------------------------------
|
||||
|
@ -183,14 +210,15 @@ public:
|
|||
class PBasicType : public PType
|
||||
{
|
||||
DECLARE_ABSTRACT_CLASS(PBasicType, PType);
|
||||
public:
|
||||
PBasicType();
|
||||
PBasicType(unsigned int size, unsigned int align);
|
||||
protected:
|
||||
PBasicType(unsigned int size = 1, unsigned int align = 1);
|
||||
};
|
||||
|
||||
class PCompoundType : public PType
|
||||
{
|
||||
DECLARE_ABSTRACT_CLASS(PCompoundType, PType);
|
||||
protected:
|
||||
PCompoundType(unsigned int size = 1, unsigned int align = 1);
|
||||
};
|
||||
|
||||
class PContainerType : public PCompoundType
|
||||
|
@ -200,11 +228,15 @@ public:
|
|||
PTypeBase *Outer; // object this type is contained within
|
||||
FName TypeName; // this type's name
|
||||
|
||||
PContainerType() : Outer(NULL) {
|
||||
mDescriptiveName = "NamedType";
|
||||
PContainerType() : Outer(NULL)
|
||||
{
|
||||
mDescriptiveName = "ContainerType";
|
||||
Flags |= TYPE_Container;
|
||||
}
|
||||
PContainerType(FName name, PTypeBase *outer) : Outer(outer), TypeName(name) {
|
||||
PContainerType(FName name, PTypeBase *outer) : Outer(outer), TypeName(name)
|
||||
{
|
||||
mDescriptiveName = name.GetChars();
|
||||
Flags |= TYPE_Container;
|
||||
}
|
||||
|
||||
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
||||
|
@ -252,7 +284,7 @@ class PFloat : public PBasicType
|
|||
{
|
||||
DECLARE_CLASS(PFloat, PBasicType);
|
||||
public:
|
||||
PFloat(unsigned int size);
|
||||
PFloat(unsigned int size = 8);
|
||||
|
||||
void WriteValue(FSerializer &ar, const char *key,const void *addr) const override;
|
||||
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
|
||||
|
@ -263,7 +295,6 @@ public:
|
|||
virtual double GetValueFloat(void *addr) const;
|
||||
virtual bool isNumeric() override { return true; }
|
||||
protected:
|
||||
PFloat();
|
||||
void SetOps();
|
||||
private:
|
||||
struct SymbolInitF
|
||||
|
|
|
@ -593,7 +593,7 @@ static void PrintExprConstant(FLispString &out, ZCC_TreeNode *node)
|
|||
{
|
||||
out.AddName(ENamedName(enode->IntVal));
|
||||
}
|
||||
else if (enode->Type->IsKindOf(RUNTIME_CLASS(PInt)))
|
||||
else if (enode->Type->isIntCompatible())
|
||||
{
|
||||
out.AddInt(enode->IntVal, static_cast<PInt *>(enode->Type)->Unsigned);
|
||||
}
|
||||
|
|
|
@ -403,7 +403,7 @@ enum_def(X) ::= ENUM(T) IDENTIFIER(A) enum_type(B) LBRACE opt_enum_list(C) RBRAC
|
|||
// Compute implicit values by adding one to the preceding value.
|
||||
assert(prev->Value != NULL);
|
||||
// If the preceding node is a constant, then we can do this now.
|
||||
if (prev->Value->Operation == PEX_ConstValue && prev->Value->Type->IsA(RUNTIME_CLASS(PInt)))
|
||||
if (prev->Value->Operation == PEX_ConstValue && prev->Value->Type->isInt())
|
||||
{
|
||||
NEW_INTCONST_NODE(cval, prev->Value->Type, static_cast<ZCC_ExprConstant *>(prev->Value)->IntVal + 1, node);
|
||||
node->Value = cval;
|
||||
|
@ -1256,9 +1256,9 @@ unary_expr(X) ::= primary(X).
|
|||
unary_expr(X) ::= SUB unary_expr(A). [UNARY]
|
||||
{
|
||||
ZCC_ExprConstant *con = static_cast<ZCC_ExprConstant *>(A);
|
||||
if (A->Operation == PEX_ConstValue && (con->Type->IsA(RUNTIME_CLASS(PInt)) || con->Type->IsA(RUNTIME_CLASS(PFloat))))
|
||||
if (A->Operation == PEX_ConstValue && (con->Type->isInt() || con->Type->isFloat()))
|
||||
{ // For constants, manipulate the child node directly, and don't create a new node.
|
||||
if (con->Type->IsA(RUNTIME_CLASS(PInt)))
|
||||
if (con->Type->isInt())
|
||||
{
|
||||
con->IntVal = -con->IntVal;
|
||||
}
|
||||
|
@ -1280,7 +1280,7 @@ unary_expr(X) ::= ADD unary_expr(A). [UNARY]
|
|||
// it so we can type check that it is being applied to something numeric.
|
||||
// But we can do that right now for constant numerals.
|
||||
ZCC_ExprConstant *con = static_cast<ZCC_ExprConstant *>(A);
|
||||
if (A->Operation != PEX_ConstValue || (!con->Type->IsA(RUNTIME_CLASS(PInt)) && !con->Type->IsA(RUNTIME_CLASS(PFloat))))
|
||||
if (A->Operation != PEX_ConstValue || (!con->Type->isInt() && !con->Type->isFloat()))
|
||||
{
|
||||
UNARY_EXPR(A,PEX_AntiNegate);
|
||||
X = expr1;
|
||||
|
|
|
@ -873,13 +873,13 @@ void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant)
|
|||
{
|
||||
def->Symbol = new PSymbolConstString(def->NodeName, *(cval->StringVal));
|
||||
}
|
||||
else if (cval->Type->IsA(RUNTIME_CLASS(PInt)))
|
||||
else if (cval->Type->isInt())
|
||||
{
|
||||
// How do we get an Enum type in here without screwing everything up???
|
||||
//auto type = def->Type != nullptr ? def->Type : cval->Type;
|
||||
def->Symbol = new PSymbolConstNumeric(def->NodeName, cval->Type, cval->IntVal);
|
||||
}
|
||||
else if (cval->Type->IsA(RUNTIME_CLASS(PFloat)))
|
||||
else if (cval->Type->isFloat())
|
||||
{
|
||||
if (def->Type != nullptr)
|
||||
{
|
||||
|
@ -899,13 +899,13 @@ void ZCCCompiler::AddConstant(ZCC_ConstantWork &constant)
|
|||
{
|
||||
def->Symbol = new PSymbolConstString(def->NodeName, c.GetString());
|
||||
}
|
||||
else if (c.Type->IsA(RUNTIME_CLASS(PInt)))
|
||||
else if (c.Type->isInt())
|
||||
{
|
||||
// How do we get an Enum type in here without screwing everything up???
|
||||
//auto type = def->Type != nullptr ? def->Type : cval->Type;
|
||||
def->Symbol = new PSymbolConstNumeric(def->NodeName, c.Type, c.GetInt());
|
||||
}
|
||||
else if (c.Type->IsA(RUNTIME_CLASS(PFloat)))
|
||||
else if (c.Type->isFloat())
|
||||
{
|
||||
if (def->Type != nullptr)
|
||||
{
|
||||
|
@ -974,7 +974,7 @@ void ZCCCompiler::CompileArrays(ZCC_StructWork *work)
|
|||
FArgumentList values;
|
||||
|
||||
// Don't use narrow typea for casting.
|
||||
if (ctype->IsA(RUNTIME_CLASS(PInt))) ctype = static_cast<PInt*>(ztype)->Unsigned ? TypeUInt32 : TypeSInt32;
|
||||
if (ctype->isInt()) ctype = static_cast<PInt*>(ztype)->Unsigned ? TypeUInt32 : TypeSInt32;
|
||||
else if (ctype == TypeFloat32) ctype = TypeFloat64;
|
||||
|
||||
ConvertNodeList(values, sas->Values);
|
||||
|
@ -1077,13 +1077,13 @@ ZCC_ExprConstant *ZCCCompiler::NodeFromSymbolConst(PSymbolConst *sym, ZCC_Expres
|
|||
if (val->Type != TypeError)
|
||||
{
|
||||
assert(sym->IsKindOf(RUNTIME_CLASS(PSymbolConstNumeric)));
|
||||
if (sym->ValueType->IsKindOf(RUNTIME_CLASS(PInt)))
|
||||
if (sym->ValueType->isIntCompatible())
|
||||
{
|
||||
val->IntVal = static_cast<PSymbolConstNumeric *>(sym)->Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(sym->ValueType->IsKindOf(RUNTIME_CLASS(PFloat)));
|
||||
assert(sym->ValueType->isFloat());
|
||||
val->DoubleVal = static_cast<PSymbolConstNumeric *>(sym)->Float;
|
||||
}
|
||||
}
|
||||
|
@ -1752,7 +1752,7 @@ PType *ZCCCompiler::ResolveArraySize(PType *baseType, ZCC_Expression *arraysize,
|
|||
ex = ex->Resolve(ctx);
|
||||
|
||||
if (ex == nullptr) return TypeError;
|
||||
if (!ex->isConstant() || !ex->ValueType->IsA(RUNTIME_CLASS(PInt)))
|
||||
if (!ex->isConstant() || !ex->ValueType->isInt())
|
||||
{
|
||||
Error(arraysize, "Array index must be an integer constant");
|
||||
return TypeError;
|
||||
|
@ -2023,15 +2023,15 @@ void ZCCCompiler::DispatchScriptProperty(PProperty *prop, ZCC_PropertyStmt *prop
|
|||
{
|
||||
*(PalEntry*)addr = V_GetColor(nullptr, GetStringConst(ex, ctx), &ex->ScriptPosition);
|
||||
}
|
||||
else if (f->Type->IsKindOf(RUNTIME_CLASS(PInt)))
|
||||
else if (f->Type->isIntCompatible())
|
||||
{
|
||||
static_cast<PInt*>(f->Type)->SetValue(addr, GetIntConst(ex, ctx));
|
||||
}
|
||||
else if (f->Type->IsKindOf(RUNTIME_CLASS(PFloat)))
|
||||
else if (f->Type->isFloat())
|
||||
{
|
||||
static_cast<PFloat*>(f->Type)->SetValue(addr, GetFloatConst(ex, ctx));
|
||||
}
|
||||
else if (f->Type->IsKindOf(RUNTIME_CLASS(PString)))
|
||||
else if (f->Type == TypeString)
|
||||
{
|
||||
*(FString*)addr = GetStringConst(ex, ctx);
|
||||
}
|
||||
|
@ -2304,7 +2304,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
do
|
||||
{
|
||||
auto type = DetermineType(c->Type(), f, f->Name, t, false, false);
|
||||
if (type->IsKindOf(RUNTIME_CLASS(PContainerType)) && type != TypeVector2 && type != TypeVector3)
|
||||
if (type->isContainer() && type != TypeVector2 && type != TypeVector3)
|
||||
{
|
||||
// structs and classes only get passed by pointer.
|
||||
type = NewPointer(type);
|
||||
|
@ -3228,23 +3228,23 @@ FxExpression *ZCCCompiler::ConvertNode(ZCC_TreeNode *ast)
|
|||
case AST_ExprConstant:
|
||||
{
|
||||
auto cnst = static_cast<ZCC_ExprConstant *>(ast);
|
||||
if (cnst->Type->IsA(RUNTIME_CLASS(PName)))
|
||||
if (cnst->Type == TypeName)
|
||||
{
|
||||
return new FxConstant(FName(ENamedName(cnst->IntVal)), *ast);
|
||||
}
|
||||
else if (cnst->Type->IsA(RUNTIME_CLASS(PInt)))
|
||||
else if (cnst->Type->isInt())
|
||||
{
|
||||
return new FxConstant(cnst->IntVal, *ast);
|
||||
}
|
||||
else if (cnst->Type->IsA(RUNTIME_CLASS(PBool)))
|
||||
else if (cnst->Type == TypeBool)
|
||||
{
|
||||
return new FxConstant(!!cnst->IntVal, *ast);
|
||||
}
|
||||
else if (cnst->Type->IsA(RUNTIME_CLASS(PFloat)))
|
||||
else if (cnst->Type->isFloat())
|
||||
{
|
||||
return new FxConstant(cnst->DoubleVal, *ast);
|
||||
}
|
||||
else if (cnst->Type->IsA(RUNTIME_CLASS(PString)))
|
||||
else if (cnst->Type == TypeString)
|
||||
{
|
||||
return new FxConstant(*cnst->StringVal, *ast);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue