From 66edc5d8991cfc9d01552d4a7502fa2e85107cf8 Mon Sep 17 00:00:00 2001 From: Damien George Date: Sat, 5 Apr 2014 13:25:13 +0100 Subject: [PATCH] py: Implement DELETE_SUBSCR bytecode; implement mp_obj_dict_delete. --- py/obj.h | 1 + py/objdict.c | 7 +++++++ py/runtime.c | 16 ++++++++++++++++ py/runtime.h | 1 + py/vm.c | 5 +++++ 5 files changed, 30 insertions(+) diff --git a/py/obj.h b/py/obj.h index b44b9c0a51..79efc4c4f2 100644 --- a/py/obj.h +++ b/py/obj.h @@ -440,6 +440,7 @@ typedef struct _mp_obj_dict_t { } mp_obj_dict_t; uint mp_obj_dict_len(mp_obj_t self_in); mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value); +mp_obj_t mp_obj_dict_delete(mp_obj_t self_in, mp_obj_t key); mp_map_t *mp_obj_dict_get_map(mp_obj_t self_in); // set diff --git a/py/objdict.c b/py/objdict.c index ad8c137489..7c9d8d74df 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -481,6 +481,13 @@ mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value) { return self_in; } +mp_obj_t mp_obj_dict_delete(mp_obj_t self_in, mp_obj_t key) { + assert(MP_OBJ_IS_TYPE(self_in, &mp_type_dict)); + mp_obj_dict_t *self = self_in; + dict_get_helper(&self->map, key, NULL, MP_MAP_LOOKUP_REMOVE_IF_FOUND); + return self_in; +} + mp_map_t *mp_obj_dict_get_map(mp_obj_t self_in) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_dict)); mp_obj_dict_t *self = self_in; diff --git a/py/runtime.c b/py/runtime.c index 773f998d34..1a1db46ec5 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -150,6 +150,7 @@ void mp_store_name(qstr qstr, mp_obj_t obj) { void mp_delete_name(qstr qstr) { DEBUG_OP_printf("delete name %s\n", qstr_str(qstr)); + // TODO raise NameError if qstr not found mp_map_lookup(map_locals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_REMOVE_IF_FOUND); } @@ -807,6 +808,21 @@ void mp_store_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { } } +void mp_delete_subscr(mp_obj_t base, mp_obj_t index) { + DEBUG_OP_printf("delete subscr %p[%p]\n", base, index); + /* list delete not implemented + if (MP_OBJ_IS_TYPE(base, &mp_type_list)) { + // list delete + mp_obj_list_delete(base, index); + } else */ + if (MP_OBJ_IS_TYPE(base, &mp_type_dict)) { + // dict delete + mp_obj_dict_delete(base, index); + } else { + nlr_jump(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object does not support item deletion", mp_obj_get_type_str(base))); + } +} + mp_obj_t mp_getiter(mp_obj_t o_in) { mp_obj_type_t *type = mp_obj_get_type(o_in); if (type->getiter != NULL) { diff --git a/py/runtime.h b/py/runtime.h index b233d23b4a..d8c43b6982 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -49,6 +49,7 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest); void mp_load_method_maybe(mp_obj_t base, qstr attr, mp_obj_t *dest); void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t val); void mp_store_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t val); +void mp_delete_subscr(mp_obj_t base, mp_obj_t index); mp_obj_t mp_getiter(mp_obj_t o); mp_obj_t mp_iternext_allow_raise(mp_obj_t o); // may return MP_OBJ_NULL instead of raising StopIteration() diff --git a/py/vm.c b/py/vm.c index 6186bbcefb..167de1d0f0 100644 --- a/py/vm.c +++ b/py/vm.c @@ -324,6 +324,11 @@ dispatch_loop: mp_delete_name(qst); break; + case MP_BC_DELETE_SUBSCR: + mp_delete_subscr(sp[-1], sp[0]); + sp -= 3; + break; + case MP_BC_DUP_TOP: obj1 = TOP(); PUSH(obj1);