summaryrefslogtreecommitdiff
path: root/py/runtime.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/runtime.c')
-rw-r--r--py/runtime.c126
1 files changed, 85 insertions, 41 deletions
diff --git a/py/runtime.c b/py/runtime.c
index b982ee32d..e1e9e31cc 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -90,13 +90,14 @@ 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);
// built-in core functions
mp_map_add_qstr(&map_builtins, MP_QSTR___build_class__, (mp_obj_t)&mp_builtin___build_class___obj);
- mp_map_add_qstr(&map_builtins, MP_QSTR___repl_print__, rt_make_function_1(mp_builtin___repl_print__));
+ mp_map_add_qstr(&map_builtins, MP_QSTR___repl_print__, (mp_obj_t)&mp_builtin___repl_print___obj);
// built-in types
mp_map_add_qstr(&map_builtins, MP_QSTR_bool, (mp_obj_t)&bool_type);
@@ -104,35 +105,43 @@ void rt_init(void) {
mp_map_add_qstr(&map_builtins, MP_QSTR_complex, (mp_obj_t)&complex_type);
#endif
mp_map_add_qstr(&map_builtins, MP_QSTR_dict, (mp_obj_t)&dict_type);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_enumerate, (mp_obj_t)&enumerate_type);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_filter, (mp_obj_t)&filter_type);
#if MICROPY_ENABLE_FLOAT
mp_map_add_qstr(&map_builtins, MP_QSTR_float, (mp_obj_t)&float_type);
#endif
mp_map_add_qstr(&map_builtins, MP_QSTR_int, (mp_obj_t)&int_type);
mp_map_add_qstr(&map_builtins, MP_QSTR_list, (mp_obj_t)&list_type);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_map, (mp_obj_t)&map_type);
mp_map_add_qstr(&map_builtins, MP_QSTR_set, (mp_obj_t)&set_type);
mp_map_add_qstr(&map_builtins, MP_QSTR_tuple, (mp_obj_t)&tuple_type);
mp_map_add_qstr(&map_builtins, MP_QSTR_type, (mp_obj_t)&mp_const_type);
-
- // built-in user functions; TODO covert all to &mp_builtin_xxx's
- mp_map_add_qstr(&map_builtins, MP_QSTR_abs, rt_make_function_1(mp_builtin_abs));
- mp_map_add_qstr(&map_builtins, MP_QSTR_all, rt_make_function_1(mp_builtin_all));
- mp_map_add_qstr(&map_builtins, MP_QSTR_any, rt_make_function_1(mp_builtin_any));
- mp_map_add_qstr(&map_builtins, MP_QSTR_callable, rt_make_function_1(mp_builtin_callable));
- mp_map_add_qstr(&map_builtins, MP_QSTR_chr, rt_make_function_1(mp_builtin_chr));
- mp_map_add_qstr(&map_builtins, MP_QSTR_divmod, rt_make_function_2(mp_builtin_divmod));
+ mp_map_add_qstr(&map_builtins, MP_QSTR_zip, (mp_obj_t)&zip_type);
+
+ // built-in user functions
+ mp_map_add_qstr(&map_builtins, MP_QSTR_abs, (mp_obj_t)&mp_builtin_abs_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_all, (mp_obj_t)&mp_builtin_all_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_any, (mp_obj_t)&mp_builtin_any_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_callable, (mp_obj_t)&mp_builtin_callable_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_chr, (mp_obj_t)&mp_builtin_chr_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_divmod, (mp_obj_t)&mp_builtin_divmod_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_eval, (mp_obj_t)&mp_builtin_eval_obj);
mp_map_add_qstr(&map_builtins, MP_QSTR_hash, (mp_obj_t)&mp_builtin_hash_obj);
mp_map_add_qstr(&map_builtins, MP_QSTR_isinstance, (mp_obj_t)&mp_builtin_isinstance_obj);
mp_map_add_qstr(&map_builtins, MP_QSTR_issubclass, (mp_obj_t)&mp_builtin_issubclass_obj);
mp_map_add_qstr(&map_builtins, MP_QSTR_iter, (mp_obj_t)&mp_builtin_iter_obj);
- mp_map_add_qstr(&map_builtins, MP_QSTR_len, rt_make_function_1(mp_builtin_len));
- mp_map_add_qstr(&map_builtins, MP_QSTR_max, rt_make_function_var(1, mp_builtin_max));
- mp_map_add_qstr(&map_builtins, MP_QSTR_min, rt_make_function_var(1, mp_builtin_min));
+ mp_map_add_qstr(&map_builtins, MP_QSTR_len, (mp_obj_t)&mp_builtin_len_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_max, (mp_obj_t)&mp_builtin_max_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_min, (mp_obj_t)&mp_builtin_min_obj);
mp_map_add_qstr(&map_builtins, MP_QSTR_next, (mp_obj_t)&mp_builtin_next_obj);
- mp_map_add_qstr(&map_builtins, MP_QSTR_ord, rt_make_function_1(mp_builtin_ord));
- mp_map_add_qstr(&map_builtins, MP_QSTR_pow, rt_make_function_var(2, mp_builtin_pow));
- mp_map_add_qstr(&map_builtins, MP_QSTR_print, rt_make_function_var(0, mp_builtin_print));
- mp_map_add_qstr(&map_builtins, MP_QSTR_range, rt_make_function_var(1, mp_builtin_range));
- mp_map_add_qstr(&map_builtins, MP_QSTR_sum, rt_make_function_var(1, mp_builtin_sum));
+ mp_map_add_qstr(&map_builtins, MP_QSTR_ord, (mp_obj_t)&mp_builtin_ord_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_pow, (mp_obj_t)&mp_builtin_pow_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_print, (mp_obj_t)&mp_builtin_print_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_range, (mp_obj_t)&mp_builtin_range_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_repr, (mp_obj_t)&mp_builtin_repr_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_sorted, (mp_obj_t)&mp_builtin_sorted_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_sum, (mp_obj_t)&mp_builtin_sum_obj);
+ mp_map_add_qstr(&map_builtins, MP_QSTR_str, (mp_obj_t)&mp_builtin_str_obj);
next_unique_code_id = 1; // 0 indicates "no code"
unique_codes_alloc = 0;
@@ -267,10 +276,6 @@ void rt_assign_inline_asm_code(int unique_code_id, void *fun, uint len, int n_ar
#endif
}
-static bool fit_small_int(mp_small_int_t o) {
- return true;
-}
-
int rt_is_true(mp_obj_t arg) {
DEBUG_OP_printf("is true %p\n", arg);
if (MP_OBJ_IS_SMALL_INT(arg)) {
@@ -435,13 +440,10 @@ mp_obj_t rt_unary_op(int op, mp_obj_t arg) {
case RT_UNARY_OP_INVERT: val = ~val; break;
default: assert(0); val = 0;
}
- if (fit_small_int(val)) {
+ if (MP_OBJ_FITS_SMALL_INT(val)) {
return MP_OBJ_NEW_SMALL_INT(val);
- } else {
- // TODO make a bignum
- assert(0);
- return mp_const_none;
}
+ return mp_obj_new_int(val);
} else { // will be an object (small ints are caught in previous if)
mp_obj_base_t *o = arg;
if (o->type->unary_op != NULL) {
@@ -467,6 +469,18 @@ 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 is, is not
+ if (op == RT_COMPARE_OP_IS) {
+ // TODO: may need to handle strings specially, CPython appears to
+ // assume all strings are interned (so "is" == "==" for strings)
+ return MP_BOOL(lhs == rhs);
+ }
+ if (op == RT_COMPARE_OP_IS_NOT) {
+ // TODO: may need to handle strings specially, CPython appears to
+ // assume all strings are interned (so "is" == "==" for strings)
+ return MP_BOOL(lhs != rhs);
+ }
+
// deal with == and != for all types
if (op == RT_COMPARE_OP_EQUAL || op == RT_COMPARE_OP_NOT_EQUAL) {
if (mp_obj_equal(lhs, rhs)) {
@@ -550,32 +564,67 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
default: assert(0);
}
- if (fit_small_int(lhs_val)) {
+ // TODO: We just should make mp_obj_new_int() inline and use that
+ if (MP_OBJ_FITS_SMALL_INT(lhs_val)) {
return MP_OBJ_NEW_SMALL_INT(lhs_val);
}
- // TODO: return long int
- assert(0);
+ return mp_obj_new_int(lhs_val);
} 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;
+ }
+
+ /* deal with `in` and `not in`
+ *
+ * NOTE `a in b` is `b.__contains__(a)`, hence why the generic dispatch
+ * needs to go below
+ */
+ if (op == RT_COMPARE_OP_IN || op == RT_COMPARE_OP_NOT_IN) {
+ if (!MP_OBJ_IS_SMALL_INT(rhs)) {
+ mp_obj_base_t *o = rhs;
if (o->type->binary_op != NULL) {
- mp_obj_t result = o->type->binary_op(op, lhs, rhs);
- if (result != NULL) {
- return result;
+ mp_obj_t res = o->type->binary_op(op, rhs, lhs);
+ if (res != NULL) {
+ return res;
}
}
+ if (o->type->getiter != NULL) {
+ /* second attempt, walk the iterator */
+ mp_obj_t next = NULL;
+ mp_obj_t iter = rt_getiter(rhs);
+ while ((next = rt_iternext(iter)) != mp_const_stop_iteration) {
+ if (mp_obj_equal(next, lhs)) {
+ return MP_BOOL(op == RT_COMPARE_OP_IN);
+ }
+ }
+ return MP_BOOL(op != RT_COMPARE_OP_IN);
+ }
+ }
+
+ nlr_jump(mp_obj_new_exception_msg_varg(
+ MP_QSTR_TypeError, "'%s' object is not iterable",
+ mp_obj_get_type_str(rhs)));
+ return mp_const_none;
+ }
+
+ 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;
+ }
}
+ // TODO implement dispatch for reverse binary ops
}
// TODO specify in error message what the operator is
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError,
"unsupported operand types for binary operator: '%s', '%s'",
mp_obj_get_type_str(lhs), mp_obj_get_type_str(rhs)));
+ return mp_const_none;
}
mp_obj_t rt_make_function_from_id(int unique_code_id) {
@@ -593,12 +642,7 @@ mp_obj_t rt_make_function_from_id(int unique_code_id) {
fun = mp_obj_new_fun_bc(c->n_args, c->n_locals + c->n_stack, c->u_byte.code);
break;
case MP_CODE_NATIVE:
- switch (c->n_args) {
- case 0: fun = rt_make_function_0(c->u_native.fun); break;
- case 1: fun = rt_make_function_1((mp_fun_1_t)c->u_native.fun); break;
- case 2: fun = rt_make_function_2((mp_fun_2_t)c->u_native.fun); break;
- default: assert(0); fun = mp_const_none;
- }
+ fun = rt_make_function_n(c->n_args, c->u_native.fun);
break;
case MP_CODE_INLINE_ASM:
fun = mp_obj_new_fun_asm(c->n_args, c->u_inline_asm.fun);