summaryrefslogtreecommitdiffstatshomepage
path: root/py/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/compile.c')
-rw-r--r--py/compile.c83
1 files changed, 36 insertions, 47 deletions
diff --git a/py/compile.c b/py/compile.c
index c8b4e5470d..f84d5e2145 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -499,8 +499,7 @@ STATIC void c_assign(compiler_t *comp, mp_parse_node_t pn, assign_kind_t assign_
// sequence of many items
uint n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns2);
c_assign_tuple(comp, pns->nodes[0], n, pns2->nodes);
- } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
- // TODO can we ever get here? can it be compiled?
+ } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_comp_for) {
goto cannot_assign;
} else {
// sequence with 2 items
@@ -900,8 +899,7 @@ STATIC void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) {
for (int i = 0; i < n; i++) {
c_del_stmt(comp, pns1->nodes[i]);
}
- } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_comp_for) {
- // TODO not implemented; can't del comprehension? can we get here?
+ } else if (MP_PARSE_NODE_STRUCT_KIND(pns1) == PN_comp_for) {
goto cannot_delete;
} else {
// sequence with 2 items
@@ -1172,17 +1170,14 @@ STATIC void compile_global_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
STATIC void compile_declare_nonlocal(compiler_t *comp, mp_parse_node_t pn, qstr qst) {
bool added;
id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qst, &added);
- if (!added && id_info->kind != ID_INFO_KIND_FREE) {
+ if (added) {
+ scope_find_local_and_close_over(comp->scope_cur, id_info, qst);
+ if (id_info->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
+ compile_syntax_error(comp, pn, "no binding for nonlocal found");
+ }
+ } else if (id_info->kind != ID_INFO_KIND_FREE) {
compile_syntax_error(comp, pn, "identifier redefined as nonlocal");
- return;
- }
- id_info_t *id_info2 = scope_find_local_in_parent(comp->scope_cur, qst);
- if (id_info2 == NULL || !(id_info2->kind == ID_INFO_KIND_LOCAL || id_info2->kind == ID_INFO_KIND_CELL || id_info2->kind == ID_INFO_KIND_FREE)) {
- compile_syntax_error(comp, pn, "no binding for nonlocal found");
- return;
}
- id_info->kind = ID_INFO_KIND_FREE;
- scope_close_over_in_parents(comp->scope_cur, qst);
}
STATIC void compile_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
@@ -1495,6 +1490,8 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_
EMIT_ARG(label_assign, l1); // start of exception handler
EMIT(start_except_handler);
+ // at this point the top of the stack contains the exception instance that was raised
+
uint l2 = comp_next_label(comp);
for (int i = 0; i < n_except; i++) {
@@ -1528,16 +1525,13 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_
EMIT_ARG(pop_jump_if, false, end_finally_label);
}
- EMIT(pop_top);
-
+ // either discard or store the exception instance
if (qstr_exception_local == 0) {
EMIT(pop_top);
} else {
compile_store_id(comp, qstr_exception_local);
}
- EMIT(pop_top);
-
uint l3 = 0;
if (qstr_exception_local != 0) {
l3 = comp_next_label(comp);
@@ -1561,7 +1555,7 @@ STATIC void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_
}
EMIT_ARG(jump, l2);
EMIT_ARG(label_assign, end_finally_label);
- EMIT_ARG(adjust_stack_size, 3); // stack adjust for the 3 exception items
+ EMIT_ARG(adjust_stack_size, 1); // stack adjust for the exception instance
}
compile_decrease_except_level(comp);
@@ -1711,14 +1705,12 @@ STATIC void compile_async_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns
EMIT_LOAD_GLOBAL(MP_QSTR_StopAsyncIteration);
EMIT_ARG(binary_op, MP_BINARY_OP_EXCEPTION_MATCH);
EMIT_ARG(pop_jump_if, false, try_finally_label);
- EMIT(pop_top);
- EMIT(pop_top);
- EMIT(pop_top);
+ EMIT(pop_top); // pop exception instance
EMIT(pop_except);
EMIT_ARG(jump, while_else_label);
EMIT_ARG(label_assign, try_finally_label);
- EMIT_ARG(adjust_stack_size, 3);
+ EMIT_ARG(adjust_stack_size, 1); // if we jump here, the exc is on the stack
compile_decrease_except_level(comp);
EMIT(end_finally);
EMIT(end_except_handler);
@@ -1779,9 +1771,21 @@ STATIC void compile_async_with_stmt_helper(compiler_t *comp, int n, mp_parse_nod
EMIT_ARG(label_assign, try_exception_label); // start of exception handler
EMIT(start_except_handler);
- EMIT(rot_three);
+
+ // at this point the stack contains: ..., __aexit__, self, exc
+ EMIT(dup_top);
+ #if MICROPY_CPYTHON_COMPAT
+ EMIT_ARG(load_attr, MP_QSTR___class__); // get type(exc)
+ #else
+ compile_load_id(comp, MP_QSTR_type);
+ EMIT(rot_two);
+ EMIT_ARG(call_function, 1, 0, 0); // get type(exc)
+ #endif
EMIT(rot_two);
+ EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); // dummy traceback value
+ // at this point the stack contains: ..., __aexit__, self, type(exc), exc, None
EMIT_ARG(call_method, 3, 0, 0);
+
compile_yield_from(comp);
EMIT_ARG(pop_jump_if, true, no_reraise_label);
EMIT_ARG(raise_varargs, 0);
@@ -1790,7 +1794,7 @@ STATIC void compile_async_with_stmt_helper(compiler_t *comp, int n, mp_parse_nod
EMIT(pop_except);
EMIT_ARG(jump, end_label);
- EMIT_ARG(adjust_stack_size, 5);
+ EMIT_ARG(adjust_stack_size, 3); // adjust for __aexit__, self, exc
compile_decrease_except_level(comp);
EMIT(end_finally);
EMIT(end_except_handler);
@@ -2719,15 +2723,8 @@ STATIC void compile_node(compiler_t *comp, mp_parse_node_t pn) {
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
EMIT_ARG(set_source_line, pns->source_line);
compile_function_t f = compile_function[MP_PARSE_NODE_STRUCT_KIND(pns)];
- if (f == NULL) {
-#if MICROPY_DEBUG_PRINTERS
- printf("node %u cannot be compiled\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns));
- mp_parse_node_print(pn, 0);
-#endif
- compile_syntax_error(comp, pn, "internal compiler error");
- } else {
- f(comp, pns);
- }
+ assert(f != NULL);
+ f(comp, pns);
}
}
@@ -2832,12 +2829,10 @@ STATIC void compile_scope_func_annotations(compiler_t *comp, mp_parse_node_t pn)
// no annotation
return;
}
- } else if (MP_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_dbl_star) {
+ } else {
+ assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_typedargslist_dbl_star);
// double star with possible annotation
// fallthrough
- } else {
- // no annotation
- return;
}
mp_parse_node_t pn_annotation = pns->nodes[1];
@@ -2869,17 +2864,11 @@ STATIC void compile_scope_comp_iter(compiler_t *comp, mp_parse_node_struct_t *pn
if (MP_PARSE_NODE_IS_NULL(pn_iter)) {
// no more nested if/for; compile inner expression
compile_node(comp, pn_inner_expr);
- if (comp->scope_cur->kind == SCOPE_LIST_COMP) {
- EMIT_ARG(list_append, for_depth + 2);
- } else if (comp->scope_cur->kind == SCOPE_DICT_COMP) {
- EMIT_ARG(map_add, for_depth + 2);
- #if MICROPY_PY_BUILTINS_SET
- } else if (comp->scope_cur->kind == SCOPE_SET_COMP) {
- EMIT_ARG(set_add, for_depth + 2);
- #endif
- } else {
+ if (comp->scope_cur->kind == SCOPE_GEN_EXPR) {
EMIT(yield_value);
EMIT(pop_top);
+ } else {
+ EMIT_ARG(store_comp, comp->scope_cur->kind, for_depth + 2);
}
} else if (MP_PARSE_NODE_IS_STRUCT_KIND(pn_iter, PN_comp_if)) {
// if condition
@@ -3285,7 +3274,7 @@ STATIC void scope_compute_things(scope_t *scope) {
// __class__ is not counted as a local; if it's used then it becomes a ID_INFO_KIND_CELL
continue;
}
- if (scope->kind >= SCOPE_FUNCTION && scope->kind <= SCOPE_GEN_EXPR && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
+ if (SCOPE_IS_FUNC_LIKE(scope->kind) && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
id->kind = ID_INFO_KIND_GLOBAL_EXPLICIT;
}
// params always count for 1 local, even if they are a cell