Add framework to support alternative implementations of long int Python type.
diff --git a/py/objint.c b/py/objint.c
index 9cd5eba..26d3c0e 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -11,8 +11,16 @@
 
 typedef struct _mp_obj_int_t {
     mp_obj_base_t base;
+#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
+    mp_longint_impl_t val;
+#endif
 } mp_obj_int_t;
 
+void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in);
+mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in);
+
+// This dispatcher function is expected to be independent of the implementation
+// of long int
 static mp_obj_t int_make_new(mp_obj_t type_in, int n_args, const mp_obj_t *args) {
     switch (n_args) {
         case 0:
@@ -20,7 +28,7 @@
 
         case 1:
             // TODO allow string as arg and parse it
-            return MP_OBJ_NEW_SMALL_INT(mp_obj_get_int(args[0]));
+            return mp_obj_new_int(mp_obj_get_int(args[0]));
 
         //case 2:
             // TODO, parse with given base
@@ -33,9 +41,41 @@
 const mp_obj_type_t int_type = {
     { &mp_const_type },
     "int",
+    .print = int_print,
     .make_new = int_make_new,
+    .binary_op = int_binary_op,
 };
 
-mp_obj_t mp_obj_new_int(machine_int_t value) {
-    return MP_OBJ_NEW_SMALL_INT(value);
+#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
+// This is called only for non-SMALL_INT
+void int_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
 }
+
+// This is called only for non-SMALL_INT
+mp_obj_t int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
+    assert(0);
+}
+
+// This is called only with strings whose value doesn't fit in SMALL_INT
+mp_obj_t mp_obj_new_int_from_long_str(const char *s) {
+    assert(0);
+}
+
+mp_obj_t mp_obj_new_int_from_uint(machine_uint_t value) {
+    // SMALL_INT accepts only signed numbers, of one bit less size
+    // then word size, which totals 2 bits less for unsigned numbers.
+    if ((value & (WORD_MSBIT_HIGH | (WORD_MSBIT_HIGH >> 1))) == 0) {
+        return MP_OBJ_NEW_SMALL_INT(value);
+    }
+    // TODO: Raise exception
+    assert(0);
+}
+
+mp_obj_t mp_obj_new_int(machine_int_t value) {
+    if (MP_OBJ_FITS_SMALL_INT(value)) {
+        return MP_OBJ_NEW_SMALL_INT(value);
+    }
+    // TODO: Raise exception
+    assert(0);
+}
+#endif