summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/compile.c')
-rw-r--r--Python/compile.c202
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.