+added unary negative meta function overriding support for referenced usertype.

This commit is contained in:
Wang Renxin 2016-06-23 10:19:14 +08:00 committed by GitHub
parent c02f468a7d
commit 0767d1d225

View File

@ -364,13 +364,14 @@ typedef struct _gc_t {
int_t collecting; int_t collecting;
} _gc_t; } _gc_t;
typedef struct _override_operator_info_t { typedef struct _calculation_operator_info_t {
mb_meta_operator_t is; mb_meta_operator_t is;
mb_meta_operator_t add; mb_meta_operator_t add;
mb_meta_operator_t sub; mb_meta_operator_t sub;
mb_meta_operator_t mul; mb_meta_operator_t mul;
mb_meta_operator_t div; mb_meta_operator_t div;
} _override_operator_info_t; mb_meta_operator_t neg;
} _calculation_operator_info_t;
typedef struct _usertype_ref_t { typedef struct _usertype_ref_t {
_ref_t ref; _ref_t ref;
@ -380,7 +381,7 @@ typedef struct _usertype_ref_t {
mb_hash_func_t hash; mb_hash_func_t hash;
mb_cmp_func_t cmp; mb_cmp_func_t cmp;
mb_fmt_func_t fmt; mb_fmt_func_t fmt;
_override_operator_info_t* operators; _calculation_operator_info_t* calc_operators;
} _usertype_ref_t; } _usertype_ref_t;
typedef struct _func_t { typedef struct _func_t {
@ -997,16 +998,16 @@ static _object_t* _exp_assign = 0;
mb_make_nil(vfst); \ mb_make_nil(vfst); \
mb_make_nil(vscd); \ mb_make_nil(vscd); \
mb_make_nil(ret); \ mb_make_nil(ret); \
if(opnd1->type == _DT_USERTYPE_REF && opnd1->data.usertype_ref->operators && opnd1->data.usertype_ref->operators->__optr) { \ if(opnd1->type == _DT_USERTYPE_REF && opnd1->data.usertype_ref->calc_operators && opnd1->data.usertype_ref->calc_operators->__optr) { \
_internal_object_to_public_value(opnd1, &vfst); \ _internal_object_to_public_value(opnd1, &vfst); \
_internal_object_to_public_value(opnd2, &vscd); \ _internal_object_to_public_value(opnd2, &vscd); \
__result = opnd1->data.usertype_ref->operators->__optr(s, (__tuple), &vfst, &vscd, &ret); \ __result = opnd1->data.usertype_ref->calc_operators->__optr(s, (__tuple), &vfst, &vscd, &ret); \
_public_value_to_internal_object(&ret, retval); \ _public_value_to_internal_object(&ret, retval); \
goto __exit; \ goto __exit; \
} else if(opnd2->type == _DT_USERTYPE_REF && opnd2->data.usertype_ref->operators && opnd2->data.usertype_ref->operators->__optr) { \ } else if(opnd2->type == _DT_USERTYPE_REF && opnd2->data.usertype_ref->calc_operators && opnd2->data.usertype_ref->calc_operators->__optr) { \
_internal_object_to_public_value(opnd1, &vfst); \ _internal_object_to_public_value(opnd1, &vfst); \
_internal_object_to_public_value(opnd2, &vscd); \ _internal_object_to_public_value(opnd2, &vscd); \
__result = opnd2->data.usertype_ref->operators->__optr(s, (__tuple), &vfst, &vscd, &ret); \ __result = opnd2->data.usertype_ref->calc_operators->__optr(s, (__tuple), &vfst, &vscd, &ret); \
_public_value_to_internal_object(&ret, retval); \ _public_value_to_internal_object(&ret, retval); \
goto __exit; \ goto __exit; \
} \ } \
@ -6131,8 +6132,8 @@ static void _destroy_usertype_ref(_usertype_ref_t* c) {
if(c->dtor) if(c->dtor)
c->dtor(c->ref.s, c->usertype); c->dtor(c->ref.s, c->usertype);
if(c->operators) { if(c->calc_operators) {
safe_free(c->operators); safe_free(c->calc_operators);
} }
_destroy_ref(&c->ref); _destroy_ref(&c->ref);
safe_free(c); safe_free(c);
@ -8529,9 +8530,9 @@ static int _clone_object(mb_interpreter_t* s, _object_t* obj, _object_t* tgt, bo
obj->data.usertype_ref->dtor, obj->data.usertype_ref->clone, obj->data.usertype_ref->dtor, obj->data.usertype_ref->clone,
obj->data.usertype_ref->hash, obj->data.usertype_ref->cmp, obj->data.usertype_ref->fmt obj->data.usertype_ref->hash, obj->data.usertype_ref->cmp, obj->data.usertype_ref->fmt
); );
if(obj->data.usertype_ref->operators) if(obj->data.usertype_ref->calc_operators)
tgt->data.usertype_ref->operators = (_override_operator_info_t*)mb_malloc(sizeof(_override_operator_info_t)); tgt->data.usertype_ref->calc_operators = (_calculation_operator_info_t*)mb_malloc(sizeof(_calculation_operator_info_t));
memcpy(tgt->data.usertype_ref->operators, obj->data.usertype_ref->operators, sizeof(_override_operator_info_t)); memcpy(tgt->data.usertype_ref->calc_operators, obj->data.usertype_ref->calc_operators, sizeof(_calculation_operator_info_t));
_ref(&tgt->data.usertype_ref->ref, tgt->data.usertype_ref); _ref(&tgt->data.usertype_ref->ref, tgt->data.usertype_ref);
break; break;
@ -11846,29 +11847,33 @@ int mb_override_value(struct mb_interpreter_t* s, void** l, mb_value_t val, mb_m
_usertype_ref_t* user = 0; _usertype_ref_t* user = 0;
_public_value_to_internal_object(&val, &obj); _public_value_to_internal_object(&val, &obj);
user = obj.data.usertype_ref; user = obj.data.usertype_ref;
if(!user->operators) { if(!user->calc_operators) {
user->operators = (_override_operator_info_t*)mb_malloc(sizeof(_override_operator_info_t)); user->calc_operators = (_calculation_operator_info_t*)mb_malloc(sizeof(_calculation_operator_info_t));
memset(user->operators, 0, sizeof(_override_operator_info_t)); memset(user->calc_operators, 0, sizeof(_calculation_operator_info_t));
} }
switch(m) { switch(m) {
case MB_MF_IS: case MB_MF_IS:
user->operators->is = f; user->calc_operators->is = f;
break; break;
case MB_MF_ADD: case MB_MF_ADD:
user->operators->add = f; user->calc_operators->add = f;
break; break;
case MB_MF_SUB: case MB_MF_SUB:
user->operators->sub = f; user->calc_operators->sub = f;
break; break;
case MB_MF_MUL: case MB_MF_MUL:
user->operators->mul = f; user->calc_operators->mul = f;
break; break;
case MB_MF_DIV: case MB_MF_DIV:
user->operators->div = f; user->calc_operators->div = f;
break;
case MB_MF_NEG:
user->calc_operators->neg = f;
break; break;
} }
@ -12622,6 +12627,9 @@ static int _core_neg(mb_interpreter_t* s, void** l) {
_running_context_t* running = 0; _running_context_t* running = 0;
int* inep = 0; int* inep = 0;
int calc_depth = 0; int calc_depth = 0;
#ifdef MB_ENABLE_USERTYPE_REF
_object_t obj;
#endif /* MB_ENABLE_USERTYPE_REF */
mb_assert(s && l); mb_assert(s && l);
@ -12666,6 +12674,18 @@ static int _core_neg(mb_interpreter_t* s, void** l) {
arg.value.float_point = -(arg.value.float_point); arg.value.float_point = -(arg.value.float_point);
break; break;
#ifdef MB_ENABLE_USERTYPE_REF
case MB_DT_USERTYPE_REF:
_MAKE_NIL(&obj);
_public_value_to_internal_object(&arg, &obj);
if(obj.data.usertype_ref->calc_operators && obj.data.usertype_ref->calc_operators->neg) {
mb_meta_operator_t neg = obj.data.usertype_ref->calc_operators->neg;
mb_check(neg(s, l, &arg, 0, &arg));
break;
}
/* Fall through */
#endif /* MB_ENABLE_USERTYPE_REF */
default: default:
_handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, s->source_file, TON(l), MB_FUNC_WARNING, _exit, result); _handle_error_on_obj(s, SE_RN_NUMBER_EXPECTED, s->source_file, TON(l), MB_FUNC_WARNING, _exit, result);