[Python-checkins] python/dist/src/Python Python-ast.c, 1.1.2.10,
1.1.2.11 ast.c, 1.1.2.56, 1.1.2.57 newcompile.c, 1.1.2.104,
1.1.2.105 symtable.c, 2.10.8.30, 2.10.8.31
nascheme at users.sourceforge.net
nascheme at users.sourceforge.net
Sat Apr 2 20:50:16 CEST 2005
Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1290/Python
Modified Files:
Tag: ast-branch
Python-ast.c ast.c newcompile.c symtable.c
Log Message:
Add support to the AST compiler for decorators (SF patch #1167709).
Index: Python-ast.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/Python-ast.c,v
retrieving revision 1.1.2.10
retrieving revision 1.1.2.11
diff -u -d -r1.1.2.10 -r1.1.2.11
--- Python-ast.c 20 Mar 2005 23:40:59 -0000 1.1.2.10
+++ Python-ast.c 2 Apr 2005 18:50:06 -0000 1.1.2.11
@@ -1,4 +1,4 @@
-/* File automatically generated by ./Parser/asdl_c.py */
+/* File automatically generated by ../Parser/asdl_c.py */
#include "Python.h"
#include "Python-ast.h"
@@ -65,7 +65,8 @@
}
stmt_ty
-FunctionDef(identifier name, arguments_ty args, asdl_seq * body, int lineno)
+FunctionDef(identifier name, arguments_ty args, asdl_seq * body, asdl_seq *
+ decorators, int lineno)
{
stmt_ty p;
if (!name) {
@@ -87,6 +88,7 @@
p->v.FunctionDef.name = name;
p->v.FunctionDef.args = args;
p->v.FunctionDef.body = body;
+ p->v.FunctionDef.decorators = decorators;
p->lineno = lineno;
return p;
}
@@ -1064,6 +1066,10 @@
{
int i, n;
asdl_seq *seq;
+
+ if (!o)
+ return;
+
switch (o->kind) {
case Module_kind:
seq = o->v.Module.body;
@@ -1094,6 +1100,10 @@
{
int i, n;
asdl_seq *seq;
+
+ if (!o)
+ return;
+
switch (o->kind) {
case FunctionDef_kind:
Py_DECREF((identifier)o->v.FunctionDef.name);
@@ -1102,6 +1112,10 @@
n = asdl_seq_LEN(seq);
for (i = 0; i < n; i++)
free_stmt((stmt_ty)asdl_seq_GET(seq, i));
+ seq = o->v.FunctionDef.decorators;
+ n = asdl_seq_LEN(seq);
+ for (i = 0; i < n; i++)
+ free_expr((expr_ty)asdl_seq_GET(seq, i));
break;
case ClassDef_kind:
Py_DECREF((identifier)o->v.ClassDef.name);
@@ -1270,6 +1284,10 @@
{
int i, n;
asdl_seq *seq;
+
+ if (!o)
+ return;
+
switch (o->kind) {
case BoolOp_kind:
free_boolop((boolop_ty)o->v.BoolOp.op);
@@ -1388,6 +1406,10 @@
void
free_expr_context(expr_context_ty o)
{
+
+ if (!o)
+ return;
+
}
void
@@ -1395,6 +1417,10 @@
{
int i, n;
asdl_seq *seq;
+
+ if (!o)
+ return;
+
switch (o->kind) {
case Ellipsis_kind:
break;
@@ -1424,21 +1450,37 @@
void
free_boolop(boolop_ty o)
{
+
+ if (!o)
+ return;
+
}
void
free_operator(operator_ty o)
{
+
+ if (!o)
+ return;
+
}
void
free_unaryop(unaryop_ty o)
{
+
+ if (!o)
+ return;
+
}
void
free_cmpop(cmpop_ty o)
{
+
+ if (!o)
+ return;
+
}
void
@@ -1446,6 +1488,10 @@
{
int i, n;
asdl_seq *seq;
+
+ if (!o)
+ return;
+
free_expr((expr_ty)o->target);
free_expr((expr_ty)o->iter);
seq = o->ifs;
@@ -1459,6 +1505,10 @@
{
int i, n;
asdl_seq *seq;
+
+ if (!o)
+ return;
+
if (o->type) {
free_expr((expr_ty)o->type);
}
@@ -1476,6 +1526,10 @@
{
int i, n;
asdl_seq *seq;
+
+ if (!o)
+ return;
+
seq = o->args;
n = asdl_seq_LEN(seq);
for (i = 0; i < n; i++)
@@ -1495,6 +1549,10 @@
void
free_keyword(keyword_ty o)
{
+
+ if (!o)
+ return;
+
Py_DECREF((identifier)o->arg);
free_expr((expr_ty)o->value);
}
@@ -1502,6 +1560,10 @@
void
free_alias(alias_ty o)
{
+
+ if (!o)
+ return;
+
Py_DECREF((identifier)o->name);
if (o->asname) {
Py_DECREF((identifier)o->asname);
@@ -1561,6 +1623,14 @@
void *elt = asdl_seq_GET(o->v.FunctionDef.body, i);
marshal_write_stmt(buf, off, (stmt_ty)elt);
}
+ marshal_write_int(buf, off,
+ asdl_seq_LEN(o->v.FunctionDef.decorators));
+ for (i = 0; i < asdl_seq_LEN(o->v.FunctionDef.decorators); i++)
+ {
+ void *elt = asdl_seq_GET(o->v.FunctionDef.decorators,
+ i);
+ marshal_write_expr(buf, off, (expr_ty)elt);
+ }
break;
case ClassDef_kind:
marshal_write_int(buf, off, 2);
Index: ast.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/ast.c,v
retrieving revision 1.1.2.56
retrieving revision 1.1.2.57
diff -u -d -r1.1.2.56 -r1.1.2.57
--- ast.c 21 Mar 2005 00:00:54 -0000 1.1.2.56
+++ ast.c 2 Apr 2005 18:50:06 -0000 1.1.2.57
@@ -47,6 +47,34 @@
#define NEW_IDENTIFIER(n) PyString_InternFromString(STR(n))
+static void
+asdl_stmt_seq_free(asdl_seq* seq)
+{
+ int n, i;
+
+ if (!seq)
+ return;
+
+ n = asdl_seq_LEN(seq);
+ for (i = 0; i < n; i++)
+ free_stmt(asdl_seq_GET(seq, i));
+ asdl_seq_free(seq);
+}
+
+static void
+asdl_expr_seq_free(asdl_seq* seq)
+{
+ int n, i;
+
+ if (!seq)
+ return;
+
+ n = asdl_seq_LEN(seq);
+ for (i = 0; i < n; i++)
+ free_expr(asdl_seq_GET(seq, i));
+ asdl_seq_free(seq);
+}
+
/* This routine provides an invalid object for the syntax error.
The outermost routine must unpack this error and create the
proper object. We do this so that we don't have to pass
@@ -260,7 +288,7 @@
}
error:
if (stmts)
- asdl_seq_free(stmts);
+ asdl_stmt_seq_free(stmts);
ast_error_finish(filename);
return NULL;
}
@@ -615,23 +643,154 @@
return NULL;
}
+static expr_ty
+ast_for_dotted_name(struct compiling *c, const node *n)
+{
+ expr_ty e = NULL;
+ expr_ty attrib = NULL;
+ identifier id = NULL;
+ int i;
+
+ REQ(n, dotted_name);
+
+ id = NEW_IDENTIFIER(CHILD(n, 0));
+ if (!id)
+ goto error;
+ e = Name(id, Load);
+ if (!e)
+ goto error;
+ id = NULL;
+
+ for (i = 2; i < NCH(n); i+=2) {
+ id = NEW_IDENTIFIER(CHILD(n, i));
+ if (!id)
+ goto error;
+ attrib = Attribute(e, id, Load);
+ if (!attrib)
+ goto error;
+ e = attrib;
+ attrib = NULL;
+ }
+
+ return e;
+
+ error:
+ Py_XDECREF(id);
+ free_expr(e);
+ return NULL;
+}
+
+static expr_ty
+ast_for_decorator(struct compiling *c, const node *n)
+{
+ /* decorator: '@' dotted_name [ '(' [arglist] ')' ] NEWLINE */
+ expr_ty d = NULL;
+ expr_ty name_expr = NULL;
+
+ REQ(n, decorator);
+
+ if ((NCH(n) < 3 && NCH(n) != 5 && NCH(n) != 6)
+ || TYPE(CHILD(n, 0)) != AT || TYPE(RCHILD(n, -1)) != NEWLINE) {
+ ast_error(n, "Invalid decorator node");
+ goto error;
+ }
+
+ name_expr = ast_for_dotted_name(c, CHILD(n, 1));
+ if (!name_expr)
+ goto error;
+
+ if (NCH(n) == 3) { /* No arguments */
+ d = name_expr;
+ name_expr = NULL;
+ }
+ else if (NCH(n) == 5) { /* Call with no arguments */
+ d = Call(name_expr, NULL, NULL, NULL, NULL);
+ if (!d)
+ goto error;
+ name_expr = NULL;
+ }
+ else {
+ d = ast_for_call(c, CHILD(n, 3), name_expr);
+ if (!d)
+ goto error;
+ name_expr = NULL;
+ }
+
+ return d;
+
+ error:
+ free_expr(name_expr);
+ free_expr(d);
+ return NULL;
+}
+
+static asdl_seq*
+ast_for_decorators(struct compiling *c, const node *n)
+{
+ asdl_seq* decorator_seq = NULL;
+ expr_ty d = NULL;
+ int i;
+
+ REQ(n, decorators);
+
+ decorator_seq = asdl_seq_new(NCH(n));
+ if (!decorator_seq)
+ return NULL;
+
+ for (i = 0; i < NCH(n); i++) {
+ d = ast_for_decorator(c, CHILD(n, i));
+ if (!d)
+ goto error;
+ asdl_seq_APPEND(decorator_seq, d);
+ d = NULL;
+ }
+ return decorator_seq;
+ error:
+ asdl_expr_seq_free(decorator_seq);
+ free_expr(d);
+ return NULL;
+}
+
static stmt_ty
ast_for_funcdef(struct compiling *c, const node *n)
{
- /* funcdef: 'def' NAME parameters ':' suite */
- identifier name = NEW_IDENTIFIER(CHILD(n, 1));
- arguments_ty args;
- asdl_seq *body;
-
+ /* funcdef: 'def' [decorators] NAME parameters ':' suite */
+ identifier name = NULL;
+ arguments_ty args = NULL;
+ asdl_seq *body = NULL;
+ asdl_seq *decorator_seq = NULL;
+ int name_i;
+
REQ(n, funcdef);
- args = ast_for_arguments(c, CHILD(n, 2));
+
+ if (NCH(n) == 6) { /* decorators are present */
+ decorator_seq = ast_for_decorators(c, CHILD(n, 0));
+ if (!decorator_seq)
+ goto error;
+ name_i = 2;
+ }
+ else {
+ name_i = 1;
+ }
+
+ name = NEW_IDENTIFIER(CHILD(n, name_i));
+ if (!name)
+ goto error;
+ args = ast_for_arguments(c, CHILD(n, name_i + 1));
if (!args)
- return NULL;
- body = ast_for_suite(c, CHILD(n, 4));
+ goto error;
+ body = ast_for_suite(c, CHILD(n, name_i + 3));
if (!body)
- return NULL;
+ goto error;
- return FunctionDef(name, args, body, LINENO(n));
+ return FunctionDef(name, args, body, decorator_seq, LINENO(n));
+
+error:
+ asdl_stmt_seq_free(body);
+ asdl_expr_seq_free(decorator_seq);
+ free_arguments(args);
+ Py_XDECREF(name);
+ return NULL;
}
static expr_ty
Index: newcompile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/Attic/newcompile.c,v
retrieving revision 1.1.2.104
retrieving revision 1.1.2.105
diff -u -d -r1.1.2.104 -r1.1.2.105
--- newcompile.c 21 Mar 2005 19:27:42 -0000 1.1.2.104
+++ newcompile.c 2 Apr 2005 18:50:06 -0000 1.1.2.105
@@ -1366,15 +1366,32 @@
}
static int
+compiler_decorators(struct compiler *c, asdl_seq* decos)
+{
+ int i;
+
+ if (!decos)
+ return 1;
+
+ for (i = 0; i < asdl_seq_LEN(decos); i++) {
+ VISIT(c, expr, asdl_seq_GET(decos, i));
+ }
+ return 1;
+}
+
+static int
compiler_function(struct compiler *c, stmt_ty s)
{
PyCodeObject *co;
PyObject *first_const = Py_None;
arguments_ty args = s->v.FunctionDef.args;
+ asdl_seq* decos = s->v.FunctionDef.decorators;
stmt_ty st;
int i, n, docstring;
assert(s->kind == FunctionDef_kind);
+ if (!compiler_decorators(c, decos))
+ return 0;
if (args->defaults)
VISIT_SEQ(c, expr, args->defaults);
if (!compiler_enter_scope(c, s->v.FunctionDef.name, (void *)s,
@@ -1421,6 +1438,11 @@
compiler_exit_scope(c);
compiler_make_closure(c, co, asdl_seq_LEN(args->defaults));
+
+ for (i = 0; i < asdl_seq_LEN(decos); i++) {
+ ADDOP_I(c, CALL_FUNCTION, 1);
+ }
+
return compiler_nameop(c, s->v.FunctionDef.name, Store);
}
Index: symtable.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/symtable.c,v
retrieving revision 2.10.8.30
retrieving revision 2.10.8.31
diff -u -d -r2.10.8.30 -r2.10.8.31
--- symtable.c 16 Jan 2005 17:09:12 -0000 2.10.8.30
+++ symtable.c 2 Apr 2005 18:50:13 -0000 2.10.8.31
@@ -756,6 +756,8 @@
return 0;
if (s->v.FunctionDef.args->defaults)
VISIT_SEQ(st, expr, s->v.FunctionDef.args->defaults);
+ if (s->v.FunctionDef.decorators)
+ VISIT_SEQ(st, expr, s->v.FunctionDef.decorators);
if (!symtable_enter_block(st, s->v.FunctionDef.name,
FunctionBlock, (void *)s, s->lineno))
return 0;
More information about the Python-checkins
mailing list