Provisional implementation of PEP 3104.

Add nonlocal_stmt to Grammar and Nonlocal node to AST.  They both
parallel the definitions for globals.  The symbol table treats
variables declared as nonlocal just like variables that are free
implicitly.

This change is missing the language spec changes, but makes some
decisions about what the spec should say via the unittests.  The PEP
is silent on a number of decisions, so we should review those before
claiming that nonlocal is complete.

Thomas Wouters made the grammer and ast changes.  Jeremy Hylton added
the symbol table changes and the tests.  Pete Shinners and Neal
Norwitz helped review the code.
This commit is contained in:
Jeremy Hylton 2007-02-27 06:50:52 +00:00
parent 8b41c3dc28
commit 81e9502df6
12 changed files with 1188 additions and 922 deletions

View file

@ -2556,6 +2556,27 @@ ast_for_global_stmt(struct compiling *c, const node *n)
return Global(s, LINENO(n), n->n_col_offset, c->c_arena);
}
static stmt_ty
ast_for_nonlocal_stmt(struct compiling *c, const node *n)
{
/* nonlocal_stmt: 'nonlocal' NAME (',' NAME)* */
identifier name;
asdl_seq *s;
int i;
REQ(n, nonlocal_stmt);
s = asdl_seq_new(NCH(n) / 2, c->c_arena);
if (!s)
return NULL;
for (i = 1; i < NCH(n); i += 2) {
name = NEW_IDENTIFIER(CHILD(n, i));
if (!name)
return NULL;
asdl_seq_SET(s, i / 2, name);
}
return Nonlocal(s, LINENO(n), n->n_col_offset, c->c_arena);
}
static stmt_ty
ast_for_assert_stmt(struct compiling *c, const node *n)
{
@ -3063,8 +3084,8 @@ ast_for_stmt(struct compiling *c, const node *n)
if (TYPE(n) == small_stmt) {
REQ(n, small_stmt);
n = CHILD(n, 0);
/* small_stmt: expr_stmt | del_stmt | pass_stmt
| flow_stmt | import_stmt | global_stmt | assert_stmt
/* small_stmt: expr_stmt | del_stmt | pass_stmt | flow_stmt
| import_stmt | global_stmt | nonlocal_stmt | assert_stmt
*/
switch (TYPE(n)) {
case expr_stmt:
@ -3079,6 +3100,8 @@ ast_for_stmt(struct compiling *c, const node *n)
return ast_for_import_stmt(c, n);
case global_stmt:
return ast_for_global_stmt(c, n);
case nonlocal_stmt:
return ast_for_nonlocal_stmt(c, n);
case assert_stmt:
return ast_for_assert_stmt(c, n);
default: