blob: f86fd2fbc802ba021cb308abd7fdeace43cefb5a [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:
69 ste->ste_type = TYPE_FUNCTION;
70 break;
71 case classdef:
72 ste->ste_type = TYPE_CLASS;
73 break;
74 case single_input:
75 case eval_input:
76 case file_input:
77 ste->ste_type = TYPE_MODULE;
78 break;
79 }
80
81 if (st->st_cur == NULL)
82 ste->ste_nested = 0;
83 else if (st->st_cur->ste_nested
84 || st->st_cur->ste_type == TYPE_FUNCTION)
85 ste->ste_nested = 1;
86 else
87 ste->ste_nested = 0;
88 ste->ste_child_free = 0;
Tim Peters5ca576e2001-06-18 22:08:13 +000089 ste->ste_generator = 0;
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +000090
91 if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0)
92 goto fail;
Jeremy Hylton74b3bc42001-02-23 17:55:27 +000093
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +000094 return (PyObject *)ste;
95 fail:
96 Py_XDECREF(ste);
97 return NULL;
98}
99
100static PyObject *
101ste_repr(PySymtableEntryObject *ste)
102{
103 char buf[256];
104
Barry Warsaw4b4ab202001-11-28 21:36:28 +0000105 PyOS_snprintf(buf, sizeof(buf),
106 "<symtable entry %.100s(%ld), line %d>",
107 PyString_AS_STRING(ste->ste_name),
108 PyInt_AS_LONG(ste->ste_id),
109 ste->ste_lineno);
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000110 return PyString_FromString(buf);
111}
112
113static void
114ste_dealloc(PySymtableEntryObject *ste)
115{
116 ste->ste_table = NULL;
117 Py_XDECREF(ste->ste_id);
118 Py_XDECREF(ste->ste_name);
119 Py_XDECREF(ste->ste_symbols);
120 Py_XDECREF(ste->ste_varnames);
121 Py_XDECREF(ste->ste_children);
122 PyObject_Del(ste);
123}
124
125#define OFF(x) offsetof(PySymtableEntryObject, x)
126
Guido van Rossum6f799372001-09-20 20:46:19 +0000127static PyMemberDef ste_memberlist[] = {
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000128 {"id", T_OBJECT, OFF(ste_id), READONLY},
129 {"name", T_OBJECT, OFF(ste_name), READONLY},
130 {"symbols", T_OBJECT, OFF(ste_symbols), READONLY},
131 {"varnames", T_OBJECT, OFF(ste_varnames), READONLY},
132 {"children", T_OBJECT, OFF(ste_children), READONLY},
133 {"type", T_INT, OFF(ste_type), READONLY},
134 {"lineno", T_INT, OFF(ste_lineno), READONLY},
135 {"optimized",T_INT, OFF(ste_optimized), READONLY},
136 {"nested", T_INT, OFF(ste_nested), READONLY},
137 {NULL}
138};
139
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000140PyTypeObject PySymtableEntry_Type = {
141 PyObject_HEAD_INIT(&PyType_Type)
142 0,
143 "symtable entry",
144 sizeof(PySymtableEntryObject),
145 0,
146 (destructor)ste_dealloc, /* tp_dealloc */
147 0, /* tp_print */
Guido van Rossum6f799372001-09-20 20:46:19 +0000148 0, /* tp_getattr */
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000149 0, /* tp_setattr */
150 0, /* tp_compare */
151 (reprfunc)ste_repr, /* tp_repr */
152 0, /* tp_as_number */
153 0, /* tp_as_sequence */
154 0, /* tp_as_mapping */
155 0, /* tp_hash */
156 0, /* tp_call */
157 0, /* tp_str */
Guido van Rossum6f799372001-09-20 20:46:19 +0000158 PyObject_GenericGetAttr, /* tp_getattro */
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000159 0, /* tp_setattro */
160 0, /* tp_as_buffer */
161 Py_TPFLAGS_DEFAULT, /* tp_flags */
162 0, /* tp_doc */
Guido van Rossum6f799372001-09-20 20:46:19 +0000163 0, /* tp_traverse */
164 0, /* tp_clear */
165 0, /* tp_richcompare */
166 0, /* tp_weaklistoffset */
167 0, /* tp_iter */
168 0, /* tp_iternext */
169 0, /* tp_methods */
170 ste_memberlist, /* tp_members */
171 0, /* tp_getset */
172 0, /* tp_base */
173 0, /* tp_dict */
174 0, /* tp_descr_get */
175 0, /* tp_descr_set */
176 0, /* tp_dictoffset */
177 0, /* tp_init */
178 0, /* tp_alloc */
179 0, /* tp_new */
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000180};