Scripting: Add default arguments

This commit is contained in:
Vicki Pfau 2022-05-13 23:18:39 -07:00
parent fa847b1e63
commit e228857eef
3 changed files with 129 additions and 50 deletions

View File

@ -284,7 +284,7 @@ CXX_GUARD_START
return false; \
}
#define _mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, S, NRET, RETURN, NPARAMS, ...) \
#define _mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, S, NRET, RETURN, NPARAMS, DEFAULTS, ...) \
static bool _mSTStructBinding_ ## TYPE ## _ ## NAME(struct mScriptFrame* frame, void* ctx); \
static const struct mScriptFunction _mSTStructBindingFunction_ ## TYPE ## _ ## NAME = { \
.call = &_mSTStructBinding_ ## TYPE ## _ ## NAME \
@ -303,6 +303,7 @@ CXX_GUARD_START
.count = _mSUCC_ ## NPARAMS, \
.entries = { mSCRIPT_TYPE_MS_ ## S(TYPE), _mCALL(mSCRIPT_PREFIX_ ## NPARAMS, mSCRIPT_TYPE_MS_, _mEVEN_ ## NPARAMS(__VA_ARGS__)) }, \
.names = { "this", _mCALL(_mCALL_ ## NPARAMS, _mSTRINGIFY, _mODD_ ## NPARAMS(__VA_ARGS__)) }, \
.defaults = DEFAULTS, \
}, \
.returnType = { \
.count = NRET, \
@ -315,49 +316,65 @@ CXX_GUARD_START
#define _mSCRIPT_DECLARE_STRUCT_METHOD_SIGNATURE(TYPE, RETURN, NAME, CONST, NPARAMS, ...) \
typedef RETURN (*_mSTStructFunctionType_ ## TYPE ## _ ## NAME)(_mCOMMA_ ## NPARAMS(CONST struct TYPE* , mSCRIPT_PREFIX_ ## NPARAMS(mSCRIPT_TYPE_C_, __VA_ARGS__)))
#define mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, RETURN, NAME, FUNCTION, NPARAMS, ...) \
_mSCRIPT_DECLARE_STRUCT_METHOD_SIGNATURE(TYPE, mSCRIPT_TYPE_C_ ## RETURN, NAME, , NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, S, 1, mSCRIPT_TYPE_MS_ ## RETURN, NPARAMS, __VA_ARGS__) \
\
#define _mSCRIPT_DECLARE_STRUCT_METHOD_BINDING(TYPE, RETURN, NAME, FUNCTION, T, NPARAMS, ...) \
static bool _mSTStructBinding_ ## TYPE ## _ ## NAME(struct mScriptFrame* frame, void* ctx) { \
UNUSED(ctx); \
_mSCRIPT_STRUCT_METHOD_POP(TYPE, S, NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_STRUCT_METHOD_POP(TYPE, T, NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_CALL(RETURN, FUNCTION, _mSUCC_ ## NPARAMS); \
return true; \
}
#define _mSCRIPT_DECLARE_STRUCT_VOID_METHOD_BINDING(TYPE, NAME, FUNCTION, T, NPARAMS, ...) \
static bool _mSTStructBinding_ ## TYPE ## _ ## NAME(struct mScriptFrame* frame, void* ctx) { \
UNUSED(ctx); \
_mSCRIPT_STRUCT_METHOD_POP(TYPE, T, NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_CALL_VOID(FUNCTION, _mSUCC_ ## NPARAMS); \
return true; \
} \
#define mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, RETURN, NAME, FUNCTION, NPARAMS, ...) \
_mSCRIPT_DECLARE_STRUCT_METHOD_SIGNATURE(TYPE, mSCRIPT_TYPE_C_ ## RETURN, NAME, , NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, S, 1, mSCRIPT_TYPE_MS_ ## RETURN, NPARAMS, NULL, __VA_ARGS__) \
_mSCRIPT_DECLARE_STRUCT_METHOD_BINDING(TYPE, RETURN, NAME, FUNCTION, S, NPARAMS, __VA_ARGS__)
#define mSCRIPT_DECLARE_STRUCT_VOID_METHOD(TYPE, NAME, FUNCTION, NPARAMS, ...) \
_mSCRIPT_DECLARE_STRUCT_METHOD_SIGNATURE(TYPE, void, NAME, , NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, S, 0, , NPARAMS, __VA_ARGS__) \
\
static bool _mSTStructBinding_ ## TYPE ## _ ## NAME(struct mScriptFrame* frame, void* ctx) { \
UNUSED(ctx); \
_mSCRIPT_STRUCT_METHOD_POP(TYPE, S, NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_CALL_VOID(FUNCTION, _mSUCC_ ## NPARAMS); \
return true; \
} \
_mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, S, 0, , NPARAMS, NULL, __VA_ARGS__) \
_mSCRIPT_DECLARE_STRUCT_VOID_METHOD_BINDING(TYPE, NAME, FUNCTION, S, NPARAMS, __VA_ARGS__)
#define mSCRIPT_DECLARE_STRUCT_C_METHOD(TYPE, RETURN, NAME, FUNCTION, NPARAMS, ...) \
_mSCRIPT_DECLARE_STRUCT_METHOD_SIGNATURE(TYPE, mSCRIPT_TYPE_C_ ## RETURN, NAME, const, NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, CS, 1, mSCRIPT_TYPE_MS_ ## RETURN, NPARAMS, __VA_ARGS__) \
\
static bool _mSTStructBinding_ ## TYPE ## _ ## NAME(struct mScriptFrame* frame, void* ctx) { \
UNUSED(ctx); \
_mSCRIPT_STRUCT_METHOD_POP(TYPE, CS, NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_CALL(RETURN, FUNCTION, _mSUCC_ ## NPARAMS); \
return true; \
} \
_mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, CS, 1, mSCRIPT_TYPE_MS_ ## RETURN, NPARAMS, NULL, __VA_ARGS__) \
_mSCRIPT_DECLARE_STRUCT_METHOD_BINDING(TYPE, RETURN, NAME, FUNCTION, CS, NPARAMS, __VA_ARGS__)
#define mSCRIPT_DECLARE_STRUCT_VOID_C_METHOD(TYPE, NAME, FUNCTION, NPARAMS, ...) \
_mSCRIPT_DECLARE_STRUCT_METHOD_SIGNATURE(TYPE, void, NAME, const, NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, CS, 0, , NPARAMS, __VA_ARGS__) \
\
static bool _mSTStructBinding_ ## TYPE ## _ ## NAME(struct mScriptFrame* frame, void* ctx) { \
UNUSED(ctx); \
_mSCRIPT_STRUCT_METHOD_POP(TYPE, CS, NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_CALL_VOID(FUNCTION, _mSUCC_ ## NPARAMS); \
return true; \
} \
_mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, CS, 0, , NPARAMS, NULL, __VA_ARGS__) \
_mSCRIPT_DECLARE_STRUCT_VOID_METHOD_BINDING(TYPE, NAME, FUNCTION, CS, NPARAMS, __VA_ARGS__)
#define mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(TYPE, RETURN, NAME, FUNCTION, NPARAMS, ...) \
static const struct mScriptValue _mSTStructBindingDefaults_ ## TYPE ## NAME[mSCRIPT_PARAMS_MAX]; \
_mSCRIPT_DECLARE_STRUCT_METHOD_SIGNATURE(TYPE, mSCRIPT_TYPE_C_ ## RETURN, NAME, , NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, S, 1, mSCRIPT_TYPE_MS_ ## RETURN, NPARAMS, _mSTStructBindingDefaults_ ## TYPE ## NAME, __VA_ARGS__) \
_mSCRIPT_DECLARE_STRUCT_METHOD_BINDING(TYPE, RETURN, NAME, FUNCTION, S, NPARAMS, __VA_ARGS__)
#define mSCRIPT_DECLARE_STRUCT_VOID_METHOD_WITH_DEFAULTS(TYPE, NAME, FUNCTION, NPARAMS, ...) \
static const struct mScriptValue _mSTStructBindingDefaults_ ## TYPE ## NAME[mSCRIPT_PARAMS_MAX]; \
_mSCRIPT_DECLARE_STRUCT_METHOD_SIGNATURE(TYPE, void, NAME, , NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, S, 0, , NPARAMS, _mSTStructBindingDefaults_ ## TYPE ## NAME, __VA_ARGS__) \
_mSCRIPT_DECLARE_STRUCT_VOID_METHOD_BINDING(TYPE, NAME, FUNCTION, S, NPARAMS, __VA_ARGS__)
#define mSCRIPT_DECLARE_STRUCT_C_METHOD_WITH_DEFAULTS(TYPE, RETURN, NAME, FUNCTION, NPARAMS, ...) \
static const struct mScriptValue _mSTStructBindingDefaults_ ## TYPE ## NAME[mSCRIPT_PARAMS_MAX]; \
_mSCRIPT_DECLARE_STRUCT_METHOD_SIGNATURE(TYPE, mSCRIPT_TYPE_C_ ## RETURN, NAME, const, NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, CS, 1, mSCRIPT_TYPE_MS_ ## RETURN, NPARAMS, _mSTStructBindingDefaults_ ## TYPE ## NAME, __VA_ARGS__) \
_mSCRIPT_DECLARE_STRUCT_METHOD_BINDING(TYPE, RETURN, NAME, FUNCTION, CS, NPARAMS, __VA_ARGS__)
#define mSCRIPT_DECLARE_STRUCT_VOID_C_METHOD_WITH_DEFAULTS(TYPE, NAME, FUNCTION, NPARAMS, ...) \
static const struct mScriptValue _mSTStructBindingDefaults_ ## TYPE ## NAME[mSCRIPT_PARAMS_MAX]; \
_mSCRIPT_DECLARE_STRUCT_METHOD_SIGNATURE(TYPE, void, NAME, const, NPARAMS, _mEVEN_ ## NPARAMS(__VA_ARGS__)); \
_mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, NAME, CS, 0, , NPARAMS, _mSTStructBindingDefaults_ ## TYPE ## NAME, __VA_ARGS__) \
_mSCRIPT_DECLARE_STRUCT_VOID_METHOD_BINDING(TYPE, NAME, FUNCTION, CS, NPARAMS, __VA_ARGS__)
#define mSCRIPT_DECLARE_STRUCT_D_METHOD(TYPE, RETURN, NAME, NPARAMS, ...) \
mSCRIPT_DECLARE_STRUCT_METHOD(TYPE, RETURN, NAME, p0->NAME, NPARAMS, __VA_ARGS__)
@ -371,6 +388,24 @@ CXX_GUARD_START
#define mSCRIPT_DECLARE_STRUCT_VOID_CD_METHOD(TYPE, NAME, NPARAMS, ...) \
mSCRIPT_DECLARE_STRUCT_VOID_C_METHOD(TYPE, NAME, p0->NAME, NPARAMS, __VA_ARGS__)
#define mSCRIPT_DECLARE_STRUCT_D_METHOD_WITH_DEFAULTS(TYPE, RETURN, NAME, NPARAMS, ...) \
mSCRIPT_DECLARE_STRUCT_METHOD_WITH_DEFAULTS(TYPE, RETURN, NAME, p0->NAME, NPARAMS, __VA_ARGS__)
#define mSCRIPT_DECLARE_STRUCT_VOID_D_METHOD_WITH_DEFAULTS(TYPE, NAME, NPARAMS, ...) \
mSCRIPT_DECLARE_STRUCT_VOID_METHOD_WITH_DEFAULTS(TYPE, NAME, p0->NAME, NPARAMS, __VA_ARGS__)
#define mSCRIPT_DECLARE_STRUCT_CD_METHOD_WITH_DEFAULTS(TYPE, RETURN, NAME, NPARAMS, ...) \
mSCRIPT_DECLARE_STRUCT_C_METHOD_WITH_DEFAULTS(TYPE, RETURN, NAME, p0->NAME, NPARAMS, __VA_ARGS__)
#define mSCRIPT_DECLARE_STRUCT_VOID_CD_METHOD_WITH_DEFAULTS(TYPE, NAME, NPARAMS, ...) \
mSCRIPT_DECLARE_STRUCT_VOID_C_METHOD_WITH_DEFAU(TYPE, NAME, p0->NAME, NPARAMS, __VA_ARGS__)
#define mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(TYPE, NAME) \
static const struct mScriptValue _mSTStructBindingDefaults_ ## TYPE ## NAME[mSCRIPT_PARAMS_MAX] = { \
mSCRIPT_NO_DEFAULT,
#define mSCRIPT_DEFINE_DEFAULTS_END }
#define _mSCRIPT_DEFINE_STRUCT_BINDING(INIT_TYPE, TYPE, EXPORTED_NAME, NAME) { \
.type = mSCRIPT_CLASS_INIT_ ## INIT_TYPE, \
.info = { \
@ -482,6 +517,12 @@ CXX_GUARD_START
#define mSCRIPT_MAKE_S(STRUCT, VALUE) mSCRIPT_MAKE(S(STRUCT), VALUE)
#define mSCRIPT_MAKE_CS(STRUCT, VALUE) mSCRIPT_MAKE(CS(STRUCT), VALUE)
#define mSCRIPT_NO_DEFAULT { \
.type = NULL, \
.refs = mSCRIPT_VALUE_UNREF, \
.value = {0} \
}
enum mScriptTypeBase {
mSCRIPT_TYPE_VOID = 0,
mSCRIPT_TYPE_SINT,
@ -532,17 +573,35 @@ extern const struct mScriptType mSTTable;
extern const struct mScriptType mSTWrapper;
extern const struct mScriptType mSTWeakref;
struct mScriptType;
struct mScriptValue {
const struct mScriptType* type;
int refs;
uint32_t flags;
union {
int32_t s32;
uint32_t u32;
float f32;
int64_t s64;
uint64_t u64;
double f64;
void* opaque;
const void* copaque;
} value;
};
struct mScriptTypeTuple {
size_t count;
const struct mScriptType* entries[mSCRIPT_PARAMS_MAX];
const char* names[mSCRIPT_PARAMS_MAX];
const struct mScriptValue* defaults;
bool variable;
};
struct mScriptTypeFunction {
struct mScriptTypeTuple parameters;
struct mScriptTypeTuple returnType;
// TODO: kwargs, defaults
// TODO: kwargs
};
struct mScriptClassMember {
@ -579,7 +638,6 @@ struct mScriptTypeClass {
struct mScriptClassMember* set; // TODO
};
struct mScriptValue;
struct mScriptType {
enum mScriptTypeBase base : 8;
bool isConst;
@ -600,22 +658,6 @@ struct mScriptType {
bool (*cast)(const struct mScriptValue*, const struct mScriptType*, struct mScriptValue*);
};
struct mScriptValue {
const struct mScriptType* type;
int refs;
uint32_t flags;
union {
int32_t s32;
uint32_t u32;
float f32;
int64_t s64;
uint64_t u64;
double f64;
void* opaque;
const void* copaque;
} value;
};
DECLARE_VECTOR(mScriptList, struct mScriptValue)
struct mScriptString {

View File

@ -66,6 +66,10 @@ static void testAv1(struct TestA* a, int b) {
a->i += b;
}
static void testAv2(struct TestA* a, int b, int c) {
a->i += b + c;
}
static int32_t testGet(struct TestE* e, const char* name) {
UNUSED(e);
return name[0];
@ -90,6 +94,7 @@ mSCRIPT_DECLARE_STRUCT_C_METHOD(TestA, S32, ic0, testAic0, 0);
mSCRIPT_DECLARE_STRUCT_C_METHOD(TestA, S32, ic1, testAic1, 1, S32, b);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(TestA, v0, testAv0, 0);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD(TestA, v1, testAv1, 1, S32, b);
mSCRIPT_DECLARE_STRUCT_VOID_METHOD_WITH_DEFAULTS(TestA, v2, testAv2, 2, S32, b, S32, c);
mSCRIPT_DEFINE_STRUCT(TestA)
mSCRIPT_DEFINE_DOCSTRING(MEMBER_A_DOCSTRING)
@ -109,8 +114,14 @@ mSCRIPT_DEFINE_STRUCT(TestA)
mSCRIPT_DEFINE_STRUCT_METHOD(TestA, ic1)
mSCRIPT_DEFINE_STRUCT_METHOD(TestA, v0)
mSCRIPT_DEFINE_STRUCT_METHOD(TestA, v1)
mSCRIPT_DEFINE_STRUCT_METHOD(TestA, v2)
mSCRIPT_DEFINE_END;
mSCRIPT_DEFINE_STRUCT_BINDING_DEFAULTS(TestA, v2)
mSCRIPT_NO_DEFAULT,
mSCRIPT_MAKE_S32(0)
mSCRIPT_DEFINE_DEFAULTS_END;
mSCRIPT_DEFINE_STRUCT(TestB)
mSCRIPT_DEFINE_INHERIT(TestA)
mSCRIPT_DEFINE_STRUCT_MEMBER(TestB, S32, i3)
@ -441,6 +452,19 @@ M_TEST_DEFINE(testAStatic) {
mSCRIPT_PUSH(&frame.arguments, S32, 2);
assert_true(mScriptInvoke(&val, &frame));
mScriptFrameDeinit(&frame);
assert_true(mScriptObjectGet(&sval, "v2", &val));
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, S(TestA), &s);
mSCRIPT_PUSH(&frame.arguments, S32, 1);
mSCRIPT_PUSH(&frame.arguments, S32, -2);
assert_true(mScriptInvoke(&val, &frame));
mScriptFrameDeinit(&frame);
assert_true(mScriptObjectGet(&sval, "v2", &val));
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, S(TestA), &s);
mSCRIPT_PUSH(&frame.arguments, S32, 1);
assert_true(mScriptInvoke(&val, &frame));
mScriptFrameDeinit(&frame);
assert_true(mScriptObjectGet(&sval, "i0", &val));
mScriptFrameInit(&frame);
mSCRIPT_PUSH(&frame.arguments, S(TestA), &s);

View File

@ -1297,11 +1297,14 @@ bool mScriptCast(const struct mScriptType* type, const struct mScriptValue* inpu
}
bool mScriptCoerceFrame(const struct mScriptTypeTuple* types, struct mScriptList* frame) {
if (types->count != mScriptListSize(frame) && (!types->variable || mScriptListSize(frame) < types->count)) {
if (types->count < mScriptListSize(frame) && !types->variable) {
return false;
}
if (types->count > mScriptListSize(frame) && !types->variable && !types->defaults) {
return false;
}
size_t i;
for (i = 0; i < types->count; ++i) {
for (i = 0; i < mScriptListSize(frame) && i < types->count; ++i) {
if (types->entries[i] == mScriptListGetPointer(frame, i)->type) {
continue;
}
@ -1316,5 +1319,15 @@ bool mScriptCoerceFrame(const struct mScriptTypeTuple* types, struct mScriptList
return false;
}
}
if (types->variable) {
return true;
}
for (; i < types->count; ++i) {
if (!types->defaults[i].type) {
return false;
}
memcpy(mScriptListAppend(frame), &types->defaults[i], sizeof(struct mScriptValue));
}
return true;
}