flesh out glil support for optional and keyword arguments
[bpt/guile.git] / libguile / procprop.c
CommitLineData
e20d7001 1/* Copyright (C) 1995,1996,1998,2000,2001,2003,2004, 2006, 2008, 2009 Free Software Foundation, Inc.
0f2d19dd 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.
0f2d19dd 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.
0f2d19dd 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
0f2d19dd 20\f
dbb605f5
LC
21#ifdef HAVE_CONFIG_H
22# include <config.h>
23#endif
0f2d19dd 24
a0599745
MD
25#include "libguile/_scm.h"
26
27#include "libguile/alist.h"
28#include "libguile/eval.h"
29#include "libguile/procs.h"
30#include "libguile/gsubr.h"
31#include "libguile/objects.h"
5540e847 32#include "libguile/smob.h"
a0599745
MD
33#include "libguile/root.h"
34#include "libguile/vectors.h"
82c76fd3 35#include "libguile/hashtab.h"
2fb924f6 36#include "libguile/programs.h"
a0599745
MD
37
38#include "libguile/validate.h"
39#include "libguile/procprop.h"
0f2d19dd
JB
40\f
41
c083a529 42SCM_GLOBAL_SYMBOL (scm_sym_system_procedure, "system-procedure");
67e60655
MD
43SCM_GLOBAL_SYMBOL (scm_sym_arity, "arity");
44
56164a5a
AW
45static SCM non_closure_props;
46static scm_i_pthread_mutex_t non_closure_props_lock = SCM_I_PTHREAD_MUTEX_INITIALIZER;
47
08906709
MD
48SCM
49scm_i_procedure_arity (SCM proc)
67e60655
MD
50{
51 int a = 0, o = 0, r = 0;
08906709
MD
52 if (SCM_IMP (proc))
53 return SCM_BOOL_F;
67e60655
MD
54 loop:
55 switch (SCM_TYP7 (proc))
56 {
57 case scm_tc7_subr_1o:
58 o = 1;
59 case scm_tc7_subr_0:
60 break;
61 case scm_tc7_subr_2o:
62 o = 1;
63 case scm_tc7_subr_1:
14b18ed6 64 case scm_tc7_dsubr:
67e60655 65 case scm_tc7_cxr:
67e60655
MD
66 a += 1;
67 break;
68 case scm_tc7_subr_2:
69 a += 2;
70 break;
71 case scm_tc7_subr_3:
72 a += 3;
73 break;
74 case scm_tc7_asubr:
75 case scm_tc7_rpsubr:
76 case scm_tc7_lsubr:
77 r = 1;
91517e28 78 break;
2fb924f6 79 case scm_tc7_program:
56164a5a
AW
80 if (scm_i_program_arity (proc, &a, &o, &r))
81 break;
82 else
83 return SCM_BOOL_F;
67e60655
MD
84 case scm_tc7_lsubr_2:
85 a += 2;
91517e28 86 r = 1;
67e60655 87 break;
5540e847 88 case scm_tc7_smob:
68b06924 89 if (SCM_SMOB_APPLICABLE_P (proc))
362306b9
DH
90 {
91 int type = SCM_SMOB_DESCRIPTOR (proc).gsubr_type;
92 a += SCM_GSUBR_REQ (type);
93 o = SCM_GSUBR_OPT (type);
94 r = SCM_GSUBR_REST (type);
95 break;
96 }
97 else
98 {
5540e847 99 return SCM_BOOL_F;
362306b9 100 }
e20d7001
LC
101 case scm_tc7_gsubr:
102 {
103 unsigned int type = SCM_GSUBR_TYPE (proc);
104 a = SCM_GSUBR_REQ (type);
105 o = SCM_GSUBR_OPT (type);
106 r = SCM_GSUBR_REST (type);
107 break;
108 }
dec118c8
MD
109 case scm_tc7_pws:
110 proc = SCM_PROCEDURE (proc);
111 goto loop;
67e60655 112 case scm_tcs_closures:
726d810a 113 proc = SCM_CLOSURE_FORMALS (proc);
d2e53ed6 114 if (scm_is_null (proc))
67e60655 115 break;
d2e53ed6 116 while (scm_is_pair (proc))
67e60655
MD
117 {
118 ++a;
119 proc = SCM_CDR (proc);
120 }
d2e53ed6 121 if (!scm_is_null (proc))
67e60655
MD
122 r = 1;
123 break;
904a077d 124 case scm_tcs_struct:
815ce8d5
MD
125 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
126 {
127 r = 1;
128 break;
129 }
130 else if (!SCM_I_OPERATORP (proc))
08906709 131 return SCM_BOOL_F;
815ce8d5
MD
132 proc = (SCM_I_ENTITYP (proc)
133 ? SCM_ENTITY_PROCEDURE (proc)
134 : SCM_OPERATOR_PROCEDURE (proc));
135 a -= 1;
136 goto loop;
08906709
MD
137 default:
138 return SCM_BOOL_F;
67e60655 139 }
e11e83f3 140 return scm_list_3 (scm_from_int (a), scm_from_int (o), scm_from_bool(r));
67e60655
MD
141}
142
56164a5a
AW
143/* FIXME: instead of the weak hash, perhaps for some kinds of procedures, use
144 other means; for example subrs have their own property slot, which is unused
145 at present. */
0f2d19dd 146
3b3b36dd 147SCM_DEFINE (scm_procedure_properties, "procedure-properties", 1, 0, 0,
1bbd0b84 148 (SCM proc),
b380b885 149 "Return @var{obj}'s property list.")
1bbd0b84 150#define FUNC_NAME s_scm_procedure_properties
0f2d19dd 151{
56164a5a
AW
152 SCM props;
153
34d19ef6 154 SCM_VALIDATE_PROC (1, proc);
56164a5a
AW
155 if (SCM_CLOSUREP (proc))
156 props = SCM_PROCPROPS (proc);
157 else
158 {
159 scm_i_pthread_mutex_lock (&non_closure_props_lock);
160 props = scm_hashq_ref (non_closure_props, proc, SCM_EOL);
161 scm_i_pthread_mutex_unlock (&non_closure_props_lock);
162 }
163 return scm_acons (scm_sym_arity, scm_i_procedure_arity (proc), props);
0f2d19dd 164}
1bbd0b84 165#undef FUNC_NAME
0f2d19dd 166
3b3b36dd 167SCM_DEFINE (scm_set_procedure_properties_x, "set-procedure-properties!", 2, 0, 0,
56164a5a
AW
168 (SCM proc, SCM alist),
169 "Set @var{proc}'s property list to @var{alist}.")
1bbd0b84 170#define FUNC_NAME s_scm_set_procedure_properties_x
0f2d19dd 171{
56164a5a
AW
172 SCM_VALIDATE_PROC (1, proc);
173
174 if (SCM_CLOSUREP (proc))
175 SCM_SETPROCPROPS (proc, alist);
176 else
177 {
178 scm_i_pthread_mutex_lock (&non_closure_props_lock);
179 scm_hashq_set_x (non_closure_props, proc, alist);
180 scm_i_pthread_mutex_unlock (&non_closure_props_lock);
181 }
0f2d19dd
JB
182 return SCM_UNSPECIFIED;
183}
1bbd0b84 184#undef FUNC_NAME
0f2d19dd 185
3b3b36dd 186SCM_DEFINE (scm_procedure_property, "procedure-property", 2, 0, 0,
56164a5a
AW
187 (SCM proc, SCM key),
188 "Return the property of @var{proc} with name @var{key}.")
1bbd0b84 189#define FUNC_NAME s_scm_procedure_property
0f2d19dd 190{
56164a5a
AW
191 SCM_VALIDATE_PROC (1, proc);
192
193 if (scm_is_eq (key, scm_sym_arity))
194 /* avoid a cons in this case */
195 return scm_i_procedure_arity (proc);
196 else
197 return scm_assq_ref (scm_procedure_properties (proc), key);
0f2d19dd 198}
1bbd0b84 199#undef FUNC_NAME
0f2d19dd 200
3b3b36dd 201SCM_DEFINE (scm_set_procedure_property_x, "set-procedure-property!", 3, 0, 0,
56164a5a
AW
202 (SCM proc, SCM key, SCM val),
203 "In @var{proc}'s property list, set the property named @var{key} to\n"
204 "@var{val}.")
1bbd0b84 205#define FUNC_NAME s_scm_set_procedure_property_x
0f2d19dd 206{
56164a5a
AW
207 SCM_VALIDATE_PROC (1, proc);
208
209 if (scm_is_eq (key, scm_sym_arity))
1bbd0b84 210 SCM_MISC_ERROR ("arity is a read-only property", SCM_EOL);
56164a5a
AW
211 scm_set_procedure_properties_x
212 (proc,
213 scm_assq_set_x (scm_procedure_properties (proc), key, val));
0f2d19dd
JB
214 return SCM_UNSPECIFIED;
215}
1bbd0b84 216#undef FUNC_NAME
0f2d19dd
JB
217
218\f
219
1cc91f1b 220
0f2d19dd
JB
221void
222scm_init_procprop ()
0f2d19dd 223{
56164a5a 224 non_closure_props = scm_make_doubly_weak_hash_table (SCM_UNDEFINED);
a0599745 225#include "libguile/procprop.x"
0f2d19dd
JB
226}
227
89e00824
ML
228
229/*
230 Local Variables:
231 c-file-style: "gnu"
232 End:
233*/