[Python-checkins] python/dist/src/Python Python-ast.c, 1.1, 2.1 asdl.c, 1.1, 2.1 ast.c, 1.1, 2.1 bltinmodule.c, 2.327, 2.328 ceval.c, 2.427, 2.428 compile.c, 2.352, 2.353 future.c, 2.15, 2.16 import.c, 2.245, 2.246 marshal.c, 1.88, 1.89 pythonrun.c, 2.217, 2.218 symtable.c, 2.12, 2.13 sysmodule.c, 2.130, 2.131 traceback.c, 2.42, 2.43

jhylton@users.sourceforge.net jhylton at users.sourceforge.net
Thu Oct 20 21:59:29 CEST 2005


Update of /cvsroot/python/python/dist/src/Python
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2121/Python

Modified Files:
	bltinmodule.c ceval.c compile.c future.c import.c marshal.c 
	pythonrun.c symtable.c sysmodule.c traceback.c 
Added Files:
	Python-ast.c asdl.c ast.c 
Log Message:
Merge ast-branch to head

This change implements a new bytecode compiler, based on a
transformation of the parse tree to an abstract syntax defined in
Parser/Python.asdl.

The compiler implementation is not complete, but it is in stable
enough shape to run the entire test suite excepting two disabled
tests. 






Index: bltinmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v
retrieving revision 2.327
retrieving revision 2.328
diff -u -d -r2.327 -r2.328
--- bltinmodule.c	24 Sep 2005 21:23:05 -0000	2.327
+++ bltinmodule.c	20 Oct 2005 19:59:25 -0000	2.328
@@ -1,9 +1,9 @@
-
 /* Built-in functions */
 
 #include "Python.h"
 
 #include "node.h"
+#include "code.h"
 #include "compile.h"
 #include "eval.h"
 

Index: ceval.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v
retrieving revision 2.427
retrieving revision 2.428
diff -u -d -r2.427 -r2.428
--- ceval.c	20 Sep 2005 18:34:01 -0000	2.427
+++ ceval.c	20 Oct 2005 19:59:25 -0000	2.428
@@ -8,7 +8,7 @@
 
 #include "Python.h"
 
-#include "compile.h"
+#include "code.h"
 #include "frameobject.h"
 #include "eval.h"
 #include "opcode.h"
@@ -543,7 +543,7 @@
 #ifdef LLTRACE
 	int lltrace;
 #endif
-#if defined(Py_DEBUG) || defined(LLTRACE)
+#if defined(Py_DEBUG)
 	/* Make it easier to find out where we are with a debugger */
 	char *filename;
 #endif
@@ -743,9 +743,9 @@
 	f->f_stacktop = NULL;	/* remains NULL unless yield suspends frame */
 
 #ifdef LLTRACE
-	lltrace = PyDict_GetItemString(f->f_globals,"__lltrace__") != NULL;
+	lltrace = PyDict_GetItemString(f->f_globals, "__lltrace__") != NULL;
 #endif
-#if defined(Py_DEBUG) || defined(LLTRACE)
+#if defined(Py_DEBUG)
 	filename = PyString_AsString(co->co_filename);
 #endif
 
@@ -2257,23 +2257,11 @@
 
 		case MAKE_CLOSURE:
 		{
-			int nfree;
 			v = POP(); /* code object */
 			x = PyFunction_New(v, f->f_globals);
-			nfree = PyCode_GetNumFree((PyCodeObject *)v);
 			Py_DECREF(v);
-			/* XXX Maybe this should be a separate opcode? */
-			if (x != NULL && nfree > 0) {
-				v = PyTuple_New(nfree);
-				if (v == NULL) {
-					Py_DECREF(x);
-					x = NULL;
-					break;
-				}
-				while (--nfree >= 0) {
-					w = POP();
-					PyTuple_SET_ITEM(v, nfree, w);
-				}
+			if (x != NULL) {
+				v = POP();
 				err = PyFunction_SetClosure(x, v);
 				Py_DECREF(v);
 			}
@@ -2695,12 +2683,18 @@
 		if (co->co_flags & CO_VARKEYWORDS)
 			nargs++;
 
-		/* Check for cells that shadow args */
-		for (i = 0; i < f->f_ncells && j < nargs; ++i) {
+		/* Initialize each cell var, taking into account
+		   cell vars that are initialized from arguments.
+
+		   Should arrange for the compiler to put cellvars
+		   that are arguments at the beginning of the cellvars
+		   list so that we can march over it more efficiently?
+		*/
+		for (i = 0; i < f->f_ncells; ++i) {
 			cellname = PyString_AS_STRING(
 				PyTuple_GET_ITEM(co->co_cellvars, i));
 			found = 0;
-			while (j < nargs) {
+			for (j = 0; j < nargs; j++) {
 				argname = PyString_AS_STRING(
 					PyTuple_GET_ITEM(co->co_varnames, j));
 				if (strcmp(cellname, argname) == 0) {
@@ -2711,7 +2705,6 @@
 					found = 1;
 					break;
 				}
-				j++;
 			}
 			if (found == 0) {
 				c = PyCell_New(NULL);
@@ -2720,14 +2713,6 @@
 				SETLOCAL(f->f_nlocals + i, c);
 			}
 		}
-		/* Initialize any that are left */
-		while (i < f->f_ncells) {
-			c = PyCell_New(NULL);
-			if (c == NULL)
-				goto fail;
-			SETLOCAL(f->f_nlocals + i, c);
-			i++;
-		}
 	}
 	if (f->f_nfreevars) {
 		int i;

Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.352
retrieving revision 2.353
diff -u -d -r2.352 -r2.353
--- compile.c	3 Aug 2005 18:33:05 -0000	2.352
+++ compile.c	20 Oct 2005 19:59:25 -0000	2.353
@@ -1,385 +1,379 @@
-/* Compile an expression node to intermediate code */
-
-/* XXX TO DO:
-   XXX add __doc__ attribute == co_doc to code object attributes?
-   XXX   (it's currently the first item of the co_const tuple)
-   XXX Generate simple jump for break/return outside 'try...finally'
-   XXX Allow 'continue' inside finally clause of try-finally
-   XXX New opcode for loading the initial index for a for loop
-   XXX other JAR tricks?
-*/
+/*
[...8965 lines suppressed...]
-		symtable_add_def(st, STR(n), DEF_LOCAL | def_flag);
-		return;
-	default:
-		if (NCH(n) == 0)
-			return;
-		if (NCH(n) == 1) {
-			n = CHILD(n, 0);
-			goto loop;
-		}
-		/* Should only occur for errors like x + 1 = 1,
-		   which will be caught in the next pass. */
-		for (i = 0; i < NCH(n); ++i)
-			if (TYPE(CHILD(n, i)) >= single_input)
-				symtable_assign(st, CHILD(n, i), def_flag);
-	}
+	co = makecode(c, &a);
+ error:
+	assemble_free(&a);
+	return co;
 }

Index: future.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/future.c,v
retrieving revision 2.15
retrieving revision 2.16
diff -u -d -r2.15 -r2.16
--- future.c	4 Feb 2005 18:38:43 -0000	2.15
+++ future.c	20 Oct 2005 19:59:25 -0000	2.16
@@ -1,37 +1,30 @@
 #include "Python.h"
+#include "Python-ast.h"
 #include "node.h"
 #include "token.h"
 #include "graminit.h"
+#include "code.h"
 #include "compile.h"
 #include "symtable.h"
 
 #define UNDEFINED_FUTURE_FEATURE "future feature %.100s is not defined"
 #define FUTURE_IMPORT_STAR "future statement does not support import *"
 
-/* FUTURE_POSSIBLE() is provided to accomodate doc strings, which is
-   the only statement that can occur before a future statement.
-*/
-#define FUTURE_POSSIBLE(FF) ((FF)->ff_last_lineno == -1)
-
 static int
-future_check_features(PyFutureFeatures *ff, node *n, const char *filename)
+future_check_features(PyFutureFeatures *ff, stmt_ty s, const char *filename)
 {
 	int i;
-	char *feature;
-	node *ch, *nn;
+	const char *feature;
+	asdl_seq *names;
 
-	REQ(n, import_from);
-	nn = CHILD(n, 3 + (TYPE(CHILD(n, 3)) == LPAR));
-	if (TYPE(nn) == STAR) {
-		PyErr_SetString(PyExc_SyntaxError, FUTURE_IMPORT_STAR);
-		PyErr_SyntaxLocation(filename, nn->n_lineno);
-		return -1;
-	}
-	REQ(nn, import_as_names);
-	for (i = 0; i < NCH(nn); i += 2) {
-		ch = CHILD(nn, i);
-		REQ(ch, import_as_name);
-		feature = STR(CHILD(ch, 0));
+	assert(s->kind == ImportFrom_kind);
+
+	names = s->v.ImportFrom.names;
+	for (i = 0; i < asdl_seq_LEN(names); i++) {
+                alias_ty name = asdl_seq_GET(names, i);
+		feature = PyString_AsString(name->name);
+		if (!feature)
+			return 0;
 		if (strcmp(feature, FUTURE_NESTED_SCOPES) == 0) {
 			continue;
 		} else if (strcmp(feature, FUTURE_GENERATORS) == 0) {
@@ -41,218 +34,97 @@
 		} else if (strcmp(feature, "braces") == 0) {
 			PyErr_SetString(PyExc_SyntaxError,
 					"not a chance");
-			PyErr_SyntaxLocation(filename, CHILD(ch, 0)->n_lineno);
-			return -1;
+			PyErr_SyntaxLocation(filename, s->lineno);
+			return 0;
 		} else {
 			PyErr_Format(PyExc_SyntaxError,
 				     UNDEFINED_FUTURE_FEATURE, feature);
-			PyErr_SyntaxLocation(filename, CHILD(ch, 0)->n_lineno);
-			return -1;
+			PyErr_SyntaxLocation(filename, s->lineno);
+			return 0;
 		}
 	}
-	return 0;
+	return 1;
 }
 
-static void
-future_error(node *n, const char *filename)
+int
+future_parse(PyFutureFeatures *ff, mod_ty mod, const char *filename)
 {
-	PyErr_SetString(PyExc_SyntaxError,
-			"from __future__ imports must occur at the "
-			"beginning of the file");
-	PyErr_SyntaxLocation(filename, n->n_lineno);
-}
-
-/* Relevant portions of the grammar:
+	int i, found_docstring = 0, done = 0, prev_line = 0;
 
-single_input: NEWLINE | simple_stmt | compound_stmt NEWLINE
-file_input: (NEWLINE | stmt)* ENDMARKER
-stmt: simple_stmt | compound_stmt
-simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
-small_stmt: expr_stmt | print_stmt  | del_stmt | pass_stmt | flow_stmt 
-    | import_stmt | global_stmt | exec_stmt | assert_stmt
-import_stmt: 'import' dotted_as_name (',' dotted_as_name)* 
-    | 'from' dotted_name 'import' ('*' | import_as_name (',' import_as_name)*)
-import_as_name: NAME [NAME NAME]
-dotted_as_name: dotted_name [NAME NAME]
-dotted_name: NAME ('.' NAME)*
-*/
+	static PyObject *future;
+	if (!future) {
+		future = PyString_InternFromString("__future__");
+		if (!future)
+			return 0;
+	}
 
-/* future_parse() finds future statements at the beginnning of a
-   module.  The function calls itself recursively, rather than
-   factoring out logic for different kinds of statements into
-   different routines.
+	if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
+		return 1;
 
-   Return values:
-   -1 indicates an error occurred, e.g. unknown feature name
-   0 indicates no feature was found
-   1 indicates a feature was found
-*/
+	/* A subsequent pass will detect future imports that don't
+	   appear at the beginning of the file.  There's one case,
+	   however, that is easier to handl here: A series of imports
+	   joined by semi-colons, where the first import is a future
+	   statement but some subsequent import has the future form
+	   but is preceded by a regular import.
+	*/
+	   
 
-static int
-future_parse(PyFutureFeatures *ff, node *n, const char *filename)
-{
-	int i, r;
- loop:
-	switch (TYPE(n)) {
+	for (i = 0; i < asdl_seq_LEN(mod->v.Module.body); i++) {
+		stmt_ty s = asdl_seq_GET(mod->v.Module.body, i);
 
-	case single_input:
-		if (TYPE(CHILD(n, 0)) == simple_stmt) {
-			n = CHILD(n, 0);
-			goto loop;
-		}
-		return 0;
+		if (done && s->lineno > prev_line)
+			return 1;
+		prev_line = s->lineno;
 
-	case file_input:
-		/* Check each statement in the file, starting with the
-		   first, and continuing until the first statement
-		   that isn't a future statement.
+		/* The tests below will return from this function unless it is
+		   still possible to find a future statement.  The only things
+		   that can precede a future statement are another future
+		   statement and a doc string.
 		*/
-		for (i = 0; i < NCH(n); i++) {
-			node *ch = CHILD(n, i);
-			if (TYPE(ch) == stmt) {
-				r = future_parse(ff, ch, filename);
-				/* Need to check both conditions below
-				   to accomodate doc strings, which
-				   causes r < 0.
-				*/
-				if (r < 1 && !FUTURE_POSSIBLE(ff))
-					return r;
-			}
-		}
-		return 0;
-
-	case simple_stmt:
-		if (NCH(n) == 2) {
-			REQ(CHILD(n, 0), small_stmt);
-			n = CHILD(n, 0);
-			goto loop;
-		} else {
-			/* Deal with the special case of a series of
-			   small statements on a single line.  If a
-			   future statement follows some other
-			   statement, the SyntaxError is raised here.
-			   In all other cases, the symtable pass
-			   raises the exception.
-			*/
-			int found = 0, end_of_future = 0;
 
-			for (i = 0; i < NCH(n); i += 2) {
-				if (TYPE(CHILD(n, i)) == small_stmt) {
-					r = future_parse(ff, CHILD(n, i), 
-							 filename);
-					if (r < 1)
-						end_of_future = 1;
-					else {
-						found = 1;
-						if (end_of_future) {
-							future_error(n, 
-								     filename);
-							return -1;
-						}
-					}
+		if (s->kind == ImportFrom_kind) {
+			if (s->v.ImportFrom.module == future) {
+				if (done) {
+					PyErr_SetString(PyExc_SyntaxError,
+							ERR_LATE_FUTURE);
+					PyErr_SyntaxLocation(filename, 
+							     s->lineno);
+					return 0;
 				}
+				if (!future_check_features(ff, s, filename))
+					return 0;
+				ff->ff_lineno = s->lineno;
 			}
-
-			/* If we found one and only one, then the
-			   current lineno is legal. 
-			*/
-			if (found)
-				ff->ff_last_lineno = n->n_lineno + 1;
 			else
-				ff->ff_last_lineno = n->n_lineno;
-
-			if (end_of_future && found)
-				return 1;
-			else 
-				return 0;
-		}
-	
-	case stmt:
-		if (TYPE(CHILD(n, 0)) == simple_stmt) {
-			n = CHILD(n, 0);
-			goto loop;
-		} else if (TYPE(CHILD(n, 0)) == expr_stmt) {
-			n = CHILD(n, 0);
-			goto loop;
-		} else {
-			REQ(CHILD(n, 0), compound_stmt);
-			ff->ff_last_lineno = n->n_lineno;
-			return 0;
-		}
-
-	case small_stmt:
-		n = CHILD(n, 0);
-		goto loop;
-
-	case import_stmt: {
-		node *name;
-
-		n = CHILD(n, 0);
-		if (TYPE(n) != import_from) {
-			ff->ff_last_lineno = n->n_lineno;
-			return 0;
-		}
-		name = CHILD(n, 1);
-		if (strcmp(STR(CHILD(name, 0)), "__future__") != 0)
-			return 0;
-		if (future_check_features(ff, n, filename) < 0)
-			return -1;
-		ff->ff_last_lineno = n->n_lineno + 1;
-		return 1;
-	}
-
-	/* The cases below -- all of them! -- are necessary to find
-	   and skip doc strings. */
-	case expr_stmt:
-	case testlist:
-	case test:
-	case and_test:
-	case not_test:
-	case comparison:
-	case expr:
-	case xor_expr:
-	case and_expr:
-	case shift_expr:
-	case arith_expr:
-	case term:
-	case factor:
-	case power:
-		if (NCH(n) == 1) {
-			n = CHILD(n, 0);
-			goto loop;
+				done = 1;
 		}
-                ff->ff_last_lineno = n->n_lineno;
-		break;
-
-	case atom:
-		if (TYPE(CHILD(n, 0)) == STRING 
-		    && ff->ff_found_docstring == 0) {
-			ff->ff_found_docstring = 1;
-			return 0;
+		else if (s->kind == Expr_kind && !found_docstring) {
+			expr_ty e = s->v.Expr.value;
+			if (e->kind != Str_kind)
+				done = 1;
+			else
+				found_docstring = 1;
 		}
-		ff->ff_last_lineno = n->n_lineno;
-		return 0;
-
-	default:
-		ff->ff_last_lineno = n->n_lineno;
-		return 0;
+		else
+			done = 1;
 	}
-	return 0;
+	return 1;
 }
 
+
 PyFutureFeatures *
-PyNode_Future(node *n, const char *filename)
+PyFuture_FromAST(mod_ty mod, const char *filename)
 {
 	PyFutureFeatures *ff;
 
 	ff = (PyFutureFeatures *)PyMem_Malloc(sizeof(PyFutureFeatures));
 	if (ff == NULL)
 		return NULL;
-	ff->ff_found_docstring = 0;
-	ff->ff_last_lineno = -1;
 	ff->ff_features = 0;
+	ff->ff_lineno = -1;
 
-	if (future_parse(ff, n, filename) < 0) {
+	if (!future_parse(ff, mod, filename)) {
 		PyMem_Free((void *)ff);
 		return NULL;
 	}

Index: import.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/import.c,v
retrieving revision 2.245
retrieving revision 2.246
diff -u -d -r2.245 -r2.246
--- import.c	3 Oct 2005 04:48:15 -0000	2.245
+++ import.c	20 Oct 2005 19:59:25 -0000	2.246
@@ -3,10 +3,11 @@
 
 #include "Python.h"
 
-#include "node.h"
-#include "token.h"
+#include "Python-ast.h"
+#include "pythonrun.h"
 #include "errcode.h"
 #include "marshal.h"
+#include "code.h"
 #include "compile.h"
 #include "eval.h"
 #include "osdefs.h"
@@ -766,17 +767,17 @@
 /* Parse a source file and return the corresponding code object */
 
 static PyCodeObject *
-parse_source_module(char *pathname, FILE *fp)
+parse_source_module(const char *pathname, FILE *fp)
 {
-	PyCodeObject *co;
-	node *n;
-
-	n = PyParser_SimpleParseFile(fp, pathname, Py_file_input);
-	if (n == NULL)
-		return NULL;
-	co = PyNode_Compile(n, pathname);
-	PyNode_Free(n);
+	PyCodeObject *co = NULL;
+	mod_ty mod;
 
+	mod = PyParser_ASTFromFile(fp, pathname, Py_file_input, 0, 0, 0, 
+				   NULL);
+	if (mod) {
+		co = PyAST_Compile(mod, pathname, NULL);
+		free_mod(mod);
+	}
 	return co;
 }
 

Index: marshal.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/marshal.c,v
retrieving revision 1.88
retrieving revision 1.89
diff -u -d -r1.88 -r1.89
--- marshal.c	16 Aug 2005 03:47:52 -0000	1.88
+++ marshal.c	20 Oct 2005 19:59:25 -0000	1.89
@@ -6,6 +6,7 @@
 
 #include "Python.h"
 #include "longintrepr.h"
+#include "code.h"
 #include "compile.h"
 #include "marshal.h"
 

Index: pythonrun.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v
retrieving revision 2.217
retrieving revision 2.218
diff -u -d -r2.217 -r2.218
--- pythonrun.c	2 Oct 2005 01:48:50 -0000	2.217
+++ pythonrun.c	20 Oct 2005 19:59:25 -0000	2.218
@@ -3,13 +3,16 @@
 
 #include "Python.h"
 
+#include "Python-ast.h"
 #include "grammar.h"
 #include "node.h"
 #include "token.h"
 #include "parsetok.h"
 #include "errcode.h"
+#include "code.h"
 #include "compile.h"
 #include "symtable.h"
+#include "ast.h"
 #include "eval.h"
 #include "marshal.h"
 
@@ -32,9 +35,9 @@
 /* Forward */
 static void initmain(void);
 static void initsite(void);
-static PyObject *run_err_node(node *, const char *, PyObject *, PyObject *,
+static PyObject *run_err_mod(mod_ty, const char *, PyObject *, PyObject *,
 			      PyCompilerFlags *);
-static PyObject *run_node(node *, const char *, PyObject *, PyObject *,
+static PyObject *run_mod(mod_ty, const char *, PyObject *, PyObject *,
 			  PyCompilerFlags *);
 static PyObject *run_pyc_file(FILE *, const char *, PyObject *, PyObject *,
 			      PyCompilerFlags *);
@@ -634,25 +637,7 @@
 /* Parse input from a file and execute it */
 
 int
-PyRun_AnyFile(FILE *fp, const char *filename)
-{
-	return PyRun_AnyFileExFlags(fp, filename, 0, NULL);
-}
-
-int
-PyRun_AnyFileFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
-{
-	return PyRun_AnyFileExFlags(fp, filename, 0, flags);
-}
-
-int
-PyRun_AnyFileEx(FILE *fp, const char *filename, int closeit)
-{
-	return PyRun_AnyFileExFlags(fp, filename, closeit, NULL);
-}
-
-int
-PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
+PyRun_AnyFileExFlags(FILE *fp, char *filename, int closeit, 
 		     PyCompilerFlags *flags)
 {
 	if (filename == NULL)
@@ -668,12 +653,6 @@
 }
 
 int
-PyRun_InteractiveLoop(FILE *fp, const char *filename)
-{
-	return PyRun_InteractiveLoopFlags(fp, filename, NULL);
-}
-
-int
 PyRun_InteractiveLoopFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
 {
 	PyObject *v;
@@ -708,12 +687,6 @@
 	}
 }
 
-int
-PyRun_InteractiveOne(FILE *fp, const char *filename)
-{
-	return PyRun_InteractiveOneFlags(fp, filename, NULL);
-}
-
 /* compute parser flags based on compiler flags */
 #define PARSER_FLAGS(flags) \
 	(((flags) && (flags)->cf_flags & PyCF_DONT_IMPLY_DEDENT) ? \
@@ -723,9 +696,9 @@
 PyRun_InteractiveOneFlags(FILE *fp, const char *filename, PyCompilerFlags *flags)
 {
 	PyObject *m, *d, *v, *w;
-	node *n;
-	perrdetail err;
+	mod_ty mod;
 	char *ps1 = "", *ps2 = "";
+	int errcode = 0;
 
 	v = PySys_GetObject("ps1");
 	if (v != NULL) {
@@ -743,26 +716,25 @@
 		else if (PyString_Check(w))
 			ps2 = PyString_AsString(w);
 	}
-	n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar,
-			    	    Py_single_input, ps1, ps2, &err,
-			    	    PARSER_FLAGS(flags));
+	mod = PyParser_ASTFromFile(fp, filename, 
+				   Py_single_input, ps1, ps2,
+				   flags, &errcode);
 	Py_XDECREF(v);
 	Py_XDECREF(w);
-	if (n == NULL) {
-		if (err.error == E_EOF) {
-			if (err.text)
-				PyMem_DEL(err.text);
+	if (mod == NULL) {
+		if (errcode == E_EOF) {
+			PyErr_Clear();
 			return E_EOF;
 		}
-		err_input(&err);
 		PyErr_Print();
-		return err.error;
+		return -1;
 	}
 	m = PyImport_AddModule("__main__");
 	if (m == NULL)
 		return -1;
 	d = PyModule_GetDict(m);
-	v = run_node(n, filename, d, d, flags);
+	v = run_mod(mod, filename, d, d, flags);
+	free_mod(mod);
 	if (v == NULL) {
 		PyErr_Print();
 		return -1;
@@ -773,12 +745,6 @@
 	return 0;
 }
 
-int
-PyRun_SimpleFile(FILE *fp, const char *filename)
-{
-	return PyRun_SimpleFileEx(fp, filename, 0);
-}
-
 /* Check whether a file maybe a pyc file: Look at the extension,
    the file type, and, if we may close it, at the first few bytes. */
 
@@ -820,12 +786,6 @@
 }
 
 int
-PyRun_SimpleFileEx(FILE *fp, const char *filename, int closeit)
-{
-	return PyRun_SimpleFileExFlags(fp, filename, closeit, NULL);
-}
-
-int
 PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
 			PyCompilerFlags *flags)
 {
@@ -874,12 +834,6 @@
 }
 
 int
-PyRun_SimpleString(const char *command)
-{
-	return PyRun_SimpleStringFlags(command, NULL);
-}
-
-int
 PyRun_SimpleStringFlags(const char *command, PyCompilerFlags *flags)
 {
 	PyObject *m, *d, *v;
@@ -1054,6 +1008,8 @@
 		handle_system_exit();
 	}
 	PyErr_Fetch(&exception, &v, &tb);
+	if (exception == NULL)
+		return;
 	PyErr_NormalizeException(&exception, &v, &tb);
 	if (exception == NULL)
 		return;
@@ -1195,74 +1151,48 @@
 }
 
 PyObject *
-PyRun_String(const char *str, int start, PyObject *globals, PyObject *locals)
-{
-	return run_err_node(PyParser_SimpleParseString(str, start),
-			    "<string>", globals, locals, NULL);
-}
-
-PyObject *
-PyRun_File(FILE *fp, const char *filename, int start, PyObject *globals,
-	   PyObject *locals)
-{
-	return PyRun_FileEx(fp, filename, start, globals, locals, 0);
-}
-
-PyObject *
-PyRun_FileEx(FILE *fp, const char *filename, int start, PyObject *globals,
-	     PyObject *locals, int closeit)
-{
-	node *n = PyParser_SimpleParseFile(fp, filename, start);
-	if (closeit)
-		fclose(fp);
-	return run_err_node(n, filename, globals, locals, NULL);
-}
-
-PyObject *
-PyRun_StringFlags(const char *str, int start, PyObject *globals, PyObject *locals,
-		  PyCompilerFlags *flags)
-{
-	return run_err_node(PyParser_SimpleParseStringFlags(
-				    str, start, PARSER_FLAGS(flags)),
-			    "<string>", globals, locals, flags);
-}
-
-PyObject *
-PyRun_FileFlags(FILE *fp, const char *filename, int start, PyObject *globals,
-		PyObject *locals, PyCompilerFlags *flags)
+PyRun_StringFlags(const char *str, int start, PyObject *globals, 
+		  PyObject *locals, PyCompilerFlags *flags)
 {
-	return PyRun_FileExFlags(fp, filename, start, globals, locals, 0,
-				 flags);
+	PyObject *ret;
+	mod_ty mod = PyParser_ASTFromString(str, "<string>", start, flags);
+	ret = run_err_mod(mod, "<string>", globals, locals, flags);
+	free_mod(mod);
+	return ret;
 }
 
 PyObject *
 PyRun_FileExFlags(FILE *fp, const char *filename, int start, PyObject *globals,
 		  PyObject *locals, int closeit, PyCompilerFlags *flags)
 {
-	node *n = PyParser_SimpleParseFileFlags(fp, filename, start,
-						PARSER_FLAGS(flags));
+	PyObject *ret;
+	mod_ty mod = PyParser_ASTFromFile(fp, filename, start, 0, 0,
+					  flags, NULL);
+	if (mod == NULL)
+		return NULL;
 	if (closeit)
 		fclose(fp);
-	return run_err_node(n, filename, globals, locals, flags);
+	ret = run_err_mod(mod, filename, globals, locals, flags);
+	free_mod(mod);
+	return ret;
 }
 
 static PyObject *
-run_err_node(node *n, const char *filename, PyObject *globals, PyObject *locals,
-	     PyCompilerFlags *flags)
+run_err_mod(mod_ty mod, const char *filename, PyObject *globals, 
+	    PyObject *locals, PyCompilerFlags *flags)
 {
-	if (n == NULL)
+	if (mod == NULL)
 		return  NULL;
-	return run_node(n, filename, globals, locals, flags);
+	return run_mod(mod, filename, globals, locals, flags);
 }
 
 static PyObject *
-run_node(node *n, const char *filename, PyObject *globals, PyObject *locals,
+run_mod(mod_ty mod, const char *filename, PyObject *globals, PyObject *locals,
 	 PyCompilerFlags *flags)
 {
 	PyCodeObject *co;
 	PyObject *v;
-	co = PyNode_CompileFlags(n, filename, flags);
-	PyNode_Free(n);
+	co = PyAST_Compile(mod, filename, flags);
 	if (co == NULL)
 		return NULL;
 	v = PyEval_EvalCode(co, globals, locals);
@@ -1271,8 +1201,8 @@
 }
 
 static PyObject *
-run_pyc_file(FILE *fp, const char *filename, PyObject *globals, PyObject *locals,
-	     PyCompilerFlags *flags)
+run_pyc_file(FILE *fp, const char *filename, PyObject *globals, 
+	     PyObject *locals, PyCompilerFlags *flags)
 {
 	PyCodeObject *co;
 	PyObject *v;
@@ -1303,41 +1233,77 @@
 }
 
 PyObject *
-Py_CompileString(const char *str, const char *filename, int start)
-{
-	return Py_CompileStringFlags(str, filename, start, NULL);
-}
-
-PyObject *
 Py_CompileStringFlags(const char *str, const char *filename, int start,
 		      PyCompilerFlags *flags)
 {
-	node *n;
+	mod_ty mod;
 	PyCodeObject *co;
-
-	n = PyParser_SimpleParseStringFlagsFilename(str, filename, start,
-						    PARSER_FLAGS(flags));
-	if (n == NULL)
+	mod = PyParser_ASTFromString(str, filename, start, flags);
+	if (mod == NULL)
 		return NULL;
-	co = PyNode_CompileFlags(n, filename, flags);
-	PyNode_Free(n);
+	co = PyAST_Compile(mod, filename, flags);
+	free_mod(mod);
 	return (PyObject *)co;
 }
 
 struct symtable *
 Py_SymtableString(const char *str, const char *filename, int start)
 {
-	node *n;
+	mod_ty mod;
 	struct symtable *st;
-	n = PyParser_SimpleParseStringFlagsFilename(str, filename,
-						    start, 0);
-	if (n == NULL)
+
+	mod = PyParser_ASTFromString(str, filename, start, NULL);
+	if (mod == NULL)
 		return NULL;
-	st = PyNode_CompileSymtable(n, filename);
-	PyNode_Free(n);
+	st = PySymtable_Build(mod, filename, 0);
+	free_mod(mod);
 	return st;
 }
 
+/* Preferred access to parser is through AST. */
+mod_ty
+PyParser_ASTFromString(const char *s, const char *filename, int start, 
+		       PyCompilerFlags *flags)
+{
+	node *n;
+	mod_ty mod;
+	perrdetail err;
+	n = PyParser_ParseStringFlagsFilename(s, filename, &_PyParser_Grammar,
+					      start, &err, 
+					      PARSER_FLAGS(flags));
+	if (n) {
+		mod = PyAST_FromNode(n, flags, filename);
+		PyNode_Free(n);
+		return mod;
+	}
+	else {
+		err_input(&err);
+		return NULL;
+	}
+}
+
+mod_ty
+PyParser_ASTFromFile(FILE *fp, const char *filename, int start, char *ps1, 
+		     char *ps2, PyCompilerFlags *flags, int *errcode)
+{
+	node *n;
+	mod_ty mod;
+	perrdetail err;
+	n = PyParser_ParseFileFlags(fp, filename, &_PyParser_Grammar, start, 
+				    ps1, ps2, &err, PARSER_FLAGS(flags));
+	if (n) {
+		mod = PyAST_FromNode(n, flags, filename);
+		PyNode_Free(n);
+		return mod;
+	}
+	else {
+		err_input(&err);
+		if (errcode)
+			*errcode = err.error;
+		return NULL;
+	}
+}
+
 /* Simplified interface to parsefile -- return node or set exception */
 
 node *
@@ -1349,15 +1315,10 @@
 					(char *)0, (char *)0, &err, flags);
 	if (n == NULL)
 		err_input(&err);
+		
 	return n;
 }
 
-node *
-PyParser_SimpleParseFile(FILE *fp, const char *filename, int start)
-{
-	return PyParser_SimpleParseFileFlags(fp, filename, start, 0);
-}
-
 /* Simplified interface to parsestring -- return node or set exception */
 
 node *
@@ -1373,12 +1334,6 @@
 }
 
 node *
-PyParser_SimpleParseString(const char *str, int start)
-{
-	return PyParser_SimpleParseStringFlags(str, start, 0);
-}
-
-node *
 PyParser_SimpleParseStringFlagsFilename(const char *str, const char *filename,
 					int start, int flags)
 {
@@ -1418,12 +1373,6 @@
 	PyObject* u = NULL;
 	char *msg = NULL;
 	errtype = PyExc_SyntaxError;
-	v = Py_BuildValue("(ziiz)", err->filename,
-			    err->lineno, err->offset, err->text);
-	if (err->text != NULL) {
-		PyMem_DEL(err->text);
-		err->text = NULL;
-	}
 	switch (err->error) {
 	case E_SYNTAX:
 		errtype = PyExc_IndentationError;
@@ -1450,11 +1399,9 @@
 	case E_INTR:
 		if (!PyErr_Occurred())
 			PyErr_SetNone(PyExc_KeyboardInterrupt);
-		Py_XDECREF(v);
 		return;
 	case E_NOMEM:
 		PyErr_NoMemory();
-		Py_XDECREF(v);
 		return;
 	case E_EOF:
 		msg = "unexpected EOF while parsing";
@@ -1498,7 +1445,15 @@
 		msg = "unknown parsing error";
 		break;
 	}
-	w = Py_BuildValue("(sO)", msg, v);
+	v = Py_BuildValue("(ziiz)", err->filename,
+			  err->lineno, err->offset, err->text);
+ 	if (err->text != NULL) {
+		PyMem_DEL(err->text);
+		err->text = NULL;
+	}
+	w = NULL;
+	if (v != NULL)
+		w = Py_BuildValue("(sO)", msg, v);
 	Py_XDECREF(u);
 	Py_XDECREF(v);
 	PyErr_SetObject(errtype, w);
@@ -1687,3 +1642,20 @@
 	return oldhandler;
 #endif
 }
+
+/* Deprecated C API functions still provided for binary compatiblity */
+
+#undef PyParser_SimpleParseFile
+#undef PyParser_SimpleParseString
+
+node *
+PyParser_SimpleParseFile(FILE *fp, const char *filename, int start)
+{
+	return PyParser_SimpleParseFileFlags(fp, filename, start, 0);
+}
+
+node *
+PyParser_SimpleParseString(const char *str, int start)
+{
+	return PyParser_SimpleParseStringFlags(str, start, 0);
+}

Index: symtable.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/symtable.c,v
retrieving revision 2.12
retrieving revision 2.13
diff -u -d -r2.12 -r2.13
--- symtable.c	19 May 2004 08:20:32 -0000	2.12
+++ symtable.c	20 Oct 2005 19:59:25 -0000	2.13
@@ -1,48 +1,35 @@
 #include "Python.h"
+#include "Python-ast.h"
+#include "code.h"
 #include "compile.h"
 #include "symtable.h"
-#include "graminit.h"
 #include "structmember.h"
 
-/* The compiler uses this function to load a PySymtableEntry object
-   for a code block.  Each block is loaded twice, once during the
-   symbol table pass and once during the code gen pass.  Entries
[...1286 lines suppressed...]
+	/* Outermost iterator is evaluated in current scope */
+	VISIT(st, expr, outermost->iter);
+	/* Create generator scope for the rest */
+	tmp = PyString_FromString("<genexpr>");
+	if (!symtable_enter_block(st, tmp, FunctionBlock, (void *)e, 0)) {
+		return 0;
+	}
+	st->st_cur->ste_generator = 1;
+	/* Outermost iter is received as an argument */
+	if (!symtable_implicit_arg(st, 0)) {
+		return 0;
+	}
+	VISIT(st, expr, outermost->target);
+	VISIT_SEQ(st, expr, outermost->ifs);
+	VISIT_SEQ_TAIL(st, comprehension, e->v.GeneratorExp.generators, 1);
+	VISIT(st, expr, e->v.GeneratorExp.elt);
+	if (!symtable_exit_block(st, (void *)e))
+		return 0;
+	return 1;
+}

Index: sysmodule.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v
retrieving revision 2.130
retrieving revision 2.131
diff -u -d -r2.130 -r2.131
--- sysmodule.c	3 Oct 2005 00:54:57 -0000	2.130
+++ sysmodule.c	20 Oct 2005 19:59:25 -0000	2.131
@@ -15,7 +15,7 @@
 */
 
 #include "Python.h"
-#include "compile.h"
+#include "code.h"
 #include "frameobject.h"
 #include "eval.h"
 

Index: traceback.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/traceback.c,v
retrieving revision 2.42
retrieving revision 2.43
diff -u -d -r2.42 -r2.43
--- traceback.c	21 Mar 2004 18:37:23 -0000	2.42
+++ traceback.c	20 Oct 2005 19:59:25 -0000	2.43
@@ -3,7 +3,7 @@
 
 #include "Python.h"
 
-#include "compile.h"
+#include "code.h"
 #include "frameobject.h"
 #include "structmember.h"
 #include "osdefs.h"



More information about the Python-checkins mailing list