summaryrefslogtreecommitdiffstatshomepage
path: root/py/runtime.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/runtime.c')
-rw-r--r--py/runtime.c145
1 files changed, 59 insertions, 86 deletions
diff --git a/py/runtime.c b/py/runtime.c
index 3ec47a9ed5..8d3e900286 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -90,6 +90,7 @@ void rt_init(void) {
mp_map_add_qstr(&map_builtins, MP_QSTR_SyntaxError, mp_obj_new_exception(MP_QSTR_SyntaxError));
mp_map_add_qstr(&map_builtins, MP_QSTR_ValueError, mp_obj_new_exception(MP_QSTR_ValueError));
mp_map_add_qstr(&map_builtins, MP_QSTR_OSError, mp_obj_new_exception(MP_QSTR_OSError));
+ mp_map_add_qstr(&map_builtins, MP_QSTR_AssertionError, mp_obj_new_exception(MP_QSTR_AssertionError));
// built-in objects
mp_map_add_qstr(&map_builtins, MP_QSTR_Ellipsis, mp_const_ellipsis);
@@ -467,6 +468,35 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
// then fail
// note that list does not implement + or +=, so that inplace_concat is reached first for +=
+ // deal with == and != for all types
+ if (op == RT_COMPARE_OP_EQUAL || op == RT_COMPARE_OP_NOT_EQUAL) {
+ if (mp_obj_equal(lhs, rhs)) {
+ if (op == RT_COMPARE_OP_EQUAL) {
+ return mp_const_true;
+ } else {
+ return mp_const_false;
+ }
+ } else {
+ if (op == RT_COMPARE_OP_EQUAL) {
+ return mp_const_false;
+ } else {
+ return mp_const_true;
+ }
+ }
+ }
+
+ // deal with exception_match for all types
+ if (op == RT_COMPARE_OP_EXCEPTION_MATCH) {
+ // TODO properly! at the moment it just compares the exception identifier for equality
+ if (MP_OBJ_IS_TYPE(lhs, &exception_type) && MP_OBJ_IS_TYPE(rhs, &exception_type)) {
+ if (mp_obj_exception_get_type(lhs) == mp_obj_exception_get_type(rhs)) {
+ return mp_const_true;
+ } else {
+ return mp_const_false;
+ }
+ }
+ }
+
if (MP_OBJ_IS_SMALL_INT(lhs)) {
mp_small_int_t lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs);
if (MP_OBJ_IS_SMALL_INT(rhs)) {
@@ -514,23 +544,31 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
lhs_val = ans;
break;
}
+ case RT_COMPARE_OP_LESS: return MP_BOOL(lhs_val < rhs_val); break;
+ case RT_COMPARE_OP_MORE: return MP_BOOL(lhs_val > rhs_val); break;
+ case RT_COMPARE_OP_LESS_EQUAL: return MP_BOOL(lhs_val <= rhs_val); break;
+ case RT_COMPARE_OP_MORE_EQUAL: return MP_BOOL(lhs_val >= rhs_val); break;
default: assert(0);
}
if (fit_small_int(lhs_val)) {
return MP_OBJ_NEW_SMALL_INT(lhs_val);
}
+ // TODO: return long int
+ assert(0);
} else if (MP_OBJ_IS_TYPE(rhs, &float_type)) {
return mp_obj_float_binary_op(op, lhs_val, rhs);
} else if (MP_OBJ_IS_TYPE(rhs, &complex_type)) {
return mp_obj_complex_binary_op(op, lhs_val, 0, rhs);
}
- } else if (MP_OBJ_IS_OBJ(lhs)) {
- mp_obj_base_t *o = lhs;
- if (o->type->binary_op != NULL) {
- mp_obj_t result = o->type->binary_op(op, lhs, rhs);
- if (result != NULL) {
- return result;
+ } else {
+ if (MP_OBJ_IS_OBJ(lhs)) {
+ mp_obj_base_t *o = lhs;
+ if (o->type->binary_op != NULL) {
+ mp_obj_t result = o->type->binary_op(op, lhs, rhs);
+ if (result != NULL) {
+ return result;
+ }
}
}
}
@@ -541,83 +579,6 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
mp_obj_get_type_str(lhs), mp_obj_get_type_str(rhs)));
}
-mp_obj_t rt_compare_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
- DEBUG_OP_printf("compare %d %p %p\n", op, lhs, rhs);
-
- // deal with == and !=
- if (op == RT_COMPARE_OP_EQUAL || op == RT_COMPARE_OP_NOT_EQUAL) {
- if (mp_obj_equal(lhs, rhs)) {
- if (op == RT_COMPARE_OP_EQUAL) {
- return mp_const_true;
- } else {
- return mp_const_false;
- }
- } else {
- if (op == RT_COMPARE_OP_EQUAL) {
- return mp_const_false;
- } else {
- return mp_const_true;
- }
- }
- }
-
- // deal with exception_match
- if (op == RT_COMPARE_OP_EXCEPTION_MATCH) {
- // TODO properly! at the moment it just compares the exception identifier for equality
- if (MP_OBJ_IS_TYPE(lhs, &exception_type) && MP_OBJ_IS_TYPE(rhs, &exception_type)) {
- if (mp_obj_exception_get_type(lhs) == mp_obj_exception_get_type(rhs)) {
- return mp_const_true;
- } else {
- return mp_const_false;
- }
- }
- }
-
- // deal with small ints
- if (MP_OBJ_IS_SMALL_INT(lhs) && MP_OBJ_IS_SMALL_INT(rhs)) {
- mp_small_int_t lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs);
- mp_small_int_t rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs);
- int cmp;
- switch (op) {
- case RT_COMPARE_OP_LESS: cmp = lhs_val < rhs_val; break;
- case RT_COMPARE_OP_MORE: cmp = lhs_val > rhs_val; break;
- case RT_COMPARE_OP_LESS_EQUAL: cmp = lhs_val <= rhs_val; break;
- case RT_COMPARE_OP_MORE_EQUAL: cmp = lhs_val >= rhs_val; break;
- default: assert(0); cmp = 0;
- }
- if (cmp) {
- return mp_const_true;
- } else {
- return mp_const_false;
- }
- }
-
-#if MICROPY_ENABLE_FLOAT
- // deal with floats
- if (MP_OBJ_IS_TYPE(lhs, &float_type) || MP_OBJ_IS_TYPE(rhs, &float_type)) {
- mp_float_t lhs_val = mp_obj_get_float(lhs);
- mp_float_t rhs_val = mp_obj_get_float(rhs);
- int cmp;
- switch (op) {
- case RT_COMPARE_OP_LESS: cmp = lhs_val < rhs_val; break;
- case RT_COMPARE_OP_MORE: cmp = lhs_val > rhs_val; break;
- case RT_COMPARE_OP_LESS_EQUAL: cmp = lhs_val <= rhs_val; break;
- case RT_COMPARE_OP_MORE_EQUAL: cmp = lhs_val >= rhs_val; break;
- default: assert(0); cmp = 0;
- }
- if (cmp) {
- return mp_const_true;
- } else {
- return mp_const_false;
- }
- }
-#endif
-
- // not implemented
- assert(0);
- return mp_const_none;
-}
-
mp_obj_t rt_make_function_from_id(int unique_code_id) {
DEBUG_OP_printf("make_function_from_id %d\n", unique_code_id);
if (unique_code_id < 1 || unique_code_id >= next_unique_code_id) {
@@ -816,12 +777,25 @@ void rt_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) {
dest[0] = base;
} else {
// generic method lookup
+ // this is a lookup in the object (ie not class or type)
const mp_method_t *meth = type->methods;
if (meth != NULL) {
for (; meth->name != NULL; meth++) {
if (strcmp(meth->name, qstr_str(attr)) == 0) {
- dest[1] = (mp_obj_t)meth->fun;
- dest[0] = base;
+ // check if the methods are functions, static or class methods
+ // see http://docs.python.org/3.3/howto/descriptor.html
+ if (MP_OBJ_IS_TYPE(meth->fun, &mp_type_staticmethod)) {
+ // return just the function
+ dest[1] = ((mp_obj_staticmethod_t*)meth->fun)->fun;
+ } else if (MP_OBJ_IS_TYPE(meth->fun, &mp_type_classmethod)) {
+ // return a bound method, with self being the type of this object
+ dest[1] = ((mp_obj_classmethod_t*)meth->fun)->fun;
+ dest[0] = mp_obj_get_type(base);
+ } else {
+ // return a bound method, with self being this object
+ dest[1] = (mp_obj_t)meth->fun;
+ dest[0] = base;
+ }
break;
}
}
@@ -956,7 +930,6 @@ void *const rt_fun_table[RT_F_NUMBER_OF] = {
rt_call_function_n,
rt_call_method_n,
rt_binary_op,
- rt_compare_op,
rt_getiter,
rt_iternext,
};