Scripting: Start adding type-aware casting

This commit is contained in:
Vicki Pfau 2021-08-30 20:03:14 -07:00
parent 9955d0d19b
commit cbae6a61e5
2 changed files with 65 additions and 69 deletions

View File

@ -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 {

View File

@ -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;
} }