[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