blob: 89cb3f7406b1b0ae5f9a8b131bbf013e852de89a [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000025/* Class object implementation */
26
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
Guido van Rossum3f5da241990-12-20 15:06:42 +000029#include "structmember.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000030
31typedef struct {
32 OB_HEAD
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000033 object *cl_bases; /* A tuple */
34 object *cl_methods; /* A dictionary */
35} classobject;
36
37object *
Guido van Rossum3f5da241990-12-20 15:06:42 +000038newclassobject(bases, methods)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000039 object *bases; /* NULL or tuple of classobjects! */
40 object *methods;
41{
42 classobject *op;
43 op = NEWOBJ(classobject, &Classtype);
44 if (op == NULL)
45 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046 if (bases != NULL)
47 INCREF(bases);
48 op->cl_bases = bases;
49 INCREF(methods);
50 op->cl_methods = methods;
51 return (object *) op;
52}
53
54/* Class methods */
55
56static void
57class_dealloc(op)
58 classobject *op;
59{
60 int i;
61 if (op->cl_bases != NULL)
62 DECREF(op->cl_bases);
63 DECREF(op->cl_methods);
64 free((ANY *)op);
65}
66
67static object *
68class_getattr(op, name)
69 register classobject *op;
70 register char *name;
71{
72 register object *v;
73 v = dictlookup(op->cl_methods, name);
74 if (v != NULL) {
75 INCREF(v);
76 return v;
77 }
78 if (op->cl_bases != NULL) {
79 int n = gettuplesize(op->cl_bases);
80 int i;
81 for (i = 0; i < n; i++) {
82 v = class_getattr(gettupleitem(op->cl_bases, i), name);
83 if (v != NULL)
84 return v;
Guido van Rossum3f5da241990-12-20 15:06:42 +000085 err_clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000086 }
87 }
Guido van Rossum3cf0ddf1990-10-14 19:58:09 +000088 err_setstr(NameError, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000089 return NULL;
90}
91
92typeobject Classtype = {
93 OB_HEAD_INIT(&Typetype)
94 0,
95 "class",
96 sizeof(classobject),
97 0,
98 class_dealloc, /*tp_dealloc*/
99 0, /*tp_print*/
100 class_getattr, /*tp_getattr*/
101 0, /*tp_setattr*/
102 0, /*tp_compare*/
103 0, /*tp_repr*/
104 0, /*tp_as_number*/
105 0, /*tp_as_sequence*/
106 0, /*tp_as_mapping*/
107};
108
109
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000110/* We're not done yet: next, we define instance objects... */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000111
112typedef struct {
113 OB_HEAD
114 classobject *cm_class; /* The class object */
115 object *cm_attr; /* A dictionary */
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000116} instanceobject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000117
118object *
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000119newinstanceobject(class)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000120 register object *class;
121{
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000122 register instanceobject *cm;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000123 if (!is_classobject(class)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000124 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125 return NULL;
126 }
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000127 cm = NEWOBJ(instanceobject, &Instancetype);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000128 if (cm == NULL)
129 return NULL;
130 INCREF(class);
131 cm->cm_class = (classobject *)class;
132 cm->cm_attr = newdictobject();
133 if (cm->cm_attr == NULL) {
134 DECREF(cm);
135 return NULL;
136 }
137 return (object *)cm;
138}
139
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000140/* Instance methods */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000141
142static void
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000143instance_dealloc(cm)
144 register instanceobject *cm;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000145{
146 DECREF(cm->cm_class);
147 if (cm->cm_attr != NULL)
148 DECREF(cm->cm_attr);
149 free((ANY *)cm);
150}
151
152static object *
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000153instance_getattr(cm, name)
154 register instanceobject *cm;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155 register char *name;
156{
157 register object *v = dictlookup(cm->cm_attr, name);
158 if (v != NULL) {
159 INCREF(v);
160 return v;
161 }
162 v = class_getattr(cm->cm_class, name);
163 if (v == NULL)
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000164 return v; /* class_getattr() has set the error */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000165 if (is_funcobject(v)) {
166 object *w = newclassmethodobject(v, (object *)cm);
167 DECREF(v);
168 return w;
169 }
170 DECREF(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000171 err_setstr(NameError, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172 return NULL;
173}
174
175static int
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000176instance_setattr(cm, name, v)
177 instanceobject *cm;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178 char *name;
179 object *v;
180{
181 if (v == NULL)
182 return dictremove(cm->cm_attr, name);
183 else
184 return dictinsert(cm->cm_attr, name, v);
185}
186
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000187typeobject Instancetype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188 OB_HEAD_INIT(&Typetype)
189 0,
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000190 "instance",
191 sizeof(instanceobject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000192 0,
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000193 instance_dealloc, /*tp_dealloc*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194 0, /*tp_print*/
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000195 instance_getattr, /*tp_getattr*/
196 instance_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 0, /*tp_compare*/
198 0, /*tp_repr*/
199 0, /*tp_as_number*/
200 0, /*tp_as_sequence*/
201 0, /*tp_as_mapping*/
202};
203
204
Guido van Rossum569fce71991-04-16 08:38:43 +0000205/* And finally, here are instance method objects
206 (accidentally called class methods) */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000207
208typedef struct {
209 OB_HEAD
210 object *cm_func; /* The method function */
211 object *cm_self; /* The object to which this applies */
212} classmethodobject;
213
214object *
215newclassmethodobject(func, self)
216 object *func;
217 object *self;
218{
219 register classmethodobject *cm;
220 if (!is_funcobject(func)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000221 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000222 return NULL;
223 }
224 cm = NEWOBJ(classmethodobject, &Classmethodtype);
225 if (cm == NULL)
226 return NULL;
227 INCREF(func);
228 cm->cm_func = func;
229 INCREF(self);
230 cm->cm_self = self;
231 return (object *)cm;
232}
233
234object *
235classmethodgetfunc(cm)
236 register object *cm;
237{
238 if (!is_classmethodobject(cm)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000239 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000240 return NULL;
241 }
242 return ((classmethodobject *)cm)->cm_func;
243}
244
245object *
246classmethodgetself(cm)
247 register object *cm;
248{
249 if (!is_classmethodobject(cm)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000250 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251 return NULL;
252 }
253 return ((classmethodobject *)cm)->cm_self;
254}
255
256/* Class method methods */
257
Guido van Rossum3f5da241990-12-20 15:06:42 +0000258#define OFF(x) offsetof(classmethodobject, x)
259
260static struct memberlist classmethod_memberlist[] = {
261 {"cm_func", T_OBJECT, OFF(cm_func)},
262 {"cm_self", T_OBJECT, OFF(cm_self)},
263 {NULL} /* Sentinel */
264};
265
266static object *
267classmethod_getattr(cm, name)
268 register classmethodobject *cm;
269 char *name;
270{
271 return getmember((char *)cm, classmethod_memberlist, name);
272}
273
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274static void
275classmethod_dealloc(cm)
276 register classmethodobject *cm;
277{
278 DECREF(cm->cm_func);
279 DECREF(cm->cm_self);
280 free((ANY *)cm);
281}
282
283typeobject Classmethodtype = {
284 OB_HEAD_INIT(&Typetype)
285 0,
Guido van Rossum569fce71991-04-16 08:38:43 +0000286 "instance method",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287 sizeof(classmethodobject),
288 0,
289 classmethod_dealloc, /*tp_dealloc*/
290 0, /*tp_print*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000291 classmethod_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292 0, /*tp_setattr*/
293 0, /*tp_compare*/
294 0, /*tp_repr*/
295 0, /*tp_as_number*/
296 0, /*tp_as_sequence*/
297 0, /*tp_as_mapping*/
298};