Browse Source

py: Implement support for "except Exception as var" clause.

For this, needed to implement DELETE_NAME bytecode (because var bound
in except clause is automatically deleted at its end).
http://docs.python.org/3/reference/compound_stmts.html#except :
"When an exception has been assigned using as target, it is cleared at
the end of the except clause."
pull/367/head
Paul Sokolovsky 11 years ago
parent
commit
f909034400
  1. 5
      py/runtime.c
  2. 1
      py/runtime.h
  3. 5
      py/vm.c
  4. 10
      tests/basics/try-as-var.py

5
py/runtime.c

@ -462,6 +462,11 @@ void rt_store_name(qstr qstr, mp_obj_t obj) {
mp_map_lookup(map_locals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = obj; mp_map_lookup(map_locals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = obj;
} }
void rt_delete_name(qstr qstr) {
DEBUG_OP_printf("delete name %s\n", qstr_str(qstr));
mp_map_lookup(map_locals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_REMOVE_IF_FOUND);
}
void rt_store_global(qstr qstr, mp_obj_t obj) { void rt_store_global(qstr qstr, mp_obj_t obj) {
DEBUG_OP_printf("store global %s <- %p\n", qstr_str(qstr), obj); DEBUG_OP_printf("store global %s <- %p\n", qstr_str(qstr), obj);
mp_map_lookup(map_globals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = obj; mp_map_lookup(map_globals, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND)->value = obj;

1
py/runtime.h

@ -12,6 +12,7 @@ mp_obj_t rt_get_cell(mp_obj_t cell);
void rt_set_cell(mp_obj_t cell, mp_obj_t val); void rt_set_cell(mp_obj_t cell, mp_obj_t val);
void rt_store_name(qstr qstr, mp_obj_t obj); void rt_store_name(qstr qstr, mp_obj_t obj);
void rt_store_global(qstr qstr, mp_obj_t obj); void rt_store_global(qstr qstr, mp_obj_t obj);
void rt_delete_name(qstr qstr);
mp_obj_t rt_unary_op(int op, mp_obj_t arg); mp_obj_t rt_unary_op(int op, mp_obj_t arg);
mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs); mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs);
mp_obj_t rt_make_function_from_id(int unique_code_id, mp_obj_t def_args); mp_obj_t rt_make_function_from_id(int unique_code_id, mp_obj_t def_args);

5
py/vm.c

@ -283,6 +283,11 @@ dispatch_loop:
sp -= 3; sp -= 3;
break; break;
case MP_BC_DELETE_NAME:
DECODE_QSTR;
rt_delete_name(qst);
break;
case MP_BC_DUP_TOP: case MP_BC_DUP_TOP:
obj1 = TOP(); obj1 = TOP();
PUSH(obj1); PUSH(obj1);

10
tests/basics/try-as-var.py

@ -0,0 +1,10 @@
try:
raise ValueError(534)
except ValueError as e:
print(repr(e))
# Var bound in except block is automatically deleted
try:
e
except NameError:
print("NameError")
Loading…
Cancel
Save