blob: edc60709b8646279f975794c37b2116982b3c6d9 [file] [log] [blame]
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001/* Class object implementation */
2
3#include <stdio.h>
4
5#include "PROTO.h"
6#include "node.h"
7#include "object.h"
8#include "stringobject.h"
9#include "tupleobject.h"
10#include "dictobject.h"
11#include "funcobject.h"
12#include "classobject.h"
13#include "objimpl.h"
Guido van Rossum3cf0ddf1990-10-14 19:58:09 +000014#include "errors.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000015
16typedef struct {
17 OB_HEAD
18 node *cl_tree; /* The entire classdef parse tree */
19 object *cl_bases; /* A tuple */
20 object *cl_methods; /* A dictionary */
21} classobject;
22
23object *
24newclassobject(tree, bases, methods)
25 node *tree;
26 object *bases; /* NULL or tuple of classobjects! */
27 object *methods;
28{
29 classobject *op;
30 op = NEWOBJ(classobject, &Classtype);
31 if (op == NULL)
32 return NULL;
33 op->cl_tree = tree;
34 if (bases != NULL)
35 INCREF(bases);
36 op->cl_bases = bases;
37 INCREF(methods);
38 op->cl_methods = methods;
39 return (object *) op;
40}
41
42/* Class methods */
43
44static void
45class_dealloc(op)
46 classobject *op;
47{
48 int i;
49 if (op->cl_bases != NULL)
50 DECREF(op->cl_bases);
51 DECREF(op->cl_methods);
52 free((ANY *)op);
53}
54
55static object *
56class_getattr(op, name)
57 register classobject *op;
58 register char *name;
59{
60 register object *v;
61 v = dictlookup(op->cl_methods, name);
62 if (v != NULL) {
63 INCREF(v);
64 return v;
65 }
66 if (op->cl_bases != NULL) {
67 int n = gettuplesize(op->cl_bases);
68 int i;
69 for (i = 0; i < n; i++) {
70 v = class_getattr(gettupleitem(op->cl_bases, i), name);
71 if (v != NULL)
72 return v;
73 }
74 }
Guido van Rossum3cf0ddf1990-10-14 19:58:09 +000075 err_setstr(NameError, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076 return NULL;
77}
78
79typeobject Classtype = {
80 OB_HEAD_INIT(&Typetype)
81 0,
82 "class",
83 sizeof(classobject),
84 0,
85 class_dealloc, /*tp_dealloc*/
86 0, /*tp_print*/
87 class_getattr, /*tp_getattr*/
88 0, /*tp_setattr*/
89 0, /*tp_compare*/
90 0, /*tp_repr*/
91 0, /*tp_as_number*/
92 0, /*tp_as_sequence*/
93 0, /*tp_as_mapping*/
94};
95
96
97/* We're not done yet: next, we define class member objects... */
98
99typedef struct {
100 OB_HEAD
101 classobject *cm_class; /* The class object */
102 object *cm_attr; /* A dictionary */
103} classmemberobject;
104
105object *
106newclassmemberobject(class)
107 register object *class;
108{
109 register classmemberobject *cm;
110 if (!is_classobject(class)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000111 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112 return NULL;
113 }
114 cm = NEWOBJ(classmemberobject, &Classmembertype);
115 if (cm == NULL)
116 return NULL;
117 INCREF(class);
118 cm->cm_class = (classobject *)class;
119 cm->cm_attr = newdictobject();
120 if (cm->cm_attr == NULL) {
121 DECREF(cm);
122 return NULL;
123 }
124 return (object *)cm;
125}
126
127/* Class member methods */
128
129static void
130classmember_dealloc(cm)
131 register classmemberobject *cm;
132{
133 DECREF(cm->cm_class);
134 if (cm->cm_attr != NULL)
135 DECREF(cm->cm_attr);
136 free((ANY *)cm);
137}
138
139static object *
140classmember_getattr(cm, name)
141 register classmemberobject *cm;
142 register char *name;
143{
144 register object *v = dictlookup(cm->cm_attr, name);
145 if (v != NULL) {
146 INCREF(v);
147 return v;
148 }
149 v = class_getattr(cm->cm_class, name);
150 if (v == NULL)
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000151 return v; /* class_getattr() has set the error */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152 if (is_funcobject(v)) {
153 object *w = newclassmethodobject(v, (object *)cm);
154 DECREF(v);
155 return w;
156 }
157 DECREF(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000158 err_setstr(NameError, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000159 return NULL;
160}
161
162static int
163classmember_setattr(cm, name, v)
164 classmemberobject *cm;
165 char *name;
166 object *v;
167{
168 if (v == NULL)
169 return dictremove(cm->cm_attr, name);
170 else
171 return dictinsert(cm->cm_attr, name, v);
172}
173
174typeobject Classmembertype = {
175 OB_HEAD_INIT(&Typetype)
176 0,
177 "class member",
178 sizeof(classmemberobject),
179 0,
180 classmember_dealloc, /*tp_dealloc*/
181 0, /*tp_print*/
182 classmember_getattr, /*tp_getattr*/
183 classmember_setattr, /*tp_setattr*/
184 0, /*tp_compare*/
185 0, /*tp_repr*/
186 0, /*tp_as_number*/
187 0, /*tp_as_sequence*/
188 0, /*tp_as_mapping*/
189};
190
191
192/* And finally, here are class method objects */
193/* (Really methods of class members) */
194
195typedef struct {
196 OB_HEAD
197 object *cm_func; /* The method function */
198 object *cm_self; /* The object to which this applies */
199} classmethodobject;
200
201object *
202newclassmethodobject(func, self)
203 object *func;
204 object *self;
205{
206 register classmethodobject *cm;
207 if (!is_funcobject(func)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000208 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209 return NULL;
210 }
211 cm = NEWOBJ(classmethodobject, &Classmethodtype);
212 if (cm == NULL)
213 return NULL;
214 INCREF(func);
215 cm->cm_func = func;
216 INCREF(self);
217 cm->cm_self = self;
218 return (object *)cm;
219}
220
221object *
222classmethodgetfunc(cm)
223 register object *cm;
224{
225 if (!is_classmethodobject(cm)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000226 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227 return NULL;
228 }
229 return ((classmethodobject *)cm)->cm_func;
230}
231
232object *
233classmethodgetself(cm)
234 register object *cm;
235{
236 if (!is_classmethodobject(cm)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000237 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000238 return NULL;
239 }
240 return ((classmethodobject *)cm)->cm_self;
241}
242
243/* Class method methods */
244
245static void
246classmethod_dealloc(cm)
247 register classmethodobject *cm;
248{
249 DECREF(cm->cm_func);
250 DECREF(cm->cm_self);
251 free((ANY *)cm);
252}
253
254typeobject Classmethodtype = {
255 OB_HEAD_INIT(&Typetype)
256 0,
257 "class method",
258 sizeof(classmethodobject),
259 0,
260 classmethod_dealloc, /*tp_dealloc*/
261 0, /*tp_print*/
262 0, /*tp_getattr*/
263 0, /*tp_setattr*/
264 0, /*tp_compare*/
265 0, /*tp_repr*/
266 0, /*tp_as_number*/
267 0, /*tp_as_sequence*/
268 0, /*tp_as_mapping*/
269};