From aedb8591778a8dc4097eb4ffd2891dd5730efdde Mon Sep 17 00:00:00 2001
From: Damien George <damien.p.george@gmail.com>
Date: Sat, 17 Oct 2015 22:57:34 +0100
Subject: [PATCH] py: Make float representation configurable with object
 representation.

---
 py/obj.c      |  4 ++++
 py/obj.h      | 30 ++++++++++++++++++++++--------
 py/objfloat.c | 16 ++++++++--------
 3 files changed, 34 insertions(+), 16 deletions(-)

diff --git a/py/obj.c b/py/obj.c
index 9d77d2546..42bf0c500 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -44,6 +44,10 @@ mp_obj_type_t *mp_obj_get_type(mp_const_obj_t o_in) {
         return (mp_obj_t)&mp_type_int;
     } else if (MP_OBJ_IS_QSTR(o_in)) {
         return (mp_obj_t)&mp_type_str;
+    #if MICROPY_PY_BUILTINS_FLOAT
+    } else if (mp_obj_is_float(o_in)) {
+        return (mp_obj_t)&mp_type_float;
+    #endif
     } else {
         const mp_obj_base_t *o = o_in;
         return (mp_obj_t)o->type;
diff --git a/py/obj.h b/py/obj.h
index 9995f9548..faf7e096a 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -83,6 +83,17 @@ static inline bool MP_OBJ_IS_QSTR(mp_const_obj_t o)
 #define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 2)
 #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 2))
 
+#if MICROPY_PY_BUILTINS_FLOAT
+#define mp_const_float_e ((mp_obj_t)&mp_const_float_e_obj)
+#define mp_const_float_pi ((mp_obj_t)&mp_const_float_pi_obj)
+extern const struct _mp_obj_float_t mp_const_float_e_obj;
+extern const struct _mp_obj_float_t mp_const_float_pi_obj;
+
+#define mp_obj_is_float(o) MP_OBJ_IS_TYPE((o), &mp_type_float)
+mp_float_t mp_obj_float_get(mp_obj_t self_in);
+mp_obj_t mp_obj_new_float(mp_float_t value);
+#endif
+
 static inline bool MP_OBJ_IS_OBJ(mp_const_obj_t o)
     { return ((((mp_int_t)(o)) & 3) == 0); }
 
@@ -98,6 +109,17 @@ static inline bool MP_OBJ_IS_QSTR(mp_const_obj_t o)
 #define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 2)
 #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 3))
 
+#if MICROPY_PY_BUILTINS_FLOAT
+#define mp_const_float_e ((mp_obj_t)&mp_const_float_e_obj)
+#define mp_const_float_pi ((mp_obj_t)&mp_const_float_pi_obj)
+extern const struct _mp_obj_float_t mp_const_float_e_obj;
+extern const struct _mp_obj_float_t mp_const_float_pi_obj;
+
+#define mp_obj_is_float(o) MP_OBJ_IS_TYPE((o), &mp_type_float)
+mp_float_t mp_obj_float_get(mp_obj_t self_in);
+mp_obj_t mp_obj_new_float(mp_float_t value);
+#endif
+
 static inline bool MP_OBJ_IS_OBJ(mp_const_obj_t o)
     { return ((((mp_int_t)(o)) & 1) == 0); }
 
@@ -473,7 +495,6 @@ mp_obj_t mp_obj_new_bytearray(mp_uint_t n, void *items);
 mp_obj_t mp_obj_new_bytearray_by_ref(mp_uint_t n, void *items);
 #if MICROPY_PY_BUILTINS_FLOAT
 mp_obj_t mp_obj_new_int_from_float(mp_float_t val);
-mp_obj_t mp_obj_new_float(mp_float_t val);
 mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag);
 #endif
 mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type);
@@ -564,13 +585,6 @@ void mp_str_print_quoted(const mp_print_t *print, const byte *str_data, mp_uint_
 
 #if MICROPY_PY_BUILTINS_FLOAT
 // float
-#define mp_const_float_e ((mp_obj_t)&mp_const_float_e_obj)
-#define mp_const_float_pi ((mp_obj_t)&mp_const_float_pi_obj)
-extern const struct _mp_obj_float_t mp_const_float_e_obj;
-extern const struct _mp_obj_float_t mp_const_float_pi_obj;
-
-#define mp_obj_is_float(o) MP_OBJ_IS_TYPE((o), &mp_type_float)
-mp_float_t mp_obj_float_get(mp_obj_t self_in);
 mp_obj_t mp_obj_float_binary_op(mp_uint_t op, mp_float_t lhs_val, mp_obj_t rhs); // can return MP_OBJ_NULL if op not supported
 
 // complex
diff --git a/py/objfloat.c b/py/objfloat.c
index f01bfe72b..7c58f320d 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -49,7 +49,7 @@ const mp_obj_float_t mp_const_float_pi_obj = {{&mp_type_float}, M_PI};
 
 STATIC void float_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) {
     (void)kind;
-    mp_obj_float_t *o = o_in;
+    mp_float_t o_val = mp_obj_float_get(o_in);
 #if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
     char buf[16];
     const int precision = 7;
@@ -57,7 +57,7 @@ STATIC void float_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t
     char buf[32];
     const int precision = 16;
 #endif
-    mp_format_float(o->value, buf, sizeof(buf), 'g', precision, '\0');
+    mp_format_float(o_val, buf, sizeof(buf), 'g', precision, '\0');
     mp_print_str(print, buf);
     if (strchr(buf, '.') == NULL && strchr(buf, 'e') == NULL && strchr(buf, 'n') == NULL) {
         // Python floats always have decimal point (unless inf or nan)
@@ -91,24 +91,24 @@ STATIC mp_obj_t float_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_k
 }
 
 STATIC mp_obj_t float_unary_op(mp_uint_t op, mp_obj_t o_in) {
-    mp_obj_float_t *o = o_in;
+    mp_float_t val = mp_obj_float_get(o_in);
     switch (op) {
-        case MP_UNARY_OP_BOOL: return mp_obj_new_bool(o->value != 0);
+        case MP_UNARY_OP_BOOL: return mp_obj_new_bool(val != 0);
         case MP_UNARY_OP_POSITIVE: return o_in;
-        case MP_UNARY_OP_NEGATIVE: return mp_obj_new_float(-o->value);
+        case MP_UNARY_OP_NEGATIVE: return mp_obj_new_float(-val);
         default: return MP_OBJ_NULL; // op not supported
     }
 }
 
 STATIC mp_obj_t float_binary_op(mp_uint_t op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
-    mp_obj_float_t *lhs = lhs_in;
+    mp_float_t lhs_val = mp_obj_float_get(lhs_in);
 #if MICROPY_PY_BUILTINS_COMPLEX
     if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_complex)) {
-        return mp_obj_complex_binary_op(op, lhs->value, 0, rhs_in);
+        return mp_obj_complex_binary_op(op, lhs_val, 0, rhs_in);
     } else
 #endif
     {
-        return mp_obj_float_binary_op(op, lhs->value, rhs_in);
+        return mp_obj_float_binary_op(op, lhs_val, rhs_in);
     }
 }
 
-- 
GitLab