blob: 23001af408f60d5c401e4f9fa2274a21ea1a120d [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;
Guido van Rossume2966a61991-12-10 13:53:23 +000045 if (bases == NULL) {
46 bases = newtupleobject(0);
47 if (bases == NULL)
48 return err_nomem();
49 }
50 else
51 INCREF(bases);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052 op = NEWOBJ(classobject, &Classtype);
Guido van Rossume2966a61991-12-10 13:53:23 +000053 if (op == NULL) {
54 DECREF(bases);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000055 return NULL;
Guido van Rossume2966a61991-12-10 13:53:23 +000056 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000057 op->cl_bases = bases;
58 INCREF(methods);
59 op->cl_methods = methods;
Guido van Rossum94308391991-10-20 20:11:48 +000060 XINCREF(name);
61 op->cl_name = name;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000062 return (object *) op;
63}
64
65/* Class methods */
66
67static void
68class_dealloc(op)
69 classobject *op;
70{
Guido van Rossume2966a61991-12-10 13:53:23 +000071 int i;
72 DECREF(op->cl_bases);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073 DECREF(op->cl_methods);
Guido van Rossum94308391991-10-20 20:11:48 +000074 XDECREF(op->cl_name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075 free((ANY *)op);
76}
77
78static object *
79class_getattr(op, name)
80 register classobject *op;
81 register char *name;
82{
83 register object *v;
Guido van Rossum94308391991-10-20 20:11:48 +000084 if (strcmp(name, "__dict__") == 0) {
85 INCREF(op->cl_methods);
86 return op->cl_methods;
87 }
88 if (strcmp(name, "__bases__") == 0) {
Guido van Rossum94308391991-10-20 20:11:48 +000089 INCREF(op->cl_bases);
90 return op->cl_bases;
91 }
92 if (strcmp(name, "__name__") == 0) {
93 if (op->cl_name == NULL)
94 v = None;
95 else
96 v = op->cl_name;
97 INCREF(v);
98 return v;
99 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100 v = dictlookup(op->cl_methods, name);
101 if (v != NULL) {
102 INCREF(v);
103 return v;
104 }
Guido van Rossume2966a61991-12-10 13:53:23 +0000105 {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000106 int n = gettuplesize(op->cl_bases);
107 int i;
108 for (i = 0; i < n; i++) {
109 v = class_getattr(gettupleitem(op->cl_bases, i), name);
110 if (v != NULL)
111 return v;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000112 err_clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113 }
114 }
Guido van Rossume2966a61991-12-10 13:53:23 +0000115 err_setstr(AttributeError, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000116 return NULL;
117}
118
Guido van Rossum94308391991-10-20 20:11:48 +0000119static int
120class_setattr(op, name, v)
121 classobject *op;
122 char *name;
123 object *v;
124{
125 if (v == NULL)
126 return dictremove(op->cl_methods, name);
127 else
128 return dictinsert(op->cl_methods, name, v);
129}
130
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000131typeobject Classtype = {
132 OB_HEAD_INIT(&Typetype)
133 0,
134 "class",
135 sizeof(classobject),
136 0,
137 class_dealloc, /*tp_dealloc*/
138 0, /*tp_print*/
139 class_getattr, /*tp_getattr*/
Guido van Rossum94308391991-10-20 20:11:48 +0000140 class_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000141 0, /*tp_compare*/
142 0, /*tp_repr*/
143 0, /*tp_as_number*/
144 0, /*tp_as_sequence*/
145 0, /*tp_as_mapping*/
146};
147
148
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000149/* We're not done yet: next, we define instance objects... */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000150
151typedef struct {
152 OB_HEAD
Guido van Rossume8122f11991-05-05 20:03:07 +0000153 classobject *in_class; /* The class object */
154 object *in_attr; /* A dictionary */
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000155} instanceobject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156
157object *
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000158newinstanceobject(class)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000159 register object *class;
160{
Guido van Rossume8122f11991-05-05 20:03:07 +0000161 register instanceobject *inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000162 if (!is_classobject(class)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000163 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000164 return NULL;
165 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000166 inst = NEWOBJ(instanceobject, &Instancetype);
167 if (inst == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168 return NULL;
169 INCREF(class);
Guido van Rossume8122f11991-05-05 20:03:07 +0000170 inst->in_class = (classobject *)class;
171 inst->in_attr = newdictobject();
172 if (inst->in_attr == NULL) {
173 DECREF(inst);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000174 return NULL;
175 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000176 return (object *)inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000177}
178
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000179/* Instance methods */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000180
181static void
Guido van Rossume8122f11991-05-05 20:03:07 +0000182instance_dealloc(inst)
183 register instanceobject *inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000184{
Guido van Rossume8122f11991-05-05 20:03:07 +0000185 DECREF(inst->in_class);
186 if (inst->in_attr != NULL)
187 DECREF(inst->in_attr);
188 free((ANY *)inst);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000189}
190
191static object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000192instance_getattr(inst, name)
193 register instanceobject *inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000194 register char *name;
195{
Guido van Rossum94308391991-10-20 20:11:48 +0000196 register object *v;
197 if (strcmp(name, "__dict__") == 0) {
198 INCREF(inst->in_attr);
199 return inst->in_attr;
200 }
201 if (strcmp(name, "__class__") == 0) {
202 INCREF(inst->in_class);
203 return (object *)inst->in_class;
204 }
205 v = dictlookup(inst->in_attr, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000206 if (v != NULL) {
207 INCREF(v);
208 return v;
209 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000210 v = class_getattr(inst->in_class, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000211 if (v == NULL)
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000212 return v; /* class_getattr() has set the error */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213 if (is_funcobject(v)) {
Guido van Rossume8122f11991-05-05 20:03:07 +0000214 object *w = newinstancemethodobject(v, (object *)inst);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000215 DECREF(v);
216 return w;
217 }
218 DECREF(v);
Guido van Rossume2966a61991-12-10 13:53:23 +0000219 err_setstr(AttributeError, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000220 return NULL;
221}
222
223static int
Guido van Rossume8122f11991-05-05 20:03:07 +0000224instance_setattr(inst, name, v)
225 instanceobject *inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226 char *name;
227 object *v;
228{
229 if (v == NULL)
Guido van Rossume8122f11991-05-05 20:03:07 +0000230 return dictremove(inst->in_attr, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000231 else
Guido van Rossume8122f11991-05-05 20:03:07 +0000232 return dictinsert(inst->in_attr, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000233}
234
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000235typeobject Instancetype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236 OB_HEAD_INIT(&Typetype)
237 0,
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000238 "instance",
239 sizeof(instanceobject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000240 0,
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000241 instance_dealloc, /*tp_dealloc*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000242 0, /*tp_print*/
Guido van Rossum21ed88c1991-04-04 10:42:10 +0000243 instance_getattr, /*tp_getattr*/
244 instance_setattr, /*tp_setattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000245 0, /*tp_compare*/
246 0, /*tp_repr*/
247 0, /*tp_as_number*/
248 0, /*tp_as_sequence*/
249 0, /*tp_as_mapping*/
250};
251
252
Guido van Rossum94308391991-10-20 20:11:48 +0000253/* And finally, here are instance method objects */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000254
255typedef struct {
256 OB_HEAD
Guido van Rossume8122f11991-05-05 20:03:07 +0000257 object *im_func; /* The method function */
258 object *im_self; /* The object to which this applies */
259} instancemethodobject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000260
261object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000262newinstancemethodobject(func, self)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000263 object *func;
264 object *self;
265{
Guido van Rossume8122f11991-05-05 20:03:07 +0000266 register instancemethodobject *im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000267 if (!is_funcobject(func)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000268 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000269 return NULL;
270 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000271 im = NEWOBJ(instancemethodobject, &Instancemethodtype);
272 if (im == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000273 return NULL;
274 INCREF(func);
Guido van Rossume8122f11991-05-05 20:03:07 +0000275 im->im_func = func;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000276 INCREF(self);
Guido van Rossume8122f11991-05-05 20:03:07 +0000277 im->im_self = self;
278 return (object *)im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000279}
280
281object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000282instancemethodgetfunc(im)
283 register object *im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284{
Guido van Rossume8122f11991-05-05 20:03:07 +0000285 if (!is_instancemethodobject(im)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000286 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000287 return NULL;
288 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000289 return ((instancemethodobject *)im)->im_func;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290}
291
292object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000293instancemethodgetself(im)
294 register object *im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000295{
Guido van Rossume8122f11991-05-05 20:03:07 +0000296 if (!is_instancemethodobject(im)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000297 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000298 return NULL;
299 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000300 return ((instancemethodobject *)im)->im_self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000301}
302
303/* Class method methods */
304
Guido van Rossume8122f11991-05-05 20:03:07 +0000305#define OFF(x) offsetof(instancemethodobject, x)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000306
Guido van Rossume8122f11991-05-05 20:03:07 +0000307static struct memberlist instancemethod_memberlist[] = {
308 {"im_func", T_OBJECT, OFF(im_func)},
309 {"im_self", T_OBJECT, OFF(im_self)},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000310 {NULL} /* Sentinel */
311};
312
313static object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000314instancemethod_getattr(im, name)
315 register instancemethodobject *im;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000316 char *name;
317{
Guido van Rossume8122f11991-05-05 20:03:07 +0000318 return getmember((char *)im, instancemethod_memberlist, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000319}
320
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000321static void
Guido van Rossume8122f11991-05-05 20:03:07 +0000322instancemethod_dealloc(im)
323 register instancemethodobject *im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000324{
Guido van Rossume8122f11991-05-05 20:03:07 +0000325 DECREF(im->im_func);
326 DECREF(im->im_self);
327 free((ANY *)im);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000328}
329
Guido van Rossume8122f11991-05-05 20:03:07 +0000330typeobject Instancemethodtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331 OB_HEAD_INIT(&Typetype)
332 0,
Guido van Rossum569fce71991-04-16 08:38:43 +0000333 "instance method",
Guido van Rossume8122f11991-05-05 20:03:07 +0000334 sizeof(instancemethodobject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000335 0,
Guido van Rossume8122f11991-05-05 20:03:07 +0000336 instancemethod_dealloc, /*tp_dealloc*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337 0, /*tp_print*/
Guido van Rossume8122f11991-05-05 20:03:07 +0000338 instancemethod_getattr, /*tp_getattr*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000339 0, /*tp_setattr*/
340 0, /*tp_compare*/
341 0, /*tp_repr*/
342 0, /*tp_as_number*/
343 0, /*tp_as_sequence*/
344 0, /*tp_as_mapping*/
345};