diff options
Diffstat (limited to 'py/runtime.c')
-rw-r--r-- | py/runtime.c | 145 |
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, }; |