Scripting: Add boolean type

This commit is contained in:
Vicki Pfau 2022-07-01 02:02:55 -07:00
parent fa985d5798
commit d053058ea3
6 changed files with 370 additions and 14 deletions

View File

@ -459,6 +459,7 @@ CXX_GUARD_START
#define mSCRIPT_MAKE_S64(VALUE) mSCRIPT_MAKE(S64, VALUE)
#define mSCRIPT_MAKE_U64(VALUE) mSCRIPT_MAKE(U64, VALUE)
#define mSCRIPT_MAKE_F64(VALUE) mSCRIPT_MAKE(F64, VALUE)
#define mSCRIPT_MAKE_BOOL(VALUE) mSCRIPT_MAKE(BOOL, VALUE)
#define mSCRIPT_MAKE_CHARP(VALUE) mSCRIPT_MAKE(CHARP, VALUE)
#define mSCRIPT_MAKE_S(STRUCT, VALUE) mSCRIPT_MAKE(S(STRUCT), VALUE)
#define mSCRIPT_MAKE_CS(STRUCT, VALUE) mSCRIPT_MAKE(CS(STRUCT), VALUE)

View File

@ -27,6 +27,7 @@ CXX_GUARD_START
#define mSCRIPT_TYPE_C_S64 int64_t
#define mSCRIPT_TYPE_C_U64 uint64_t
#define mSCRIPT_TYPE_C_F64 double
#define mSCRIPT_TYPE_C_BOOL bool
#define mSCRIPT_TYPE_C_STR struct mScriptString*
#define mSCRIPT_TYPE_C_CHARP const char*
#define mSCRIPT_TYPE_C_PTR void*
@ -55,6 +56,7 @@ CXX_GUARD_START
#define mSCRIPT_TYPE_FIELD_S64 s64
#define mSCRIPT_TYPE_FIELD_U64 u64
#define mSCRIPT_TYPE_FIELD_F64 f64
#define mSCRIPT_TYPE_FIELD_BOOL u32
#define mSCRIPT_TYPE_FIELD_STR string
#define mSCRIPT_TYPE_FIELD_CHARP copaque
#define mSCRIPT_TYPE_FIELD_PTR opaque
@ -82,6 +84,7 @@ CXX_GUARD_START
#define mSCRIPT_TYPE_MS_S64 (&mSTSInt64)
#define mSCRIPT_TYPE_MS_U64 (&mSTUInt64)
#define mSCRIPT_TYPE_MS_F64 (&mSTFloat64)
#define mSCRIPT_TYPE_MS_BOOL (&mSTBool)
#define mSCRIPT_TYPE_MS_STR (&mSTString)
#define mSCRIPT_TYPE_MS_CHARP (&mSTCharPtr)
#define mSCRIPT_TYPE_MS_LIST (&mSTList)
@ -109,6 +112,7 @@ CXX_GUARD_START
#define mSCRIPT_TYPE_CMP_U64(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_U64, TYPE)
#define mSCRIPT_TYPE_CMP_S64(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_S64, TYPE)
#define mSCRIPT_TYPE_CMP_F64(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_F64, TYPE)
#define mSCRIPT_TYPE_CMP_BOOL(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_BOOL, TYPE)
#define mSCRIPT_TYPE_CMP_STR(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_STR, TYPE)
#define mSCRIPT_TYPE_CMP_CHARP(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_CHARP, TYPE)
#define mSCRIPT_TYPE_CMP_LIST(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_LIST, TYPE)
@ -165,6 +169,7 @@ extern const struct mScriptType mSTFloat32;
extern const struct mScriptType mSTSInt64;
extern const struct mScriptType mSTUInt64;
extern const struct mScriptType mSTFloat64;
extern const struct mScriptType mSTBool;
extern const struct mScriptType mSTString;
extern const struct mScriptType mSTCharPtr;
extern const struct mScriptType mSTList;
@ -329,6 +334,7 @@ bool mScriptPopF32(struct mScriptList* list, float* out);
bool mScriptPopS64(struct mScriptList* list, int64_t* out);
bool mScriptPopU64(struct mScriptList* list, uint64_t* out);
bool mScriptPopF64(struct mScriptList* list, double* out);
bool mScriptPopBool(struct mScriptList* list, bool* out);
bool mScriptPopPointer(struct mScriptList* list, void** out);
bool mScriptCast(const struct mScriptType* type, const struct mScriptValue* input, struct mScriptValue* output);

View File

@ -413,9 +413,9 @@ static void _mScriptCoreTakeScreenshot(struct mCore* core, const char* filename)
}
// Loading functions
mSCRIPT_DECLARE_STRUCT_METHOD(mCore, S32, loadFile, mCoreLoadFile, 1, CHARP, path);
mSCRIPT_DECLARE_STRUCT_METHOD(mCore, S32, autoloadSave, mCoreAutoloadSave, 0);
mSCRIPT_DECLARE_STRUCT_METHOD(mCore, S32, loadSaveFile, mCoreLoadSaveFile, 2, CHARP, path, S8, temporary);
mSCRIPT_DECLARE_STRUCT_METHOD(mCore, BOOL, loadFile, mCoreLoadFile, 1, CHARP, path);
mSCRIPT_DECLARE_STRUCT_METHOD(mCore, BOOL, autoloadSave, mCoreAutoloadSave, 0);
mSCRIPT_DECLARE_STRUCT_METHOD(mCore, BOOL, loadSaveFile, mCoreLoadSaveFile, 2, CHARP, path, BOOL, temporary);
// Info functions
mSCRIPT_DECLARE_STRUCT_CD_METHOD(mCore, S32, platform, 0);
@ -454,12 +454,12 @@ mSCRIPT_DECLARE_STRUCT_METHOD(mCore, WSTR, readRegister, _mScriptCoreReadRegiste
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(mCore, writeRegister, _mScriptCoreWriteRegister, 2, CHARP, regName, S32, value);
// Savestate functions
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, S32, saveStateSlot, mCoreSaveState, 2, S32, slot, S32, flags);
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, saveStateSlot, mCoreSaveState, 2, S32, slot, S32, flags);
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, WSTR, saveStateBuffer, _mScriptCoreSaveState, 1, S32, flags);
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, S32, saveStateFile, _mScriptCoreSaveStateFile, 2, CHARP, path, S32, flags);
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, S32, loadStateSlot, mCoreLoadState, 2, S32, slot, S32, flags);
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, S32, loadStateBuffer, _mScriptCoreLoadState, 2, STR, buffer, S32, flags);
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, S32, loadStateFile, _mScriptCoreLoadStateFile, 2, CHARP, path, S32, flags);
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, saveStateFile, _mScriptCoreSaveStateFile, 2, CHARP, path, S32, flags);
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, loadStateSlot, mCoreLoadState, 2, S32, slot, S32, flags);
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, loadStateBuffer, _mScriptCoreLoadState, 2, STR, buffer, S32, flags);
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(mCore, BOOL, loadStateFile, _mScriptCoreLoadStateFile, 2, CHARP, path, S32, flags);
// Miscellaneous functions
mSCRIPT_DECLARE_STRUCT_VOID_METHOD_WITH_DEFAULTS(mCore, screenshot, _mScriptCoreTakeScreenshot, 1, CHARP, filename);

View File

@ -335,8 +335,8 @@ struct mScriptValue* _luaCoerce(struct mScriptEngineContextLua* luaContext, bool
value->value.f64 = lua_tonumber(luaContext->lua, -1);
break;
case LUA_TBOOLEAN:
value = mScriptValueAlloc(mSCRIPT_TYPE_MS_S32);
value->value.s32 = lua_toboolean(luaContext->lua, -1);
value = mScriptValueAlloc(mSCRIPT_TYPE_MS_BOOL);
value->value.u32 = lua_toboolean(luaContext->lua, -1);
break;
case LUA_TSTRING:
buffer = lua_tolstring(luaContext->lua, -1, &size);
@ -414,7 +414,9 @@ bool _luaWrap(struct mScriptEngineContextLua* luaContext, struct mScriptValue* v
}
break;
case mSCRIPT_TYPE_UINT:
if (value->type->size <= 4) {
if (value->type == mSCRIPT_TYPE_MS_BOOL) {
lua_pushboolean(luaContext->lua, !!value->value.u32);
} else if (value->type->size <= 4) {
lua_pushinteger(luaContext->lua, value->value.u32);
} else if (value->type->size == 8) {
lua_pushinteger(luaContext->lua, value->value.u64);

View File

@ -206,41 +206,58 @@ M_TEST_DEFINE(wrongPopType) {
uint64_t u64;
float f32;
double f64;
bool b;
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, S32, 0);
assert_false(mScriptPopU32(&frame.arguments, &u32));
assert_false(mScriptPopF32(&frame.arguments, &f32));
assert_false(mScriptPopBool(&frame.arguments, &b));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, S64, 0);
assert_false(mScriptPopU64(&frame.arguments, &u64));
assert_false(mScriptPopF64(&frame.arguments, &f64));
assert_false(mScriptPopBool(&frame.arguments, &b));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, U32, 0);
assert_false(mScriptPopS32(&frame.arguments, &s32));
assert_false(mScriptPopF32(&frame.arguments, &f32));
assert_false(mScriptPopBool(&frame.arguments, &b));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, U64, 0);
assert_false(mScriptPopS64(&frame.arguments, &s64));
assert_false(mScriptPopF64(&frame.arguments, &f64));
assert_false(mScriptPopBool(&frame.arguments, &b));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, F32, 0);
assert_false(mScriptPopS32(&frame.arguments, &s32));
assert_false(mScriptPopU32(&frame.arguments, &u32));
assert_false(mScriptPopBool(&frame.arguments, &b));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, F64, 0);
assert_false(mScriptPopS64(&frame.arguments, &s64));
assert_false(mScriptPopU64(&frame.arguments, &u64));
assert_false(mScriptPopBool(&frame.arguments, &b));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, BOOL, 0);
assert_false(mScriptPopS32(&frame.arguments, &s32));
assert_false(mScriptPopU32(&frame.arguments, &u32));
assert_false(mScriptPopS64(&frame.arguments, &s64));
assert_false(mScriptPopU64(&frame.arguments, &u64));
assert_false(mScriptPopF32(&frame.arguments, &f32));
assert_false(mScriptPopF64(&frame.arguments, &f64));
mScriptFrameDeinit(&frame);
}
@ -382,6 +399,100 @@ M_TEST_DEFINE(coerceFromFloat) {
mScriptFrameDeinit(&frame);
}
M_TEST_DEFINE(coerceToBool) {
struct mScriptValue a;
struct mScriptValue b;
a = mSCRIPT_MAKE_S32(0);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_BOOL, &a, &b));
assert_true(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(false)));
assert_false(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(true)));
a = mSCRIPT_MAKE_S32(1);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_BOOL, &a, &b));
assert_true(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(true)));
assert_false(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(false)));
a = mSCRIPT_MAKE_S32(-1);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_BOOL, &a, &b));
assert_true(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(true)));
assert_false(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(false)));
a = mSCRIPT_MAKE_S32(INT_MAX);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_BOOL, &a, &b));
assert_true(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(true)));
assert_false(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(false)));
a = mSCRIPT_MAKE_S32(INT_MIN);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_BOOL, &a, &b));
assert_true(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(true)));
assert_false(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(false)));
a = mSCRIPT_MAKE_U32(0);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_BOOL, &a, &b));
assert_true(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(false)));
assert_false(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(true)));
a = mSCRIPT_MAKE_U32(1);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_BOOL, &a, &b));
assert_true(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(true)));
assert_false(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(false)));
a = mSCRIPT_MAKE_U32(UINT_MAX);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_BOOL, &a, &b));
assert_true(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(true)));
assert_false(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(false)));
a = mSCRIPT_MAKE_F32(0);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_BOOL, &a, &b));
assert_true(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(false)));
assert_false(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(true)));
a = mSCRIPT_MAKE_F32(1);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_BOOL, &a, &b));
assert_true(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(true)));
assert_false(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(false)));
a = mSCRIPT_MAKE_F32(1e30f);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_BOOL, &a, &b));
assert_true(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(true)));
assert_false(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(false)));
a = mSCRIPT_MAKE_F32(1e-30f);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_BOOL, &a, &b));
assert_true(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(true)));
assert_false(mSCRIPT_TYPE_MS_BOOL->equal(&b, &mSCRIPT_MAKE_BOOL(false)));
}
M_TEST_DEFINE(coerceFromBool) {
struct mScriptValue a;
struct mScriptValue b;
a = mSCRIPT_MAKE_BOOL(false);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_S32, &a, &b));
assert_true(mSCRIPT_TYPE_MS_S32->equal(&b, &mSCRIPT_MAKE_S32(0)));
a = mSCRIPT_MAKE_BOOL(true);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_S32, &a, &b));
assert_true(mSCRIPT_TYPE_MS_S32->equal(&b, &mSCRIPT_MAKE_S32(1)));
a = mSCRIPT_MAKE_BOOL(true);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_S32, &a, &b));
assert_false(mSCRIPT_TYPE_MS_S32->equal(&b, &mSCRIPT_MAKE_S32(-1)));
a = mSCRIPT_MAKE_BOOL(false);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_U32, &a, &b));
assert_true(mSCRIPT_TYPE_MS_U32->equal(&b, &mSCRIPT_MAKE_U32(0)));
a = mSCRIPT_MAKE_BOOL(true);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_U32, &a, &b));
assert_true(mSCRIPT_TYPE_MS_U32->equal(&b, &mSCRIPT_MAKE_U32(1)));
a = mSCRIPT_MAKE_BOOL(true);
assert_true(mScriptCast(mSCRIPT_TYPE_MS_U32, &a, &b));
assert_false(mSCRIPT_TYPE_MS_U32->equal(&b, &mSCRIPT_MAKE_U32(2)));
}
M_TEST_DEFINE(coerceWiden) {
struct mScriptFrame frame;
mScriptFrameInit(&frame);
@ -471,6 +582,20 @@ M_TEST_DEFINE(s32Equality) {
COMPARE_BOOL(false, S32, 0, F64, 0.1);
COMPARE_BOOL(true, S32, 0x40000000, F64, 0x40000000);
COMPARE_BOOL(true, S32, -0x40000000, F64, -0x40000000);
// BOOL
COMPARE_BOOL(true, S32, 0, BOOL, false);
COMPARE_BOOL(false, S32, 0, BOOL, true);
COMPARE_BOOL(false, S32, 1, BOOL, false);
COMPARE_BOOL(true, S32, 1, BOOL, true);
COMPARE_BOOL(false, S32, -1, BOOL, false);
COMPARE_BOOL(true, S32, -1, BOOL, true);
COMPARE_BOOL(false, S32, 2, BOOL, false);
COMPARE_BOOL(true, S32, 2, BOOL, true);
COMPARE_BOOL(false, S32, 0x7FFFFFFF, BOOL, false);
COMPARE_BOOL(true, S32, 0x7FFFFFFF, BOOL, true);
COMPARE_BOOL(false, S32, -0x80000000, BOOL, false);
COMPARE_BOOL(true, S32, -0x80000000, BOOL, true);
}
M_TEST_DEFINE(s64Equality) {
@ -552,6 +677,20 @@ M_TEST_DEFINE(s64Equality) {
COMPARE_BOOL(false, S64, 0, F64, 0.1);
COMPARE_BOOL(true, S64, 0x4000000000000000LL, F64, 0x4000000000000000LL);
COMPARE_BOOL(true, S64, -0x4000000000000000LL, F64, -0x4000000000000000LL);
// BOOL
COMPARE_BOOL(true, S64, 0, BOOL, false);
COMPARE_BOOL(false, S64, 0, BOOL, true);
COMPARE_BOOL(false, S64, 1, BOOL, false);
COMPARE_BOOL(true, S64, 1, BOOL, true);
COMPARE_BOOL(false, S64, -1, BOOL, false);
COMPARE_BOOL(true, S64, -1, BOOL, true);
COMPARE_BOOL(false, S64, 2, BOOL, false);
COMPARE_BOOL(true, S64, 2, BOOL, true);
COMPARE_BOOL(false, S64, 0x7FFFFFFFFFFFFFFFLL, BOOL, false);
COMPARE_BOOL(true, S64, 0x7FFFFFFFFFFFFFFFLL, BOOL, true);
COMPARE_BOOL(false, S64, -0x8000000000000000LL, BOOL, false);
COMPARE_BOOL(true, S64, -0x8000000000000000LL, BOOL, true);
}
M_TEST_DEFINE(u32Equality) {
@ -623,6 +762,18 @@ M_TEST_DEFINE(u32Equality) {
COMPARE_BOOL(false, U32, 0x80000000U, F64, 0);
COMPARE_BOOL(false, U32, 1, F64, 1.1);
COMPARE_BOOL(false, U32, 0, F64, 0.1);
// BOOL
COMPARE_BOOL(true, U32, 0, BOOL, false);
COMPARE_BOOL(false, U32, 0, BOOL, true);
COMPARE_BOOL(false, U32, 1, BOOL, false);
COMPARE_BOOL(true, U32, 1, BOOL, true);
COMPARE_BOOL(false, U32, 2, BOOL, false);
COMPARE_BOOL(true, U32, 2, BOOL, true);
COMPARE_BOOL(false, U32, 0xFFFFFFFFU, BOOL, false);
COMPARE_BOOL(true, U32, 0xFFFFFFFFU, BOOL, true);
COMPARE_BOOL(false, U32, 0x80000000U, BOOL, false);
COMPARE_BOOL(true, U32, 0x80000000U, BOOL, true);
}
M_TEST_DEFINE(u64Equality) {
@ -701,6 +852,18 @@ M_TEST_DEFINE(u64Equality) {
COMPARE_BOOL(false, U64, 0x8000000000000000ULL, F64, 0);
COMPARE_BOOL(false, U64, 1, F64, 1.1);
COMPARE_BOOL(false, U64, 0, F64, 0.1);
// BOOL
COMPARE_BOOL(true, U64, 0, BOOL, false);
COMPARE_BOOL(false, U64, 0, BOOL, true);
COMPARE_BOOL(false, U64, 1, BOOL, false);
COMPARE_BOOL(true, U64, 1, BOOL, true);
COMPARE_BOOL(false, U64, 2, BOOL, false);
COMPARE_BOOL(true, U64, 2, BOOL, true);
COMPARE_BOOL(false, U64, 0xFFFFFFFFFFFFFFFFULL, BOOL, false);
COMPARE_BOOL(true, U64, 0xFFFFFFFFFFFFFFFFULL, BOOL, true);
COMPARE_BOOL(false, U64, 0x8000000000000000ULL, BOOL, false);
COMPARE_BOOL(true, U64, 0x8000000000000000ULL, BOOL, true);
}
M_TEST_DEFINE(f32Equality) {
@ -768,6 +931,18 @@ M_TEST_DEFINE(f32Equality) {
COMPARE_BOOL(true, F32, 0x100000000ULL, U64, 0x100000000ULL);
COMPARE_BOOL(false, F32, 0x100000000ULL, U64, 0);
COMPARE_BOOL(false, F32, 0, U64, 0x100000000ULL);
// BOOL
COMPARE_BOOL(true, F32, 0, BOOL, false);
COMPARE_BOOL(false, F32, 0, BOOL, true);
COMPARE_BOOL(false, F32, 1, BOOL, false);
COMPARE_BOOL(true, F32, 1, BOOL, true);
COMPARE_BOOL(false, F32, 1.1, BOOL, false);
COMPARE_BOOL(true, F32, 1.1, BOOL, true);
COMPARE_BOOL(false, F32, 0x040000000ULL, BOOL, false);
COMPARE_BOOL(true, F32, 0x040000000ULL, BOOL, true);
COMPARE_BOOL(false, F32, 0x100000000ULL, BOOL, false);
COMPARE_BOOL(true, F32, 0x100000000ULL, BOOL, true);
}
M_TEST_DEFINE(f64Equality) {
@ -835,6 +1010,107 @@ M_TEST_DEFINE(f64Equality) {
COMPARE_BOOL(true, F64, 0x100000000ULL, U64, 0x100000000ULL);
COMPARE_BOOL(false, F64, 0x100000000ULL, U64, 0);
COMPARE_BOOL(false, F64, 0, U64, 0x100000000ULL);
// BOOL
COMPARE_BOOL(true, F64, 0, BOOL, false);
COMPARE_BOOL(false, F64, 0, BOOL, true);
COMPARE_BOOL(false, F64, 1, BOOL, false);
COMPARE_BOOL(true, F64, 1, BOOL, true);
COMPARE_BOOL(false, F64, 1.1, BOOL, false);
COMPARE_BOOL(true, F64, 1.1, BOOL, true);
COMPARE_BOOL(false, F64, 0x040000000ULL, BOOL, false);
COMPARE_BOOL(true, F64, 0x040000000ULL, BOOL, true);
COMPARE_BOOL(false, F64, 0x100000000ULL, BOOL, false);
COMPARE_BOOL(true, F64, 0x100000000ULL, BOOL, true);
}
M_TEST_DEFINE(boolEquality) {
struct mScriptValue a;
struct mScriptValue b;
// S32
COMPARE_BOOL(true, BOOL, false, S32, 0);
COMPARE_BOOL(false, BOOL, false, S32, 1);
COMPARE_BOOL(false, BOOL, false, S32, -1);
COMPARE_BOOL(false, BOOL, false, S32, 2);
COMPARE_BOOL(false, BOOL, false, S32, 0x7FFFFFFF);
COMPARE_BOOL(false, BOOL, false, S32, -0x80000000);
COMPARE_BOOL(false, BOOL, true, S32, 0);
COMPARE_BOOL(true, BOOL, true, S32, 1);
COMPARE_BOOL(true, BOOL, true, S32, -1);
COMPARE_BOOL(true, BOOL, true, S32, 2);
COMPARE_BOOL(true, BOOL, true, S32, 0x7FFFFFFF);
COMPARE_BOOL(true, BOOL, true, S32, -0x80000000);
// S64
COMPARE_BOOL(true, BOOL, false, S64, 0);
COMPARE_BOOL(false, BOOL, false, S64, 1);
COMPARE_BOOL(false, BOOL, false, S64, -1);
COMPARE_BOOL(false, BOOL, false, S64, 2);
COMPARE_BOOL(false, BOOL, false, S64, INT64_MIN);
COMPARE_BOOL(false, BOOL, false, S64, INT64_MAX);
COMPARE_BOOL(false, BOOL, true, S64, 0);
COMPARE_BOOL(true, BOOL, true, S64, 1);
COMPARE_BOOL(true, BOOL, true, S64, -1);
COMPARE_BOOL(true, BOOL, true, S64, 2);
COMPARE_BOOL(true, BOOL, true, S64, INT64_MIN);
COMPARE_BOOL(true, BOOL, true, S64, INT64_MAX);
// U32
COMPARE_BOOL(true, BOOL, false, U32, 0);
COMPARE_BOOL(false, BOOL, false, U32, 1);
COMPARE_BOOL(false, BOOL, false, U32, 2);
COMPARE_BOOL(false, BOOL, false, U32, UINT32_MAX);
COMPARE_BOOL(false, BOOL, true, U32, 0);
COMPARE_BOOL(true, BOOL, true, U32, 1);
COMPARE_BOOL(true, BOOL, true, U32, 2);
COMPARE_BOOL(true, BOOL, true, U32, UINT32_MAX);
// U64
COMPARE_BOOL(true, BOOL, false, U64, 0);
COMPARE_BOOL(false, BOOL, false, U64, 1);
COMPARE_BOOL(false, BOOL, false, U64, 2);
COMPARE_BOOL(false, BOOL, false, U64, INT64_MAX);
COMPARE_BOOL(false, BOOL, true, U64, 0);
COMPARE_BOOL(true, BOOL, true, U64, 1);
COMPARE_BOOL(true, BOOL, true, U64, 2);
COMPARE_BOOL(true, BOOL, true, U64, INT64_MAX);
// F32
COMPARE_BOOL(true, BOOL, false, F32, 0);
COMPARE_BOOL(false, BOOL, true, F32, 0);
COMPARE_BOOL(false, BOOL, false, F32, 1);
COMPARE_BOOL(true, BOOL, true, F32, 1);
COMPARE_BOOL(false, BOOL, false, F32, 1.1f);
COMPARE_BOOL(true, BOOL, true, F32, 1.1f);
COMPARE_BOOL(false, BOOL, false, F32, 1e30f);
COMPARE_BOOL(true, BOOL, true, F32, 1e30f);
COMPARE_BOOL(false, BOOL, false, F32, -1);
COMPARE_BOOL(true, BOOL, true, F32, -1);
COMPARE_BOOL(false, BOOL, false, F32, -1.1f);
COMPARE_BOOL(true, BOOL, true, F32, -1.1f);
COMPARE_BOOL(false, BOOL, false, F32, -0.1e-30f);
COMPARE_BOOL(true, BOOL, true, F32, -0.1e-30f);
COMPARE_BOOL(false, BOOL, false, F32, -1e30f);
COMPARE_BOOL(true, BOOL, true, F32, -1e30f);
// F64
COMPARE_BOOL(true, BOOL, false, F64, 0);
COMPARE_BOOL(false, BOOL, true, F64, 0);
COMPARE_BOOL(false, BOOL, false, F64, 1);
COMPARE_BOOL(true, BOOL, true, F64, 1);
COMPARE_BOOL(false, BOOL, false, F64, 1.1);
COMPARE_BOOL(true, BOOL, true, F64, 1.1);
COMPARE_BOOL(false, BOOL, false, F64, 1e30);
COMPARE_BOOL(true, BOOL, true, F64, 1e30);
COMPARE_BOOL(false, BOOL, false, F64, -1);
COMPARE_BOOL(true, BOOL, true, F64, -1);
COMPARE_BOOL(false, BOOL, false, F64, -1.1);
COMPARE_BOOL(true, BOOL, true, F64, -1.1);
COMPARE_BOOL(false, BOOL, false, F64, -0.1e-300);
COMPARE_BOOL(true, BOOL, true, F64, -0.1e-300);
COMPARE_BOOL(false, BOOL, false, F64, -1e300);
COMPARE_BOOL(true, BOOL, true, F64, -1e300);
}
M_TEST_DEFINE(stringEquality) {
@ -1002,6 +1278,8 @@ M_TEST_SUITE_DEFINE(mScript,
cmocka_unit_test(wrongConst),
cmocka_unit_test(coerceToFloat),
cmocka_unit_test(coerceFromFloat),
cmocka_unit_test(coerceToBool),
cmocka_unit_test(coerceFromBool),
cmocka_unit_test(coerceNarrow),
cmocka_unit_test(coerceWiden),
cmocka_unit_test(s32Equality),
@ -1010,6 +1288,7 @@ M_TEST_SUITE_DEFINE(mScript,
cmocka_unit_test(u64Equality),
cmocka_unit_test(f32Equality),
cmocka_unit_test(f64Equality),
cmocka_unit_test(boolEquality),
cmocka_unit_test(stringEquality),
cmocka_unit_test(hashTableBasic),
cmocka_unit_test(hashTableString),

View File

@ -38,6 +38,7 @@ static bool _f32Equal(const struct mScriptValue*, const struct mScriptValue*);
static bool _s64Equal(const struct mScriptValue*, const struct mScriptValue*);
static bool _u64Equal(const struct mScriptValue*, const struct mScriptValue*);
static bool _f64Equal(const struct mScriptValue*, const struct mScriptValue*);
static bool _boolEqual(const struct mScriptValue*, const struct mScriptValue*);
static bool _charpEqual(const struct mScriptValue*, const struct mScriptValue*);
static bool _stringEqual(const struct mScriptValue*, const struct mScriptValue*);
@ -162,6 +163,17 @@ const struct mScriptType mSTFloat64 = {
.cast = _castScalar,
};
const struct mScriptType mSTBool = {
.base = mSCRIPT_TYPE_UINT,
.size = 1,
.name = "bool",
.alloc = NULL,
.free = NULL,
.hash = _hashScalar,
.equal = _boolEqual,
.cast = _castScalar,
};
const struct mScriptType mSTString = {
.base = mSCRIPT_TYPE_STRING,
.size = sizeof(struct mScriptString),
@ -394,6 +406,7 @@ AS(Float32, F32);
AS(SInt64, S64);
AS(UInt64, U64);
AS(Float64, F64);
AS(Bool, BOOL);
bool _castScalar(const struct mScriptValue* input, const struct mScriptType* type, struct mScriptValue* output) {
switch (type->base) {
@ -411,7 +424,13 @@ bool _castScalar(const struct mScriptValue* input, const struct mScriptType* typ
}
break;
case mSCRIPT_TYPE_UINT:
if (type->size <= 4) {
if (type == mSCRIPT_TYPE_MS_BOOL) {
bool b;
if (!_asBool(input, &b)) {
return false;
}
output->value.u32 = b;
} else if (type->size <= 4) {
if (!_asUInt32(input, &output->value.u32)) {
return false;
}
@ -485,6 +504,9 @@ bool _s32Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
}
break;
case mSCRIPT_TYPE_UINT:
if (b->type == mSCRIPT_TYPE_MS_BOOL) {
return !!a->value.s32 == b->value.u32;
}
if (a->value.s32 < 0) {
return false;
}
@ -532,6 +554,9 @@ bool _u32Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
}
break;
case mSCRIPT_TYPE_UINT:
if (b->type == mSCRIPT_TYPE_MS_BOOL) {
return !!a->value.u32 == b->value.u32;
}
if (b->type->size <= 4) {
val = b->value.u32;
} else if (b->type->size == 8) {
@ -554,8 +579,12 @@ bool _u32Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
bool _f32Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
float val;
switch (b->type->base) {
case mSCRIPT_TYPE_SINT:
case mSCRIPT_TYPE_UINT:
if (b->type == mSCRIPT_TYPE_MS_BOOL) {
return (!(uint32_t) !a->value.f32)== b->value.u32;
}
// Fall through
case mSCRIPT_TYPE_SINT:
case mSCRIPT_TYPE_FLOAT:
if (!_asFloat32(b, &val)) {
return false;
@ -582,6 +611,9 @@ bool _s64Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
}
break;
case mSCRIPT_TYPE_UINT:
if (b->type == mSCRIPT_TYPE_MS_BOOL) {
return !!a->value.s64 == b->value.u32;
}
if (a->value.s64 < 0) {
return false;
}
@ -629,6 +661,9 @@ bool _u64Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
}
break;
case mSCRIPT_TYPE_UINT:
if (b->type == mSCRIPT_TYPE_MS_BOOL) {
return !!a->value.u64 == b->value.u32;
}
if (b->type->size <= 4) {
val = b->value.u32;
} else if (b->type->size == 8) {
@ -648,8 +683,12 @@ bool _u64Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
bool _f64Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
double val;
switch (b->type->base) {
case mSCRIPT_TYPE_SINT:
case mSCRIPT_TYPE_UINT:
if (b->type == mSCRIPT_TYPE_MS_BOOL) {
return (!(uint32_t) !a->value.f64)== b->value.u32;
}
// Fall through
case mSCRIPT_TYPE_SINT:
case mSCRIPT_TYPE_FLOAT:
if (!_asFloat64(b, &val)) {
return false;
@ -663,6 +702,29 @@ bool _f64Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
return a->value.f64 == val;
}
bool _boolEqual(const struct mScriptValue* a, const struct mScriptValue* b) {
switch (b->type->base) {
case mSCRIPT_TYPE_SINT:
if (b->type->size <= 4) {
return a->value.u32 == !!b->value.s32;
} else if (b->type->size == 8) {
return a->value.u32 == !!b->value.s64;
}
return false;
case mSCRIPT_TYPE_UINT:
if (b->type->size <= 4) {
return a->value.u32 == !!b->value.u32;
} else if (b->type->size == 8) {
return a->value.u32 == !!b->value.u64;
}
return false;
case mSCRIPT_TYPE_VOID:
return false;
default:
return b->type->equal && b->type->equal(b, a);
}
}
bool _charpEqual(const struct mScriptValue* a, const struct mScriptValue* b) {
const char* valA = a->value.opaque;
const char* valB;
@ -1368,6 +1430,12 @@ bool mScriptPopF64(struct mScriptList* list, double* out) {
return true;
}
bool mScriptPopBool(struct mScriptList* list, bool* out) {
mSCRIPT_POP(list, BOOL, val);
*out = val;
return true;
}
bool mScriptPopPointer(struct mScriptList* list, void** out) {
mSCRIPT_POP(list, PTR, val);
*out = val;