blob: 6b38dfce8e0c5d0a605a549a78cd2501b7d7111c [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
Guido van Rossume8122f11991-05-05 20:03:07 +0000114 classobject *in_class; /* The class object */
115 object *in_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 Rossume8122f11991-05-05 20:03:07 +0000122 register instanceobject *inst;
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 Rossume8122f11991-05-05 20:03:07 +0000127 inst = NEWOBJ(instanceobject, &Instancetype);
128 if (inst == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000129 return NULL;
130 INCREF(class);
Guido van Rossume8122f11991-05-05 20:03:07 +0000131 inst->in_class = (classobject *)class;
132 inst->in_attr = newdictobject();
133 if (inst->in_attr == NULL) {
134 DECREF(inst);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000135 return NULL;
136 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000137 return (object *)inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000138}
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 Rossume8122f11991-05-05 20:03:07 +0000143instance_dealloc(inst)
144 register instanceobject *inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000145{
Guido van Rossume8122f11991-05-05 20:03:07 +0000146 DECREF(inst->in_class);
147 if (inst->in_attr != NULL)
148 DECREF(inst->in_attr);
149 free((ANY *)inst);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000150}
151
152static object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000153instance_getattr(inst, name)
154 register instanceobject *inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155 register char *name;
156{
Guido van Rossume8122f11991-05-05 20:03:07 +0000157 register object *v = dictlookup(inst->in_attr, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000158 if (v != NULL) {
159 INCREF(v);
160 return v;
161 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000162 v = class_getattr(inst->in_class, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163 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)) {
Guido van Rossume8122f11991-05-05 20:03:07 +0000166 object *w = newinstancemethodobject(v, (object *)inst);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000167 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 Rossume8122f11991-05-05 20:03:07 +0000176instance_setattr(inst, name, v)
177 instanceobject *inst;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000178 char *name;
179 object *v;
180{
181 if (v == NULL)
Guido van Rossume8122f11991-05-05 20:03:07 +0000182 return dictremove(inst->in_attr, name);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000183 else
Guido van Rossume8122f11991-05-05 20:03:07 +0000184 return dictinsert(inst->in_attr, name, v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000185}
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
Guido van Rossume8122f11991-05-05 20:03:07 +0000210 object *im_func; /* The method function */
211 object *im_self; /* The object to which this applies */
212} instancemethodobject;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213
214object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000215newinstancemethodobject(func, self)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000216 object *func;
217 object *self;
218{
Guido van Rossume8122f11991-05-05 20:03:07 +0000219 register instancemethodobject *im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000220 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 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000224 im = NEWOBJ(instancemethodobject, &Instancemethodtype);
225 if (im == NULL)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000226 return NULL;
227 INCREF(func);
Guido van Rossume8122f11991-05-05 20:03:07 +0000228 im->im_func = func;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000229 INCREF(self);
Guido van Rossume8122f11991-05-05 20:03:07 +0000230 im->im_self = self;
231 return (object *)im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000232}
233
234object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000235instancemethodgetfunc(im)
236 register object *im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000237{
Guido van Rossume8122f11991-05-05 20:03:07 +0000238 if (!is_instancemethodobject(im)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000239 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000240 return NULL;
241 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000242 return ((instancemethodobject *)im)->im_func;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000243}
244
245object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000246instancemethodgetself(im)
247 register object *im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000248{
Guido van Rossume8122f11991-05-05 20:03:07 +0000249 if (!is_instancemethodobject(im)) {
Guido van Rossum2a9096b1990-10-21 22:15:08 +0000250 err_badcall();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000251 return NULL;
252 }
Guido van Rossume8122f11991-05-05 20:03:07 +0000253 return ((instancemethodobject *)im)->im_self;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000254}
255
256/* Class method methods */
257
Guido van Rossume8122f11991-05-05 20:03:07 +0000258#define OFF(x) offsetof(instancemethodobject, x)
Guido van Rossum3f5da241990-12-20 15:06:42 +0000259
Guido van Rossume8122f11991-05-05 20:03:07 +0000260static struct memberlist instancemethod_memberlist[] = {
261 {"im_func", T_OBJECT, OFF(im_func)},
262 {"im_self", T_OBJECT, OFF(im_self)},
Guido van Rossum3f5da241990-12-20 15:06:42 +0000263 {NULL} /* Sentinel */
264};
265
266static object *
Guido van Rossume8122f11991-05-05 20:03:07 +0000267instancemethod_getattr(im, name)
268 register instancemethodobject *im;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000269 char *name;
270{
Guido van Rossume8122f11991-05-05 20:03:07 +0000271 return getmember((char *)im, instancemethod_memberlist, name);
Guido van Rossum3f5da241990-12-20 15:06:42 +0000272}
273
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000274static void
Guido van Rossume8122f11991-05-05 20:03:07 +0000275instancemethod_dealloc(im)
276 register instancemethodobject *im;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000277{
Guido van Rossume8122f11991-05-05 20:03:07 +0000278 DECREF(im->im_func);
279 DECREF(im->im_self);
280 free((ANY *)im);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000281}
282
Guido van Rossume8122f11991-05-05 20:03:07 +0000283typeobject Instancemethodtype = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000284 OB_HEAD_INIT(&Typetype)
285 0,
Guido van Rossum569fce71991-04-16 08:38:43 +0000286 "instance method",
Guido van Rossume8122f11991-05-05 20:03:07 +0000287 sizeof(instancemethodobject),
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288 0,
Guido van Rossume8122f11991-05-05 20:03:07 +0000289 instancemethod_dealloc, /*tp_dealloc*/
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000290 0, /*tp_print*/
Guido van Rossume8122f11991-05-05 20:03:07 +0000291 instancemethod_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};