symtable.c revision cb17ae8b19c35cc63e7daec871c025d903c49105
1#include "Python.h"
2#include "symtable.h"
3#include "graminit.h"
4#include "structmember.h"
5
6PyObject *
7PySymtableEntry_New(struct symtable *st, char *name, int type, int lineno)
8{
9	PySymtableEntryObject *ste = NULL;
10	PyObject *k, *v;
11
12	k = PyInt_FromLong(st->st_nscopes++);
13	if (k == NULL)
14		goto fail;
15	v = PyDict_GetItem(st->st_symbols, k);
16	if (v) /* XXX could check that name, type, lineno match */
17	    return v;
18
19	ste = (PySymtableEntryObject *)PyObject_New(PySymtableEntryObject,
20						    &PySymtableEntry_Type);
21	ste->ste_table = st;
22	ste->ste_id = k;
23
24	v = PyString_FromString(name);
25	if (v == NULL)
26		goto fail;
27	ste->ste_name = v;
28
29	v = PyDict_New();
30	if (v == NULL)
31	    goto fail;
32	ste->ste_symbols = v;
33
34	v = PyList_New(0);
35	if (v == NULL)
36	    goto fail;
37	ste->ste_varnames = v;
38
39	v = PyList_New(0);
40	if (v == NULL)
41	    goto fail;
42	ste->ste_children = v;
43
44	ste->ste_optimized = 1;
45	ste->ste_lineno = lineno;
46	switch (type) {
47	case funcdef:
48	case lambdef:
49		ste->ste_type = TYPE_FUNCTION;
50		break;
51	case classdef:
52		ste->ste_type = TYPE_CLASS;
53		break;
54	case single_input:
55	case eval_input:
56	case file_input:
57		ste->ste_type = TYPE_MODULE;
58		break;
59	}
60
61	if (st->st_cur == NULL)
62		ste->ste_nested = 0;
63	else if (st->st_cur->ste_nested
64		 || st->st_cur->ste_type == TYPE_FUNCTION)
65		ste->ste_nested = 1;
66	else
67		ste->ste_nested = 0;
68	ste->ste_child_free = 0;
69
70	if (PyDict_SetItem(st->st_symbols, ste->ste_id, (PyObject *)ste) < 0)
71	    goto fail;
72
73	return (PyObject *)ste;
74 fail:
75	Py_XDECREF(ste);
76	return NULL;
77}
78
79static PyObject *
80ste_repr(PySymtableEntryObject *ste)
81{
82	char buf[256];
83
84	sprintf(buf, "<symtable entry %.100s(%ld), line %d>",
85		PyString_AS_STRING(ste->ste_name),
86		PyInt_AS_LONG(ste->ste_id),
87		ste->ste_lineno);
88	return PyString_FromString(buf);
89}
90
91static void
92ste_dealloc(PySymtableEntryObject *ste)
93{
94	ste->ste_table = NULL;
95	Py_XDECREF(ste->ste_id);
96	Py_XDECREF(ste->ste_name);
97	Py_XDECREF(ste->ste_symbols);
98	Py_XDECREF(ste->ste_varnames);
99	Py_XDECREF(ste->ste_children);
100	PyObject_Del(ste);
101}
102
103#define OFF(x) offsetof(PySymtableEntryObject, x)
104
105static struct memberlist ste_memberlist[] = {
106	{"id",       T_OBJECT, OFF(ste_id), READONLY},
107	{"name",     T_OBJECT, OFF(ste_name), READONLY},
108	{"symbols",  T_OBJECT, OFF(ste_symbols), READONLY},
109	{"varnames", T_OBJECT, OFF(ste_varnames), READONLY},
110	{"children", T_OBJECT, OFF(ste_children), READONLY},
111	{"type",     T_INT,    OFF(ste_type), READONLY},
112	{"lineno",   T_INT,    OFF(ste_lineno), READONLY},
113	{"optimized",T_INT,    OFF(ste_optimized), READONLY},
114	{"nested",   T_INT,    OFF(ste_nested), READONLY},
115	{NULL}
116};
117
118static PyObject *
119ste_getattr(PySymtableEntryObject *ste, char *name)
120{
121	return PyMember_Get((char *)ste, ste_memberlist, name);
122}
123
124PyTypeObject PySymtableEntry_Type = {
125	PyObject_HEAD_INIT(&PyType_Type)
126	0,
127	"symtable entry",
128	sizeof(PySymtableEntryObject),
129	0,
130	(destructor)ste_dealloc,                /* tp_dealloc */
131	0,                                      /* tp_print */
132	(getattrfunc)ste_getattr,               /* tp_getattr */
133	0,					/* tp_setattr */
134	0,			                /* tp_compare */
135	(reprfunc)ste_repr,			/* tp_repr */
136	0,					/* tp_as_number */
137	0,			                /* tp_as_sequence */
138	0,					/* tp_as_mapping */
139	0,					/* tp_hash */
140	0,					/* tp_call */
141	0,					/* tp_str */
142	0,					/* tp_getattro */
143	0,					/* tp_setattro */
144	0,					/* tp_as_buffer */
145	Py_TPFLAGS_DEFAULT,	                /* tp_flags */
146 	0,					/* tp_doc */
147};
148