Bump version number to 2.4.2 to pick up the latest minor bug fixes.
[python/dscho.git] / Python / symtable.c
blobe48eaea1d547ca2e0815d7f7620fe4d4628417ee
1 #include "Python.h"
2 #include "compile.h"
3 #include "symtable.h"
4 #include "graminit.h"
5 #include "structmember.h"
7 /* The compiler uses this function to load a PySymtableEntry object
8 for a code block. Each block is loaded twice, once during the
9 symbol table pass and once during the code gen pass. Entries
10 created during the first pass are cached for the second pass, using
11 the st_symbols dictionary.
13 The cache is keyed by st_nscopes. Each code block node in a
14 module's parse tree can be assigned a unique id based on the order
15 in which the nodes are visited by the compiler. This strategy
16 works so long as the symbol table and codegen passes visit the same
17 nodes in the same order.
21 PyObject *
22 PySymtableEntry_New(struct symtable *st, char *name, int type, int lineno)
24 PySymtableEntryObject *ste = NULL;
25 PyObject *k, *v;
27 k = PyInt_FromLong(st->st_nscopes++);
28 if (k == NULL)
29 goto fail;
30 v = PyDict_GetItem(st->st_symbols, k);
31 if (v) {
32 Py_DECREF(k);
33 Py_INCREF(v);
34 return v;
37 ste = (PySymtableEntryObject *)PyObject_New(PySymtableEntryObject,
38 &PySymtableEntry_Type);
39 ste->ste_table = st;
40 ste->ste_id = k;
42 v = PyString_FromString(name);
43 if (v == NULL)
44 goto fail;
45 ste->ste_name = v;
47 v = PyDict_New();
48 if (v == NULL)
49 goto fail;
50 ste->ste_symbols = v;
52 v = PyList_New(0);
53 if (v == NULL)
54 goto fail;
55 ste->ste_varnames = v;
57 v = PyList_New(0);
58 if (v == NULL)
59 goto fail;
60 ste->ste_children = v;
62 ste->ste_optimized = 0;
63 ste->ste_opt_lineno = 0;
64 ste->ste_lineno = lineno;
65 switch (type) {
66 case funcdef:
67 case lambdef:
68 ste->ste_type = TYPE_FUNCTION;
69 break;
70 case classdef:
71 ste->ste_type = TYPE_CLASS;
72 break;
73 case single_input:
74 case eval_input:
75 case file_input:
76 ste->ste_type = TYPE_MODULE;
77 break;
80 if (st->st_cur == NULL)
81 ste->ste_nested = 0;
82 else if (st->st_cur->ste_nested
83 || st->st_cur->ste_type == TYPE_FUNCTION)
84 ste->ste_nested = 1;
85 else
86 ste->ste_nested = 0;
87 ste->ste_child_free = 0;
88 ste->ste_generator = 0;
90 if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0)
91 goto fail;
93 return (PyObject *)ste;
94 fail:
95 Py_XDECREF(ste);
96 return NULL;
99 static PyObject *
100 ste_repr(PySymtableEntryObject *ste)
102 char buf[256];
104 PyOS_snprintf(buf, sizeof(buf),
105 "<symtable entry %.100s(%ld), line %d>",
106 PyString_AS_STRING(ste->ste_name),
107 PyInt_AS_LONG(ste->ste_id),
108 ste->ste_lineno);
109 return PyString_FromString(buf);
112 static void
113 ste_dealloc(PySymtableEntryObject *ste)
115 ste->ste_table = NULL;
116 Py_XDECREF(ste->ste_id);
117 Py_XDECREF(ste->ste_name);
118 Py_XDECREF(ste->ste_symbols);
119 Py_XDECREF(ste->ste_varnames);
120 Py_XDECREF(ste->ste_children);
121 PyObject_Del(ste);
124 #define OFF(x) offsetof(PySymtableEntryObject, x)
126 static PyMemberDef ste_memberlist[] = {
127 {"id", T_OBJECT, OFF(ste_id), READONLY},
128 {"name", T_OBJECT, OFF(ste_name), READONLY},
129 {"symbols", T_OBJECT, OFF(ste_symbols), READONLY},
130 {"varnames", T_OBJECT, OFF(ste_varnames), READONLY},
131 {"children", T_OBJECT, OFF(ste_children), READONLY},
132 {"type", T_INT, OFF(ste_type), READONLY},
133 {"lineno", T_INT, OFF(ste_lineno), READONLY},
134 {"optimized",T_INT, OFF(ste_optimized), READONLY},
135 {"nested", T_INT, OFF(ste_nested), READONLY},
136 {NULL}
139 PyTypeObject PySymtableEntry_Type = {
140 PyObject_HEAD_INIT(&PyType_Type)
142 "symtable entry",
143 sizeof(PySymtableEntryObject),
145 (destructor)ste_dealloc, /* tp_dealloc */
146 0, /* tp_print */
147 0, /* tp_getattr */
148 0, /* tp_setattr */
149 0, /* tp_compare */
150 (reprfunc)ste_repr, /* tp_repr */
151 0, /* tp_as_number */
152 0, /* tp_as_sequence */
153 0, /* tp_as_mapping */
154 0, /* tp_hash */
155 0, /* tp_call */
156 0, /* tp_str */
157 PyObject_GenericGetAttr, /* tp_getattro */
158 0, /* tp_setattro */
159 0, /* tp_as_buffer */
160 Py_TPFLAGS_DEFAULT, /* tp_flags */
161 0, /* tp_doc */
162 0, /* tp_traverse */
163 0, /* tp_clear */
164 0, /* tp_richcompare */
165 0, /* tp_weaklistoffset */
166 0, /* tp_iter */
167 0, /* tp_iternext */
168 0, /* tp_methods */
169 ste_memberlist, /* tp_members */
170 0, /* tp_getset */
171 0, /* tp_base */
172 0, /* tp_dict */
173 0, /* tp_descr_get */
174 0, /* tp_descr_set */
175 0, /* tp_dictoffset */
176 0, /* tp_init */
177 0, /* tp_alloc */
178 0, /* tp_new */