1 /* Copyright (C) 1995,1996,1998,2000,2001,2003,2004, 2006, 2008, 2009 Free Software Foundation, Inc.
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.
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.
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
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "libguile/_scm.h"
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"
31 #include "libguile/smob.h"
32 #include "libguile/root.h"
33 #include "libguile/vectors.h"
34 #include "libguile/hashtab.h"
36 #include "libguile/validate.h"
37 #include "libguile/procprop.h"
40 SCM_GLOBAL_SYMBOL (scm_sym_system_procedure
, "system-procedure");
41 SCM_GLOBAL_SYMBOL (scm_sym_arity
, "arity");
44 scm_i_procedure_arity (SCM proc
)
46 int a
= 0, o
= 0, r
= 0;
50 switch (SCM_TYP7 (proc
))
79 if (SCM_SMOB_APPLICABLE_P (proc
))
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
);
93 unsigned int type
= SCM_GSUBR_TYPE (proc
);
94 a
= SCM_GSUBR_REQ (type
);
95 o
= SCM_GSUBR_OPT (type
);
96 r
= SCM_GSUBR_REST (type
);
100 proc
= SCM_PROCEDURE (proc
);
102 case scm_tcs_closures
:
103 proc
= SCM_CLOSURE_FORMALS (proc
);
104 if (scm_is_null (proc
))
106 while (scm_is_pair (proc
))
109 proc
= SCM_CDR (proc
);
111 if (!scm_is_null (proc
))
115 if (SCM_OBJ_CLASS_FLAGS (proc
) & SCM_CLASSF_PURE_GENERIC
)
120 else if (!SCM_I_OPERATORP (proc
))
122 proc
= (SCM_I_ENTITYP (proc
)
123 ? SCM_ENTITY_PROCEDURE (proc
)
124 : SCM_OPERATOR_PROCEDURE (proc
));
130 return scm_list_3 (scm_from_int (a
), scm_from_int (o
), scm_from_bool(r
));
133 /* XXX - instead of using a stand-in value for everything except
134 closures, we should find other ways to store the procedure
135 properties for those other kinds of procedures. For example, subrs
136 have their own property slot, which is unused at present.
140 scm_stand_in_scm_proc(SCM proc
)
143 handle
= scm_hashq_get_handle (scm_stand_in_procs
, proc
);
144 if (scm_is_false (handle
))
146 answer
= scm_closure (scm_list_2 (SCM_EOL
, SCM_BOOL_F
), SCM_EOL
);
147 scm_hashq_set_x (scm_stand_in_procs
, proc
, answer
);
150 answer
= SCM_CDR (handle
);
154 SCM_DEFINE (scm_procedure_properties
, "procedure-properties", 1, 0, 0,
156 "Return @var{obj}'s property list.")
157 #define FUNC_NAME s_scm_procedure_properties
159 SCM_VALIDATE_PROC (1, proc
);
160 return scm_acons (scm_sym_arity
, scm_i_procedure_arity (proc
),
161 SCM_PROCPROPS (SCM_CLOSUREP (proc
)
163 : scm_stand_in_scm_proc (proc
)));
167 SCM_DEFINE (scm_set_procedure_properties_x
, "set-procedure-properties!", 2, 0, 0,
168 (SCM proc
, SCM new_val
),
169 "Set @var{obj}'s property list to @var{alist}.")
170 #define FUNC_NAME s_scm_set_procedure_properties_x
172 if (!SCM_CLOSUREP (proc
))
173 proc
= scm_stand_in_scm_proc(proc
);
174 SCM_VALIDATE_CLOSURE (1, proc
);
175 SCM_SETPROCPROPS (proc
, new_val
);
176 return SCM_UNSPECIFIED
;
180 SCM_DEFINE (scm_procedure_property
, "procedure-property", 2, 0, 0,
182 "Return the property of @var{obj} with name @var{key}.")
183 #define FUNC_NAME s_scm_procedure_property
186 if (scm_is_eq (k
, scm_sym_arity
))
189 SCM_ASSERT (scm_is_true (arity
= scm_i_procedure_arity (p
)),
190 p
, SCM_ARG1
, FUNC_NAME
);
193 SCM_VALIDATE_PROC (1, p
);
194 assoc
= scm_sloppy_assq (k
,
195 SCM_PROCPROPS (SCM_CLOSUREP (p
)
197 : scm_stand_in_scm_proc (p
)));
198 return (SCM_NIMP (assoc
) ? SCM_CDR (assoc
) : SCM_BOOL_F
);
202 SCM_DEFINE (scm_set_procedure_property_x
, "set-procedure-property!", 3, 0, 0,
203 (SCM p
, SCM k
, SCM v
),
204 "In @var{obj}'s property list, set the property named @var{key} to\n"
206 #define FUNC_NAME s_scm_set_procedure_property_x
209 if (!SCM_CLOSUREP (p
))
210 p
= scm_stand_in_scm_proc(p
);
211 SCM_VALIDATE_CLOSURE (1, p
);
212 if (scm_is_eq (k
, scm_sym_arity
))
213 SCM_MISC_ERROR ("arity is a read-only property", SCM_EOL
);
214 assoc
= scm_sloppy_assq (k
, SCM_PROCPROPS (p
));
215 if (SCM_NIMP (assoc
))
216 SCM_SETCDR (assoc
, v
);
218 SCM_SETPROCPROPS (p
, scm_acons (k
, v
, SCM_PROCPROPS (p
)));
219 return SCM_UNSPECIFIED
;
229 #include "libguile/procprop.x"