summaryrefslogtreecommitdiff
path: root/Python/ast.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2006-02-27 22:32:47 +0000
committerGuido van Rossum <guido@python.org>2006-02-27 22:32:47 +0000
commitc2e20744b2b7811632030470971c31630f0975e2 (patch)
treee97b1c1471fd00e4e5648ed317274c1d9005d2ca /Python/ast.c
parent5fec904f84a40005f824abe295525a1710056be0 (diff)
downloadcpython-git-c2e20744b2b7811632030470971c31630f0975e2.tar.gz
PEP 343 -- the with-statement.
This was started by Mike Bland and completed by Guido (with help from Neal). This still needs a __future__ statement added; Thomas is working on Michael's patch for that aspect. There's a small amount of code cleanup and refactoring in ast.c, compile.c and ceval.c (I fixed the lltrace behavior when EXT_POP is used -- however I had to make lltrace a static global).
Diffstat (limited to 'Python/ast.c')
-rw-r--r--Python/ast.c46
1 files changed, 44 insertions, 2 deletions
diff --git a/Python/ast.c b/Python/ast.c
index 94998d3682..dbfec20b38 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -314,7 +314,7 @@ get_operator(const node *n)
}
}
-/* Set the context ctx for expr_ty e returning 0 on success, -1 on error.
+/* Set the context ctx for expr_ty e returning 1 on success, 0 on error.
Only sets context for expr kinds that "can appear in assignment context"
(according to ../Parser/Python.asdl). For other expr kinds, it sets
@@ -339,7 +339,7 @@ set_context(expr_ty e, expr_context_ty ctx, const node *n)
a little more complex than necessary as a result. It also means
that expressions in an augmented assignment have no context.
Consider restructuring so that augmented assignment uses
- set_context(), too
+ set_context(), too.
*/
assert(ctx != AugStore && ctx != AugLoad);
@@ -2713,6 +2713,46 @@ ast_for_try_stmt(struct compiling *c, const node *n)
return TryFinally(body, finally, LINENO(n), c->c_arena);
}
+static expr_ty
+ast_for_with_var(struct compiling *c, const node *n)
+{
+ REQ(n, with_var);
+ if (strcmp(STR(CHILD(n, 0)), "as") != 0) {
+ ast_error(n, "expected \"with [expr] as [var]\"");
+ return NULL;
+ }
+ return ast_for_expr(c, CHILD(n, 1));
+}
+
+/* with_stmt: 'with' test [ with_var ] ':' suite */
+static stmt_ty
+ast_for_with_stmt(struct compiling *c, const node *n)
+{
+ expr_ty context_expr, optional_vars = NULL;
+ int suite_index = 3; /* skip 'with', test, and ':' */
+ asdl_seq *suite_seq;
+
+ assert(TYPE(n) == with_stmt);
+ context_expr = ast_for_expr(c, CHILD(n, 1));
+ if (TYPE(CHILD(n, 2)) == with_var) {
+ optional_vars = ast_for_with_var(c, CHILD(n, 2));
+
+ if (!optional_vars) {
+ return NULL;
+ }
+ if (!set_context(optional_vars, Store, n)) {
+ return NULL;
+ }
+ suite_index = 4;
+ }
+
+ suite_seq = ast_for_suite(c, CHILD(n, suite_index));
+ if (!suite_seq) {
+ return NULL;
+ }
+ return With(context_expr, optional_vars, suite_seq, LINENO(n), c->c_arena);
+}
+
static stmt_ty
ast_for_classdef(struct compiling *c, const node *n)
{
@@ -2813,6 +2853,8 @@ ast_for_stmt(struct compiling *c, const node *n)
return ast_for_for_stmt(c, ch);
case try_stmt:
return ast_for_try_stmt(c, ch);
+ case with_stmt:
+ return ast_for_with_stmt(c, ch);
case funcdef:
return ast_for_funcdef(c, ch);
case classdef: