@@@ py_buffer/freebin wip
[catacomb-python] / field.c
diff --git a/field.c b/field.c
index 88793b0..2e99efc 100644 (file)
--- a/field.c
+++ b/field.c
@@ -107,23 +107,18 @@ PyObject *fe_pywrap(PyObject *fobj, mp *x)
   return ((PyObject *)z);
 }
 
-static mp *tofe(field *f, PyObject *o)
+static mp *implicitfe(field *f, PyObject *o)
 {
-  mp *x = 0, *y = 0;
-
-  if (FE_PYCHECK(o)) {
-    if (FE_F(o) != f && !field_samep(FE_F(o), f)) return (0);
-    y = MP_COPY(FE_X(o));
-  } else if ((x = tomp(o)) != 0) {
-    if (MP_ZEROP(x))
-      y = MP_COPY(f->zero);
-    else if (MP_EQ(x, MP_ONE))
-      y = MP_COPY(f->one);
-    else
-      y = F_IN(f, MP_NEW, x);
-    MP_DROP(x);
+  mp *x;
+
+  if (FE_PYCHECK(o) && FE_F(o) == f) return (MP_COPY(FE_X(o)));
+  switch (f->ops->ty) {
+    case FTY_PRIME: x = implicitmp(o); break;
+    case FTY_BINARY: x = implicitgf(o); break;
+    default: assert(!"huh?");
   }
-  return (y);
+  if (!x) return (0);
+  return (F_IN(f, MP_NEW, x));
 }
 
 /*----- Field elements ----------------------------------------------------*/
@@ -135,9 +130,9 @@ static int febinop(PyObject *x, PyObject *y,
   else if (FE_PYCHECK(y)) *fobj = FE_FOBJ(y);
   else return (-1);
   *f = FIELD_F(*fobj);
-  if ((*xx = tofe(*f, x)) == 0)
+  if ((*xx = implicitfe(*f, x)) == 0)
     return (-1);
-  if ((*yy = tofe(*f, y)) == 0) {
+  if ((*yy = implicitfe(*f, y)) == 0) {
     MP_DROP(*xx);
     return (-1);
   }
@@ -179,7 +174,10 @@ static PyObject *fe_pyexp(PyObject *x, PyObject *y, PyObject *z)
   field *ff;
   mp *xx, *yy;
 
-  if (z != Py_None || !FE_PYCHECK(x) || (yy = tomp(y)) == 0)
+  if (z != Py_None || !FE_PYCHECK(x)) RETURN_NOTIMPL;
+  if (FE_PYCHECK(y) && FE_F(y)->ops->ty == FTY_PRIME)
+    yy = F_OUT(FE_F(y), MP_NEW, FE_X(y));
+  else if ((yy = implicitmp(y)) == 0)
     RETURN_NOTIMPL;
   ff = FE_F(x); xx = FE_X(x); MP_COPY(xx);
   if (MP_NEGP(yy) && F_ZEROP(ff, xx)) ZDIVERR("division by zero");
@@ -221,6 +219,7 @@ end:
 static Py_hash_t fe_pyhash(PyObject *me)
   { return (mphash(FE_X(me))); }
 
+#ifdef PY2
 static int fe_pycoerce(PyObject **x, PyObject **y)
 {
   mp *z;
@@ -231,7 +230,7 @@ static int fe_pycoerce(PyObject **x, PyObject **y)
     Py_INCREF(*x); Py_INCREF(*y);
     return (0);
   }
-  if ((z = tofe(FE_F(*x), *y)) != 0) {
+  if ((z = implicitfe(FE_F(*x), *y)) != 0) {
     Py_INCREF(*x);
     *y = fe_pywrap(FE_FOBJ(*x), z);
     return (0);
@@ -241,6 +240,7 @@ static int fe_pycoerce(PyObject **x, PyObject **y)
 end:
   return (-1);
 }
+#endif
 
 static PyObject *fe_pyint(PyObject *x)
 {
@@ -253,6 +253,7 @@ static PyObject *fe_pyint(PyObject *x)
   return (rc);
 }
 
+#ifdef PY2
 static PyObject *fe_pylong(PyObject *x)
 {
   mp *xx = F_OUT(FE_F(x), MP_NEW, FE_X(x));
@@ -260,6 +261,7 @@ static PyObject *fe_pylong(PyObject *x)
   MP_DROP(xx);
   return (rc);
 }
+#endif
 
 #define BASEOP(name, radix, pre)                                       \
   static PyObject *fe_py##name(PyObject *x) {                          \
@@ -268,7 +270,9 @@ static PyObject *fe_pylong(PyObject *x)
     MP_DROP(xx);                                                       \
     return (rc);                                                       \
   }
+#ifdef PY2
 BASEOP(oct, 8, "0");
+#endif
 BASEOP(hex, 16, "0x");
 #undef BASEOP
 
@@ -322,7 +326,7 @@ static PyObject *feget__value(PyObject *me, void *hunoz)
 
 static const PyMemberDef fe_pymembers[] = {
 #define MEMBERSTRUCT fe_pyobj
-  MEMRNM(field, T_OBJECT, ob_type, READONLY,
+  MEMRNM(field, T_OBJECT, PY23(ob_type, ob_base.ob_type), READONLY,
                        "X.field -> field containing X")
 #undef MEMBERSTRUCT
   { 0 }
@@ -354,7 +358,9 @@ static const PyNumberMethods fe_pynumber = {
   fe_pyadd,                            /* @nb_add@ */
   fe_pysub,                            /* @nb_subtract@ */
   fe_pymul,                            /* @nb_multiply@ */
+#ifdef PY2
   fe_pydiv,                            /* @nb_divide@ */
+#endif
   0,                                   /* @nb_remainder@ */
   0,                                   /* @nb_divmod@ */
   fe_pyexp,                            /* @nb_power@ */
@@ -368,17 +374,23 @@ static const PyNumberMethods fe_pynumber = {
   0,                                   /* @nb_and@ */
   0,                                   /* @nb_xor@ */
   0,                                   /* @nb_or@ */
+#ifdef PY2
   fe_pycoerce,                         /* @nb_coerce@ */
+#endif
   fe_pyint,                            /* @nb_int@ */
-  fe_pylong,                           /* @nb_long@ */
+  PY23(fe_pylong, 0),                  /* @nb_long@ */
   0 /* meaningless */,                 /* @nb_float@ */
+#ifdef PY2
   fe_pyoct,                            /* @nb_oct@ */
   fe_pyhex,                            /* @nb_hex@ */
+#endif
 
   0,                                   /* @nb_inplace_add@ */
   0,                                   /* @nb_inplace_subtract@ */
   0,                                   /* @nb_inplace_multiply@ */
+#ifdef PY2
   0,                                   /* @nb_inplace_divide@ */
+#endif
   0,                                   /* @nb_inplace_remainder@ */
   0,                                   /* @nb_inplace_power@ */
   0,                                   /* @nb_inplace_lshift@ */