[Python-checkins] CVS: python/dist/src/Python compile.c,2.157,2.158 pythonrun.c,2.120,2.121

Jeremy Hylton jhylton@users.sourceforge.net
Fri, 02 Feb 2001 10:19:17 -0800


Update of /cvsroot/python/python/dist/src/Python
In directory usw-pr-cvs1:/tmp/cvs-serv27353/Python

Modified Files:
	compile.c pythonrun.c 
Log Message:
Move a bunch of definitions that were internal to compile.c to
symtable.h, so that they can be used by external module.

Improve error handling in symtable_enter_scope(), which return an
error code that went unchecked by most callers. XXX The error handling
in symtable code is sloppy in general.

Modify symtable to record the line number that begins each scope.
This can help to identify which code block is being referred to when
multiple blocks are bound to the same name.

Add st_scopes dict that is used to preserve scope info when
PyNode_CompileSymtable() is called.  Otherwise, this information is
tossed as soon as it is no longer needed.

Add Py_SymtableString() to pythonrun; analogous to Py_CompileString().



Index: compile.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v
retrieving revision 2.157
retrieving revision 2.158
diff -C2 -r2.157 -r2.158
*** compile.c	2001/02/02 02:58:48	2.157
--- compile.c	2001/02/02 18:19:15	2.158
***************
*** 17,20 ****
--- 17,21 ----
  #include "graminit.h"
  #include "compile.h"
+ #include "symtable.h"
  #include "opcode.h"
  #include "structmember.h"
***************
*** 46,59 ****
  #define VAR_DELETE 2
  
- #define TYPE_FUNCTION 1
- #define TYPE_CLASS 2
- #define TYPE_MODULE 3
- 
- #define LOCAL 1
- #define GLOBAL_EXPLICIT 2
- #define GLOBAL_IMPLICIT 3
- #define FREE 4
- #define CELL 5
- 
  #define DEL_CLOSURE_ERROR \
  "can not delete variable '%.400s' referenced in nested scope"
--- 47,50 ----
***************
*** 368,439 ****
  };
  
- /* A symbol table is constructed each time PyNode_Compile() is
-    called.  The table walks the entire parse tree and identifies each
-    use or definition of a variable. 
- 
-    The symbol table contains a dictionary for each code block in a
-    module: The symbol dictionary for the block.  They keys of these
-    dictionaries are the name of all variables used or defined in the
-    block; the integer values are used to store several flags,
-    e.g. DEF_PARAM indicates that a variable is a parameter to a
-    function. 
- 
-    The slots st_cur_XXX pointers always refer to the current code
-    block.  The st_cur slot is the symbol dictionary.  The st_cur_id
-    slot is the id is the key in st_symbols.  The st_cur_name slot is
-    the name of the current scope. The st_cur_type slot is one of
-    TYPE_FUNCTION, TYPE_CLASS, or TYPE_MODULE.  The st_cur_children is
-    a list of the ids of the current node's children.
- 
-    The st_symbols slot is a dictionary that maps code block ids to
-    symbol dictionaries.  The keys are generated by a counter that is
-    incremented each time a new code block is found.  The counter is
-    identifies a specific scope, because both passes walk the parse
-    tree in the same order.
- 
-    The st_varnames slot is a dictionary that maps code block ids to
-    parameter lists.  The st_global slot always refers to the symbol 
-    dictionary for the module.
- 
-    The st_children slot is a dictionary that maps ids to a list
-    containing the ids of its children.
- */
- 
- struct symtable {
- 	int st_pass;             /* pass == 1 or 2 */
- 	PyObject *st_symbols;    /* dictionary of symbol tables */
- 	PyObject *st_varnames;   /* dictionary of parameter lists */
-         PyObject *st_stack;      /* stack of namespace info */
- 	PyObject *st_children;   /* dictionary (id=[ids]) */
- 	PyObject *st_cur;        /* borrowed ref to dict in st_symbols */
- 	PyObject *st_cur_name;   /* string, name of current scope */
- 	PyObject *st_cur_id;     /* int id of current code block */
- 	PyObject *st_cur_children; /* ref to current children list */
- 	int st_cur_type;         /* type of current scope */ 
- 	PyObject *st_global;     /* borrowed ref to MODULE in st_symbols */
- 	int st_scopes;           /* number of scopes */
- 	int st_errors;           /* number of errors */
- 	char *st_private;        /* name of current class or NULL */
- 	int st_tmpname;          /* temporary name counter */
- 	int st_nested;           /* bool (true if nested scope) */
- };
- 
- #define TOP "global"
- #define NOOPT ".noopt"
- 
- /* Flags for def-use information */
- 
- #define DEF_GLOBAL 1           /* global stmt */
- #define DEF_LOCAL 2            /* assignment in code block */
- #define DEF_PARAM 2<<1         /* formal parameter */
- #define USE 2<<2               /* name is used */
- #define DEF_STAR 2<<3          /* parameter is star arg */
- #define DEF_DOUBLESTAR 2<<4    /* parameter is star-star arg */
- #define DEF_INTUPLE 2<<5       /* name defined in tuple in parameters */
- #define DEF_FREE 2<<6          /* name used by not defined in nested scope */
- #define DEF_FREE_GLOBAL 2<<7   /* free variable is actually implicit global */
- #define DEF_FREE_CLASS 2<<8    /* free variable from class's method */
- #define DEF_IMPORT 2<<9        /* assignment occurred via import */
- 
  int is_free(int v)
  {
--- 359,362 ----
***************
*** 554,560 ****
  static int symtable_build(struct compiling *, node *);
  static int symtable_load_symbols(struct compiling *);
! static struct symtable *symtable_init(void);
! static void symtable_free(struct symtable *);
! static int symtable_enter_scope(struct symtable *, char *, int);
  static int symtable_exit_scope(struct symtable *);
  static int symtable_update_cur(struct symtable *);
--- 477,482 ----
  static int symtable_build(struct compiling *, node *);
  static int symtable_load_symbols(struct compiling *);
! static struct symtable *symtable_init(int);
! static void symtable_enter_scope(struct symtable *, char *, int, int);
  static int symtable_exit_scope(struct symtable *);
  static int symtable_update_cur(struct symtable *);
***************
*** 2218,2222 ****
  		int i, closure;
  		int ndefs = com_argdefs(c, CHILD(n, 0));
! 		symtable_enter_scope(c->c_symtable, "lambda", lambdef);
  		co = (PyObject *) icompile(CHILD(n, 0), c);
  		symtable_exit_scope(c->c_symtable);
--- 2140,2145 ----
  		int i, closure;
  		int ndefs = com_argdefs(c, CHILD(n, 0));
! 		symtable_enter_scope(c->c_symtable, "lambda", lambdef,
! 				     n->n_lineno);
  		co = (PyObject *) icompile(CHILD(n, 0), c);
  		symtable_exit_scope(c->c_symtable);
***************
*** 3336,3340 ****
  	REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
  	ndefs = com_argdefs(c, n);
! 	symtable_enter_scope(c->c_symtable, STR(CHILD(n, 1)), TYPE(n));
  	co = (PyObject *)icompile(n, c);
  	symtable_exit_scope(c->c_symtable);
--- 3259,3264 ----
  	REQ(n, funcdef); /* funcdef: 'def' NAME parameters ':' suite */
  	ndefs = com_argdefs(c, n);
! 	symtable_enter_scope(c->c_symtable, STR(CHILD(n, 1)), TYPE(n),
! 			     n->n_lineno);
  	co = (PyObject *)icompile(n, c);
  	symtable_exit_scope(c->c_symtable);
***************
*** 3396,3400 ****
  		com_bases(c, CHILD(n, 3));
  	name = STR(CHILD(n, 1));
! 	symtable_enter_scope(c->c_symtable, name, TYPE(n));
  	co = (PyObject *)icompile(n, c);
  	symtable_exit_scope(c->c_symtable);
--- 3320,3324 ----
  		com_bases(c, CHILD(n, 3));
  	name = STR(CHILD(n, 1));
! 	symtable_enter_scope(c->c_symtable, name, TYPE(n), n->n_lineno);
  	co = (PyObject *)icompile(n, c);
  	symtable_exit_scope(c->c_symtable);
***************
*** 3873,3876 ****
--- 3797,3821 ----
  }
  
+ struct symtable *
+ PyNode_CompileSymtable(node *n, char *filename)
+ {
+ 	struct symtable *st;
+ 
+ 	st = symtable_init(1);
+ 	if (st == NULL)
+ 		return NULL;
+ 	symtable_enter_scope(st, TOP, TYPE(n), n->n_lineno);
+ 	if (st->st_errors > 0) {
+ 		PySymtable_Free(st);
+ 		return NULL;
+ 	}
+ 	symtable_node(st, n);
+ 	if (st->st_errors > 0) {
+ 		PySymtable_Free(st);
+ 		return NULL;
+ 	}
+ 	return st;
+ }
+ 
  static PyCodeObject *
  icompile(node *n, struct compiling *base)
***************
*** 3949,3953 ****
   exit:
  	if (base == NULL)
! 		symtable_free(sc.c_symtable);
  	com_free(&sc);
  	return co;
--- 3894,3898 ----
   exit:
  	if (base == NULL)
! 		PySymtable_Free(sc.c_symtable);
  	com_free(&sc);
  	return co;
***************
*** 4006,4012 ****
  symtable_build(struct compiling *c, node *n)
  {
! 	if ((c->c_symtable = symtable_init()) == NULL)
  		return -1;
! 	if (symtable_enter_scope(c->c_symtable, TOP, TYPE(n)) < 0)
  		return -1;
  	symtable_node(c->c_symtable, n);
--- 3951,3958 ----
  symtable_build(struct compiling *c, node *n)
  {
! 	if ((c->c_symtable = symtable_init(0)) == NULL)
  		return -1;
! 	symtable_enter_scope(c->c_symtable, TOP, TYPE(n), n->n_lineno);
! 	if (c->c_symtable->st_errors > 0)
  		return -1;
  	symtable_node(c->c_symtable, n);
***************
*** 4014,4018 ****
  		return -1;
  	/* reset for second pass */
! 	c->c_symtable->st_scopes = 1;
  	c->c_symtable->st_pass = 2;
  	return 0;
--- 3960,3964 ----
  		return -1;
  	/* reset for second pass */
! 	c->c_symtable->st_nscopes = 1;
  	c->c_symtable->st_pass = 2;
  	return 0;
***************
*** 4193,4197 ****
  
  static struct symtable *
! symtable_init()
  {
  	struct symtable *st;
--- 4139,4143 ----
  
  static struct symtable *
! symtable_init(int keep)
  {
  	struct symtable *st;
***************
*** 4202,4205 ****
--- 4148,4152 ----
  		return NULL;
  	st->st_pass = 1;
+ 	st->st_keep = keep;
  	if ((st->st_stack = PyList_New(0)) == NULL)
  		goto fail;
***************
*** 4215,4219 ****
  		goto fail;
  	Py_DECREF(d);
! 	st->st_global = d;
  	st->st_cur = NULL;
  	st->st_cur_id = NULL;
--- 4162,4172 ----
  		goto fail;
  	Py_DECREF(d);
! 	if (keep) {
! 		if ((d = PyDict_New()) == NULL)
! 			goto fail;
! 		st->st_scopes = d;
! 	} else 
! 		st->st_scopes = NULL;
! 	st->st_global = d; /* use ref borrowed from st->st_symbols */
  	st->st_cur = NULL;
  	st->st_cur_id = NULL;
***************
*** 4222,4226 ****
  	st->st_cur_type = 0;
  	st->st_nested = 0;
! 	st->st_scopes = 0;
  	st->st_errors = 0;
  	st->st_tmpname = 0;
--- 4175,4179 ----
  	st->st_cur_type = 0;
  	st->st_nested = 0;
! 	st->st_nscopes = 0;
  	st->st_errors = 0;
  	st->st_tmpname = 0;
***************
*** 4228,4237 ****
  	return st;
   fail:
! 	symtable_free(st);
  	return NULL;
  }
  
! static void
! symtable_free(struct symtable *st)
  {
  	Py_XDECREF(st->st_symbols);
--- 4181,4190 ----
  	return st;
   fail:
! 	PySymtable_Free(st);
  	return NULL;
  }
  
! void
! PySymtable_Free(struct symtable *st)
  {
  	Py_XDECREF(st->st_symbols);
***************
*** 4239,4242 ****
--- 4192,4196 ----
  	Py_XDECREF(st->st_children);
  	Py_XDECREF(st->st_stack);
+ 	Py_XDECREF(st->st_scopes);
  	Py_XDECREF(st->st_cur_id);
  	Py_XDECREF(st->st_cur_name);
***************
*** 4245,4253 ****
  
  static PyObject *
! make_scope_info(PyObject *id, PyObject *name, int nested, int type)
  {
! 	PyObject *t, *i1 = NULL, *i2 = NULL;
  
! 	t = PyTuple_New(4);
  	if (t == NULL)
  		return NULL;
--- 4199,4208 ----
  
  static PyObject *
! make_scope_info(PyObject *id, PyObject *name, int nested, int type,
! 		int lineno)
  {
! 	PyObject *t, *i1 = NULL, *i2 = NULL, *i3 = NULL;
  
! 	t = PyTuple_New(5);
  	if (t == NULL)
  		return NULL;
***************
*** 4258,4261 ****
--- 4213,4219 ----
  	if (i2 == NULL)
  		goto fail;
+ 	i3 = PyInt_FromLong(lineno);
+ 	if (i3 == NULL)
+ 		goto fail;
  
  	Py_INCREF(name);
***************
*** 4266,4269 ****
--- 4224,4228 ----
  	PyTuple_SET_ITEM(t, 2, i1);
  	PyTuple_SET_ITEM(t, 3, i2);
+ 	PyTuple_SET_ITEM(t, 4, i3);
  	return t;
   fail:
***************
*** 4271,4274 ****
--- 4230,4234 ----
  	Py_XDECREF(i1);
  	Py_XDECREF(i2);
+ 	Py_XDECREF(i3);
  	return NULL;
  }
***************
*** 4379,4383 ****
  }
  
- 
  static int
  symtable_exit_scope(struct symtable *st)
--- 4339,4342 ----
***************
*** 4403,4408 ****
  }
  
! static int
! symtable_enter_scope(struct symtable *st, char *name, int type)
  {
  	PyObject *o;
--- 4362,4368 ----
  }
  
! static void
! symtable_enter_scope(struct symtable *st, char *name, int type,
! 		     int lineno)
  {
  	PyObject *o;
***************
*** 4411,4420 ****
  		/* push current scope info on stack */
  		o = make_scope_info(st->st_cur_id, st->st_cur_name, 
! 				    st->st_nested, st->st_cur_type);
! 		if (o == NULL)
! 			return -1;
  		if (PyList_Append(st->st_stack, o) < 0) {
  			Py_DECREF(o);
! 			return -1;
  		}
  		Py_DECREF(o);
--- 4371,4392 ----
  		/* push current scope info on stack */
  		o = make_scope_info(st->st_cur_id, st->st_cur_name, 
! 				    st->st_nested, st->st_cur_type,
! 				    st->st_cur_lineno);
! 		if (o == NULL) {
! 			st->st_errors++;
! 			return;
! 		}
  		if (PyList_Append(st->st_stack, o) < 0) {
  			Py_DECREF(o);
! 			st->st_errors++;
! 			return;
! 		}
! 		if (st->st_keep) {
! 			if (PyDict_SetItem(st->st_scopes,
! 					   st->st_cur_id, o) < 0) {
! 				Py_DECREF(o);
! 				st->st_errors++;
! 				return;
! 			}
  		}
  		Py_DECREF(o);
***************
*** 4423,4426 ****
--- 4395,4399 ----
  	if (st->st_nested || st->st_cur_type == TYPE_FUNCTION)
  		st->st_nested = 1;
+ 	st->st_cur_lineno = lineno;
  	switch (type) {
  	case funcdef:
***************
*** 4438,4451 ****
  	default:
  		fprintf(stderr, "invalid symtable scope: %d\n", type);
! 		return -1;
  	}
  	/* update st_cur_id and parent's st_cur_children */
! 	o = PyInt_FromLong(st->st_scopes++);
! 	if (o == NULL)
! 		return -1;
  	if (st->st_cur_children) {
  		if (PyList_Append(st->st_cur_children, o) < 0) {
  			Py_DECREF(o);
! 			return -1;
  		}
  	}
--- 4411,4428 ----
  	default:
  		fprintf(stderr, "invalid symtable scope: %d\n", type);
! 		st->st_errors++;
! 		return;
  	}
  	/* update st_cur_id and parent's st_cur_children */
! 	o = PyInt_FromLong(st->st_nscopes++);
! 	if (o == NULL) {
! 		st->st_errors++;
! 		return;
! 	}
  	if (st->st_cur_children) {
  		if (PyList_Append(st->st_cur_children, o) < 0) {
  			Py_DECREF(o);
! 			st->st_errors++;
! 			return;
  		}
  	}
***************
*** 4453,4465 ****
  	/* create st_cur_children list */
  	o = PyList_New(0);
! 	if (o == NULL)
! 		return -1;
  	if (PyDict_SetItem(st->st_children, st->st_cur_id, o) < 0) {
  		Py_DECREF(o);
! 		return -1;
  	}
  	Py_DECREF(o);
  
! 	return symtable_update_cur(st);
  }
  
--- 4430,4445 ----
  	/* create st_cur_children list */
  	o = PyList_New(0);
! 	if (o == NULL) {
! 		st->st_errors++;
! 		return;
! 	}
  	if (PyDict_SetItem(st->st_children, st->st_cur_id, o) < 0) {
  		Py_DECREF(o);
! 		st->st_errors++;
! 		return;
  	}
  	Py_DECREF(o);
  
! 	symtable_update_cur(st);
  }
  
***************
*** 4576,4580 ****
  		symtable_add_def(st, func_name, DEF_LOCAL);
  		symtable_default_args(st, CHILD(n, 2));
! 		symtable_enter_scope(st, func_name, TYPE(n));
  		symtable_funcdef(st, n);
  		symtable_exit_scope(st);
--- 4556,4560 ----
  		symtable_add_def(st, func_name, DEF_LOCAL);
  		symtable_default_args(st, CHILD(n, 2));
! 		symtable_enter_scope(st, func_name, TYPE(n), n->n_lineno);
  		symtable_funcdef(st, n);
  		symtable_exit_scope(st);
***************
*** 4584,4588 ****
  		if (NCH(n) == 4)
  			symtable_default_args(st, CHILD(n, 1));
! 		symtable_enter_scope(st, "lambda", TYPE(n));
  		symtable_funcdef(st, n);
  		symtable_exit_scope(st);
--- 4564,4568 ----
  		if (NCH(n) == 4)
  			symtable_default_args(st, CHILD(n, 1));
! 		symtable_enter_scope(st, "lambda", TYPE(n), n->n_lineno);
  		symtable_funcdef(st, n);
  		symtable_exit_scope(st);
***************
*** 4598,4602 ****
  			}
  		}
! 		symtable_enter_scope(st, class_name, TYPE(n));
  		tmp = st->st_private;
  		st->st_private = class_name;
--- 4578,4582 ----
  			}
  		}
! 		symtable_enter_scope(st, class_name, TYPE(n), n->n_lineno);
  		tmp = st->st_private;
  		st->st_private = class_name;

Index: pythonrun.c
===================================================================
RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v
retrieving revision 2.120
retrieving revision 2.121
diff -C2 -r2.120 -r2.121
*** pythonrun.c	2001/01/28 00:27:39	2.120
--- pythonrun.c	2001/02/02 18:19:15	2.121
***************
*** 10,13 ****
--- 10,14 ----
  #include "errcode.h"
  #include "compile.h"
+ #include "symtable.h"
  #include "eval.h"
  #include "marshal.h"
***************
*** 962,965 ****
--- 963,979 ----
  	PyNode_Free(n);
  	return (PyObject *)co;
+ }
+ 
+ struct symtable *
+ Py_SymtableString(char *str, char *filename, int start)
+ {
+ 	node *n;
+ 	struct symtable *st;
+ 	n = PyParser_SimpleParseString(str, start);
+ 	if (n == NULL)
+ 		return NULL;
+ 	st = PyNode_CompileSymtable(n, filename);
+ 	PyNode_Free(n);
+ 	return st;
  }