summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--ports/unix/mpconfigport_coverage.h1
-rw-r--r--py/mpconfig.h10
-rw-r--r--py/objtype.c7
-rw-r--r--py/runtime.c15
-rw-r--r--py/runtime0.h17
5 files changed, 48 insertions, 2 deletions
diff --git a/ports/unix/mpconfigport_coverage.h b/ports/unix/mpconfigport_coverage.h
index a9e0a38fa0..367b4853af 100644
--- a/ports/unix/mpconfigport_coverage.h
+++ b/ports/unix/mpconfigport_coverage.h
@@ -35,6 +35,7 @@
#define MICROPY_FLOAT_HIGH_QUALITY_HASH (1)
#define MICROPY_ENABLE_SCHEDULER (1)
#define MICROPY_PY_DELATTR_SETATTR (1)
+#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1)
#define MICROPY_PY_BUILTINS_HELP (1)
#define MICROPY_PY_BUILTINS_HELP_MODULES (1)
#define MICROPY_PY_SYS_GETSIZEOF (1)
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 38cf4b5605..63438a8465 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -759,11 +759,19 @@ typedef double mp_float_t;
#endif
// Whether to support complete set of special methods
-// for user classes, otherwise only the most used
+// for user classes, or only the most used ones. "Reverse"
+// methods are controlled by MICROPY_PY_REVERSE_SPECIAL_METHODS
+// below.
#ifndef MICROPY_PY_ALL_SPECIAL_METHODS
#define MICROPY_PY_ALL_SPECIAL_METHODS (0)
#endif
+// Whether to support reverse arithmetic operarions methods
+// (__radd__, etc.)
+#ifndef MICROPY_PY_REVERSE_SPECIAL_METHODS
+#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0)
+#endif
+
// Whether to support compile function
#ifndef MICROPY_PY_BUILTINS_COMPILE
#define MICROPY_PY_BUILTINS_COMPILE (0)
diff --git a/py/objtype.c b/py/objtype.c
index 8ce593dba7..cf9311d5cb 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -441,6 +441,13 @@ const qstr mp_binary_op_method_name[] = {
MP_BINARY_OP_INPLACE_TRUE_DIVIDE,
MP_BINARY_OP_INPLACE_MODULO,
MP_BINARY_OP_INPLACE_POWER,*/
+
+ #if MICROPY_PY_REVERSE_SPECIAL_METHODS
+ [MP_BINARY_OP_REVERSE_ADD] = MP_QSTR___radd__,
+ [MP_BINARY_OP_REVERSE_SUBTRACT] = MP_QSTR___rsub__,
+ [MP_BINARY_OP_REVERSE_MULTIPLY] = MP_QSTR___rmul__,
+ #endif
+
[MP_BINARY_OP_LESS] = MP_QSTR___lt__,
[MP_BINARY_OP_MORE] = MP_QSTR___gt__,
[MP_BINARY_OP_EQUAL] = MP_QSTR___eq__,
diff --git a/py/runtime.c b/py/runtime.c
index 21ef42577f..c533558dab 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -555,7 +555,20 @@ generic_binary_op:
}
}
- // TODO implement dispatch for reverse binary ops
+#if MICROPY_PY_REVERSE_SPECIAL_METHODS
+ if (op >= MP_BINARY_OP_OR && op <= MP_BINARY_OP_REVERSE_POWER) {
+ mp_obj_t t = rhs;
+ rhs = lhs;
+ lhs = t;
+ if (op <= MP_BINARY_OP_POWER) {
+ op += MP_BINARY_OP_REVERSE_OR - MP_BINARY_OP_OR;
+ goto generic_binary_op;
+ }
+
+ // Convert __rop__ back to __op__ for error message
+ op -= MP_BINARY_OP_REVERSE_OR - MP_BINARY_OP_OR;
+ }
+#endif
unsupported_op:
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
diff --git a/py/runtime0.h b/py/runtime0.h
index 3cf5e530dc..a3e9d46b97 100644
--- a/py/runtime0.h
+++ b/py/runtime0.h
@@ -101,6 +101,23 @@ typedef enum {
// Operations below this line don't appear in bytecode, they
// just identify special methods.
+ // MP_BINARY_OP_REVERSE_* must follow immediately after MP_BINARY_OP_*
+#if MICROPY_PY_REVERSE_SPECIAL_METHODS
+ MP_BINARY_OP_REVERSE_OR,
+ MP_BINARY_OP_REVERSE_XOR,
+ MP_BINARY_OP_REVERSE_AND,
+ MP_BINARY_OP_REVERSE_LSHIFT,
+ MP_BINARY_OP_REVERSE_RSHIFT,
+ MP_BINARY_OP_REVERSE_ADD,
+
+ MP_BINARY_OP_REVERSE_SUBTRACT,
+ MP_BINARY_OP_REVERSE_MULTIPLY,
+ MP_BINARY_OP_REVERSE_FLOOR_DIVIDE,
+ MP_BINARY_OP_REVERSE_TRUE_DIVIDE,
+ MP_BINARY_OP_REVERSE_MODULO,
+ MP_BINARY_OP_REVERSE_POWER,
+#endif
+
MP_BINARY_OP_DIVMOD, // not emitted by the compiler but supported by the runtime
MP_BINARY_OP_LAST,