diff options
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 202 |
1 files changed, 45 insertions, 157 deletions
diff --git a/Python/compile.c b/Python/compile.c index f228e16..55333b3 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -193,8 +193,8 @@ static int compiler_visit_keyword(struct compiler *, keyword_ty); static int compiler_visit_expr(struct compiler *, expr_ty); static int compiler_augassign(struct compiler *, stmt_ty); static int compiler_annassign(struct compiler *, stmt_ty); -static int compiler_visit_slice(struct compiler *, slice_ty, - expr_context_ty); +static int compiler_subscript(struct compiler *, expr_ty); +static int compiler_slice(struct compiler *, expr_ty); static int inplace_binop(struct compiler *, operator_ty); static int are_all_items_const(asdl_seq *, Py_ssize_t, Py_ssize_t); @@ -4045,14 +4045,11 @@ check_subscripter(struct compiler *c, expr_ty e) } static int -check_index(struct compiler *c, expr_ty e, slice_ty s) +check_index(struct compiler *c, expr_ty e, expr_ty s) { PyObject *v; - if (s->kind != Index_kind) { - return 1; - } - PyTypeObject *index_type = infer_type(s->v.Index.value); + PyTypeObject *index_type = infer_type(s); if (index_type == NULL || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS) || index_type == &PySlice_Type) { @@ -5065,39 +5062,7 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) } break; case Subscript_kind: - switch (e->v.Subscript.ctx) { - case AugLoad: - VISIT(c, expr, e->v.Subscript.value); - VISIT_SLICE(c, e->v.Subscript.slice, AugLoad); - break; - case Load: - if (!check_subscripter(c, e->v.Subscript.value)) { - return 0; - } - if (!check_index(c, e->v.Subscript.value, e->v.Subscript.slice)) { - return 0; - } - VISIT(c, expr, e->v.Subscript.value); - VISIT_SLICE(c, e->v.Subscript.slice, Load); - break; - case AugStore: - VISIT_SLICE(c, e->v.Subscript.slice, AugStore); - break; - case Store: - VISIT(c, expr, e->v.Subscript.value); - VISIT_SLICE(c, e->v.Subscript.slice, Store); - break; - case Del: - VISIT(c, expr, e->v.Subscript.value); - VISIT_SLICE(c, e->v.Subscript.slice, Del); - break; - case Param: - default: - PyErr_SetString(PyExc_SystemError, - "param invalid in subscript expression"); - return 0; - } - break; + return compiler_subscript(c, e); case Starred_kind: switch (e->v.Starred.ctx) { case Store: @@ -5109,6 +5074,9 @@ compiler_visit_expr1(struct compiler *c, expr_ty e) return compiler_error(c, "can't use starred expression here"); } + break; + case Slice_kind: + return compiler_slice(c, e); case Name_kind: return compiler_nameop(c, e->v.Name.id, e->v.Name.ctx); /* child nodes of List and Tuple will have expr_context set */ @@ -5213,68 +5181,35 @@ check_annotation(struct compiler *c, stmt_ty s) } static int -check_ann_slice(struct compiler *c, slice_ty sl) +check_ann_subscr(struct compiler *c, expr_ty e) { - switch(sl->kind) { - case Index_kind: - return check_ann_expr(c, sl->v.Index.value); + /* We check that everything in a subscript is defined at runtime. */ + switch (e->kind) { case Slice_kind: - if (sl->v.Slice.lower && !check_ann_expr(c, sl->v.Slice.lower)) { - return 0; - } - if (sl->v.Slice.upper && !check_ann_expr(c, sl->v.Slice.upper)) { + if (e->v.Slice.lower && !check_ann_expr(c, e->v.Slice.lower)) { return 0; } - if (sl->v.Slice.step && !check_ann_expr(c, sl->v.Slice.step)) { + if (e->v.Slice.upper && !check_ann_expr(c, e->v.Slice.upper)) { return 0; } - break; - default: - PyErr_SetString(PyExc_SystemError, - "unexpected slice kind"); - return 0; - } - return 1; -} - -static int -check_ann_subscr(struct compiler *c, slice_ty sl) -{ - /* We check that everything in a subscript is defined at runtime. */ - Py_ssize_t i, n; - - switch (sl->kind) { - case Index_kind: - case Slice_kind: - if (!check_ann_slice(c, sl)) { + if (e->v.Slice.step && !check_ann_expr(c, e->v.Slice.step)) { return 0; } - break; - case ExtSlice_kind: - n = asdl_seq_LEN(sl->v.ExtSlice.dims); + return 1; + case Tuple_kind: { + /* extended slice */ + asdl_seq *elts = e->v.Tuple.elts; + Py_ssize_t i, n = asdl_seq_LEN(elts); for (i = 0; i < n; i++) { - slice_ty subsl = (slice_ty)asdl_seq_GET(sl->v.ExtSlice.dims, i); - switch (subsl->kind) { - case Index_kind: - case Slice_kind: - if (!check_ann_slice(c, subsl)) { - return 0; - } - break; - case ExtSlice_kind: - default: - PyErr_SetString(PyExc_SystemError, - "extended slice invalid in nested slice"); + if (!check_ann_subscr(c, asdl_seq_GET(elts, i))) { return 0; } } - break; + return 1; + } default: - PyErr_Format(PyExc_SystemError, - "invalid subscript kind %d", sl->kind); - return 0; + return check_ann_expr(c, e); } - return 1; } static int @@ -5400,12 +5335,20 @@ compiler_warn(struct compiler *c, const char *format, ...) } static int -compiler_handle_subscr(struct compiler *c, const char *kind, - expr_context_ty ctx) +compiler_subscript(struct compiler *c, expr_ty e) { + expr_context_ty ctx = e->v.Subscript.ctx; int op = 0; - /* XXX this code is duplicated */ + if (ctx == Load) { + if (!check_subscripter(c, e->v.Subscript.value)) { + return 0; + } + if (!check_index(c, e->v.Subscript.value, e->v.Subscript.slice)) { + return 0; + } + } + switch (ctx) { case AugLoad: /* fall through to Load */ case Load: op = BINARY_SUBSCR; break; @@ -5413,23 +5356,26 @@ compiler_handle_subscr(struct compiler *c, const char *kind, case Store: op = STORE_SUBSCR; break; case Del: op = DELETE_SUBSCR; break; case Param: - PyErr_Format(PyExc_SystemError, - "invalid %s kind %d in subscript\n", - kind, ctx); + PyErr_SetString(PyExc_SystemError, + "param invalid in subscript expression"); return 0; } - if (ctx == AugLoad) { - ADDOP(c, DUP_TOP_TWO); - } - else if (ctx == AugStore) { + if (ctx == AugStore) { ADDOP(c, ROT_THREE); } + else { + VISIT(c, expr, e->v.Subscript.value); + VISIT(c, expr, e->v.Subscript.slice); + if (ctx == AugLoad) { + ADDOP(c, DUP_TOP_TWO); + } + } ADDOP(c, op); return 1; } static int -compiler_slice(struct compiler *c, slice_ty s, expr_context_ty ctx) +compiler_slice(struct compiler *c, expr_ty s) { int n = 2; assert(s->kind == Slice_kind); @@ -5457,64 +5403,6 @@ compiler_slice(struct compiler *c, slice_ty s, expr_context_ty ctx) return 1; } -static int -compiler_visit_nested_slice(struct compiler *c, slice_ty s, - expr_context_ty ctx) -{ - switch (s->kind) { - case Slice_kind: - return compiler_slice(c, s, ctx); - case Index_kind: - VISIT(c, expr, s->v.Index.value); - break; - case ExtSlice_kind: - default: - PyErr_SetString(PyExc_SystemError, - "extended slice invalid in nested slice"); - return 0; - } - return 1; -} - -static int -compiler_visit_slice(struct compiler *c, slice_ty s, expr_context_ty ctx) -{ - const char * kindname = NULL; - switch (s->kind) { - case Index_kind: - kindname = "index"; - if (ctx != AugStore) { - VISIT(c, expr, s->v.Index.value); - } - break; - case Slice_kind: - kindname = "slice"; - if (ctx != AugStore) { - if (!compiler_slice(c, s, ctx)) - return 0; - } - break; - case ExtSlice_kind: - kindname = "extended slice"; - if (ctx != AugStore) { - Py_ssize_t i, n = asdl_seq_LEN(s->v.ExtSlice.dims); - for (i = 0; i < n; i++) { - slice_ty sub = (slice_ty)asdl_seq_GET( - s->v.ExtSlice.dims, i); - if (!compiler_visit_nested_slice(c, sub, ctx)) - return 0; - } - ADDOP_I(c, BUILD_TUPLE, n); - } - break; - default: - PyErr_Format(PyExc_SystemError, - "invalid subscript kind %d", s->kind); - return 0; - } - return compiler_handle_subscr(c, kindname, ctx); -} - /* End of the compiler section, beginning of the assembler section */ /* do depth-first search of basic block graph, starting with block. |