blob: e48eaea1d547ca2e0815d7f7620fe4d4628417ee [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 Hyltoncb17ae82001-02-09 22:22:18 +000064 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;
78 }
79
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;
Tim Peters5ca576e2001-06-18 22:08:13 +000088 ste->ste_generator = 0;
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +000089
90 if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0)
91 goto fail;
Jeremy Hylton74b3bc42001-02-23 17:55:27 +000092
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +000093 return (PyObject *)ste;
94 fail:
95 Py_XDECREF(ste);
96 return NULL;
97}
98
99static PyObject *
100ste_repr(PySymtableEntryObject *ste)
101{
102 char buf[256];
103
Barry Warsaw4b4ab202001-11-28 21:36:28 +0000104 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);
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000109 return PyString_FromString(buf);
110}
111
112static void
113ste_dealloc(PySymtableEntryObject *ste)
114{
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);
122}
123
124#define OFF(x) offsetof(PySymtableEntryObject, x)
125
Guido van Rossum6f799372001-09-20 20:46:19 +0000126static PyMemberDef ste_memberlist[] = {
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000127 {"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}
137};
138
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000139PyTypeObject PySymtableEntry_Type = {
140 PyObject_HEAD_INIT(&PyType_Type)
141 0,
142 "symtable entry",
143 sizeof(PySymtableEntryObject),
144 0,
145 (destructor)ste_dealloc, /* tp_dealloc */
146 0, /* tp_print */
Guido van Rossum6f799372001-09-20 20:46:19 +0000147 0, /* tp_getattr */
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000148 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 */
Guido van Rossum6f799372001-09-20 20:46:19 +0000157 PyObject_GenericGetAttr, /* tp_getattro */
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000158 0, /* tp_setattro */
159 0, /* tp_as_buffer */
160 Py_TPFLAGS_DEFAULT, /* tp_flags */
161 0, /* tp_doc */
Guido van Rossum6f799372001-09-20 20:46:19 +0000162 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 */
Jeremy Hyltoncb17ae82001-02-09 22:22:18 +0000179};