Scripting: Add 64-bit types

This commit is contained in:
Vicki Pfau 2022-02-16 00:45:51 -08:00
parent cbae6a61e5
commit 2a81e5a1ba
3 changed files with 804 additions and 231 deletions

View File

@ -20,6 +20,9 @@ CXX_GUARD_START
#define mSCRIPT_TYPE_C_S32 int32_t
#define mSCRIPT_TYPE_C_U32 uint32_t
#define mSCRIPT_TYPE_C_F32 float
#define mSCRIPT_TYPE_C_S64 int64_t
#define mSCRIPT_TYPE_C_U64 uint64_t
#define mSCRIPT_TYPE_C_F64 double
#define mSCRIPT_TYPE_C_STR mScriptString*
#define mSCRIPT_TYPE_C_CHARP const char*
#define mSCRIPT_TYPE_C_PTR void*
@ -29,6 +32,9 @@ CXX_GUARD_START
#define mSCRIPT_TYPE_FIELD_S32 s32
#define mSCRIPT_TYPE_FIELD_U32 u32
#define mSCRIPT_TYPE_FIELD_F32 f32
#define mSCRIPT_TYPE_FIELD_S64 s64
#define mSCRIPT_TYPE_FIELD_U64 u64
#define mSCRIPT_TYPE_FIELD_F64 f64
#define mSCRIPT_TYPE_FIELD_STR opaque
#define mSCRIPT_TYPE_FIELD_CHARP opaque
#define mSCRIPT_TYPE_FIELD_PTR opaque
@ -38,6 +44,9 @@ CXX_GUARD_START
#define mSCRIPT_TYPE_MS_S32 (&mSTSInt32)
#define mSCRIPT_TYPE_MS_U32 (&mSTUInt32)
#define mSCRIPT_TYPE_MS_F32 (&mSTFloat32)
#define mSCRIPT_TYPE_MS_S64 (&mSTSInt64)
#define mSCRIPT_TYPE_MS_U64 (&mSTUInt64)
#define mSCRIPT_TYPE_MS_F64 (&mSTFloat64)
#define mSCRIPT_TYPE_MS_STR (&mSTString)
#define mSCRIPT_TYPE_MS_CHARP (&mSTCharPtr)
#define mSCRIPT_TYPE_MS_TABLE (&mSTTable)
@ -49,6 +58,9 @@ CXX_GUARD_START
#define mSCRIPT_TYPE_CMP_U32(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_U32, TYPE)
#define mSCRIPT_TYPE_CMP_S32(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_S32, TYPE)
#define mSCRIPT_TYPE_CMP_F32(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_F32, TYPE)
#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_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_PTR(TYPE) ((TYPE)->base >= mSCRIPT_TYPE_OPAQUE)
@ -174,6 +186,9 @@ CXX_GUARD_START
#define mSCRIPT_MAKE_S32(VALUE) mSCRIPT_MAKE(mSCRIPT_TYPE_MS_S32, s32, VALUE)
#define mSCRIPT_MAKE_U32(VALUE) mSCRIPT_MAKE(mSCRIPT_TYPE_MS_U32, u32, VALUE)
#define mSCRIPT_MAKE_F32(VALUE) mSCRIPT_MAKE(mSCRIPT_TYPE_MS_F32, f32, VALUE)
#define mSCRIPT_MAKE_S64(VALUE) mSCRIPT_MAKE(mSCRIPT_TYPE_MS_S64, s64, VALUE)
#define mSCRIPT_MAKE_U64(VALUE) mSCRIPT_MAKE(mSCRIPT_TYPE_MS_U64, u64, VALUE)
#define mSCRIPT_MAKE_F64(VALUE) mSCRIPT_MAKE(mSCRIPT_TYPE_MS_F64, f64, VALUE)
#define mSCRIPT_MAKE_CHARP(VALUE) mSCRIPT_MAKE(mSCRIPT_TYPE_MS_CHARP, opaque, VALUE)
enum {
@ -196,6 +211,9 @@ extern const struct mScriptType mSTVoid;
extern const struct mScriptType mSTSInt32;
extern const struct mScriptType mSTUInt32;
extern const struct mScriptType mSTFloat32;
extern const struct mScriptType mSTSInt64;
extern const struct mScriptType mSTUInt64;
extern const struct mScriptType mSTFloat64;
extern const struct mScriptType mSTString;
extern const struct mScriptType mSTCharPtr;
extern const struct mScriptType mSTTable;
@ -235,6 +253,9 @@ struct mScriptValue {
int32_t s32;
uint32_t u32;
float f32;
int64_t s64;
uint64_t u64;
double f64;
void* opaque;
} value;
};
@ -275,6 +296,9 @@ void mScriptFrameDeinit(struct mScriptFrame* frame);
bool mScriptPopS32(struct mScriptList* list, int32_t* out);
bool mScriptPopU32(struct mScriptList* list, uint32_t* out);
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 mScriptPopPointer(struct mScriptList* list, void** out);
bool mScriptCast(const struct mScriptType* type, const struct mScriptValue* input, struct mScriptValue* output);

View File

@ -25,6 +25,10 @@ static int identityInt(int in) {
return in;
}
static int64_t identityInt64(int64_t in) {
return in;
}
static float identityFloat(float in) {
return in;
}
@ -48,6 +52,7 @@ static int isHello(const char* str) {
mSCRIPT_BIND_FUNCTION(boundVoidOne, S32, voidOne, 0);
mSCRIPT_BIND_VOID_FUNCTION(boundDiscard, discard, 1, S32);
mSCRIPT_BIND_FUNCTION(boundIdentityInt, S32, identityInt, 1, S32);
mSCRIPT_BIND_FUNCTION(boundIdentityInt64, S64, identityInt64, 1, S64);
mSCRIPT_BIND_FUNCTION(boundIdentityFloat, F32, identityFloat, 1, F32);
mSCRIPT_BIND_FUNCTION(boundIdentityStruct, S(Test), identityStruct, 1, S(Test));
mSCRIPT_BIND_FUNCTION(boundAddInts, S32, addInts, 2, S32, S32);
@ -83,6 +88,17 @@ M_TEST_DEFINE(identityFunctionS32) {
mScriptFrameDeinit(&frame);
}
M_TEST_DEFINE(identityFunctionS64) {
struct mScriptFrame frame;
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, S64, 1);
assert_true(mScriptInvoke(&boundIdentityInt64, &frame));
int64_t val;
assert_true(mScriptPopS64(&frame.returnValues, &val));
assert_int_equal(val, 1);
mScriptFrameDeinit(&frame);
}
M_TEST_DEFINE(identityFunctionF32) {
struct mScriptFrame frame;
mScriptFrameInit(&frame);
@ -154,6 +170,92 @@ M_TEST_DEFINE(wrongArgType) {
mScriptFrameDeinit(&frame);
}
M_TEST_DEFINE(wrongPopType) {
struct mScriptFrame frame;
int32_t s32;
int64_t s64;
uint32_t u32;
uint64_t u64;
float f32;
double f64;
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, S32, 0);
assert_false(mScriptPopU32(&frame.arguments, &u32));
assert_false(mScriptPopF32(&frame.arguments, &f32));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, S64, 0);
assert_false(mScriptPopU64(&frame.arguments, &u64));
assert_false(mScriptPopF64(&frame.arguments, &f64));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, U32, 0);
assert_false(mScriptPopS32(&frame.arguments, &s32));
assert_false(mScriptPopF32(&frame.arguments, &f32));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, U64, 0);
assert_false(mScriptPopS64(&frame.arguments, &s64));
assert_false(mScriptPopF64(&frame.arguments, &f64));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, F32, 0);
assert_false(mScriptPopS32(&frame.arguments, &s32));
assert_false(mScriptPopU32(&frame.arguments, &u32));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, F64, 0);
assert_false(mScriptPopS64(&frame.arguments, &s64));
assert_false(mScriptPopU64(&frame.arguments, &u64));
mScriptFrameDeinit(&frame);
}
M_TEST_DEFINE(wrongPopSize) {
struct mScriptFrame frame;
int32_t s32;
int64_t s64;
uint32_t u32;
uint64_t u64;
float f32;
double f64;
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, S32, 0);
assert_false(mScriptPopS64(&frame.arguments, &s64));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, S64, 0);
assert_false(mScriptPopS32(&frame.arguments, &s32));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, U32, 0);
assert_false(mScriptPopU64(&frame.arguments, &u64));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, U64, 0);
assert_false(mScriptPopU32(&frame.arguments, &u32));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, F32, 0);
assert_false(mScriptPopF64(&frame.arguments, &f64));
mScriptFrameDeinit(&frame);
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, F64, 0);
assert_false(mScriptPopF32(&frame.arguments, &f32));
mScriptFrameDeinit(&frame);
}
M_TEST_DEFINE(coerceToFloat) {
struct mScriptFrame frame;
mScriptFrameInit(&frame);
@ -176,233 +278,459 @@ M_TEST_DEFINE(coerceFromFloat) {
mScriptFrameDeinit(&frame);
}
M_TEST_DEFINE(coerceWiden) {
struct mScriptFrame frame;
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, S32, -1);
assert_true(mScriptInvoke(&boundIdentityInt64, &frame));
int64_t val;
assert_true(mScriptPopS64(&frame.returnValues, &val));
assert_true(val == -1LL);
mScriptFrameDeinit(&frame);
}
M_TEST_DEFINE(coerceNarrow) {
struct mScriptFrame frame;
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, S64, -1);
assert_true(mScriptInvoke(&boundIdentityInt, &frame));
int32_t val;
assert_true(mScriptPopS32(&frame.returnValues, &val));
assert_true(val == -1);
mScriptFrameDeinit(&frame);
}
#define COMPARE_BOOL(EXPECT, T0, V0, T1, V1) \
a = mSCRIPT_MAKE_ ## T0 (V0); \
b = mSCRIPT_MAKE_ ## T1 (V1); \
assert_ ## EXPECT (a.type->equal(&a, &b));
M_TEST_DEFINE(s32Equality) {
struct mScriptValue s32A;
struct mScriptValue s32B;
struct mScriptValue u32;
struct mScriptValue f32;
struct mScriptValue a;
struct mScriptValue b;
s32A = mSCRIPT_MAKE_S32(0);
s32B = mSCRIPT_MAKE_S32(0);
assert_true(s32A.type->equal(&s32A, &s32B));
// S32
COMPARE_BOOL(true, S32, 0, S32, 0);
COMPARE_BOOL(false, S32, 0, S32, 1);
COMPARE_BOOL(true, S32, 1, S32, 1);
COMPARE_BOOL(false, S32, 1, S32, -1);
COMPARE_BOOL(true, S32, -1, S32, -1);
s32B = mSCRIPT_MAKE_S32(1);
assert_false(s32A.type->equal(&s32A, &s32B));
// S64
COMPARE_BOOL(true, S32, 0, S64, 0);
COMPARE_BOOL(false, S32, 0, S64, 1);
COMPARE_BOOL(true, S32, 1, S64, 1);
COMPARE_BOOL(false, S32, 1, S64, -1);
COMPARE_BOOL(true, S32, -1, S64, -1);
COMPARE_BOOL(false, S32, 0, S64, 0x100000000LL);
COMPARE_BOOL(false, S32, -1, S64, 0x1FFFFFFFFLL);
COMPARE_BOOL(false, S32, -1, S64, -0x100000001LL);
s32A = mSCRIPT_MAKE_S32(1);
assert_true(s32A.type->equal(&s32A, &s32B));
// U32
COMPARE_BOOL(true, S32, 0, U32, 0);
COMPARE_BOOL(false, S32, 0, U32, 1);
COMPARE_BOOL(true, S32, 1, U32, 1);
COMPARE_BOOL(true, S32, 0x7FFFFFFF, U32, 0x7FFFFFFFU);
COMPARE_BOOL(false, S32, 0xFFFFFFFF, U32, 0xFFFFFFFFU);
COMPARE_BOOL(false, S32, 0x80000000, U32, 0x80000000U);
s32B = mSCRIPT_MAKE_S32(-1);
assert_false(s32A.type->equal(&s32A, &s32B));
// U64
COMPARE_BOOL(true, S32, 0, U64, 0);
COMPARE_BOOL(false, S32, 0, U64, 1);
COMPARE_BOOL(true, S32, 1, U64, 1);
COMPARE_BOOL(true, S32, 0x7FFFFFFF, U64, 0x7FFFFFFFULL);
COMPARE_BOOL(false, S32, 0xFFFFFFFF, U64, 0xFFFFFFFFULL);
COMPARE_BOOL(false, S32, 0x80000000, U64, 0x80000000ULL);
s32A = mSCRIPT_MAKE_S32(-1);
assert_true(s32A.type->equal(&s32A, &s32B));
// F32
COMPARE_BOOL(true, S32, 0, F32, 0);
COMPARE_BOOL(false, S32, 1, F32, 0);
COMPARE_BOOL(false, S32, 0, F32, 1);
COMPARE_BOOL(true, S32, 1, F32, 1);
COMPARE_BOOL(false, S32, 0, F32, -1);
COMPARE_BOOL(false, S32, 1, F32, -1);
COMPARE_BOOL(true, S32, -1, F32, -1);
COMPARE_BOOL(false, S32, 1, F32, 1.1);
COMPARE_BOOL(false, S32, 0, F32, 0.1);
COMPARE_BOOL(true, S32, 0x40000000, F32, 0x40000000);
COMPARE_BOOL(true, S32, -0x40000000, F32, -0x40000000);
s32A = mSCRIPT_MAKE_S32(0);
u32 = mSCRIPT_MAKE_U32(0);
assert_true(s32A.type->equal(&s32A, &u32));
// F64
COMPARE_BOOL(true, S32, 0, F64, 0);
COMPARE_BOOL(false, S32, 1, F64, 0);
COMPARE_BOOL(false, S32, 0, F64, 1);
COMPARE_BOOL(true, S32, 1, F64, 1);
COMPARE_BOOL(false, S32, 0, F64, -1);
COMPARE_BOOL(false, S32, 1, F64, -1);
COMPARE_BOOL(true, S32, -1, F64, -1);
COMPARE_BOOL(false, S32, 1, F64, 1.1);
COMPARE_BOOL(false, S32, 0, F64, 0.1);
COMPARE_BOOL(true, S32, 0x40000000, F64, 0x40000000);
COMPARE_BOOL(true, S32, -0x40000000, F64, -0x40000000);
}
s32A = mSCRIPT_MAKE_S32(1);
u32 = mSCRIPT_MAKE_U32(1);
assert_true(s32A.type->equal(&s32A, &u32));
M_TEST_DEFINE(s64Equality) {
struct mScriptValue a;
struct mScriptValue b;
s32A = mSCRIPT_MAKE_S32(0);
u32 = mSCRIPT_MAKE_U32(1);
assert_false(s32A.type->equal(&s32A, &u32));
// S32
COMPARE_BOOL(true, S64, 0, S32, 0);
COMPARE_BOOL(false, S64, 0, S32, 1);
COMPARE_BOOL(true, S64, 1, S32, 1);
COMPARE_BOOL(false, S64, 1, S32, -1);
COMPARE_BOOL(true, S64, -1, S32, -1);
COMPARE_BOOL(false, S64, 0x100000000LL, S32, 0);
COMPARE_BOOL(false, S64, 0x1FFFFFFFFLL, S32, -1);
COMPARE_BOOL(false, S64, -0x100000001LL, S32, -1);
s32A = mSCRIPT_MAKE_S32(1);
u32 = mSCRIPT_MAKE_U32(0);
assert_false(s32A.type->equal(&s32A, &u32));
// S64
COMPARE_BOOL(true, S64, 0, S64, 0);
COMPARE_BOOL(false, S64, 0, S64, 1);
COMPARE_BOOL(true, S64, 1, S64, 1);
COMPARE_BOOL(false, S64, 1, S64, -1);
COMPARE_BOOL(true, S64, -1, S64, -1);
COMPARE_BOOL(false, S64, 0, S64, 0x100000000LL);
COMPARE_BOOL(false, S64, -1, S64, 0x1FFFFFFFFLL);
COMPARE_BOOL(false, S64, -1, S64, -0x100000001LL);
COMPARE_BOOL(false, S64, 0x100000000LL, S64, 0);
COMPARE_BOOL(false, S64, 0x1FFFFFFFFLL, S64, -1);
COMPARE_BOOL(false, S64, -0x100000001LL, S64, -1);
COMPARE_BOOL(true, S64, 0x100000000LL, S64, 0x100000000LL);
COMPARE_BOOL(true, S64, 0x1FFFFFFFFLL, S64, 0x1FFFFFFFFLL);
COMPARE_BOOL(true, S64, -0x100000001LL, S64, -0x100000001LL);
s32A = mSCRIPT_MAKE_S32(0x7FFFFFFF);
u32 = mSCRIPT_MAKE_U32(0x7FFFFFFF);
assert_true(s32A.type->equal(&s32A, &u32));
// U32
COMPARE_BOOL(true, S64, 0, U32, 0);
COMPARE_BOOL(false, S64, 0, U32, 1);
COMPARE_BOOL(true, S64, 1, U32, 1);
COMPARE_BOOL(true, S64, 0x7FFFFFFFLL, U32, 0x7FFFFFFFU);
COMPARE_BOOL(true, S64, 0xFFFFFFFFLL, U32, 0xFFFFFFFFU);
COMPARE_BOOL(true, S64, 0x80000000LL, U32, 0x80000000U);
COMPARE_BOOL(false, S64, -1, U32, 0xFFFFFFFFU);
COMPARE_BOOL(false, S64, -0x80000000LL, U32, 0x80000000U);
s32A = mSCRIPT_MAKE_S32(0xFFFFFFFF);
u32 = mSCRIPT_MAKE_U32(0xFFFFFFFF);
assert_false(s32A.type->equal(&s32A, &u32));
// U64
COMPARE_BOOL(true, S64, 0, U64, 0);
COMPARE_BOOL(false, S64, 0, U64, 1);
COMPARE_BOOL(true, S64, 1, U64, 1);
COMPARE_BOOL(true, S64, 0x07FFFFFFFLL, U64, 0x07FFFFFFFULL);
COMPARE_BOOL(true, S64, 0x0FFFFFFFFLL, U64, 0x0FFFFFFFFULL);
COMPARE_BOOL(true, S64, 0x080000000LL, U64, 0x080000000ULL);
COMPARE_BOOL(false, S64, 0, U64, 0x100000000ULL);
COMPARE_BOOL(false, S64, 0x100000000LL, U64, 0);
COMPARE_BOOL(true, S64, 0x100000000LL, U64, 0x100000000ULL);
COMPARE_BOOL(false, S64, -1, U64, 0x0FFFFFFFFULL);
COMPARE_BOOL(false, S64, -1, U64, 0xFFFFFFFFFFFFFFFFULL);
COMPARE_BOOL(false, S64, -0x080000000LL, U64, 0x080000000ULL);
s32A = mSCRIPT_MAKE_S32(0x80000000);
u32 = mSCRIPT_MAKE_U32(0x80000000);
assert_false(s32A.type->equal(&s32A, &u32));
// F32
COMPARE_BOOL(true, S64, 0, F32, 0);
COMPARE_BOOL(false, S64, 1, F32, 0);
COMPARE_BOOL(false, S64, 0, F32, 1);
COMPARE_BOOL(true, S64, 1, F32, 1);
COMPARE_BOOL(false, S64, 0, F32, -1);
COMPARE_BOOL(false, S64, 1, F32, -1);
COMPARE_BOOL(true, S64, -1, F32, -1);
COMPARE_BOOL(false, S64, 1, F32, 1.1);
COMPARE_BOOL(false, S64, 0, F32, 0.1);
COMPARE_BOOL(true, S64, 0x4000000000000000LL, F32, 0x4000000000000000LL);
COMPARE_BOOL(true, S64, -0x4000000000000000LL, F32, -0x4000000000000000LL);
s32A = mSCRIPT_MAKE_S32(0);
f32 = mSCRIPT_MAKE_F32(0);
assert_true(s32A.type->equal(&s32A, &f32));
s32A = mSCRIPT_MAKE_S32(1);
f32 = mSCRIPT_MAKE_F32(1);
assert_true(s32A.type->equal(&s32A, &f32));
s32A = mSCRIPT_MAKE_S32(0);
f32 = mSCRIPT_MAKE_F32(1);
assert_false(s32A.type->equal(&s32A, &f32));
s32A = mSCRIPT_MAKE_S32(1);
f32 = mSCRIPT_MAKE_F32(0);
assert_false(s32A.type->equal(&s32A, &f32));
s32A = mSCRIPT_MAKE_S32(-1);
f32 = mSCRIPT_MAKE_F32(-1);
assert_true(s32A.type->equal(&s32A, &f32));
s32A = mSCRIPT_MAKE_S32(0);
f32 = mSCRIPT_MAKE_F32(-1);
assert_false(s32A.type->equal(&s32A, &f32));
s32A = mSCRIPT_MAKE_S32(-1);
f32 = mSCRIPT_MAKE_F32(0);
assert_false(s32A.type->equal(&s32A, &f32));
// F64
COMPARE_BOOL(true, S64, 0, F64, 0);
COMPARE_BOOL(false, S64, 1, F64, 0);
COMPARE_BOOL(false, S64, 0, F64, 1);
COMPARE_BOOL(true, S64, 1, F64, 1);
COMPARE_BOOL(false, S64, 0, F64, -1);
COMPARE_BOOL(false, S64, 1, F64, -1);
COMPARE_BOOL(true, S64, -1, F64, -1);
COMPARE_BOOL(false, S64, 1, F64, 1.1);
COMPARE_BOOL(false, S64, 0, F64, 0.1);
COMPARE_BOOL(true, S64, 0x4000000000000000LL, F64, 0x4000000000000000LL);
COMPARE_BOOL(true, S64, -0x4000000000000000LL, F64, -0x4000000000000000LL);
}
M_TEST_DEFINE(u32Equality) {
struct mScriptValue u32A;
struct mScriptValue u32B;
struct mScriptValue s32;
struct mScriptValue f32;
struct mScriptValue a;
struct mScriptValue b;
u32A = mSCRIPT_MAKE_U32(0);
u32B = mSCRIPT_MAKE_U32(0);
assert_true(u32A.type->equal(&u32A, &u32B));
// U32
COMPARE_BOOL(true, U32, 0, U32, 0);
COMPARE_BOOL(false, U32, 0, U32, 1);
COMPARE_BOOL(true, U32, 1, U32, 1);
COMPARE_BOOL(false, U32, 0x80000000U, U32, 1);
COMPARE_BOOL(true, U32, 0x80000000U, U32, 0x80000000U);
COMPARE_BOOL(false, U32, 0x7FFFFFFFU, U32, 1);
COMPARE_BOOL(true, U32, 0x7FFFFFFFU, U32, 0x7FFFFFFFU);
u32B = mSCRIPT_MAKE_U32(1);
assert_false(u32A.type->equal(&u32A, &u32B));
// U64
COMPARE_BOOL(true, U32, 0, U64, 0);
COMPARE_BOOL(false, U32, 0, U64, 1);
COMPARE_BOOL(true, U32, 1, U64, 1);
COMPARE_BOOL(false, U32, 0x80000000U, U64, 1);
COMPARE_BOOL(true, U32, 0x80000000U, U64, 0x080000000ULL);
COMPARE_BOOL(false, U32, 0x7FFFFFFFU, U64, 1);
COMPARE_BOOL(true, U32, 0x7FFFFFFFU, U64, 0x07FFFFFFFULL);
COMPARE_BOOL(false, U32, 0x80000000U, U64, 0x180000000ULL);
COMPARE_BOOL(false, U32, 0, U64, 0x100000000ULL);
u32A = mSCRIPT_MAKE_U32(1);
assert_true(u32A.type->equal(&u32A, &u32B));
// S32
COMPARE_BOOL(true, U32, 0, S32, 0);
COMPARE_BOOL(false, U32, 0, S32, 1);
COMPARE_BOOL(true, U32, 1, S32, 1);
COMPARE_BOOL(true, U32, 0x7FFFFFFFU, S32, 0x7FFFFFFF);
COMPARE_BOOL(false, U32, 0xFFFFFFFFU, S32, 0xFFFFFFFF);
COMPARE_BOOL(false, U32, 0x80000000U, S32, 0x80000000);
u32B = mSCRIPT_MAKE_U32(0x80000000U);
assert_false(u32A.type->equal(&u32A, &u32B));
// S64
COMPARE_BOOL(true, U32, 0, S64, 0);
COMPARE_BOOL(false, U32, 0, S64, 1);
COMPARE_BOOL(true, U32, 1, S64, 1);
COMPARE_BOOL(true, U32, 0x7FFFFFFFU, S64, 0x07FFFFFFFLL);
COMPARE_BOOL(true, U32, 0xFFFFFFFFU, S64, 0x0FFFFFFFFLL);
COMPARE_BOOL(true, U32, 0x80000000U, S64, 0x080000000LL);
COMPARE_BOOL(false, U32, 0x80000000U, S64, 0x180000000LL);
COMPARE_BOOL(false, U32, 0, S64, 0x100000000LL);
u32A = mSCRIPT_MAKE_U32(0x80000000U);
assert_true(u32A.type->equal(&u32A, &u32B));
// F32
COMPARE_BOOL(true, U32, 0, F32, 0);
COMPARE_BOOL(false, U32, 1, F32, 0);
COMPARE_BOOL(false, U32, 0, F32, 1);
COMPARE_BOOL(true, U32, 1, F32, 1);
COMPARE_BOOL(false, U32, 0, F32, -1);
COMPARE_BOOL(false, U32, 1, F32, -1);
COMPARE_BOOL(false, U32, 0xFFFFFFFFU, F32, -1);
COMPARE_BOOL(true, U32, 0x80000000U, F32, 0x80000000);
COMPARE_BOOL(false, U32, 0, F32, 0x80000000);
COMPARE_BOOL(false, U32, 0x80000000U, F32, 0);
COMPARE_BOOL(false, U32, 1, F32, 1.1);
COMPARE_BOOL(false, U32, 0, F32, 0.1);
u32A = mSCRIPT_MAKE_U32(0);
s32 = mSCRIPT_MAKE_S32(0);
assert_true(u32A.type->equal(&u32A, &s32));
// F64
COMPARE_BOOL(true, U32, 0, F64, 0);
COMPARE_BOOL(false, U32, 1, F64, 0);
COMPARE_BOOL(false, U32, 0, F64, 1);
COMPARE_BOOL(true, U32, 1, F64, 1);
COMPARE_BOOL(false, U32, 0, F64, -1);
COMPARE_BOOL(false, U32, 1, F64, -1);
COMPARE_BOOL(false, U32, 0xFFFFFFFFU, F64, -1);
COMPARE_BOOL(true, U32, 0x80000000U, F64, 0x80000000);
COMPARE_BOOL(false, U32, 0, F64, 0x80000000);
COMPARE_BOOL(false, U32, 0x80000000U, F64, 0);
COMPARE_BOOL(false, U32, 1, F64, 1.1);
COMPARE_BOOL(false, U32, 0, F64, 0.1);
}
u32A = mSCRIPT_MAKE_U32(1);
s32 = mSCRIPT_MAKE_S32(1);
assert_true(u32A.type->equal(&u32A, &s32));
M_TEST_DEFINE(u64Equality) {
struct mScriptValue a;
struct mScriptValue b;
u32A = mSCRIPT_MAKE_U32(0);
s32 = mSCRIPT_MAKE_S32(1);
assert_false(u32A.type->equal(&u32A, &s32));
// U32
COMPARE_BOOL(true, U64, 0, U32, 0);
COMPARE_BOOL(false, U64, 0, U32, 1);
COMPARE_BOOL(true, U64, 1, U32, 1);
COMPARE_BOOL(false, U64, 0x080000000ULL, U32, 1);
COMPARE_BOOL(true, U64, 0x080000000ULL, U32, 0x80000000U);
COMPARE_BOOL(false, U64, 0x07FFFFFFFULL, U32, 1);
COMPARE_BOOL(true, U64, 0x07FFFFFFFULL, U32, 0x7FFFFFFFU);
COMPARE_BOOL(false, U64, 0x180000000ULL, U32, 0x80000000U);
COMPARE_BOOL(false, U64, 0x100000000ULL, U32, 0);
u32A = mSCRIPT_MAKE_U32(1);
s32 = mSCRIPT_MAKE_S32(0);
assert_false(u32A.type->equal(&u32A, &s32));
// U64
COMPARE_BOOL(true, U64, 0, U64, 0);
COMPARE_BOOL(false, U64, 0, U64, 1);
COMPARE_BOOL(true, U64, 1, U64, 1);
COMPARE_BOOL(false, U64, 0x080000000ULL, U64, 1);
COMPARE_BOOL(true, U64, 0x080000000ULL, U64, 0x080000000ULL);
COMPARE_BOOL(false, U64, 0x07FFFFFFFULL, U64, 1);
COMPARE_BOOL(true, U64, 0x07FFFFFFFULL, U64, 0x07FFFFFFFULL);
COMPARE_BOOL(true, U64, 0x180000000ULL, U64, 0x180000000ULL);
COMPARE_BOOL(true, U64, 0x100000000ULL, U64, 0x100000000ULL);
u32A = mSCRIPT_MAKE_U32(0x7FFFFFFF);
s32 = mSCRIPT_MAKE_S32(0x7FFFFFFF);
assert_true(u32A.type->equal(&u32A, &s32));
// S32
COMPARE_BOOL(true, U64, 0, S32, 0);
COMPARE_BOOL(false, U64, 0, S32, 1);
COMPARE_BOOL(true, U64, 1, S32, 1);
COMPARE_BOOL(true, U64, 0x07FFFFFFFULL, S32, 0x7FFFFFFF);
COMPARE_BOOL(false, U64, 0x0FFFFFFFFULL, S32, 0xFFFFFFFF);
COMPARE_BOOL(false, U64, 0x080000000ULL, S32, 0x80000000);
COMPARE_BOOL(false, U64, 0x100000000ULL, S32, 0);
u32A = mSCRIPT_MAKE_U32(0xFFFFFFFF);
s32 = mSCRIPT_MAKE_S32(0xFFFFFFFF);
assert_false(u32A.type->equal(&u32A, &s32));
// S64
COMPARE_BOOL(true, U64, 0, S64, 0);
COMPARE_BOOL(false, U64, 0, S64, 1);
COMPARE_BOOL(true, U64, 1, S64, 1);
COMPARE_BOOL(true, U64, 0x07FFFFFFFULL, S64, 0x07FFFFFFFLL);
COMPARE_BOOL(true, U64, 0x0FFFFFFFFULL, S64, 0x0FFFFFFFFLL);
COMPARE_BOOL(true, U64, 0x080000000ULL, S64, 0x080000000LL);
COMPARE_BOOL(false, U64, 0, S64, 0x100000000LL);
COMPARE_BOOL(false, U64, 0x100000000ULL, S64, 0);
COMPARE_BOOL(true, U64, 0x100000000ULL, S64, 0x100000000LL);
COMPARE_BOOL(false, U64, 0x0FFFFFFFFULL, S64, -1);
COMPARE_BOOL(false, U64, 0xFFFFFFFFFFFFFFFFULL, S64, -1);
COMPARE_BOOL(true, U64, 0x080000000ULL, S64, 0x080000000LL);
u32A = mSCRIPT_MAKE_U32(0x80000000);
s32 = mSCRIPT_MAKE_S32(0x80000000);
assert_false(u32A.type->equal(&u32A, &s32));
// F32
COMPARE_BOOL(true, U64, 0, F32, 0);
COMPARE_BOOL(false, U64, 1, F32, 0);
COMPARE_BOOL(false, U64, 0, F32, 1);
COMPARE_BOOL(true, U64, 1, F32, 1);
COMPARE_BOOL(false, U64, 0, F32, -1);
COMPARE_BOOL(false, U64, 1, F32, -1);
COMPARE_BOOL(false, U64, 0xFFFFFFFFFFFFFFFFULL, F32, -1);
COMPARE_BOOL(true, U64, 0x8000000000000000ULL, F32, 0x8000000000000000ULL);
COMPARE_BOOL(false, U64, 0, F32, 0x8000000000000000ULL);
COMPARE_BOOL(false, U64, 0x8000000000000000ULL, F32, 0);
COMPARE_BOOL(false, U64, 1, F32, 1.1);
COMPARE_BOOL(false, U64, 0, F32, 0.1);
u32A = mSCRIPT_MAKE_U32(0);
f32 = mSCRIPT_MAKE_F32(0);
assert_true(u32A.type->equal(&u32A, &f32));
u32A = mSCRIPT_MAKE_U32(1);
f32 = mSCRIPT_MAKE_F32(1);
assert_true(u32A.type->equal(&u32A, &f32));
u32A = mSCRIPT_MAKE_U32(0);
f32 = mSCRIPT_MAKE_F32(1);
assert_false(u32A.type->equal(&u32A, &f32));
u32A = mSCRIPT_MAKE_U32(1);
f32 = mSCRIPT_MAKE_F32(0);
assert_false(u32A.type->equal(&u32A, &f32));
u32A = mSCRIPT_MAKE_U32(0x80000000);
f32 = mSCRIPT_MAKE_F32(0x80000000);
assert_true(u32A.type->equal(&u32A, &f32));
u32A = mSCRIPT_MAKE_U32(0);
f32 = mSCRIPT_MAKE_F32(0x80000000);
assert_false(u32A.type->equal(&u32A, &f32));
u32A = mSCRIPT_MAKE_U32(0x80000000);
f32 = mSCRIPT_MAKE_F32(0);
assert_false(u32A.type->equal(&u32A, &f32));
// F64
COMPARE_BOOL(true, U64, 0, F64, 0);
COMPARE_BOOL(false, U64, 1, F64, 0);
COMPARE_BOOL(false, U64, 0, F64, 1);
COMPARE_BOOL(true, U64, 1, F64, 1);
COMPARE_BOOL(false, U64, 0, F64, -1);
COMPARE_BOOL(false, U64, 1, F64, -1);
COMPARE_BOOL(false, U64, 0xFFFFFFFFFFFFFFFFULL, F64, -1);
COMPARE_BOOL(true, U64, 0x8000000000000000ULL, F64, 0x8000000000000000ULL);
COMPARE_BOOL(false, U64, 0, F64, 0x8000000000000000ULL);
COMPARE_BOOL(false, U64, 0x8000000000000000ULL, F64, 0);
COMPARE_BOOL(false, U64, 1, F64, 1.1);
COMPARE_BOOL(false, U64, 0, F64, 0.1);
}
M_TEST_DEFINE(f32Equality) {
struct mScriptValue f32A;
struct mScriptValue f32B;
struct mScriptValue s32;
struct mScriptValue u32;
struct mScriptValue a;
struct mScriptValue b;
f32A = mSCRIPT_MAKE_F32(0);
f32B = mSCRIPT_MAKE_F32(0);
assert_true(f32A.type->equal(&f32A, &f32B));
// F32
COMPARE_BOOL(true, F32, 0, F32, 0);
COMPARE_BOOL(false, F32, 0, F32, 1);
COMPARE_BOOL(true, F32, 1, F32, 1);
COMPARE_BOOL(true, F32, -1, F32, -1);
COMPARE_BOOL(false, F32, 1.1, F32, 1);
COMPARE_BOOL(false, F32, 1, F32, 1.1);
COMPARE_BOOL(true, F32, 1.1, F32, 1.1);
f32B = mSCRIPT_MAKE_F32(1);
assert_false(f32A.type->equal(&f32A, &f32B));
// F64
COMPARE_BOOL(true, F32, 0, F64, 0);
COMPARE_BOOL(false, F32, 0, F64, 1);
COMPARE_BOOL(true, F32, 1, F64, 1);
COMPARE_BOOL(true, F32, -1, F64, -1);
COMPARE_BOOL(false, F32, 1.1, F64, 1);
COMPARE_BOOL(false, F32, 1, F64, 1.1);
COMPARE_BOOL(true, F32, 1.25, F64, 1.25);
f32A = mSCRIPT_MAKE_F32(1);
assert_true(f32A.type->equal(&f32A, &f32B));
// S32
COMPARE_BOOL(true, F32, 0, S32, 0);
COMPARE_BOOL(false, F32, 0, S32, 1);
COMPARE_BOOL(false, F32, 1, S32, 0);
COMPARE_BOOL(true, F32, 1, S32, 1);
COMPARE_BOOL(false, F32, 1.1, S32, 1);
COMPARE_BOOL(true, F32, -1, S32, -1);
COMPARE_BOOL(false, F32, -1.1, S32, -1);
COMPARE_BOOL(true, F32, 0x40000000, S32, 0x40000000);
COMPARE_BOOL(true, F32, -0x40000000, S32, -0x40000000);
f32B = mSCRIPT_MAKE_F32(1.1);
assert_false(f32A.type->equal(&f32A, &f32B));
// S64
COMPARE_BOOL(true, F32, 0, S64, 0);
COMPARE_BOOL(false, F32, 0, S64, 1);
COMPARE_BOOL(false, F32, 1, S64, 0);
COMPARE_BOOL(true, F32, 1, S64, 1);
COMPARE_BOOL(false, F32, 1.1, S64, 1);
COMPARE_BOOL(true, F32, -1, S64, -1);
COMPARE_BOOL(false, F32, -1.1, S64, -1);
COMPARE_BOOL(true, F32, 0x040000000LL, S64, 0x040000000LL);
COMPARE_BOOL(true, F32, 0x100000000LL, S64, 0x100000000LL);
COMPARE_BOOL(false, F32, 0x100000000LL, S64, 0);
COMPARE_BOOL(false, F32, 0, S64, 0x100000000LL);
COMPARE_BOOL(true, F32, -0x040000000LL, S64, -0x040000000LL);
f32A = mSCRIPT_MAKE_F32(1.1);
assert_true(f32A.type->equal(&f32A, &f32B));
// U32
COMPARE_BOOL(true, F32, 0, U32, 0);
COMPARE_BOOL(false, F32, 0, U32, 1);
COMPARE_BOOL(false, F32, 1, U32, 0);
COMPARE_BOOL(true, F32, 1, U32, 1);
COMPARE_BOOL(false, F32, 1.1, U32, 1);
COMPARE_BOOL(true, F32, 0x40000000, U32, 0x40000000);
f32A = mSCRIPT_MAKE_F32(0);
s32 = mSCRIPT_MAKE_S32(0);
assert_true(f32A.type->equal(&f32A, &s32));
// U64
COMPARE_BOOL(true, F32, 0, U64, 0);
COMPARE_BOOL(false, F32, 0, U64, 1);
COMPARE_BOOL(false, F32, 1, U64, 0);
COMPARE_BOOL(true, F32, 1, U64, 1);
COMPARE_BOOL(false, F32, 1.1, U64, 1);
COMPARE_BOOL(true, F32, 0x040000000ULL, U64, 0x040000000ULL);
COMPARE_BOOL(true, F32, 0x100000000ULL, U64, 0x100000000ULL);
COMPARE_BOOL(false, F32, 0x100000000ULL, U64, 0);
COMPARE_BOOL(false, F32, 0, U64, 0x100000000ULL);
}
f32A = mSCRIPT_MAKE_F32(1);
s32 = mSCRIPT_MAKE_S32(1);
assert_true(f32A.type->equal(&f32A, &s32));
M_TEST_DEFINE(f64Equality) {
struct mScriptValue a;
struct mScriptValue b;
f32A = mSCRIPT_MAKE_F32(0);
s32 = mSCRIPT_MAKE_S32(1);
assert_false(f32A.type->equal(&f32A, &s32));
// F32
COMPARE_BOOL(true, F64, 0, F32, 0);
COMPARE_BOOL(false, F64, 0, F32, 1);
COMPARE_BOOL(true, F64, 1, F32, 1);
COMPARE_BOOL(true, F64, -1, F32, -1);
COMPARE_BOOL(false, F64, 1.1, F32, 1);
COMPARE_BOOL(false, F64, 1, F32, 1.1);
COMPARE_BOOL(true, F64, 1.25, F32, 1.25);
f32A = mSCRIPT_MAKE_F32(1);
s32 = mSCRIPT_MAKE_S32(0);
assert_false(f32A.type->equal(&f32A, &s32));
// F64
COMPARE_BOOL(true, F64, 0, F64, 0);
COMPARE_BOOL(false, F64, 0, F64, 1);
COMPARE_BOOL(true, F64, 1, F64, 1);
COMPARE_BOOL(true, F64, -1, F64, -1);
COMPARE_BOOL(false, F64, 1.1, F64, 1);
COMPARE_BOOL(false, F64, 1, F64, 1.1);
COMPARE_BOOL(true, F64, 1.1, F64, 1.1);
f32A = mSCRIPT_MAKE_F32(1.1);
s32 = mSCRIPT_MAKE_S32(1);
assert_false(f32A.type->equal(&f32A, &s32));
// S32
COMPARE_BOOL(true, F64, 0, S32, 0);
COMPARE_BOOL(false, F64, 0, S32, 1);
COMPARE_BOOL(false, F64, 1, S32, 0);
COMPARE_BOOL(true, F64, 1, S32, 1);
COMPARE_BOOL(false, F64, 1.1, S32, 1);
COMPARE_BOOL(true, F64, -1, S32, -1);
COMPARE_BOOL(false, F64, -1.1, S32, -1);
COMPARE_BOOL(true, F64, 0x40000000, S32, 0x40000000);
COMPARE_BOOL(true, F64, -0x40000000, S32, -0x40000000);
f32A = mSCRIPT_MAKE_F32(0x40000000);
s32 = mSCRIPT_MAKE_S32(0x40000000);
assert_true(f32A.type->equal(&f32A, &s32));
// S64
COMPARE_BOOL(true, F64, 0, S64, 0);
COMPARE_BOOL(false, F64, 0, S64, 1);
COMPARE_BOOL(false, F64, 1, S64, 0);
COMPARE_BOOL(true, F64, 1, S64, 1);
COMPARE_BOOL(false, F64, 1.1, S64, 1);
COMPARE_BOOL(true, F64, -1, S64, -1);
COMPARE_BOOL(false, F64, -1.1, S64, -1);
COMPARE_BOOL(true, F64, 0x040000000LL, S64, 0x040000000LL);
COMPARE_BOOL(true, F64, 0x100000000LL, S64, 0x100000000LL);
COMPARE_BOOL(false, F64, 0x100000000LL, S64, 0);
COMPARE_BOOL(false, F64, 0, S64, 0x100000000LL);
COMPARE_BOOL(true, F64, -0x040000000LL, S64, -0x040000000LL);
f32A = mSCRIPT_MAKE_F32(0);
u32 = mSCRIPT_MAKE_U32(0);
assert_true(f32A.type->equal(&f32A, &u32));
// U32
COMPARE_BOOL(true, F64, 0, U32, 0);
COMPARE_BOOL(false, F64, 0, U32, 1);
COMPARE_BOOL(false, F64, 1, U32, 0);
COMPARE_BOOL(true, F64, 1, U32, 1);
COMPARE_BOOL(false, F64, 1.1, U32, 1);
COMPARE_BOOL(true, F64, 0x40000000, U32, 0x40000000);
f32A = mSCRIPT_MAKE_F32(1);
u32 = mSCRIPT_MAKE_U32(1);
assert_true(f32A.type->equal(&f32A, &u32));
f32A = mSCRIPT_MAKE_F32(0);
u32 = mSCRIPT_MAKE_U32(1);
assert_false(f32A.type->equal(&f32A, &u32));
f32A = mSCRIPT_MAKE_F32(1);
u32 = mSCRIPT_MAKE_U32(0);
assert_false(f32A.type->equal(&f32A, &u32));
f32A = mSCRIPT_MAKE_F32(1.1);
u32 = mSCRIPT_MAKE_U32(1);
assert_false(f32A.type->equal(&f32A, &u32));
f32A = mSCRIPT_MAKE_F32(0x40000000);
u32 = mSCRIPT_MAKE_U32(0x40000000);
assert_true(f32A.type->equal(&f32A, &u32));
// U64
COMPARE_BOOL(true, F64, 0, U64, 0);
COMPARE_BOOL(false, F64, 0, U64, 1);
COMPARE_BOOL(false, F64, 1, U64, 0);
COMPARE_BOOL(true, F64, 1, U64, 1);
COMPARE_BOOL(false, F64, 1.1, U64, 1);
COMPARE_BOOL(true, F64, 0x040000000ULL, U64, 0x040000000ULL);
COMPARE_BOOL(true, F64, 0x100000000ULL, U64, 0x100000000ULL);
COMPARE_BOOL(false, F64, 0x100000000ULL, U64, 0);
COMPARE_BOOL(false, F64, 0, U64, 0x100000000ULL);
}
M_TEST_DEFINE(stringEquality) {
@ -516,6 +844,7 @@ M_TEST_SUITE_DEFINE(mScript,
cmocka_unit_test(voidArgs),
cmocka_unit_test(voidFunc),
cmocka_unit_test(identityFunctionS32),
cmocka_unit_test(identityFunctionS64),
cmocka_unit_test(identityFunctionF32),
cmocka_unit_test(identityFunctionStruct),
cmocka_unit_test(addS32),
@ -523,11 +852,18 @@ M_TEST_SUITE_DEFINE(mScript,
cmocka_unit_test(wrongArgCountLo),
cmocka_unit_test(wrongArgCountHi),
cmocka_unit_test(wrongArgType),
cmocka_unit_test(wrongPopType),
cmocka_unit_test(wrongPopSize),
cmocka_unit_test(coerceToFloat),
cmocka_unit_test(coerceFromFloat),
cmocka_unit_test(coerceNarrow),
cmocka_unit_test(coerceWiden),
cmocka_unit_test(s32Equality),
cmocka_unit_test(s64Equality),
cmocka_unit_test(u32Equality),
cmocka_unit_test(u64Equality),
cmocka_unit_test(f32Equality),
cmocka_unit_test(f64Equality),
cmocka_unit_test(stringEquality),
cmocka_unit_test(hashTableBasic),
cmocka_unit_test(hashTableString),

View File

@ -28,6 +28,9 @@ static bool _typeEqual(const struct mScriptValue*, const struct mScriptValue*);
static bool _s32Equal(const struct mScriptValue*, const struct mScriptValue*);
static bool _u32Equal(const struct mScriptValue*, const struct mScriptValue*);
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 _charpEqual(const struct mScriptValue*, const struct mScriptValue*);
static bool _stringEqual(const struct mScriptValue*, const struct mScriptValue*);
@ -75,6 +78,39 @@ const struct mScriptType mSTFloat32 = {
.cast = _castScalar,
};
const struct mScriptType mSTSInt64 = {
.base = mSCRIPT_TYPE_SINT,
.size = 8,
.name = "s64",
.alloc = NULL,
.free = NULL,
.hash = _hashScalar,
.equal = _s64Equal,
.cast = _castScalar,
};
const struct mScriptType mSTUInt64 = {
.base = mSCRIPT_TYPE_UINT,
.size = 8,
.name = "u64",
.alloc = NULL,
.free = NULL,
.hash = _hashScalar,
.equal = _u64Equal,
.cast = _castScalar,
};
const struct mScriptType mSTFloat64 = {
.base = mSCRIPT_TYPE_FLOAT,
.size = 8,
.name = "f64",
.alloc = NULL,
.free = NULL,
.hash = NULL,
.equal = _f64Equal,
.cast = _castScalar,
};
const struct mScriptType mSTString = {
.base = mSCRIPT_TYPE_STRING,
.size = sizeof(struct mScriptString),
@ -158,7 +194,7 @@ static uint32_t _hashString(const struct mScriptValue* val) {
uint32_t _hashScalar(const struct mScriptValue* val) {
// From https://stackoverflow.com/questions/664014/what-integer-hash-function-are-good-that-accepts-an-integer-hash-key
uint32_t x;
uint32_t x = 0;
switch (val->type->base) {
case mSCRIPT_TYPE_SINT:
x = val->value.s32;
@ -173,50 +209,81 @@ uint32_t _hashScalar(const struct mScriptValue* val) {
return x;
}
#define AS(NAME, TYPE) \
bool _as ## NAME(const struct mScriptValue* input, mSCRIPT_TYPE_C_ ## TYPE * T) { \
switch (input->type->base) { \
case mSCRIPT_TYPE_SINT: \
if (input->type->size == 4) { \
*T = input->value.s32; \
} else if (input->type->size == 8) { \
*T = input->value.s64; \
} \
break; \
case mSCRIPT_TYPE_UINT: \
if (input->type->size == 4) { \
*T = input->value.u32; \
} else if (input->type->size == 8) { \
*T = input->value.u64; \
} \
break; \
case mSCRIPT_TYPE_FLOAT: \
if (input->type->size == 4) { \
*T = input->value.f32; \
} else if (input->type->size == 8) { \
*T = input->value.f64; \
} \
break; \
default: \
return false; \
} \
return true; \
}
_mAPPLY(AS(SInt32, S32));
_mAPPLY(AS(UInt32, U32));
_mAPPLY(AS(Float32, F32));
_mAPPLY(AS(SInt64, S64));
_mAPPLY(AS(UInt64, U64));
_mAPPLY(AS(Float64, F64));
bool _castScalar(const struct mScriptValue* input, const struct mScriptType* type, struct mScriptValue* output) {
switch (type->base) {
case mSCRIPT_TYPE_SINT:
switch (input->type->base) {
case mSCRIPT_TYPE_SINT:
output->value.s32 = input->value.s32;
break;
case mSCRIPT_TYPE_UINT:
output->value.s32 = input->value.u32;
break;
case mSCRIPT_TYPE_FLOAT:
output->value.s32 = input->value.f32;
break;
default:
if (type->size == 4) {
if (!_asSInt32(input, &output->value.s32)) {
return false;
}
} else if (type->size == 8) {
if (!_asSInt64(input, &output->value.s64)) {
return false;
}
} else {
return false;
}
break;
case mSCRIPT_TYPE_UINT:
switch (input->type->base) {
case mSCRIPT_TYPE_SINT:
output->value.u32 = input->value.s32;
break;
case mSCRIPT_TYPE_UINT:
output->value.u32 = input->value.u32;
break;
case mSCRIPT_TYPE_FLOAT:
output->value.u32 = input->value.f32;
break;
default:
if (type->size == 4) {
if (!_asUInt32(input, &output->value.u32)) {
return false;
}
} else if (type->size == 8) {
if (!_asUInt64(input, &output->value.u64)) {
return false;
}
} else {
return false;
}
break;
case mSCRIPT_TYPE_FLOAT:
switch (input->type->base) {
case mSCRIPT_TYPE_SINT:
output->value.f32 = input->value.s32;
break;
case mSCRIPT_TYPE_UINT:
output->value.f32 = input->value.u32;
break;
case mSCRIPT_TYPE_FLOAT:
output->value.f32 = input->value.f32;
break;
default:
if (type->size == 4) {
if (!_asFloat32(input, &output->value.f32)) {
return false;
}
} else if (type->size == 8) {
if (!_asFloat64(input, &output->value.f64)) {
return false;
}
} else {
return false;
}
break;
@ -257,16 +324,34 @@ bool _s32Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
int32_t val;
switch (b->type->base) {
case mSCRIPT_TYPE_SINT:
val = b->value.s32;
break;
case mSCRIPT_TYPE_UINT:
if (b->value.u32 > (uint32_t) INT_MAX) {
if (b->type->size == 4) {
val = b->value.s32;
} else if (b->type->size == 8) {
if (b->value.s64 > INT_MAX || b->value.s64 < INT_MIN) {
return false;
}
val = b->value.s64;
} else {
return false;
}
break;
case mSCRIPT_TYPE_UINT:
if (a->value.s32 < 0) {
return false;
}
val = b->value.u32;
if (b->type->size == 4) {
if (b->value.u32 > (uint32_t) INT_MAX) {
return false;
}
val = b->value.u32;
} else if (b->type->size == 8) {
if (b->value.u64 > (uint64_t) INT_MAX) {
return false;
}
val = b->value.u64;
} else {
return false;
}
break;
case mSCRIPT_TYPE_VOID:
return false;
@ -280,16 +365,34 @@ bool _u32Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
uint32_t val;
switch (b->type->base) {
case mSCRIPT_TYPE_SINT:
if (b->value.s32 < 0) {
if (b->type->size == 4) {
if (a->value.u32 > (uint32_t) INT_MAX) {
return false;
}
if (b->value.s32 < 0) {
return false;
}
val = b->value.s32;
} else if (b->type->size == 8) {
if (b->value.s64 > (int64_t) UINT_MAX || b->value.s64 < 0) {
return false;
}
val = b->value.s64;
} else {
return false;
}
if (a->value.u32 > (uint32_t) INT_MAX) {
return false;
}
val = b->value.s32;
break;
case mSCRIPT_TYPE_UINT:
val = b->value.u32;
if (b->type->size == 4) {
val = b->value.u32;
} else if (b->type->size == 8) {
if (b->value.u64 > UINT_MAX) {
return false;
}
val = b->value.u64;
} else {
return false;
}
break;
case mSCRIPT_TYPE_VOID:
return false;
@ -303,13 +406,11 @@ bool _f32Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
float val;
switch (b->type->base) {
case mSCRIPT_TYPE_SINT:
val = b->value.s32;
break;
case mSCRIPT_TYPE_UINT:
val = b->value.u32;
break;
case mSCRIPT_TYPE_FLOAT:
val = b->value.f32;
if (!_asFloat32(b, &val)) {
return false;
}
break;
case mSCRIPT_TYPE_VOID:
return false;
@ -319,6 +420,100 @@ bool _f32Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
return a->value.f32 == val;
}
bool _s64Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
int64_t val;
switch (b->type->base) {
case mSCRIPT_TYPE_SINT:
if (b->type->size == 4) {
val = b->value.s32;
} else if (b->type->size == 8) {
val = b->value.s64;
} else {
return false;
}
break;
case mSCRIPT_TYPE_UINT:
if (a->value.s64 < 0) {
return false;
}
if (b->type->size == 4) {
val = b->value.u32;
} else if (b->type->size == 8) {
if (b->value.u64 > (uint64_t) INT64_MAX) {
return false;
}
val = b->value.u64;
} else {
return false;
}
break;
case mSCRIPT_TYPE_VOID:
return false;
default:
return b->type->equal && b->type->equal(b, a);
}
return a->value.s64 == val;
}
bool _u64Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
uint64_t val;
switch (b->type->base) {
case mSCRIPT_TYPE_SINT:
if (b->type->size == 4) {
if (a->value.u64 > (uint64_t) INT_MAX) {
return false;
}
if (b->value.s32 < 0) {
return false;
}
val = b->value.s32;
} else if (b->type->size == 8) {
if (a->value.u64 > (uint64_t) INT64_MAX) {
return false;
}
if (b->value.s64 < 0) {
return false;
}
val = b->value.s64;
} else {
return false;
}
break;
case mSCRIPT_TYPE_UINT:
if (b->type->size == 4) {
val = b->value.u32;
} else if (b->type->size == 8) {
val = b->value.u64;
} else {
return false;
}
break;
case mSCRIPT_TYPE_VOID:
return false;
default:
return b->type->equal && b->type->equal(b, a);
}
return a->value.u64 == val;
}
bool _f64Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
double val;
switch (b->type->base) {
case mSCRIPT_TYPE_SINT:
case mSCRIPT_TYPE_UINT:
case mSCRIPT_TYPE_FLOAT:
if (!_asFloat64(b, &val)) {
return false;
}
break;
case mSCRIPT_TYPE_VOID:
return false;
default:
return b->type->equal && b->type->equal(b, a);
}
return a->value.f64 == val;
}
bool _charpEqual(const struct mScriptValue* a, const struct mScriptValue* b) {
const char* valA = a->value.opaque;
const char* valB;
@ -467,18 +662,36 @@ bool mScriptPopS32(struct mScriptList* list, int32_t* out) {
return true;
}
bool mScriptPopS64(struct mScriptList* list, int64_t* out) {
mSCRIPT_POP(list, S64, val);
*out = val;
return true;
}
bool mScriptPopU32(struct mScriptList* list, uint32_t* out) {
mSCRIPT_POP(list, U32, val);
*out = val;
return true;
}
bool mScriptPopU64(struct mScriptList* list, uint64_t* out) {
mSCRIPT_POP(list, U64, val);
*out = val;
return true;
}
bool mScriptPopF32(struct mScriptList* list, float* out) {
mSCRIPT_POP(list, F32, val);
*out = val;
return true;
}
bool mScriptPopF64(struct mScriptList* list, double* out) {
mSCRIPT_POP(list, F64, val);
*out = val;
return true;
}
bool mScriptPopPointer(struct mScriptList* list, void** out) {
mSCRIPT_POP(list, PTR, val);
*out = val;