blob: 5ca204164a2225a7d8d63c22f5de4311ce654b28 [file] [log] [blame]
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +00001#include "Python.h"
Jeremy Hylton4db62b12001-02-27 19:07:02 +00002#include "compile.h"
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +00003#include "symtable.h"
4#include "graminit.h"
5#include "structmember.h"
6
Jeremy Hylton29906402001-12-10 00:53:18 +00007/* 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.
12
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.
18*/
19
20
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +000021PyObject *
22PySymtableEntry_New(struct symtable *st, char *name, int type, int lineno)
23{
24 PySymtableEntryObject *ste = NULL;
25 PyObject *k, *v;
26
27 k = PyInt_FromLong(st->st_nscopes++);
28 if (k == NULL)
29 goto fail;
30 v = PyDict_GetItem(st->st_symbols, k);
Jeremy Hylton29906402001-12-10 00:53:18 +000031 if (v) {
Tim Peters0f2d4b82001-12-08 23:40:38 +000032 Py_DECREF(k);
Jeremy Hylton74b3bc42001-02-23 17:55:27 +000033 Py_INCREF(v);
34 return v;
35 }
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +000036
37 ste = (PySymtableEntryObject *)PyObject_New(PySymtableEntryObject,
38 &PySymtableEntry_Type);
39 ste->ste_table = st;
40 ste->ste_id = k;
41
42 v = PyString_FromString(name);
43 if (v == NULL)
44 goto fail;
45 ste->ste_name = v;
46
47 v = PyDict_New();
48 if (v == NULL)
49 goto fail;
50 ste->ste_symbols = v;
51
52 v = PyList_New(0);
53 if (v == NULL)
54 goto fail;
55 ste->ste_varnames = v;
56
57 v = PyList_New(0);
58 if (v == NULL)
59 goto fail;
60 ste->ste_children = v;
61
Jeremy Hylton29906ee2001-02-27 04:23:34 +000062 ste->ste_optimized = 0;
Jeremy Hylton86424e32001-12-04 02:41:46 +000063 ste->ste_opt_lineno = 0;
Jeremy Hylton4d508ad2003-05-21 17:34:50 +000064 ste->ste_tmpname = 0;
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +000065 ste->ste_lineno = lineno;
66 switch (type) {
67 case funcdef:
68 case lambdef:
Raymond Hettinger354433a2004-05-19 08:20:33 +000069 case testlist_gexp: /* generator expression */
70 case argument: /* generator expression */
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +000071 ste->ste_type = TYPE_FUNCTION;
72 break;
73 case classdef:
74 ste->ste_type = TYPE_CLASS;
75 break;
76 case single_input:
77 case eval_input:
78 case file_input:
79 ste->ste_type = TYPE_MODULE;
80 break;
81 }
82
83 if (st->st_cur == NULL)
84 ste->ste_nested = 0;
85 else if (st->st_cur->ste_nested
86 || st->st_cur->ste_type == TYPE_FUNCTION)
87 ste->ste_nested = 1;
88 else
89 ste->ste_nested = 0;
90 ste->ste_child_free = 0;
Tim Peters5ca576e2001-06-18 22:08:13 +000091 ste->ste_generator = 0;
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +000092
93 if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0)
94 goto fail;
Jeremy Hylton74b3bc42001-02-23 17:55:27 +000095
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +000096 return (PyObject *)ste;
97 fail:
98 Py_XDECREF(ste);
99 return NULL;
100}
101
102static PyObject *
103ste_repr(PySymtableEntryObject *ste)
104{
105 char buf[256];
106
Barry Warsaw4b4ab202001-11-28 21:36:28 +0000107 PyOS_snprintf(buf, sizeof(buf),
108 "<symtable entry %.100s(%ld), line %d>",
109 PyString_AS_STRING(ste->ste_name),
110 PyInt_AS_LONG(ste->ste_id),
111 ste->ste_lineno);
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000112 return PyString_FromString(buf);
113}
114
115static void
116ste_dealloc(PySymtableEntryObject *ste)
117{
118 ste->ste_table = NULL;
119 Py_XDECREF(ste->ste_id);
120 Py_XDECREF(ste->ste_name);
121 Py_XDECREF(ste->ste_symbols);
122 Py_XDECREF(ste->ste_varnames);
123 Py_XDECREF(ste->ste_children);
124 PyObject_Del(ste);
125}
126
127#define OFF(x) offsetof(PySymtableEntryObject, x)
128
Guido van Rossum6f799372001-09-20 20:46:19 +0000129static PyMemberDef ste_memberlist[] = {
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000130 {"id", T_OBJECT, OFF(ste_id), READONLY},
131 {"name", T_OBJECT, OFF(ste_name), READONLY},
132 {"symbols", T_OBJECT, OFF(ste_symbols), READONLY},
133 {"varnames", T_OBJECT, OFF(ste_varnames), READONLY},
134 {"children", T_OBJECT, OFF(ste_children), READONLY},
135 {"type", T_INT, OFF(ste_type), READONLY},
136 {"lineno", T_INT, OFF(ste_lineno), READONLY},
137 {"optimized",T_INT, OFF(ste_optimized), READONLY},
138 {"nested", T_INT, OFF(ste_nested), READONLY},
139 {NULL}
140};
141
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000142PyTypeObject PySymtableEntry_Type = {
143 PyObject_HEAD_INIT(&PyType_Type)
144 0,
145 "symtable entry",
146 sizeof(PySymtableEntryObject),
147 0,
148 (destructor)ste_dealloc, /* tp_dealloc */
149 0, /* tp_print */
Guido van Rossum6f799372001-09-20 20:46:19 +0000150 0, /* tp_getattr */
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000151 0, /* tp_setattr */
152 0, /* tp_compare */
153 (reprfunc)ste_repr, /* tp_repr */
154 0, /* tp_as_number */
155 0, /* tp_as_sequence */
156 0, /* tp_as_mapping */
157 0, /* tp_hash */
158 0, /* tp_call */
159 0, /* tp_str */
Guido van Rossum6f799372001-09-20 20:46:19 +0000160 PyObject_GenericGetAttr, /* tp_getattro */
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000161 0, /* tp_setattro */
162 0, /* tp_as_buffer */
163 Py_TPFLAGS_DEFAULT, /* tp_flags */
164 0, /* tp_doc */
Guido van Rossum6f799372001-09-20 20:46:19 +0000165 0, /* tp_traverse */
166 0, /* tp_clear */
167 0, /* tp_richcompare */
168 0, /* tp_weaklistoffset */
169 0, /* tp_iter */
170 0, /* tp_iternext */
171 0, /* tp_methods */
172 ste_memberlist, /* tp_members */
173 0, /* tp_getset */
174 0, /* tp_base */
175 0, /* tp_dict */
176 0, /* tp_descr_get */
177 0, /* tp_descr_set */
178 0, /* tp_dictoffset */
179 0, /* tp_init */
180 0, /* tp_alloc */
181 0, /* tp_new */
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000182};