unary + (__pos__)

This commit is contained in:
K. Lange 2022-07-06 15:20:27 +09:00
parent ed52b72ae8
commit 17772c74ef
8 changed files with 33 additions and 20 deletions

View File

@ -2525,7 +2525,7 @@ static void unary(int exprType) {
parsePrecedence(PREC_FACTOR);
invalidTarget(exprType, "operator");
switch (operatorType) {
case TOKEN_PLUS: break; /* no op, but explicitly listed here for clarity */
case TOKEN_PLUS: emitByte(OP_POS); break;
case TOKEN_MINUS: emitByte(OP_NEGATE); break;
case TOKEN_TILDE: emitByte(OP_BITNEGATE); break;
case TOKEN_BANG: emitByte(OP_NOT); break;

View File

@ -72,6 +72,7 @@ typedef enum {
OP_UNSET,
OP_RAISE_FROM,
OP_MATMUL,
OP_POS,
OP_INPLACE_ADD,
OP_INPLACE_BITAND,

View File

@ -236,6 +236,7 @@ typedef struct KrkClass {
KrkObj * _invert, * _negate;
KrkObj * _set_name;
KrkObj * _matmul, * _rmatmul, * _imatmul;
KrkObj * _pos;
} KrkClass;
/**

View File

@ -44,6 +44,7 @@ CACHED_METHOD(GE, "__ge__", _ge)
CACHED_METHOD(INVERT, "__invert__", _invert)
CACHED_METHOD(NEGATE, "__neg__", _negate)
CACHED_METHOD(SETNAME, "__set_name__", _set_name)
CACHED_METHOD(POS, "__pos__", _pos)
/* These are not methods */
SPECIAL_ATTRS(CLASS, "__class__")

View File

@ -1510,6 +1510,10 @@ KRK_Method(long,__abs__) {
return make_long_obj(&tmp);
}
KRK_Method(long,__pos__) {
return argv[0];
}
static KrkValue long_bit_count(KrkLong * val) {
size_t count = 0;
size_t bits = _bits_in(val);
@ -1768,6 +1772,7 @@ void _createAndBind_longClass(void) {
BIND_METHOD(long,__int__);
BIND_METHOD(long,__len__);
BIND_METHOD(long,__float__);
BIND_METHOD(long,__pos__);
krk_defineNative(&_long->methods,"__repr__", FUNC_NAME(long,__str__));
BIND_TRIPLET(long,add);

View File

@ -302,6 +302,10 @@ KRK_Method(int,__abs__) {
return self < 0 ? INTEGER_VAL(-self) : INTEGER_VAL(self);
}
KRK_Method(int,__pos__) {
return argv[0];
}
#undef CURRENT_CTYPE
#define CURRENT_CTYPE double
@ -447,6 +451,10 @@ KRK_Method(float,__rfloordiv__) {
return NOTIMPL_VAL();
}
KRK_Method(float,__pos__) {
return argv[0];
}
#undef CURRENT_CTYPE
#define CURRENT_CTYPE krk_integer_type
@ -545,6 +553,7 @@ void _createAndBind_numericClasses(void) {
BIND_METHOD(int,__invert__);
BIND_METHOD(int,__neg__);
BIND_METHOD(int,__abs__);
BIND_METHOD(int,__pos__);
krk_defineNative(&_int->methods, "__repr__", FUNC_NAME(int,__str__));
krk_finalizeClass(_int);
@ -569,6 +578,7 @@ void _createAndBind_numericClasses(void) {
BIND_METHOD(float,__ge__);
BIND_METHOD(float,__neg__);
BIND_METHOD(float,__abs__);
BIND_METHOD(float,__pos__);
krk_defineNative(&_float->methods, "__repr__", FUNC_NAME(float,__str__));
krk_finalizeClass(_float);
KRK_DOC(_float, "Convert a number or string type to a float representation.");

View File

@ -25,6 +25,7 @@ SIMPLE(OP_BITAND)
SIMPLE(OP_SHIFTLEFT)
SIMPLE(OP_SHIFTRIGHT)
SIMPLE(OP_BITNEGATE)
SIMPLE(OP_POS)
SIMPLE(OP_INVOKE_GETTER)
SIMPLE(OP_INVOKE_SETTER)
SIMPLE(OP_INVOKE_DELETE)

View File

@ -1712,27 +1712,20 @@ KrkValue krk_operator_is(KrkValue a, KrkValue b) {
return BOOLEAN_VAL(krk_valuesSame(a,b));
}
_protected
KrkValue krk_operator_invert(KrkValue value) {
KrkClass * type = krk_getType(value);
if (likely(type->_invert != NULL)) {
krk_push(value);
return krk_callDirect(type->_invert, 1);
#define MAKE_UNARY_OP(sname,operator,op) \
_protected KrkValue krk_operator_ ## operator (KrkValue value) { \
KrkClass * type = krk_getType(value); \
if (likely(type-> sname != NULL)) { \
krk_push(value); \
return krk_callDirect(type-> sname, 1); \
} \
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL(); \
return krk_runtimeError(vm.exceptions->typeError, "bad operand type for unary %s: '%s'", #op, krk_typeName(value)); \
}
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL();
return krk_runtimeError(vm.exceptions->typeError, "bad operand type for unary %c: '%s'", '~', krk_typeName(value));
}
_protected
KrkValue krk_operator_neg(KrkValue value) {
KrkClass * type = krk_getType(value);
if (likely(type->_negate != NULL)) {
krk_push(value);
return krk_callDirect(type->_negate, 1);
}
if (krk_currentThread.flags & KRK_THREAD_HAS_EXCEPTION) return NONE_VAL();
return krk_runtimeError(vm.exceptions->typeError, "bad operand type for unary %c: '%s'", '-', krk_typeName(value));
}
MAKE_UNARY_OP(_invert,invert,~)
MAKE_UNARY_OP(_negate,neg,-)
MAKE_UNARY_OP(_pos,pos,+)
/**
* At the end of each instruction cycle, we check the exception flag to see
@ -2642,6 +2635,7 @@ _finishReturn: (void)0;
case OP_IS: BINARY_OP(is);
case OP_BITNEGATE: LIKELY_INT_UNARY_OP(invert,~)
case OP_NEGATE: LIKELY_INT_UNARY_OP(neg,-)
case OP_POS: LIKELY_INT_UNARY_OP(pos,+)
case OP_NONE: krk_push(NONE_VAL()); break;
case OP_TRUE: krk_push(BOOLEAN_VAL(1)); break;
case OP_FALSE: krk_push(BOOLEAN_VAL(0)); break;