forked from Mirrors/openclonk
Replace C4Value typecheck table with switch statements
This has the advantage that the compiler can simplify the check when the target type is known at compile time.
parent
2a770e37da
commit
7eedece257
|
@ -68,83 +68,22 @@ bool C4Value::FnCnvObject() const
|
|||
if (Data.PropList->GetObject()) return true;
|
||||
return false;
|
||||
}
|
||||
// Type conversion table
|
||||
#define CnvOK C4VCnvFn::CnvOK, false // allow conversion by same value
|
||||
#define CnvOK0 C4VCnvFn::CnvOK0, true
|
||||
#define CnvError C4VCnvFn::CnvError, true
|
||||
#define CnvObject C4VCnvFn::CnvObject, false
|
||||
|
||||
C4VCnvFn C4Value::C4ScriptCnvMap[C4V_Last+1][C4V_Last+1] =
|
||||
|
||||
bool C4Value::WarnAboutConversion(C4V_Type Type, C4V_Type vtToType)
|
||||
{
|
||||
{ // C4V_Any - is always 0, convertible to everything
|
||||
{ CnvOK }, // any same
|
||||
{ CnvOK }, // int
|
||||
{ CnvOK }, // Bool
|
||||
{ CnvOK }, // PropList
|
||||
{ CnvOK }, // C4Object
|
||||
{ CnvOK }, // String
|
||||
{ CnvOK }, // Array
|
||||
},
|
||||
{ // C4V_Int
|
||||
{ CnvOK }, // any
|
||||
{ CnvOK }, // int same
|
||||
{ CnvOK }, // Bool
|
||||
{ CnvOK0 }, // PropList only if 0
|
||||
{ CnvOK0 }, // C4Object only if 0
|
||||
{ CnvOK0 }, // String only if 0
|
||||
{ CnvOK0 }, // Array only if 0
|
||||
},
|
||||
{ // C4V_Bool
|
||||
{ CnvOK }, // any
|
||||
{ CnvOK }, // int might be used
|
||||
{ CnvOK }, // Bool same
|
||||
{ CnvError }, // PropList NEVER!
|
||||
{ CnvError }, // C4Object NEVER!
|
||||
{ CnvError }, // String NEVER!
|
||||
{ CnvError }, // Array NEVER!
|
||||
},
|
||||
{ // C4V_PropList
|
||||
{ CnvOK }, // any
|
||||
{ CnvError }, // int NEVER!
|
||||
{ CnvOK }, // Bool
|
||||
{ CnvOK }, // PropList same
|
||||
{ CnvObject }, // C4Object
|
||||
{ CnvError }, // String NEVER!
|
||||
{ CnvError }, // Array NEVER!
|
||||
},
|
||||
{ // C4V_Object
|
||||
{ CnvOK }, // any
|
||||
{ CnvError }, // int NEVER!
|
||||
{ CnvOK }, // Bool
|
||||
{ CnvOK }, // PropList
|
||||
{ CnvOK }, // C4Object same
|
||||
{ CnvError }, // String NEVER!
|
||||
{ CnvError }, // Array NEVER!
|
||||
},
|
||||
{ // C4V_String
|
||||
{ CnvOK }, // any
|
||||
{ CnvError }, // int NEVER!
|
||||
{ CnvOK }, // Bool
|
||||
{ CnvError }, // PropList NEVER!
|
||||
{ CnvError }, // C4Object NEVER!
|
||||
{ CnvOK }, // String same
|
||||
{ CnvError }, // Array NEVER!
|
||||
},
|
||||
{ // C4V_Array
|
||||
{ CnvOK }, // any
|
||||
{ CnvError }, // int NEVER!
|
||||
{ CnvOK }, // Bool
|
||||
{ CnvError }, // PropList NEVER!
|
||||
{ CnvError }, // C4Object NEVER!
|
||||
{ CnvError }, // String NEVER!
|
||||
{ CnvOK }, // Array same
|
||||
switch (vtToType)
|
||||
{
|
||||
case C4V_Any: return false;
|
||||
case C4V_Int: return Type != C4V_Int && Type != C4V_Any && Type != C4V_Bool;
|
||||
case C4V_Bool: return false;
|
||||
case C4V_PropList: return Type != C4V_PropList && Type != C4V_C4Object && Type != C4V_Any;
|
||||
case C4V_C4Object: return Type != C4V_C4Object && Type != C4V_PropList && Type != C4V_Any;
|
||||
case C4V_String: return Type != C4V_String && Type != C4V_Any;
|
||||
case C4V_Array: return Type != C4V_Array && Type != C4V_Any;
|
||||
default: assert(!"C4Value::ConvertTo: impossible conversion target"); return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#undef CnvOK
|
||||
#undef CnvOK0
|
||||
#undef CnvError
|
||||
#undef CnvObject
|
||||
|
||||
// Humanreadable debug output
|
||||
StdStrBuf C4Value::GetDataString() const
|
||||
|
|
|
@ -60,13 +60,6 @@ union C4V_Data
|
|||
C4V_Data &operator = (void *p) { Obj = reinterpret_cast<C4Object *>(p); return *this; }
|
||||
};
|
||||
|
||||
// converter function, used in converter table
|
||||
struct C4VCnvFn
|
||||
{
|
||||
enum { CnvOK, CnvOK0, CnvError, CnvObject } Function;
|
||||
bool Warn;
|
||||
};
|
||||
|
||||
class C4Value
|
||||
{
|
||||
public:
|
||||
|
@ -153,22 +146,21 @@ public:
|
|||
|
||||
StdStrBuf GetDataString() const;
|
||||
|
||||
inline bool ConvertTo(C4V_Type vtToType) const // convert to dest type
|
||||
ALWAYS_INLINE bool ConvertTo(C4V_Type vtToType) const // convert to dest type
|
||||
{
|
||||
switch (C4ScriptCnvMap[Type][vtToType].Function)
|
||||
switch (vtToType)
|
||||
{
|
||||
case C4VCnvFn::CnvOK: return true;
|
||||
case C4VCnvFn::CnvOK0: return !*this;
|
||||
case C4VCnvFn::CnvError: return false;
|
||||
case C4VCnvFn::CnvObject: return FnCnvObject();
|
||||
case C4V_Any: return true;
|
||||
case C4V_Int: return Type == C4V_Int || Type == C4V_Any || Type == C4V_Bool;
|
||||
case C4V_Bool: return true;
|
||||
case C4V_PropList: return Type == C4V_PropList || Type == C4V_C4Object || Type == C4V_Any || (Type == C4V_Int && !*this);
|
||||
case C4V_C4Object: return Type == C4V_C4Object || (Type == C4V_PropList && FnCnvObject()) || Type == C4V_Any || (Type == C4V_Int && !*this);
|
||||
case C4V_String: return Type == C4V_String || Type == C4V_Any || (Type == C4V_Int && !*this);
|
||||
case C4V_Array: return Type == C4V_Array || Type == C4V_Any || (Type == C4V_Int && !*this);
|
||||
default: assert(!"C4Value::ConvertTo: impossible conversion target"); return false;
|
||||
}
|
||||
assert(!"C4Value::ConvertTo: Invalid conversion function specified");
|
||||
return false;
|
||||
}
|
||||
inline static bool WarnAboutConversion(C4V_Type vtFromType, C4V_Type vtToType)
|
||||
{
|
||||
return C4ScriptCnvMap[vtFromType][vtToType].Warn;
|
||||
}
|
||||
static bool WarnAboutConversion(C4V_Type Type, C4V_Type vtToType);
|
||||
|
||||
// Compilation
|
||||
void CompileFunc(StdCompiler *pComp, C4ValueNumbers *);
|
||||
|
@ -194,7 +186,6 @@ protected:
|
|||
void AddDataRef();
|
||||
void DelDataRef(C4V_Data Data, C4V_Type Type, C4Value *pNextRef);
|
||||
|
||||
static C4VCnvFn C4ScriptCnvMap[C4V_Last+1][C4V_Last+1];
|
||||
bool FnCnvObject() const;
|
||||
void LogDeletedObjectWarning(C4PropList *);
|
||||
|
||||
|
|
Loading…
Reference in New Issue