mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-25 05:21:02 +00:00
- preparations for null pointer support.
- add pointer support to FxAssign.
This commit is contained in:
parent
5bed0a2b39
commit
89416835a8
4 changed files with 90 additions and 22 deletions
|
@ -84,6 +84,7 @@ PColor *TypeColor;
|
|||
PStatePointer *TypeState;
|
||||
PStruct *TypeVector2;
|
||||
PStruct *TypeVector3;
|
||||
PPointer *TypeNullPtr;
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
|
@ -616,6 +617,7 @@ void PType::StaticInit()
|
|||
TypeTable.AddType(TypeSound = new PSound);
|
||||
TypeTable.AddType(TypeColor = new PColor);
|
||||
TypeTable.AddType(TypeState = new PStatePointer);
|
||||
TypeTable.AddType(TypeNullPtr = new PPointer);
|
||||
|
||||
TypeVector2 = new PStruct(NAME_Vector2, nullptr);
|
||||
TypeVector2->AddField(NAME_X, TypeFloat64);
|
||||
|
@ -1635,7 +1637,7 @@ END_POINTERS
|
|||
PPointer::PPointer()
|
||||
: PBasicType(sizeof(void *), __alignof(void *)), PointedType(NULL)
|
||||
{
|
||||
mDescriptiveName = "Pointer";
|
||||
mDescriptiveName = "NullPointer";
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -530,6 +530,7 @@ class PPointer : public PBasicType
|
|||
DECLARE_CLASS(PPointer, PBasicType);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
PPointer();
|
||||
PPointer(PType *pointsat);
|
||||
|
||||
PType *PointedType;
|
||||
|
@ -546,7 +547,6 @@ public:
|
|||
bool ReadValue(FSerializer &ar, const char *key,void *addr) const override;
|
||||
|
||||
protected:
|
||||
PPointer();
|
||||
};
|
||||
|
||||
class PClassPointer : public PPointer
|
||||
|
@ -890,6 +890,7 @@ extern PColor *TypeColor;
|
|||
extern PStruct *TypeVector2;
|
||||
extern PStruct *TypeVector3;
|
||||
extern PStatePointer *TypeState;
|
||||
extern PPointer *TypeNullPtr;
|
||||
|
||||
// A constant value ---------------------------------------------------------
|
||||
|
||||
|
|
|
@ -1078,6 +1078,10 @@ 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))))
|
||||
{
|
||||
goto basereturn;
|
||||
}
|
||||
else if (ValueType->GetRegType() == REGT_FLOAT)
|
||||
{
|
||||
FxExpression *x = new FxFloatCast(basex);
|
||||
|
@ -1199,6 +1203,7 @@ basereturn:
|
|||
auto x = basex;
|
||||
basex = nullptr;
|
||||
delete this;
|
||||
x->ValueType = ValueType;
|
||||
return x;
|
||||
|
||||
}
|
||||
|
@ -1772,9 +1777,64 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx)
|
|||
|
||||
SAFE_RESOLVE(Right, ctx);
|
||||
|
||||
if (!Base->IsNumeric() || !Right->IsNumeric())
|
||||
if (Base->IsNumeric() && Right->IsNumeric())
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
|
||||
if (Right->ValueType != ValueType)
|
||||
{
|
||||
if (ValueType == TypeBool)
|
||||
{
|
||||
Right = new FxBoolCast(Right);
|
||||
}
|
||||
else if (ValueType->GetRegType() == REGT_INT)
|
||||
{
|
||||
Right = new FxIntCast(Right, ctx.FromDecorate);
|
||||
}
|
||||
else
|
||||
{
|
||||
Right = new FxFloatCast(Right);
|
||||
}
|
||||
SAFE_RESOLVE(Right, ctx);
|
||||
}
|
||||
}
|
||||
else if (Base->ValueType == Right->ValueType)
|
||||
{
|
||||
if (Base->ValueType->IsKindOf(RUNTIME_CLASS(PArray)))
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Cannot assign arrays");
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
if (Base->ValueType->IsKindOf(RUNTIME_CLASS(PStruct)))
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Struct assignment not implemented yet");
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
// Both types are the same so this is ok.
|
||||
}
|
||||
else if ((Base->ValueType == TypeState || Base->ValueType->IsKindOf(RUNTIME_CLASS(PPointer))) && Right->ValueType == TypeNullPtr)
|
||||
{
|
||||
// null pointers can be assigned to any other pointer
|
||||
}
|
||||
else if (Base->ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
|
||||
{
|
||||
// class pointers may be assignable so add a cast which performs a check.
|
||||
Right = new FxClassTypeCast(static_cast<PClassPointer *>(ValueType), Right);
|
||||
SAFE_RESOLVE(Right, ctx);
|
||||
}
|
||||
else if (Base->ValueType == TypeString && (Right->ValueType == TypeName || Right->ValueType == TypeSound))
|
||||
{
|
||||
Right = new FxStringCast(Right);
|
||||
SAFE_RESOLVE(Right, ctx);
|
||||
}
|
||||
else if (Base->ValueType == TypeName && Right->ValueType == TypeString)
|
||||
{
|
||||
Right = new FxNameCast(Right);
|
||||
SAFE_RESOLVE(Right, ctx);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Assignment between incompatible types.");
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -1785,22 +1845,6 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx)
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
if (Right->ValueType != ValueType)
|
||||
{
|
||||
if (ValueType == TypeBool)
|
||||
{
|
||||
Right = new FxBoolCast(Right);
|
||||
}
|
||||
else if (ValueType->GetRegType() == REGT_INT)
|
||||
{
|
||||
Right = new FxIntCast(Right, ctx.FromDecorate);
|
||||
}
|
||||
else
|
||||
{
|
||||
Right = new FxFloatCast(Right);
|
||||
}
|
||||
SAFE_RESOLVE(Right, ctx);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@ -1808,7 +1852,7 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx)
|
|||
ExpEmit FxAssign::Emit(VMFunctionBuilder *build)
|
||||
{
|
||||
static const BYTE loadops[] = { OP_LK, OP_LKF, OP_LKS, OP_LKP };
|
||||
assert(ValueType == Base->ValueType && IsNumeric());
|
||||
assert(ValueType == Base->ValueType);
|
||||
assert(ValueType->GetRegType() == Right->ValueType->GetRegType());
|
||||
|
||||
ExpEmit pointer = Base->Emit(build);
|
||||
|
@ -2272,8 +2316,14 @@ FxExpression *FxPow::Resolve(FCompileContext& ctx)
|
|||
{
|
||||
CHECKRESOLVED();
|
||||
|
||||
if (!ResolveLR(ctx, true)) return NULL;
|
||||
if (!ResolveLR(ctx, true)) return nullptr;
|
||||
|
||||
if (!IsNumeric())
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Numeric type expected");
|
||||
delete this;
|
||||
return nullptr;
|
||||
}
|
||||
if (left->isConstant() && right->isConstant())
|
||||
{
|
||||
double v1 = static_cast<FxConstant *>(left)->GetValue().GetFloat();
|
||||
|
@ -6015,6 +6065,14 @@ FxExpression *FxClassTypeCast::Resolve(FCompileContext &ctx)
|
|||
CHECKRESOLVED();
|
||||
SAFE_RESOLVE(basex, ctx);
|
||||
|
||||
if (basex->ValueType == TypeNullPtr)
|
||||
{
|
||||
basex->ValueType = ValueType;
|
||||
auto x = basex;
|
||||
basex = nullptr;
|
||||
delete this;
|
||||
return x;
|
||||
}
|
||||
if (basex->ValueType->GetClass() == RUNTIME_CLASS(PClassPointer))
|
||||
{
|
||||
auto to = static_cast<PClassPointer *>(ValueType);
|
||||
|
|
|
@ -379,6 +379,13 @@ public:
|
|||
ValueType = value.Type = TypeState;
|
||||
isresolved = true;
|
||||
}
|
||||
|
||||
FxConstant(nullptr_t *nullp, const FScriptPosition &pos) : FxExpression(pos)
|
||||
{
|
||||
value.pointer = nullptr;
|
||||
ValueType = value.Type = TypeNullPtr;
|
||||
isresolved = true;
|
||||
}
|
||||
|
||||
static FxExpression *MakeConstant(PSymbol *sym, const FScriptPosition &pos);
|
||||
|
||||
|
|
Loading…
Reference in a new issue