mirror of https://github.com/mgba-emu/mgba.git
Scripting: Start string bringup
This commit is contained in:
parent
8818bf4048
commit
9955d0d19b
|
@ -20,6 +20,8 @@ CXX_GUARD_START
|
||||||
#define mSCRIPT_TYPE_C_S32 int32_t
|
#define mSCRIPT_TYPE_C_S32 int32_t
|
||||||
#define mSCRIPT_TYPE_C_U32 uint32_t
|
#define mSCRIPT_TYPE_C_U32 uint32_t
|
||||||
#define mSCRIPT_TYPE_C_F32 float
|
#define mSCRIPT_TYPE_C_F32 float
|
||||||
|
#define mSCRIPT_TYPE_C_STR mScriptString*
|
||||||
|
#define mSCRIPT_TYPE_C_CHARP const char*
|
||||||
#define mSCRIPT_TYPE_C_PTR void*
|
#define mSCRIPT_TYPE_C_PTR void*
|
||||||
#define mSCRIPT_TYPE_C_TABLE Table*
|
#define mSCRIPT_TYPE_C_TABLE Table*
|
||||||
#define mSCRIPT_TYPE_C_S(STRUCT) struct STRUCT*
|
#define mSCRIPT_TYPE_C_S(STRUCT) struct STRUCT*
|
||||||
|
@ -27,6 +29,8 @@ CXX_GUARD_START
|
||||||
#define mSCRIPT_TYPE_FIELD_S32 s32
|
#define mSCRIPT_TYPE_FIELD_S32 s32
|
||||||
#define mSCRIPT_TYPE_FIELD_U32 u32
|
#define mSCRIPT_TYPE_FIELD_U32 u32
|
||||||
#define mSCRIPT_TYPE_FIELD_F32 f32
|
#define mSCRIPT_TYPE_FIELD_F32 f32
|
||||||
|
#define mSCRIPT_TYPE_FIELD_STR opaque
|
||||||
|
#define mSCRIPT_TYPE_FIELD_CHARP opaque
|
||||||
#define mSCRIPT_TYPE_FIELD_PTR opaque
|
#define mSCRIPT_TYPE_FIELD_PTR opaque
|
||||||
#define mSCRIPT_TYPE_FIELD_TABLE opaque
|
#define mSCRIPT_TYPE_FIELD_TABLE opaque
|
||||||
#define mSCRIPT_TYPE_FIELD_S(STRUCT) opaque
|
#define mSCRIPT_TYPE_FIELD_S(STRUCT) opaque
|
||||||
|
@ -34,6 +38,8 @@ CXX_GUARD_START
|
||||||
#define mSCRIPT_TYPE_MS_S32 (&mSTSInt32)
|
#define mSCRIPT_TYPE_MS_S32 (&mSTSInt32)
|
||||||
#define mSCRIPT_TYPE_MS_U32 (&mSTUInt32)
|
#define mSCRIPT_TYPE_MS_U32 (&mSTUInt32)
|
||||||
#define mSCRIPT_TYPE_MS_F32 (&mSTFloat32)
|
#define mSCRIPT_TYPE_MS_F32 (&mSTFloat32)
|
||||||
|
#define mSCRIPT_TYPE_MS_STR (&mSTString)
|
||||||
|
#define mSCRIPT_TYPE_MS_CHARP (&mSTCharPtr)
|
||||||
#define mSCRIPT_TYPE_MS_TABLE (&mSTTable)
|
#define mSCRIPT_TYPE_MS_TABLE (&mSTTable)
|
||||||
#define mSCRIPT_TYPE_MS_S(STRUCT) (&mSTStruct_ ## STRUCT)
|
#define mSCRIPT_TYPE_MS_S(STRUCT) (&mSTStruct_ ## STRUCT)
|
||||||
|
|
||||||
|
@ -43,6 +49,8 @@ CXX_GUARD_START
|
||||||
#define mSCRIPT_TYPE_CMP_U32(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_U32, TYPE)
|
#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_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_F32(TYPE) mSCRIPT_TYPE_CMP_GENERIC(mSCRIPT_TYPE_MS_F32, 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)
|
#define mSCRIPT_TYPE_CMP_PTR(TYPE) ((TYPE)->base >= mSCRIPT_TYPE_OPAQUE)
|
||||||
#define mSCRIPT_TYPE_CMP_S(STRUCT) mSCRIPT_TYPE_MS_S(STRUCT)->name == _mSCRIPT_FIELD_NAME
|
#define mSCRIPT_TYPE_CMP_S(STRUCT) mSCRIPT_TYPE_MS_S(STRUCT)->name == _mSCRIPT_FIELD_NAME
|
||||||
#define mSCRIPT_TYPE_CMP(TYPE0, TYPE1) _mAPPLY(mSCRIPT_TYPE_CMP_ ## TYPE0(TYPE1))
|
#define mSCRIPT_TYPE_CMP(TYPE0, TYPE1) _mAPPLY(mSCRIPT_TYPE_CMP_ ## TYPE0(TYPE1))
|
||||||
|
@ -166,6 +174,7 @@ CXX_GUARD_START
|
||||||
#define mSCRIPT_MAKE_S32(VALUE) mSCRIPT_MAKE(mSCRIPT_TYPE_MS_S32, s32, VALUE)
|
#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_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_F32(VALUE) mSCRIPT_MAKE(mSCRIPT_TYPE_MS_F32, f32, VALUE)
|
||||||
|
#define mSCRIPT_MAKE_CHARP(VALUE) mSCRIPT_MAKE(mSCRIPT_TYPE_MS_CHARP, opaque, VALUE)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
mSCRIPT_TYPE_VOID = 0,
|
mSCRIPT_TYPE_VOID = 0,
|
||||||
|
@ -187,6 +196,8 @@ extern const struct mScriptType mSTVoid;
|
||||||
extern const struct mScriptType mSTSInt32;
|
extern const struct mScriptType mSTSInt32;
|
||||||
extern const struct mScriptType mSTUInt32;
|
extern const struct mScriptType mSTUInt32;
|
||||||
extern const struct mScriptType mSTFloat32;
|
extern const struct mScriptType mSTFloat32;
|
||||||
|
extern const struct mScriptType mSTString;
|
||||||
|
extern const struct mScriptType mSTCharPtr;
|
||||||
extern const struct mScriptType mSTTable;
|
extern const struct mScriptType mSTTable;
|
||||||
|
|
||||||
struct mScriptTypeTuple {
|
struct mScriptTypeTuple {
|
||||||
|
@ -229,6 +240,12 @@ struct mScriptValue {
|
||||||
|
|
||||||
DECLARE_VECTOR(mScriptList, struct mScriptValue)
|
DECLARE_VECTOR(mScriptList, struct mScriptValue)
|
||||||
|
|
||||||
|
struct mScriptString {
|
||||||
|
size_t length; // Size of the string in code points
|
||||||
|
size_t size; // Size of the buffer in bytes, excluding NULL byte terminator
|
||||||
|
char* buffer; // UTF-8 representation of the string
|
||||||
|
};
|
||||||
|
|
||||||
struct mScriptFrame {
|
struct mScriptFrame {
|
||||||
struct mScriptList arguments;
|
struct mScriptList arguments;
|
||||||
struct mScriptList returnValues;
|
struct mScriptList returnValues;
|
||||||
|
@ -238,12 +255,15 @@ struct mScriptFrame {
|
||||||
struct mScriptFunction {
|
struct mScriptFunction {
|
||||||
struct mScriptTypeFunction signature;
|
struct mScriptTypeFunction signature;
|
||||||
bool (*call)(struct mScriptFrame*);
|
bool (*call)(struct mScriptFrame*);
|
||||||
|
void* context;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mScriptValue* mScriptValueAlloc(const struct mScriptType* type);
|
struct mScriptValue* mScriptValueAlloc(const struct mScriptType* type);
|
||||||
void mScriptValueRef(struct mScriptValue* val);
|
void mScriptValueRef(struct mScriptValue* val);
|
||||||
void mScriptValueDeref(struct mScriptValue* val);
|
void mScriptValueDeref(struct mScriptValue* val);
|
||||||
|
|
||||||
|
struct mScriptValue* mScriptStringCreateFromUTF8(const char* string);
|
||||||
|
|
||||||
bool mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, struct mScriptValue* value);
|
bool mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, struct mScriptValue* value);
|
||||||
bool mScriptTableRemove(struct mScriptValue* table, struct mScriptValue* key);
|
bool mScriptTableRemove(struct mScriptValue* table, struct mScriptValue* key);
|
||||||
struct mScriptValue* mScriptTableLookup(struct mScriptValue* table, struct mScriptValue* key);
|
struct mScriptValue* mScriptTableLookup(struct mScriptValue* table, struct mScriptValue* key);
|
||||||
|
|
|
@ -41,6 +41,10 @@ static int subInts(int a, int b) {
|
||||||
return a - b;
|
return a - b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int isHello(const char* str) {
|
||||||
|
return strcmp(str, "hello") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
mSCRIPT_BIND_FUNCTION(boundVoidOne, S32, voidOne, 0);
|
mSCRIPT_BIND_FUNCTION(boundVoidOne, S32, voidOne, 0);
|
||||||
mSCRIPT_BIND_VOID_FUNCTION(boundDiscard, discard, 1, S32);
|
mSCRIPT_BIND_VOID_FUNCTION(boundDiscard, discard, 1, S32);
|
||||||
mSCRIPT_BIND_FUNCTION(boundIdentityInt, S32, identityInt, 1, S32);
|
mSCRIPT_BIND_FUNCTION(boundIdentityInt, S32, identityInt, 1, S32);
|
||||||
|
@ -48,6 +52,7 @@ mSCRIPT_BIND_FUNCTION(boundIdentityFloat, F32, identityFloat, 1, F32);
|
||||||
mSCRIPT_BIND_FUNCTION(boundIdentityStruct, S(Test), identityStruct, 1, S(Test));
|
mSCRIPT_BIND_FUNCTION(boundIdentityStruct, S(Test), identityStruct, 1, S(Test));
|
||||||
mSCRIPT_BIND_FUNCTION(boundAddInts, S32, addInts, 2, S32, S32);
|
mSCRIPT_BIND_FUNCTION(boundAddInts, S32, addInts, 2, S32, S32);
|
||||||
mSCRIPT_BIND_FUNCTION(boundSubInts, S32, subInts, 2, S32, S32);
|
mSCRIPT_BIND_FUNCTION(boundSubInts, S32, subInts, 2, S32, S32);
|
||||||
|
mSCRIPT_BIND_FUNCTION(boundIsHello, S32, isHello, 1, CHARP);
|
||||||
|
|
||||||
M_TEST_DEFINE(voidArgs) {
|
M_TEST_DEFINE(voidArgs) {
|
||||||
struct mScriptFrame frame;
|
struct mScriptFrame frame;
|
||||||
|
@ -400,6 +405,33 @@ M_TEST_DEFINE(f32Equality) {
|
||||||
assert_true(f32A.type->equal(&f32A, &u32));
|
assert_true(f32A.type->equal(&f32A, &u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(stringEquality) {
|
||||||
|
struct mScriptValue* stringA = mScriptStringCreateFromUTF8("hello");
|
||||||
|
struct mScriptValue* stringB = mScriptStringCreateFromUTF8("world");
|
||||||
|
struct mScriptValue* stringC = mScriptStringCreateFromUTF8("hello");
|
||||||
|
struct mScriptValue charpA = mSCRIPT_MAKE_CHARP("hello");
|
||||||
|
struct mScriptValue charpB = mSCRIPT_MAKE_CHARP("world");
|
||||||
|
|
||||||
|
assert_true(stringA->type->equal(stringA, stringC));
|
||||||
|
assert_false(stringA->type->equal(stringA, stringB));
|
||||||
|
|
||||||
|
assert_true(stringA->type->equal(stringA, &charpA));
|
||||||
|
assert_false(stringA->type->equal(stringA, &charpB));
|
||||||
|
|
||||||
|
assert_true(charpA.type->equal(&charpA, stringA));
|
||||||
|
assert_false(charpA.type->equal(&charpA, stringB));
|
||||||
|
|
||||||
|
charpB = mSCRIPT_MAKE_CHARP("hello");
|
||||||
|
assert_true(charpA.type->equal(&charpA, &charpB));
|
||||||
|
|
||||||
|
charpB = mSCRIPT_MAKE_CHARP("world");
|
||||||
|
assert_false(charpA.type->equal(&charpA, &charpB));
|
||||||
|
|
||||||
|
mScriptValueDeref(stringA);
|
||||||
|
mScriptValueDeref(stringB);
|
||||||
|
mScriptValueDeref(stringC);
|
||||||
|
}
|
||||||
|
|
||||||
M_TEST_DEFINE(hashTableBasic) {
|
M_TEST_DEFINE(hashTableBasic) {
|
||||||
struct mScriptValue* table = mScriptValueAlloc(mSCRIPT_TYPE_MS_TABLE);
|
struct mScriptValue* table = mScriptValueAlloc(mSCRIPT_TYPE_MS_TABLE);
|
||||||
assert_non_null(table);
|
assert_non_null(table);
|
||||||
|
@ -429,6 +461,57 @@ M_TEST_DEFINE(hashTableBasic) {
|
||||||
mScriptValueDeref(table);
|
mScriptValueDeref(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(hashTableString) {
|
||||||
|
struct mScriptValue* table = mScriptValueAlloc(mSCRIPT_TYPE_MS_TABLE);
|
||||||
|
assert_non_null(table);
|
||||||
|
|
||||||
|
struct mScriptValue* intValue = mScriptValueAlloc(mSCRIPT_TYPE_MS_S32);
|
||||||
|
assert_ptr_equal(intValue->type, mSCRIPT_TYPE_MS_S32);
|
||||||
|
assert_int_equal(intValue->value.s32, 0);
|
||||||
|
assert_int_equal(intValue->refs, 1);
|
||||||
|
|
||||||
|
struct mScriptValue key = mSCRIPT_MAKE_CHARP("key");
|
||||||
|
struct mScriptValue badKey = mSCRIPT_MAKE_CHARP("bad");
|
||||||
|
|
||||||
|
assert_true(mScriptTableInsert(table, &key, intValue));
|
||||||
|
assert_int_equal(intValue->refs, 2);
|
||||||
|
|
||||||
|
struct mScriptValue* lookupValue = mScriptTableLookup(table, &key);
|
||||||
|
assert_non_null(lookupValue);
|
||||||
|
assert_ptr_equal(lookupValue, intValue);
|
||||||
|
|
||||||
|
lookupValue = mScriptTableLookup(table, &badKey);
|
||||||
|
assert_null(lookupValue);
|
||||||
|
|
||||||
|
assert_true(mScriptTableRemove(table, &key));
|
||||||
|
assert_int_equal(intValue->refs, 1);
|
||||||
|
|
||||||
|
mScriptValueDeref(intValue);
|
||||||
|
mScriptValueDeref(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(stringIsHello) {
|
||||||
|
struct mScriptFrame frame;
|
||||||
|
mScriptFrameInit(&frame);
|
||||||
|
mSCRIPT_PUSH(&frame.arguments, CHARP, "hello");
|
||||||
|
assert_true(mScriptInvoke(&boundIsHello, &frame));
|
||||||
|
int val;
|
||||||
|
assert_true(mScriptPopS32(&frame.returnValues, &val));
|
||||||
|
assert_int_equal(val, 1);
|
||||||
|
mScriptFrameDeinit(&frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(stringIsNotHello) {
|
||||||
|
struct mScriptFrame frame;
|
||||||
|
mScriptFrameInit(&frame);
|
||||||
|
mSCRIPT_PUSH(&frame.arguments, CHARP, "world");
|
||||||
|
assert_true(mScriptInvoke(&boundIsHello, &frame));
|
||||||
|
int val;
|
||||||
|
assert_true(mScriptPopS32(&frame.returnValues, &val));
|
||||||
|
assert_int_equal(val, 0);
|
||||||
|
mScriptFrameDeinit(&frame);
|
||||||
|
}
|
||||||
|
|
||||||
M_TEST_SUITE_DEFINE(mScript,
|
M_TEST_SUITE_DEFINE(mScript,
|
||||||
cmocka_unit_test(voidArgs),
|
cmocka_unit_test(voidArgs),
|
||||||
cmocka_unit_test(voidFunc),
|
cmocka_unit_test(voidFunc),
|
||||||
|
@ -445,4 +528,8 @@ M_TEST_SUITE_DEFINE(mScript,
|
||||||
cmocka_unit_test(s32Equality),
|
cmocka_unit_test(s32Equality),
|
||||||
cmocka_unit_test(u32Equality),
|
cmocka_unit_test(u32Equality),
|
||||||
cmocka_unit_test(f32Equality),
|
cmocka_unit_test(f32Equality),
|
||||||
cmocka_unit_test(hashTableBasic))
|
cmocka_unit_test(stringEquality),
|
||||||
|
cmocka_unit_test(hashTableBasic),
|
||||||
|
cmocka_unit_test(hashTableString),
|
||||||
|
cmocka_unit_test(stringIsHello),
|
||||||
|
cmocka_unit_test(stringIsNotHello))
|
||||||
|
|
|
@ -5,12 +5,17 @@
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
#include <mgba/script/types.h>
|
#include <mgba/script/types.h>
|
||||||
|
|
||||||
|
#include <mgba-util/hash.h>
|
||||||
#include <mgba-util/table.h>
|
#include <mgba-util/table.h>
|
||||||
|
|
||||||
static void _allocTable(struct mScriptValue*);
|
static void _allocTable(struct mScriptValue*);
|
||||||
static void _freeTable(struct mScriptValue*);
|
static void _freeTable(struct mScriptValue*);
|
||||||
static void _deinitTableValue(void*);
|
static void _deinitTableValue(void*);
|
||||||
|
|
||||||
|
static void _allocString(struct mScriptValue*);
|
||||||
|
static void _freeString(struct mScriptValue*);
|
||||||
|
static uint32_t _hashString(const struct mScriptValue*);
|
||||||
|
|
||||||
static uint32_t _hashScalar(const struct mScriptValue*);
|
static uint32_t _hashScalar(const struct mScriptValue*);
|
||||||
|
|
||||||
static uint32_t _valHash(const void* val, size_t len, uint32_t seed);
|
static uint32_t _valHash(const void* val, size_t len, uint32_t seed);
|
||||||
|
@ -22,6 +27,8 @@ static bool _typeEqual(const struct mScriptValue*, const struct mScriptValue*);
|
||||||
static bool _s32Equal(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 _u32Equal(const struct mScriptValue*, const struct mScriptValue*);
|
||||||
static bool _f32Equal(const struct mScriptValue*, const struct mScriptValue*);
|
static bool _f32Equal(const struct mScriptValue*, const struct mScriptValue*);
|
||||||
|
static bool _charpEqual(const struct mScriptValue*, const struct mScriptValue*);
|
||||||
|
static bool _stringEqual(const struct mScriptValue*, const struct mScriptValue*);
|
||||||
|
|
||||||
const struct mScriptType mSTVoid = {
|
const struct mScriptType mSTVoid = {
|
||||||
.base = mSCRIPT_TYPE_VOID,
|
.base = mSCRIPT_TYPE_VOID,
|
||||||
|
@ -63,6 +70,26 @@ const struct mScriptType mSTFloat32 = {
|
||||||
.equal = _f32Equal,
|
.equal = _f32Equal,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct mScriptType mSTString = {
|
||||||
|
.base = mSCRIPT_TYPE_STRING,
|
||||||
|
.size = sizeof(struct mScriptString),
|
||||||
|
.name = "string",
|
||||||
|
.alloc = _allocString,
|
||||||
|
.free = _freeString,
|
||||||
|
.hash = _hashString,
|
||||||
|
.equal = _stringEqual,
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct mScriptType mSTCharPtr = {
|
||||||
|
.base = mSCRIPT_TYPE_STRING,
|
||||||
|
.size = sizeof(char*),
|
||||||
|
.name = "charptr",
|
||||||
|
.alloc = NULL,
|
||||||
|
.free = NULL,
|
||||||
|
.hash = _hashString,
|
||||||
|
.equal = _charpEqual,
|
||||||
|
};
|
||||||
|
|
||||||
const struct mScriptType mSTTable = {
|
const struct mScriptType mSTTable = {
|
||||||
.base = mSCRIPT_TYPE_TABLE,
|
.base = mSCRIPT_TYPE_TABLE,
|
||||||
.size = sizeof(struct Table),
|
.size = sizeof(struct Table),
|
||||||
|
@ -95,6 +122,35 @@ void _deinitTableValue(void* val) {
|
||||||
mScriptValueDeref(val);
|
mScriptValueDeref(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _allocString(struct mScriptValue* val) {
|
||||||
|
struct mScriptString* string = calloc(1, sizeof(*string));
|
||||||
|
string->size = 0;
|
||||||
|
string->buffer = NULL;
|
||||||
|
val->value.opaque = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _freeString(struct mScriptValue* val) {
|
||||||
|
struct mScriptString* string = val->value.opaque;
|
||||||
|
if (string->size) {
|
||||||
|
free(string->buffer);
|
||||||
|
}
|
||||||
|
free(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t _hashString(const struct mScriptValue* val) {
|
||||||
|
const char* buffer = 0;
|
||||||
|
size_t size = 0;
|
||||||
|
if (val->type == &mSTString) {
|
||||||
|
struct mScriptString* string = val->value.opaque;
|
||||||
|
buffer = string->buffer;
|
||||||
|
size = string->size;
|
||||||
|
} else if (val->type == &mSTCharPtr) {
|
||||||
|
buffer = val->value.opaque;
|
||||||
|
size = strlen(buffer);
|
||||||
|
}
|
||||||
|
return hash32(buffer, size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t _hashScalar(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
|
// From https://stackoverflow.com/questions/664014/what-integer-hash-function-are-good-that-accepts-an-integer-hash-key
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
|
@ -136,7 +192,6 @@ void _valDeref(void* val) {
|
||||||
|
|
||||||
bool _typeEqual(const struct mScriptValue* a, const struct mScriptValue* b) {
|
bool _typeEqual(const struct mScriptValue* a, const struct mScriptValue* b) {
|
||||||
return a->type == b->type;
|
return a->type == b->type;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _s32Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
|
bool _s32Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
|
||||||
|
@ -205,6 +260,58 @@ bool _f32Equal(const struct mScriptValue* a, const struct mScriptValue* b) {
|
||||||
return a->value.f32 == val;
|
return a->value.f32 == val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool _charpEqual(const struct mScriptValue* a, const struct mScriptValue* b) {
|
||||||
|
const char* valA = a->value.opaque;
|
||||||
|
const char* valB;
|
||||||
|
size_t lenA;
|
||||||
|
size_t lenB;
|
||||||
|
if (b->type->base != mSCRIPT_TYPE_STRING) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (b->type == &mSTCharPtr) {
|
||||||
|
valB = b->value.opaque;
|
||||||
|
lenB = strlen(valB);
|
||||||
|
} else if (b->type == &mSTString) {
|
||||||
|
struct mScriptString* stringB = b->value.opaque;
|
||||||
|
valB = stringB->buffer;
|
||||||
|
lenB = stringB->size;
|
||||||
|
} else {
|
||||||
|
// TODO: Allow casting
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
lenA = strlen(valA);
|
||||||
|
if (lenA != lenB) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return strncmp(valA, valB, lenA) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool _stringEqual(const struct mScriptValue* a, const struct mScriptValue* b) {
|
||||||
|
struct mScriptString* stringA = a->value.opaque;
|
||||||
|
const char* valA = stringA->buffer;
|
||||||
|
const char* valB;
|
||||||
|
size_t lenA = stringA->size;
|
||||||
|
size_t lenB;
|
||||||
|
if (b->type->base != mSCRIPT_TYPE_STRING) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (b->type == &mSTCharPtr) {
|
||||||
|
valB = b->value.opaque;
|
||||||
|
lenB = strlen(valB);
|
||||||
|
} else if (b->type == &mSTString) {
|
||||||
|
struct mScriptString* stringB = b->value.opaque;
|
||||||
|
valB = stringB->buffer;
|
||||||
|
lenB = stringB->size;
|
||||||
|
} else {
|
||||||
|
// TODO: Allow casting
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (lenA != lenB) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return strncmp(valA, valB, lenA) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct mScriptValue* mScriptValueAlloc(const struct mScriptType* type) {
|
struct mScriptValue* mScriptValueAlloc(const struct mScriptType* type) {
|
||||||
// TODO: Use an arena instead of just the generic heap
|
// TODO: Use an arena instead of just the generic heap
|
||||||
struct mScriptValue* val = malloc(sizeof(*val));
|
struct mScriptValue* val = malloc(sizeof(*val));
|
||||||
|
@ -241,6 +348,14 @@ void mScriptValueDeref(struct mScriptValue* val) {
|
||||||
free(val);
|
free(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mScriptValue* mScriptStringCreateFromUTF8(const char* string) {
|
||||||
|
struct mScriptValue* val = mScriptValueAlloc(mSCRIPT_TYPE_MS_STR);
|
||||||
|
struct mScriptString* internal = val->value.opaque;
|
||||||
|
internal->size = strlen(string);
|
||||||
|
internal->buffer = strdup(string);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
bool mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, struct mScriptValue* value) {
|
bool mScriptTableInsert(struct mScriptValue* table, struct mScriptValue* key, struct mScriptValue* value) {
|
||||||
if (table->type != mSCRIPT_TYPE_MS_TABLE) {
|
if (table->type != mSCRIPT_TYPE_MS_TABLE) {
|
||||||
return false;
|
return false;
|
||||||
|
|
Loading…
Reference in New Issue