blob: ad4f627f07fb6f3c3381b296c1f4bac35ff0d602 [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 */
Guido van Rossum94308391991-10-20 20:11:48 +000035 object *cl_name; /* A string */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036} classobject;
37
38object *
Guido van Rossum94308391991-10-20 20:11:48 +000039newclassobject(bases, methods, name)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000040 object *bases; /* NULL or tuple of classobjects! */
41 object *methods;
Guido van Rossum94308391991-10-20 20:11:48 +000042 object *name; /* String; NULL if unknown */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000043{
44 classobject *op;
45 op = NEWOBJ(classobject, &Classtype);
46 if (op == NULL)
47 return NULL;
Guido van Rossum94308391991-10-20 20:11:48 +000048 XINCREF(bases);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000049 op->cl_bases = bases;
50 INCREF(methods);
51 op->cl_methods = methods;
Guido van Rossum94308391991-10-20 20:11:48 +000052 XINCREF(name);
53 op->cl_name = name;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000054 return (object *) op;
55}
56
57/* Class methods */
58
59static void
60class_dealloc(op)
61 classobject *op;
62{
63 int i;
Guido van Rossum94308391991-10-20 20:11:48 +000064 XDECREF(op->cl_bases);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000065 DECREF(op->cl_methods);
Guido van Rossum94308391991-10-20 20:11:48 +000066 XDECREF(op->cl_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067 free((ANY *)op);
68}
69
70static object *
71class_getattr(op, name)
72 register classobject *op;
73 register char *name;
74{
75 register object *v;
Guido van Rossum94308391991-10-20 20:11:48 +000076 if (strcmp(name, "__dict__") == 0) {
77 INCREF(op->cl_methods);
78 return op->cl_methods;
79 }
80 if (strcmp(name, "__bases__") == 0) {
81 if (op->cl_bases == NULL)
82 return newtupleobject(0);
83 INCREF(op->cl_bases);
84 return op->cl_bases;
85 }
86 if (strcmp(name, "__name__") == 0) {
87 if (op->cl_name == NULL)
88 v = None;
89 else
90 v = op->cl_name;
91 INCREF(v);
92 return v;
93 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094 v = dictlookup(op->cl_methods, name);
95 if (v != NULL) {
96 INCREF(v);
97 return v;
98 }
99 if (op->cl_bases != NULL) {
100 int n = gettuplesize(op->cl_bases);
101 int i;
102 for (i = 0; i < n; i++) {
103 v = class_getattr(gettupleitem(op->cl_bases, i), name);
104 if (v != NULL)
105 return v;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000106 err_clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107 }
108 }
Guido van Rossum3cf0ddf1990-10-14 19:58:09 +0000109 err_setstr(NameError, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 return NULL;
111}
112
Guido van Rossum94308391991-10-20 20:11:48 +0000113static int
114class_setattr(op, name, v)
115 classobject *op;
116 char *name;
117 object *v;
118{
119 if (v == NULL)
120 return dictremove(op->cl_methods, name);
121 else
122 return dictinsert(op->cl_methods, name, v);
123}
124
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000125typeobject Classtype = {
126 OB_HEAD_INIT(&Typetype)
127 0,
128 "class",
129 sizeof(classobject),
130 0,
131 class_dealloc, /*tp_dealloc*/
132 0, /*tp_print*/
133 class_getattr, /*tp_getattr*/
Guido van Rossum94308391991-10-20 20:11:48 +0000134 class_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135 0, /*tp_compare*/
136 0, /*tp_repr*/
137 0, /*tp_as_number*/
138 0, /*tp_as_sequence*/
139 0, /*tp_as_mapping*/
140};
141
142
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000143/* We're not done yet: next, we define instance objects... */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000144
145typedef struct {
146 OB_HEAD
Guido van Rossume8122f11991-05-05 20:03:07 +0000147 classobject *in_class; /* The class object */
148 object *in_attr; /* A dictionary */
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000149} instanceobject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000150
151object *
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000152newinstanceobject(class)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000153 register object *class;
154{
Guido van Rossume8122f11991-05-05 20:03:07 +0000155 register instanceobject *inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156 if (!is_classobject(class)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000157 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000158 return NULL;
159 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000160 inst = NEWOBJ(instanceobject, &Instancetype);
161 if (inst == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162 return NULL;
163 INCREF(class);
Guido van Rossume8122f11991-05-05 20:03:07 +0000164 inst->in_class = (classobject *)class;
165 inst->in_attr = newdictobject();
166 if (inst->in_attr == NULL) {
167 DECREF(inst);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168 return NULL;
169 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000170 return (object *)inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171}
172
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000173/* Instance methods */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174
175static void
Guido van Rossume8122f11991-05-05 20:03:07 +0000176instance_dealloc(inst)
177 register instanceobject *inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178{
Guido van Rossume8122f11991-05-05 20:03:07 +0000179 DECREF(inst->in_class);
180 if (inst->in_attr != NULL)
181 DECREF(inst->in_attr);
182 free((ANY *)inst);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000183}
184
185static object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000186instance_getattr(inst, name)
187 register instanceobject *inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000188 register char *name;
189{
Guido van Rossum94308391991-10-20 20:11:48 +0000190 register object *v;
191 if (strcmp(name, "__dict__") == 0) {
192 INCREF(inst->in_attr);
193 return inst->in_attr;
194 }
195 if (strcmp(name, "__class__") == 0) {
196 INCREF(inst->in_class);
197 return (object *)inst->in_class;
198 }
199 v = dictlookup(inst->in_attr, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200 if (v != NULL) {
201 INCREF(v);
202 return v;
203 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000204 v = class_getattr(inst->in_class, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205 if (v == NULL)
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000206 return v; /* class_getattr() has set the error */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000207 if (is_funcobject(v)) {
Guido van Rossume8122f11991-05-05 20:03:07 +0000208 object *w = newinstancemethodobject(v, (object *)inst);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000209 DECREF(v);
210 return w;
211 }
212 DECREF(v);
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000213 err_setstr(NameError, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000214 return NULL;
215}
216
217static int
Guido van Rossume8122f11991-05-05 20:03:07 +0000218instance_setattr(inst, name, v)
219 instanceobject *inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000220 char *name;
221 object *v;
222{
223 if (v == NULL)
Guido van Rossume8122f11991-05-05 20:03:07 +0000224 return dictremove(inst->in_attr, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000225 else
Guido van Rossume8122f11991-05-05 20:03:07 +0000226 return dictinsert(inst->in_attr, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000227}
228
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000229typeobject Instancetype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000230 OB_HEAD_INIT(&Typetype)
231 0,
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000232 "instance",
233 sizeof(instanceobject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234 0,
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000235 instance_dealloc, /*tp_dealloc*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236 0, /*tp_print*/
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000237 instance_getattr, /*tp_getattr*/
238 instance_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000239 0, /*tp_compare*/
240 0, /*tp_repr*/
241 0, /*tp_as_number*/
242 0, /*tp_as_sequence*/
243 0, /*tp_as_mapping*/
244};
245
246
Guido van Rossum94308391991-10-20 20:11:48 +0000247/* And finally, here are instance method objects */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000248
249typedef struct {
250 OB_HEAD
Guido van Rossume8122f11991-05-05 20:03:07 +0000251 object *im_func; /* The method function */
252 object *im_self; /* The object to which this applies */
253} instancemethodobject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000254
255object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000256newinstancemethodobject(func, self)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000257 object *func;
258 object *self;
259{
Guido van Rossume8122f11991-05-05 20:03:07 +0000260 register instancemethodobject *im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000261 if (!is_funcobject(func)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000262 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263 return NULL;
264 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000265 im = NEWOBJ(instancemethodobject, &Instancemethodtype);
266 if (im == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000267 return NULL;
268 INCREF(func);
Guido van Rossume8122f11991-05-05 20:03:07 +0000269 im->im_func = func;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000270 INCREF(self);
Guido van Rossume8122f11991-05-05 20:03:07 +0000271 im->im_self = self;
272 return (object *)im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000273}
274
275object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000276instancemethodgetfunc(im)
277 register object *im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000278{
Guido van Rossume8122f11991-05-05 20:03:07 +0000279 if (!is_instancemethodobject(im)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000280 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281 return NULL;
282 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000283 return ((instancemethodobject *)im)->im_func;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284}
285
286object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000287instancemethodgetself(im)
288 register object *im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289{
Guido van Rossume8122f11991-05-05 20:03:07 +0000290 if (!is_instancemethodobject(im)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000291 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292 return NULL;
293 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000294 return ((instancemethodobject *)im)->im_self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295}
296
297/* Class method methods */
298
Guido van Rossume8122f11991-05-05 20:03:07 +0000299#define OFF(x) offsetof(instancemethodobject, x)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000300
Guido van Rossume8122f11991-05-05 20:03:07 +0000301static struct memberlist instancemethod_memberlist[] = {
302 {"im_func", T_OBJECT, OFF(im_func)},
303 {"im_self", T_OBJECT, OFF(im_self)},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000304 {NULL} /* Sentinel */
305};
306
307static object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000308instancemethod_getattr(im, name)
309 register instancemethodobject *im;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000310 char *name;
311{
Guido van Rossume8122f11991-05-05 20:03:07 +0000312 return getmember((char *)im, instancemethod_memberlist, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000313}
314
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000315static void
Guido van Rossume8122f11991-05-05 20:03:07 +0000316instancemethod_dealloc(im)
317 register instancemethodobject *im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000318{
Guido van Rossume8122f11991-05-05 20:03:07 +0000319 DECREF(im->im_func);
320 DECREF(im->im_self);
321 free((ANY *)im);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322}
323
Guido van Rossume8122f11991-05-05 20:03:07 +0000324typeobject Instancemethodtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000325 OB_HEAD_INIT(&Typetype)
326 0,
Guido van Rossum569fce71991-04-16 08:38:43 +0000327 "instance method",
Guido van Rossume8122f11991-05-05 20:03:07 +0000328 sizeof(instancemethodobject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000329 0,
Guido van Rossume8122f11991-05-05 20:03:07 +0000330 instancemethod_dealloc, /*tp_dealloc*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331 0, /*tp_print*/
Guido van Rossume8122f11991-05-05 20:03:07 +0000332 instancemethod_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000333 0, /*tp_setattr*/
334 0, /*tp_compare*/
335 0, /*tp_repr*/
336 0, /*tp_as_number*/
337 0, /*tp_as_sequence*/
338 0, /*tp_as_mapping*/
339};