Commit cde8631f authored by Rachel Dowdall's avatar Rachel Dowdall
Browse files

Fixed modulo operator on ints and mp ints to agree with python. Added...

Fixed modulo operator on ints and mp ints to agree with python. Added intdivmod.c and tests/basics/modulo.py.
parent 721c55dc
......@@ -15,6 +15,7 @@
#include "obj.h"
#include "compile.h"
#include "runtime.h"
#include "intdivmod.h"
// TODO need to mangle __attr names
......@@ -141,7 +142,8 @@ mp_parse_node_t fold_constants(mp_parse_node_t pn) {
; // pass
} else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_PERCENT)) {
// XXX implement this properly as Python's % operator acts differently to C's
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 % arg1);
//pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 % arg1);
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, python_modulo(arg0, arg1));
} else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[1], MP_TOKEN_OP_DBL_SLASH)) {
// XXX implement this properly as Python's // operator acts differently to C's
pn = mp_parse_node_new_leaf(MP_PARSE_NODE_SMALL_INT, arg0 / arg1);
......
......@@ -102,10 +102,13 @@ mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
}
case RT_BINARY_OP_MODULO:
case RT_BINARY_OP_INPLACE_MODULO: {
// TODO check that this operation matches the CPython operation
mpz_t quo; mpz_init_zero(&quo);
mpz_divmod_inpl(&quo, &res->mpz, zlhs, zrhs);
mpz_deinit(&quo);
// Check signs and do Python style modulo
if (zlhs->neg != zrhs->neg) {
mpz_add_inpl(&res->mpz, &res->mpz, zrhs);
}
break;
}
......
......@@ -78,6 +78,7 @@ PY_O_BASENAME = \
vm.o \
showbc.o \
repl.o \
intdivmod.o \
# prepend the build destination prefix to the py object files
PY_O = $(addprefix $(PY_BUILD)/, $(PY_O_BASENAME))
......
......@@ -18,6 +18,7 @@
#include "builtin.h"
#include "objarray.h"
#include "bc.h"
#include "intdivmod.h"
#if 0 // print debugging info
#define DEBUG_PRINT (1)
......@@ -666,10 +667,12 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: return mp_obj_new_float((mp_float_t)lhs_val / (mp_float_t)rhs_val);
#endif
// TODO implement modulo as specified by Python
case RT_BINARY_OP_MODULO:
case RT_BINARY_OP_INPLACE_MODULO: lhs_val %= rhs_val; break;
case RT_BINARY_OP_INPLACE_MODULO:
{
lhs_val = python_modulo(lhs_val, rhs_val);
break;
}
case RT_BINARY_OP_POWER:
case RT_BINARY_OP_INPLACE_POWER:
if (rhs_val < 0) {
......
# check modulo matches python definition
print(123 % 7)
print(-123 % 7)
print(123 % -7)
print(-123 % -7)
a = 321
b = 19
print(a % b)
print(a % -b)
print(-a % b)
print(-a % -b)
a = 987654321987987987987987987987
b = 19
print(a % b)
print(a % -b)
print(-a % b)
print(-a % -b)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment