Include <config.h> in all C files; use `#ifdef HAVE_CONFIG_H' rather than `#if'.
[bpt/guile.git] / libguile / procprop.c
CommitLineData
dbb605f5 1/* Copyright (C) 1995,1996,1998,2000,2001,2003,2004, 2006, 2008 Free Software Foundation, Inc.
0f2d19dd 2 *
73be1d9e
MV
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
0f2d19dd 7 *
73be1d9e
MV
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
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
92205699 15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
73be1d9e 16 */
1bbd0b84 17
1bbd0b84 18
0f2d19dd 19\f
dbb605f5
LC
20#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
0f2d19dd 23
a0599745
MD
24#include "libguile/_scm.h"
25
26#include "libguile/alist.h"
27#include "libguile/eval.h"
28#include "libguile/procs.h"
29#include "libguile/gsubr.h"
30#include "libguile/objects.h"
5540e847 31#include "libguile/smob.h"
a0599745
MD
32#include "libguile/root.h"
33#include "libguile/vectors.h"
82c76fd3 34#include "libguile/hashtab.h"
a0599745
MD
35
36#include "libguile/validate.h"
37#include "libguile/procprop.h"
0f2d19dd
JB
38\f
39
c083a529 40SCM_GLOBAL_SYMBOL (scm_sym_system_procedure, "system-procedure");
67e60655
MD
41SCM_GLOBAL_SYMBOL (scm_sym_arity, "arity");
42
08906709
MD
43SCM
44scm_i_procedure_arity (SCM proc)
67e60655
MD
45{
46 int a = 0, o = 0, r = 0;
08906709
MD
47 if (SCM_IMP (proc))
48 return SCM_BOOL_F;
67e60655
MD
49 loop:
50 switch (SCM_TYP7 (proc))
51 {
52 case scm_tc7_subr_1o:
53 o = 1;
54 case scm_tc7_subr_0:
55 break;
56 case scm_tc7_subr_2o:
57 o = 1;
58 case scm_tc7_subr_1:
14b18ed6 59 case scm_tc7_dsubr:
67e60655 60 case scm_tc7_cxr:
67e60655
MD
61 a += 1;
62 break;
63 case scm_tc7_subr_2:
64 a += 2;
65 break;
66 case scm_tc7_subr_3:
67 a += 3;
68 break;
69 case scm_tc7_asubr:
70 case scm_tc7_rpsubr:
71 case scm_tc7_lsubr:
72 r = 1;
91517e28 73 break;
67e60655
MD
74 case scm_tc7_lsubr_2:
75 a += 2;
91517e28 76 r = 1;
67e60655 77 break;
5540e847 78 case scm_tc7_smob:
68b06924 79 if (SCM_SMOB_APPLICABLE_P (proc))
362306b9
DH
80 {
81 int type = SCM_SMOB_DESCRIPTOR (proc).gsubr_type;
82 a += SCM_GSUBR_REQ (type);
83 o = SCM_GSUBR_OPT (type);
84 r = SCM_GSUBR_REST (type);
85 break;
86 }
87 else
88 {
5540e847 89 return SCM_BOOL_F;
362306b9
DH
90 }
91 case scm_tc7_cclo:
bc36d050 92 if (scm_is_eq (SCM_CCLO_SUBR (proc), scm_f_gsubr_apply))
67e60655 93 {
e11e83f3 94 int type = scm_to_int (SCM_GSUBR_TYPE (proc));
08906709 95 a += SCM_GSUBR_REQ (type);
67e60655
MD
96 o = SCM_GSUBR_OPT (type);
97 r = SCM_GSUBR_REST (type);
98 break;
99 }
362306b9
DH
100 else
101 {
102 proc = SCM_CCLO_SUBR (proc);
103 a -= 1;
104 goto loop;
105 }
dec118c8
MD
106 case scm_tc7_pws:
107 proc = SCM_PROCEDURE (proc);
108 goto loop;
67e60655 109 case scm_tcs_closures:
726d810a 110 proc = SCM_CLOSURE_FORMALS (proc);
d2e53ed6 111 if (scm_is_null (proc))
67e60655 112 break;
d2e53ed6 113 while (scm_is_pair (proc))
67e60655
MD
114 {
115 ++a;
116 proc = SCM_CDR (proc);
117 }
d2e53ed6 118 if (!scm_is_null (proc))
67e60655
MD
119 r = 1;
120 break;
904a077d 121 case scm_tcs_struct:
815ce8d5
MD
122 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
123 {
124 r = 1;
125 break;
126 }
127 else if (!SCM_I_OPERATORP (proc))
08906709 128 return SCM_BOOL_F;
815ce8d5
MD
129 proc = (SCM_I_ENTITYP (proc)
130 ? SCM_ENTITY_PROCEDURE (proc)
131 : SCM_OPERATOR_PROCEDURE (proc));
132 a -= 1;
133 goto loop;
08906709
MD
134 default:
135 return SCM_BOOL_F;
67e60655 136 }
e11e83f3 137 return scm_list_3 (scm_from_int (a), scm_from_int (o), scm_from_bool(r));
67e60655
MD
138}
139
ece721f0
MV
140/* XXX - instead of using a stand-in value for everything except
141 closures, we should find other ways to store the procedure
142 properties for those other kinds of procedures. For example, subrs
143 have their own property slot, which is unused at present.
144*/
145
0f2d19dd 146static SCM
1bbd0b84 147scm_stand_in_scm_proc(SCM proc)
0f2d19dd 148{
82c76fd3
MV
149 SCM handle, answer;
150 handle = scm_hashq_get_handle (scm_stand_in_procs, proc);
151 if (scm_is_false (handle))
0f2d19dd 152 {
1afff620 153 answer = scm_closure (scm_list_2 (SCM_EOL, SCM_BOOL_F), SCM_EOL);
82c76fd3 154 scm_hashq_set_x (scm_stand_in_procs, proc, answer);
0f2d19dd
JB
155 }
156 else
82c76fd3 157 answer = SCM_CDR (handle);
0f2d19dd
JB
158 return answer;
159}
160
3b3b36dd 161SCM_DEFINE (scm_procedure_properties, "procedure-properties", 1, 0, 0,
1bbd0b84 162 (SCM proc),
b380b885 163 "Return @var{obj}'s property list.")
1bbd0b84 164#define FUNC_NAME s_scm_procedure_properties
0f2d19dd 165{
34d19ef6 166 SCM_VALIDATE_PROC (1, proc);
67e60655 167 return scm_acons (scm_sym_arity, scm_i_procedure_arity (proc),
0c95b57d 168 SCM_PROCPROPS (SCM_CLOSUREP (proc)
67e60655
MD
169 ? proc
170 : scm_stand_in_scm_proc (proc)));
0f2d19dd 171}
1bbd0b84 172#undef FUNC_NAME
0f2d19dd 173
3b3b36dd 174SCM_DEFINE (scm_set_procedure_properties_x, "set-procedure-properties!", 2, 0, 0,
1bbd0b84 175 (SCM proc, SCM new_val),
b380b885 176 "Set @var{obj}'s property list to @var{alist}.")
1bbd0b84 177#define FUNC_NAME s_scm_set_procedure_properties_x
0f2d19dd 178{
0c95b57d 179 if (!SCM_CLOSUREP (proc))
0f2d19dd 180 proc = scm_stand_in_scm_proc(proc);
34d19ef6 181 SCM_VALIDATE_CLOSURE (1, proc);
a6c64c3c 182 SCM_SETPROCPROPS (proc, new_val);
0f2d19dd
JB
183 return SCM_UNSPECIFIED;
184}
1bbd0b84 185#undef FUNC_NAME
0f2d19dd 186
3b3b36dd 187SCM_DEFINE (scm_procedure_property, "procedure-property", 2, 0, 0,
1bbd0b84 188 (SCM p, SCM k),
b380b885 189 "Return the property of @var{obj} with name @var{key}.")
1bbd0b84 190#define FUNC_NAME s_scm_procedure_property
0f2d19dd
JB
191{
192 SCM assoc;
bc36d050 193 if (scm_is_eq (k, scm_sym_arity))
08906709
MD
194 {
195 SCM arity;
7888309b 196 SCM_ASSERT (scm_is_true (arity = scm_i_procedure_arity (p)),
1bbd0b84 197 p, SCM_ARG1, FUNC_NAME);
08906709
MD
198 return arity;
199 }
34d19ef6 200 SCM_VALIDATE_PROC (1, p);
67e60655 201 assoc = scm_sloppy_assq (k,
0c95b57d 202 SCM_PROCPROPS (SCM_CLOSUREP (p)
67e60655
MD
203 ? p
204 : scm_stand_in_scm_proc (p)));
0f2d19dd
JB
205 return (SCM_NIMP (assoc) ? SCM_CDR (assoc) : SCM_BOOL_F);
206}
1bbd0b84 207#undef FUNC_NAME
0f2d19dd 208
3b3b36dd 209SCM_DEFINE (scm_set_procedure_property_x, "set-procedure-property!", 3, 0, 0,
1bbd0b84 210 (SCM p, SCM k, SCM v),
b380b885
MD
211 "In @var{obj}'s property list, set the property named @var{key} to\n"
212 "@var{value}.")
1bbd0b84 213#define FUNC_NAME s_scm_set_procedure_property_x
0f2d19dd
JB
214{
215 SCM assoc;
0c95b57d 216 if (!SCM_CLOSUREP (p))
0f2d19dd 217 p = scm_stand_in_scm_proc(p);
34d19ef6 218 SCM_VALIDATE_CLOSURE (1, p);
bc36d050 219 if (scm_is_eq (k, scm_sym_arity))
1bbd0b84 220 SCM_MISC_ERROR ("arity is a read-only property", SCM_EOL);
0f2d19dd
JB
221 assoc = scm_sloppy_assq (k, SCM_PROCPROPS (p));
222 if (SCM_NIMP (assoc))
223 SCM_SETCDR (assoc, v);
224 else
a6c64c3c 225 SCM_SETPROCPROPS (p, scm_acons (k, v, SCM_PROCPROPS (p)));
0f2d19dd
JB
226 return SCM_UNSPECIFIED;
227}
1bbd0b84 228#undef FUNC_NAME
0f2d19dd
JB
229
230\f
231
1cc91f1b 232
0f2d19dd
JB
233void
234scm_init_procprop ()
0f2d19dd 235{
a0599745 236#include "libguile/procprop.x"
0f2d19dd
JB
237}
238
89e00824
ML
239
240/*
241 Local Variables:
242 c-file-style: "gnu"
243 End:
244*/