| 
									
										
										
										
											2001-02-09 22:22:18 +00:00
										 |  |  | #include "Python.h"
 | 
					
						
							| 
									
										
										
										
											2001-02-27 19:07:02 +00:00
										 |  |  | #include "compile.h"
 | 
					
						
							| 
									
										
										
										
											2001-02-09 22:22:18 +00:00
										 |  |  | #include "symtable.h"
 | 
					
						
							|  |  |  | #include "graminit.h"
 | 
					
						
							|  |  |  | #include "structmember.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-12-10 00:53:18 +00:00
										 |  |  | /* 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 | 
					
						
							|  |  |  |    created during the first pass are cached for the second pass, using | 
					
						
							|  |  |  |    the st_symbols dictionary.   | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |    The cache is keyed by st_nscopes.  Each code block node in a | 
					
						
							|  |  |  |    module's parse tree can be assigned a unique id based on the order | 
					
						
							|  |  |  |    in which the nodes are visited by the compiler.  This strategy | 
					
						
							|  |  |  |    works so long as the symbol table and codegen passes visit the same | 
					
						
							|  |  |  |    nodes in the same order. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-02-09 22:22:18 +00:00
										 |  |  | PyObject * | 
					
						
							|  |  |  | PySymtableEntry_New(struct symtable *st, char *name, int type, int lineno) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	PySymtableEntryObject *ste = NULL; | 
					
						
							|  |  |  | 	PyObject *k, *v; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	k = PyInt_FromLong(st->st_nscopes++); | 
					
						
							|  |  |  | 	if (k == NULL) | 
					
						
							|  |  |  | 		goto fail; | 
					
						
							|  |  |  | 	v = PyDict_GetItem(st->st_symbols, k); | 
					
						
							| 
									
										
										
										
											2001-12-10 00:53:18 +00:00
										 |  |  | 	if (v) { | 
					
						
							| 
									
										
										
										
											2001-12-08 23:40:38 +00:00
										 |  |  | 		Py_DECREF(k); | 
					
						
							| 
									
										
										
										
											2001-02-23 17:55:27 +00:00
										 |  |  | 		Py_INCREF(v); | 
					
						
							|  |  |  | 		return v; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2001-02-09 22:22:18 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	ste = (PySymtableEntryObject *)PyObject_New(PySymtableEntryObject, | 
					
						
							|  |  |  | 						    &PySymtableEntry_Type); | 
					
						
							|  |  |  | 	ste->ste_table = st; | 
					
						
							|  |  |  | 	ste->ste_id = k; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	v = PyString_FromString(name); | 
					
						
							|  |  |  | 	if (v == NULL) | 
					
						
							|  |  |  | 		goto fail; | 
					
						
							|  |  |  | 	ste->ste_name = v; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	v = PyDict_New(); | 
					
						
							|  |  |  | 	if (v == NULL) | 
					
						
							|  |  |  | 	    goto fail; | 
					
						
							|  |  |  | 	ste->ste_symbols = v; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	v = PyList_New(0); | 
					
						
							|  |  |  | 	if (v == NULL) | 
					
						
							|  |  |  | 	    goto fail; | 
					
						
							|  |  |  | 	ste->ste_varnames = v; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	v = PyList_New(0); | 
					
						
							|  |  |  | 	if (v == NULL) | 
					
						
							|  |  |  | 	    goto fail; | 
					
						
							|  |  |  | 	ste->ste_children = v; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-02-27 04:23:34 +00:00
										 |  |  | 	ste->ste_optimized = 0; | 
					
						
							| 
									
										
										
										
											2001-12-04 02:41:46 +00:00
										 |  |  | 	ste->ste_opt_lineno = 0; | 
					
						
							| 
									
										
										
										
											2001-02-09 22:22:18 +00:00
										 |  |  | 	ste->ste_lineno = lineno; | 
					
						
							|  |  |  | 	switch (type) { | 
					
						
							|  |  |  | 	case funcdef: | 
					
						
							|  |  |  | 	case lambdef: | 
					
						
							|  |  |  | 		ste->ste_type = TYPE_FUNCTION; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case classdef: | 
					
						
							|  |  |  | 		ste->ste_type = TYPE_CLASS; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	case single_input: | 
					
						
							|  |  |  | 	case eval_input: | 
					
						
							|  |  |  | 	case file_input: | 
					
						
							|  |  |  | 		ste->ste_type = TYPE_MODULE; | 
					
						
							|  |  |  | 		break; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (st->st_cur == NULL) | 
					
						
							|  |  |  | 		ste->ste_nested = 0; | 
					
						
							|  |  |  | 	else if (st->st_cur->ste_nested  | 
					
						
							|  |  |  | 		 || st->st_cur->ste_type == TYPE_FUNCTION) | 
					
						
							|  |  |  | 		ste->ste_nested = 1; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		ste->ste_nested = 0; | 
					
						
							|  |  |  | 	ste->ste_child_free = 0; | 
					
						
							| 
									
										
										
										
											2001-06-18 22:08:13 +00:00
										 |  |  | 	ste->ste_generator = 0; | 
					
						
							| 
									
										
										
										
											2001-02-09 22:22:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0) | 
					
						
							|  |  |  | 	    goto fail; | 
					
						
							| 
									
										
										
										
											2001-02-23 17:55:27 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2001-02-09 22:22:18 +00:00
										 |  |  | 	return (PyObject *)ste; | 
					
						
							|  |  |  |  fail: | 
					
						
							|  |  |  | 	Py_XDECREF(ste); | 
					
						
							|  |  |  | 	return NULL; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static PyObject * | 
					
						
							|  |  |  | ste_repr(PySymtableEntryObject *ste) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	char buf[256]; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-28 21:36:28 +00:00
										 |  |  | 	PyOS_snprintf(buf, sizeof(buf), | 
					
						
							|  |  |  | 		      "<symtable entry %.100s(%ld), line %d>", | 
					
						
							|  |  |  | 		      PyString_AS_STRING(ste->ste_name), | 
					
						
							|  |  |  | 		      PyInt_AS_LONG(ste->ste_id), | 
					
						
							|  |  |  | 		      ste->ste_lineno); | 
					
						
							| 
									
										
										
										
											2001-02-09 22:22:18 +00:00
										 |  |  | 	return PyString_FromString(buf); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | ste_dealloc(PySymtableEntryObject *ste) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ste->ste_table = NULL; | 
					
						
							|  |  |  | 	Py_XDECREF(ste->ste_id); | 
					
						
							|  |  |  | 	Py_XDECREF(ste->ste_name); | 
					
						
							|  |  |  | 	Py_XDECREF(ste->ste_symbols); | 
					
						
							|  |  |  | 	Py_XDECREF(ste->ste_varnames); | 
					
						
							|  |  |  | 	Py_XDECREF(ste->ste_children); | 
					
						
							|  |  |  | 	PyObject_Del(ste); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define OFF(x) offsetof(PySymtableEntryObject, x)
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-09-20 20:46:19 +00:00
										 |  |  | static PyMemberDef ste_memberlist[] = { | 
					
						
							| 
									
										
										
										
											2001-02-09 22:22:18 +00:00
										 |  |  | 	{"id",       T_OBJECT, OFF(ste_id), READONLY}, | 
					
						
							|  |  |  | 	{"name",     T_OBJECT, OFF(ste_name), READONLY}, | 
					
						
							|  |  |  | 	{"symbols",  T_OBJECT, OFF(ste_symbols), READONLY}, | 
					
						
							|  |  |  | 	{"varnames", T_OBJECT, OFF(ste_varnames), READONLY}, | 
					
						
							|  |  |  | 	{"children", T_OBJECT, OFF(ste_children), READONLY}, | 
					
						
							|  |  |  | 	{"type",     T_INT,    OFF(ste_type), READONLY}, | 
					
						
							|  |  |  | 	{"lineno",   T_INT,    OFF(ste_lineno), READONLY}, | 
					
						
							|  |  |  | 	{"optimized",T_INT,    OFF(ste_optimized), READONLY}, | 
					
						
							|  |  |  | 	{"nested",   T_INT,    OFF(ste_nested), READONLY}, | 
					
						
							|  |  |  | 	{NULL} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PyTypeObject PySymtableEntry_Type = { | 
					
						
							|  |  |  | 	PyObject_HEAD_INIT(&PyType_Type) | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | 	"symtable entry", | 
					
						
							|  |  |  | 	sizeof(PySymtableEntryObject), | 
					
						
							|  |  |  | 	0, | 
					
						
							|  |  |  | 	(destructor)ste_dealloc,                /* tp_dealloc */ | 
					
						
							|  |  |  | 	0,                                      /* tp_print */ | 
					
						
							| 
									
										
										
										
											2001-09-20 20:46:19 +00:00
										 |  |  | 	0,			               /* tp_getattr */ | 
					
						
							| 
									
										
										
										
											2001-02-09 22:22:18 +00:00
										 |  |  | 	0,					/* tp_setattr */ | 
					
						
							|  |  |  | 	0,			                /* tp_compare */ | 
					
						
							|  |  |  | 	(reprfunc)ste_repr,			/* tp_repr */ | 
					
						
							|  |  |  | 	0,					/* tp_as_number */ | 
					
						
							|  |  |  | 	0,			                /* tp_as_sequence */ | 
					
						
							|  |  |  | 	0,					/* tp_as_mapping */ | 
					
						
							|  |  |  | 	0,					/* tp_hash */ | 
					
						
							|  |  |  | 	0,					/* tp_call */ | 
					
						
							|  |  |  | 	0,					/* tp_str */ | 
					
						
							| 
									
										
										
										
											2001-09-20 20:46:19 +00:00
										 |  |  | 	PyObject_GenericGetAttr,		/* tp_getattro */ | 
					
						
							| 
									
										
										
										
											2001-02-09 22:22:18 +00:00
										 |  |  | 	0,					/* tp_setattro */ | 
					
						
							|  |  |  | 	0,					/* tp_as_buffer */ | 
					
						
							|  |  |  | 	Py_TPFLAGS_DEFAULT,	                /* tp_flags */ | 
					
						
							|  |  |  |  	0,					/* tp_doc */ | 
					
						
							| 
									
										
										
										
											2001-09-20 20:46:19 +00:00
										 |  |  | 	0,					/* tp_traverse */ | 
					
						
							|  |  |  | 	0,					/* tp_clear */ | 
					
						
							|  |  |  | 	0,					/* tp_richcompare */ | 
					
						
							|  |  |  | 	0,					/* tp_weaklistoffset */ | 
					
						
							|  |  |  | 	0,					/* tp_iter */ | 
					
						
							|  |  |  | 	0,					/* tp_iternext */ | 
					
						
							|  |  |  | 	0,					/* tp_methods */ | 
					
						
							|  |  |  | 	ste_memberlist,				/* tp_members */ | 
					
						
							|  |  |  | 	0,					/* tp_getset */ | 
					
						
							|  |  |  | 	0,					/* tp_base */ | 
					
						
							|  |  |  | 	0,					/* tp_dict */ | 
					
						
							|  |  |  | 	0,					/* tp_descr_get */ | 
					
						
							|  |  |  | 	0,					/* tp_descr_set */ | 
					
						
							|  |  |  | 	0,					/* tp_dictoffset */ | 
					
						
							|  |  |  | 	0,					/* tp_init */ | 
					
						
							|  |  |  | 	0,					/* tp_alloc */ | 
					
						
							|  |  |  | 	0,					/* tp_new */ | 
					
						
							| 
									
										
										
										
											2001-02-09 22:22:18 +00:00
										 |  |  | }; |