remove support for "entities" -- a form of applicable struct
[bpt/guile.git] / libguile / objects.c
CommitLineData
730d8ad9 1/* Copyright (C) 1995,1996,1999,2000,2001, 2003, 2004, 2006, 2008, 2009 Free Software Foundation, Inc.
1d9ee7c7 2 *
73be1d9e 3 * This library is free software; you can redistribute it and/or
53befeb7
NJ
4 * modify it under the terms of the GNU Lesser General Public License
5 * as published by the Free Software Foundation; either version 3 of
6 * the License, or (at your option) any later version.
1d9ee7c7 7 *
53befeb7
NJ
8 * This library is distributed in the hope that it will be useful, but
9 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
1d9ee7c7 12 *
73be1d9e
MV
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
53befeb7
NJ
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 * 02110-1301 USA
73be1d9e 17 */
1bbd0b84 18
1bbd0b84 19
1d9ee7c7
MD
20\f
21
da7f71d7
MD
22/* This file and objects.h contains those minimal pieces of the Guile
23 * Object Oriented Programming System which need to be included in
24 * libguile. See the comments in objects.h.
1d9ee7c7
MD
25 */
26
dbb605f5
LC
27#ifdef HAVE_CONFIG_H
28# include <config.h>
29#endif
30
a0599745
MD
31#include "libguile/_scm.h"
32
33#include "libguile/struct.h"
34#include "libguile/procprop.h"
35#include "libguile/chars.h"
36#include "libguile/keywords.h"
37#include "libguile/smob.h"
38#include "libguile/eval.h"
39#include "libguile/alist.h"
40#include "libguile/ports.h"
41#include "libguile/strings.h"
42#include "libguile/vectors.h"
ef7e1868
AW
43#include "libguile/programs.h"
44#include "libguile/vm.h"
a0599745
MD
45
46#include "libguile/validate.h"
47#include "libguile/objects.h"
38c9cccb
MV
48#include "libguile/goops.h"
49
1d9ee7c7
MD
50\f
51
52SCM scm_metaclass_standard;
1d9ee7c7 53
5843e5c9
DH
54/* The cache argument for scm_mcache_lookup_cmethod has one of two possible
55 * formats:
56 *
57 * Format #1:
58 * (SCM_IM_DISPATCH ARGS N-SPECIALIZED
a12be546
MD
59 * #((TYPE1 ... ENV FORMALS FORM ...) ...)
60 * GF)
61 *
5843e5c9 62 * Format #2:
a12be546
MD
63 * (SCM_IM_HASH_DISPATCH ARGS N-SPECIALIZED HASHSET MASK
64 * #((TYPE1 ... ENV FORMALS FORM ...) ...)
65 * GF)
66 *
67 * ARGS is either a list of expressions, in which case they
68 * are interpreted as the arguments of an application, or
69 * a non-pair, which is interpreted as a single expression
70 * yielding all arguments.
71 *
72 * SCM_IM_DISPATCH expressions in generic functions always
73 * have ARGS = the symbol `args' or the iloc #@0-0.
74 *
75 * Need FORMALS in order to support varying arity. This
76 * also avoids the need for renaming of bindings.
77 *
78 * We should probably not complicate this mechanism by
79 * introducing "optimizations" for getters and setters or
80 * primitive methods. Getters and setter will normally be
81 * compiled into @slot-[ref|set!] or a procedure call.
82 * They rely on the dispatch performed before executing
83 * the code which contains them.
84 *
85 * We might want to use a more efficient representation of
86 * this form in the future, perhaps after we have introduced
87 * low-level support for syntax-case macros.
88 */
89
9de33deb
MD
90SCM
91scm_mcache_lookup_cmethod (SCM cache, SCM args)
92{
e11e83f3 93 unsigned long i, mask, n, end;
9de33deb 94 SCM ls, methods, z = SCM_CDDR (cache);
e11e83f3 95 n = scm_to_ulong (SCM_CAR (z)); /* maximum number of specializers */
9de33deb
MD
96 methods = SCM_CADR (z);
97
4057a3e0 98 if (scm_is_simple_vector (methods))
e11e83f3
MV
99 {
100 /* cache format #1: prepare for linear search */
101 mask = -1;
102 i = 0;
4057a3e0 103 end = SCM_SIMPLE_VECTOR_LENGTH (methods);
e11e83f3
MV
104 }
105 else
9de33deb 106 {
5843e5c9 107 /* cache format #2: compute a hash value */
e11e83f3 108 unsigned long hashset = scm_to_ulong (methods);
c014a02e 109 long j = n;
bab246f3 110 z = SCM_CDDR (z);
e11e83f3 111 mask = scm_to_ulong (SCM_CAR (z));
9de33deb
MD
112 methods = SCM_CADR (z);
113 i = 0;
114 ls = args;
d2e53ed6 115 if (!scm_is_null (ls))
a12be546
MD
116 do
117 {
d8c40b9f
DH
118 i += SCM_STRUCT_DATA (scm_class_of (SCM_CAR (ls)))
119 [scm_si_hashsets + hashset];
a12be546
MD
120 ls = SCM_CDR (ls);
121 }
d2e53ed6 122 while (j-- && !scm_is_null (ls));
9de33deb
MD
123 i &= mask;
124 end = i;
125 }
126
127 /* Search for match */
128 do
129 {
c014a02e 130 long j = n;
4057a3e0 131 z = SCM_SIMPLE_VECTOR_REF (methods, i);
9de33deb 132 ls = args; /* list of arguments */
d2e53ed6 133 if (!scm_is_null (ls))
a12be546
MD
134 do
135 {
136 /* More arguments than specifiers => CLASS != ENV */
bc36d050 137 if (! scm_is_eq (scm_class_of (SCM_CAR (ls)), SCM_CAR (z)))
a12be546
MD
138 goto next_method;
139 ls = SCM_CDR (ls);
140 z = SCM_CDR (z);
141 }
d2e53ed6 142 while (j-- && !scm_is_null (ls));
05b37c17
AW
143 /* Fewer arguments than specifiers => CAR != CLASS or `no-method' */
144 if (!scm_is_pair (z)
145 || (!SCM_CLASSP (SCM_CAR (z)) && !scm_is_symbol (SCM_CAR (z))))
5843e5c9 146 return z;
9de33deb
MD
147 next_method:
148 i = (i + 1) & mask;
149 } while (i != end);
150 return SCM_BOOL_F;
151}
152
153SCM
a12be546 154scm_mcache_compute_cmethod (SCM cache, SCM args)
9de33deb
MD
155{
156 SCM cmethod = scm_mcache_lookup_cmethod (cache, args);
7888309b 157 if (scm_is_false (cmethod))
9de33deb
MD
158 /* No match - memoize */
159 return scm_memoize_method (cache, args);
160 return cmethod;
161}
162
163SCM
a12be546 164scm_apply_generic (SCM gf, SCM args)
9de33deb 165{
521ac49b 166 SCM cmethod = scm_mcache_compute_cmethod (SCM_GENERIC_METHOD_CACHE (gf), args);
ef7e1868
AW
167 if (SCM_PROGRAM_P (cmethod))
168 return scm_vm_apply (scm_the_vm (), cmethod, args);
169 else if (scm_is_pair (cmethod))
5487977b
AW
170 return scm_eval_body (SCM_CDR (SCM_CMETHOD_CODE (cmethod)),
171 SCM_EXTEND_ENV (SCM_CAR (SCM_CMETHOD_CODE (cmethod)),
172 args,
173 SCM_CMETHOD_ENV (cmethod)));
174 else
175 return scm_apply (cmethod, args, SCM_EOL);
9de33deb
MD
176}
177
178SCM
a12be546 179scm_call_generic_0 (SCM gf)
9de33deb 180{
a12be546 181 return scm_apply_generic (gf, SCM_EOL);
9de33deb
MD
182}
183
184SCM
a12be546 185scm_call_generic_1 (SCM gf, SCM a1)
9de33deb 186{
1afff620 187 return scm_apply_generic (gf, scm_list_1 (a1));
9de33deb
MD
188}
189
190SCM
a12be546
MD
191scm_call_generic_2 (SCM gf, SCM a1, SCM a2)
192{
1afff620 193 return scm_apply_generic (gf, scm_list_2 (a1, a2));
a12be546
MD
194}
195
196SCM
197scm_call_generic_3 (SCM gf, SCM a1, SCM a2, SCM a3)
9de33deb 198{
1afff620 199 return scm_apply_generic (gf, scm_list_3 (a1, a2, a3));
9de33deb
MD
200}
201
1d9ee7c7
MD
202void
203scm_init_objects ()
204{
a0599745 205#include "libguile/objects.x"
1d9ee7c7 206}
89e00824
ML
207
208/*
209 Local Variables:
210 c-file-style: "gnu"
211 End:
212*/