mirror of https://github.com/mgba-emu/mgba.git
Scripting: Start adding type-aware casting
This commit is contained in:
parent
9955d0d19b
commit
cbae6a61e5
|
@ -225,6 +225,7 @@ struct mScriptType {
|
||||||
void (*free)(struct mScriptValue*);
|
void (*free)(struct mScriptValue*);
|
||||||
uint32_t (*hash)(const struct mScriptValue*);
|
uint32_t (*hash)(const struct mScriptValue*);
|
||||||
bool (*equal)(const struct mScriptValue*, const struct mScriptValue*);
|
bool (*equal)(const struct mScriptValue*, const struct mScriptValue*);
|
||||||
|
bool (*cast)(const struct mScriptValue*, const struct mScriptType*, struct mScriptValue*);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mScriptValue {
|
struct mScriptValue {
|
||||||
|
|
|
@ -16,6 +16,7 @@ static void _allocString(struct mScriptValue*);
|
||||||
static void _freeString(struct mScriptValue*);
|
static void _freeString(struct mScriptValue*);
|
||||||
static uint32_t _hashString(const struct mScriptValue*);
|
static uint32_t _hashString(const struct mScriptValue*);
|
||||||
|
|
||||||
|
static bool _castScalar(const struct mScriptValue*, const struct mScriptType*, 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);
|
||||||
|
@ -38,6 +39,7 @@ const struct mScriptType mSTVoid = {
|
||||||
.free = NULL,
|
.free = NULL,
|
||||||
.hash = NULL,
|
.hash = NULL,
|
||||||
.equal = _typeEqual,
|
.equal = _typeEqual,
|
||||||
|
.cast = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct mScriptType mSTSInt32 = {
|
const struct mScriptType mSTSInt32 = {
|
||||||
|
@ -48,6 +50,7 @@ const struct mScriptType mSTSInt32 = {
|
||||||
.free = NULL,
|
.free = NULL,
|
||||||
.hash = _hashScalar,
|
.hash = _hashScalar,
|
||||||
.equal = _s32Equal,
|
.equal = _s32Equal,
|
||||||
|
.cast = _castScalar,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct mScriptType mSTUInt32 = {
|
const struct mScriptType mSTUInt32 = {
|
||||||
|
@ -58,6 +61,7 @@ const struct mScriptType mSTUInt32 = {
|
||||||
.free = NULL,
|
.free = NULL,
|
||||||
.hash = _hashScalar,
|
.hash = _hashScalar,
|
||||||
.equal = _u32Equal,
|
.equal = _u32Equal,
|
||||||
|
.cast = _castScalar,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct mScriptType mSTFloat32 = {
|
const struct mScriptType mSTFloat32 = {
|
||||||
|
@ -68,6 +72,7 @@ const struct mScriptType mSTFloat32 = {
|
||||||
.free = NULL,
|
.free = NULL,
|
||||||
.hash = NULL,
|
.hash = NULL,
|
||||||
.equal = _f32Equal,
|
.equal = _f32Equal,
|
||||||
|
.cast = _castScalar,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct mScriptType mSTString = {
|
const struct mScriptType mSTString = {
|
||||||
|
@ -168,6 +173,60 @@ uint32_t _hashScalar(const struct mScriptValue* val) {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
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:
|
||||||
|
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:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
output->type = type;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t _valHash(const void* val, size_t len, uint32_t seed) {
|
uint32_t _valHash(const void* val, size_t len, uint32_t seed) {
|
||||||
UNUSED(len);
|
UNUSED(len);
|
||||||
const struct mScriptValue* value = val;
|
const struct mScriptValue* value = val;
|
||||||
|
@ -427,76 +486,12 @@ bool mScriptPopPointer(struct mScriptList* list, void** out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mScriptCast(const struct mScriptType* type, const struct mScriptValue* input, struct mScriptValue* output) {
|
bool mScriptCast(const struct mScriptType* type, const struct mScriptValue* input, struct mScriptValue* output) {
|
||||||
switch (type->base) {
|
if (type->cast && type->cast(input, type, output)) {
|
||||||
case mSCRIPT_TYPE_VOID:
|
return true;
|
||||||
return false;
|
}
|
||||||
case mSCRIPT_TYPE_SINT:
|
if (input->type->cast && input->type->cast(input, type, output)) {
|
||||||
switch (input->type->base) {
|
return true;
|
||||||
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:
|
|
||||||
switch (input->type->size) {
|
|
||||||
case 4:
|
|
||||||
output->value.s32 = input->value.f32;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
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:
|
|
||||||
switch (input->type->size) {
|
|
||||||
case 4:
|
|
||||||
output->value.u32 = input->value.f32;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
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:
|
|
||||||
switch (input->type->size) {
|
|
||||||
case 4:
|
|
||||||
output->value.f32 = input->value.f32;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
output->type = type;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue