mirror of
https://github.com/python/cpython.git
synced 2025-08-03 16:39:00 +00:00
Relax the rules for using 'from ... import *' and exec in the presence
of nested functions. Either is allowed in a function if it contains no defs or lambdas or the defs and lambdas it contains have no free variables. If a function is itself nested and has free variables, either is illegal. Revise the symtable to use a PySymtableEntryObject, which holds all the revelent information for a scope, rather than using a bunch of st_cur_XXX pointers in the symtable struct. The changes simplify the internal management of the current symtable scope and of the stack. Added new C source file: Python/symtable.c. (Does the Windows build process need to be updated?) As part of these changes, the initial _symtable module interface introduced in 2.1a2 is replaced. A dictionary of PySymtableEntryObjects are returned.
This commit is contained in:
parent
670fa52698
commit
cb17ae8b19
5 changed files with 289 additions and 336 deletions
|
@ -14,61 +14,51 @@ extern "C" {
|
|||
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.
|
||||
|
||||
If st_keep is true then the namespace info pushed on st_stack will
|
||||
also be stored in st_scopes. This is useful if the symbol table is
|
||||
being passed to something other than the compiler.
|
||||
*/
|
||||
|
||||
struct _symtable_entry;
|
||||
|
||||
struct symtable {
|
||||
int st_pass; /* pass == 1 or 2 */
|
||||
int st_keep; /* true if symtable will be returned */
|
||||
char *st_filename; /* name of file being compiled */
|
||||
PyObject *st_symbols; /* dictionary of symbol tables */
|
||||
PyObject *st_varnames; /* dictionary of parameter lists */
|
||||
struct _symtable_entry *st_cur; /* current symbol table entry */
|
||||
PyObject *st_symbols; /* dictionary of symbol table entries */
|
||||
PyObject *st_stack; /* stack of namespace info */
|
||||
PyObject *st_scopes; /* dictionary 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 */
|
||||
int st_cur_lineno; /* line number where current scope begins */
|
||||
PyObject *st_global; /* borrowed ref to MODULE in st_symbols */
|
||||
int st_nscopes; /* 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) */
|
||||
};
|
||||
|
||||
typedef struct _symtable_entry {
|
||||
PyObject_HEAD
|
||||
PyObject *ste_id; /* int: key in st_symbols) */
|
||||
PyObject *ste_symbols; /* dict: name to flags) */
|
||||
PyObject *ste_name; /* string: name of scope */
|
||||
PyObject *ste_varnames; /* list of variable names */
|
||||
PyObject *ste_children; /* list of child ids */
|
||||
int ste_type; /* module, class, or function */
|
||||
int ste_lineno; /* first line of scope */
|
||||
int ste_optimized; /* true if namespace is optimized */
|
||||
int ste_nested; /* true if scope is nested */
|
||||
int ste_child_free; /* true if a child scope has free variables,
|
||||
including free refs to globals */
|
||||
struct symtable *ste_table;
|
||||
} PySymtableEntryObject;
|
||||
|
||||
extern DL_IMPORT(PyTypeObject) PySymtableEntry_Type;
|
||||
|
||||
#define PySymtableEntry_Check(op) ((op)->ob_type == &PySymtableEntry_Type)
|
||||
|
||||
extern DL_IMPORT(PyObject *) PySymtableEntry_New(struct symtable *,
|
||||
char *, int, int);
|
||||
|
||||
DL_IMPORT(struct symtable *) PyNode_CompileSymtable(struct _node *, char *);
|
||||
DL_IMPORT(void) PySymtable_Free(struct symtable *);
|
||||
|
||||
|
||||
#define TOP "global"
|
||||
#define NOOPT ".noopt"
|
||||
|
||||
/* Flags for def-use information */
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue