better debuggability for interpreted procedures
[bpt/guile.git] / libguile / procprop.c
CommitLineData
f2ed4473 1/* Copyright (C) 1995,1996,1998,2000,2001,2003,2004, 2006, 2008, 2009, 2010, 2011 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
3fc7e2c1
AW
25#define SCM_BUILDING_DEPRECATED_CODE
26
a0599745
MD
27#include "libguile/_scm.h"
28
29#include "libguile/alist.h"
3fc7e2c1
AW
30#include "libguile/deprecation.h"
31#include "libguile/deprecated.h"
a0599745
MD
32#include "libguile/eval.h"
33#include "libguile/procs.h"
34#include "libguile/gsubr.h"
5540e847 35#include "libguile/smob.h"
a0599745
MD
36#include "libguile/root.h"
37#include "libguile/vectors.h"
82c76fd3 38#include "libguile/hashtab.h"
2fb924f6 39#include "libguile/programs.h"
a0599745
MD
40
41#include "libguile/validate.h"
42#include "libguile/procprop.h"
0f2d19dd
JB
43\f
44
c083a529 45SCM_GLOBAL_SYMBOL (scm_sym_system_procedure, "system-procedure");
3fc7e2c1 46#if (SCM_ENABLE_DEPRECATED == 1)
67e60655 47SCM_GLOBAL_SYMBOL (scm_sym_arity, "arity");
3fc7e2c1 48#endif
fd12a19a 49SCM_GLOBAL_SYMBOL (scm_sym_name, "name");
67e60655 50
e1bdf9e2
AW
51static SCM overrides;
52static scm_i_pthread_mutex_t overrides_lock = SCM_I_PTHREAD_MUTEX_INITIALIZER;
56164a5a 53
f3cf9421
AW
54static SCM arity_overrides;
55
314b8716
AW
56int
57scm_i_procedure_arity (SCM proc, int *req, int *opt, int *rest)
67e60655 58{
f3cf9421
AW
59 SCM o;
60
61 scm_i_pthread_mutex_lock (&overrides_lock);
62 o = scm_hashq_ref (arity_overrides, proc, SCM_BOOL_F);
63 scm_i_pthread_mutex_unlock (&overrides_lock);
64
65 if (scm_is_true (o))
66 {
67 *req = scm_to_int (scm_car (o));
68 *opt = scm_to_int (scm_cadr (o));
69 *rest = scm_is_true (scm_caddr (o));
70 return 1;
71 }
72
75c3ed28 73 while (!SCM_PROGRAM_P (proc))
67e60655 74 {
75c3ed28 75 if (SCM_IMP (proc))
314b8716 76 return 0;
75c3ed28
AW
77 switch (SCM_TYP7 (proc))
78 {
79 case scm_tc7_smob:
80 if (!SCM_SMOB_APPLICABLE_P (proc))
81 return 0;
82 proc = scm_i_smob_apply_trampoline (proc);
83 break;
84 case scm_tcs_struct:
85 if (!SCM_STRUCT_APPLICABLE_P (proc))
86 return 0;
87 proc = SCM_STRUCT_PROCEDURE (proc);
88 break;
89 default:
90 return 0;
91 }
67e60655 92 }
f3cf9421 93
75c3ed28 94 return scm_i_program_arity (proc, req, opt, rest);
67e60655
MD
95}
96
f3cf9421
AW
97SCM_DEFINE (scm_set_procedure_minimum_arity_x, "set-procedure-minimum-arity!",
98 4, 0, 0, (SCM proc, SCM req, SCM opt, SCM rest),
99 "")
100#define FUNC_NAME s_scm_set_procedure_minimum_arity_x
101{
102 int t SCM_UNUSED;
103
104 SCM_VALIDATE_PROC (1, proc);
105 SCM_VALIDATE_INT_COPY (2, req, t);
106 SCM_VALIDATE_INT_COPY (3, opt, t);
107 SCM_VALIDATE_BOOL (4, rest);
108
109 scm_i_pthread_mutex_lock (&overrides_lock);
110 scm_hashq_set_x (arity_overrides, proc, scm_list_3 (req, opt, rest));
111 scm_i_pthread_mutex_unlock (&overrides_lock);
112 return SCM_UNDEFINED;
113}
114#undef FUNC_NAME
115
cb2ce548
AW
116SCM_DEFINE (scm_procedure_minimum_arity, "procedure-minimum-arity", 1, 0, 0,
117 (SCM proc),
118 "Return the \"minimum arity\" of a procedure.\n\n"
119 "If the procedure has only one arity, that arity is returned\n"
120 "as a list of three values: the number of required arguments,\n"
121 "the number of optional arguments, and a boolean indicating\n"
122 "whether or not the procedure takes rest arguments.\n\n"
123 "For a case-lambda procedure, the arity returned is the one\n"
124 "with the lowest minimum number of arguments, and the highest\n"
125 "maximum number of arguments.\n\n"
126 "If it was not possible to determine the arity of the procedure,\n"
127 "@code{#f} is returned.")
128#define FUNC_NAME s_scm_procedure_minimum_arity
129{
130 int req, opt, rest;
131
132 if (scm_i_procedure_arity (proc, &req, &opt, &rest))
133 return scm_list_3 (scm_from_int (req),
134 scm_from_int (opt),
135 scm_from_bool (rest));
136 else
137 return SCM_BOOL_F;
138}
139#undef FUNC_NAME
140
3b3b36dd 141SCM_DEFINE (scm_procedure_properties, "procedure-properties", 1, 0, 0,
1bbd0b84 142 (SCM proc),
b380b885 143 "Return @var{obj}'s property list.")
1bbd0b84 144#define FUNC_NAME s_scm_procedure_properties
0f2d19dd 145{
314b8716 146 SCM ret;
56164a5a 147
34d19ef6 148 SCM_VALIDATE_PROC (1, proc);
314b8716 149
e1bdf9e2
AW
150 scm_i_pthread_mutex_lock (&overrides_lock);
151 ret = scm_hashq_ref (overrides, proc, SCM_BOOL_F);
152 scm_i_pthread_mutex_unlock (&overrides_lock);
314b8716 153
e1bdf9e2
AW
154 if (scm_is_false (ret))
155 {
156 if (SCM_PROGRAM_P (proc))
07e424b7 157 ret = scm_i_program_properties (proc);
e1bdf9e2
AW
158 else
159 ret = SCM_EOL;
160 }
161
3fc7e2c1
AW
162#if (SCM_ENABLE_DEPRECATED == 1)
163 ret = scm_acons (scm_sym_arity, scm_procedure_minimum_arity (proc), ret);
164#endif
314b8716 165
3fc7e2c1 166 return ret;
0f2d19dd 167}
1bbd0b84 168#undef FUNC_NAME
0f2d19dd 169
3b3b36dd 170SCM_DEFINE (scm_set_procedure_properties_x, "set-procedure-properties!", 2, 0, 0,
56164a5a
AW
171 (SCM proc, SCM alist),
172 "Set @var{proc}'s property list to @var{alist}.")
1bbd0b84 173#define FUNC_NAME s_scm_set_procedure_properties_x
0f2d19dd 174{
56164a5a
AW
175 SCM_VALIDATE_PROC (1, proc);
176
3fc7e2c1 177#if (SCM_ENABLE_DEPRECATED == 1)
e1bdf9e2
AW
178 if (scm_assq (alist, scm_sym_arity))
179 SCM_MISC_ERROR ("arity is a read-only property", SCM_EOL);
3fc7e2c1 180#endif
e1bdf9e2
AW
181
182 scm_i_pthread_mutex_lock (&overrides_lock);
183 scm_hashq_set_x (overrides, proc, alist);
184 scm_i_pthread_mutex_unlock (&overrides_lock);
314b8716 185
0f2d19dd
JB
186 return SCM_UNSPECIFIED;
187}
1bbd0b84 188#undef FUNC_NAME
0f2d19dd 189
3b3b36dd 190SCM_DEFINE (scm_procedure_property, "procedure-property", 2, 0, 0,
56164a5a
AW
191 (SCM proc, SCM key),
192 "Return the property of @var{proc} with name @var{key}.")
1bbd0b84 193#define FUNC_NAME s_scm_procedure_property
0f2d19dd 194{
56164a5a
AW
195 SCM_VALIDATE_PROC (1, proc);
196
3fc7e2c1 197#if (SCM_ENABLE_DEPRECATED == 1)
56164a5a 198 if (scm_is_eq (key, scm_sym_arity))
3fc7e2c1
AW
199 scm_c_issue_deprecation_warning
200 ("Accessing a procedure's arity via `procedure-property' is deprecated.\n"
201 "Use `procedure-minimum-arity instead.");
202#endif
203
204 return scm_assq_ref (scm_procedure_properties (proc), key);
0f2d19dd 205}
1bbd0b84 206#undef FUNC_NAME
0f2d19dd 207
3b3b36dd 208SCM_DEFINE (scm_set_procedure_property_x, "set-procedure-property!", 3, 0, 0,
56164a5a
AW
209 (SCM proc, SCM key, SCM val),
210 "In @var{proc}'s property list, set the property named @var{key} to\n"
211 "@var{val}.")
1bbd0b84 212#define FUNC_NAME s_scm_set_procedure_property_x
0f2d19dd 213{
90fa152c 214 SCM props;
56164a5a 215
e1bdf9e2 216 SCM_VALIDATE_PROC (1, proc);
3fc7e2c1
AW
217
218#if (SCM_ENABLE_DEPRECATED == 1)
56164a5a 219 if (scm_is_eq (key, scm_sym_arity))
3fc7e2c1
AW
220 SCM_MISC_ERROR ("arity is a deprecated read-only property", SCM_EOL);
221#endif
c783b082 222
e1bdf9e2 223 scm_i_pthread_mutex_lock (&overrides_lock);
f2ed4473
AW
224 props = scm_hashq_ref (overrides, proc, SCM_BOOL_F);
225 if (scm_is_false (props))
226 {
227 if (SCM_PROGRAM_P (proc))
228 props = scm_i_program_properties (proc);
229 else
230 props = SCM_EOL;
231 }
90fa152c 232 scm_hashq_set_x (overrides, proc, scm_assq_set_x (props, key, val));
e1bdf9e2 233 scm_i_pthread_mutex_unlock (&overrides_lock);
c783b082 234
0f2d19dd
JB
235 return SCM_UNSPECIFIED;
236}
1bbd0b84 237#undef FUNC_NAME
0f2d19dd
JB
238
239\f
240
1cc91f1b 241
0f2d19dd
JB
242void
243scm_init_procprop ()
0f2d19dd 244{
e1bdf9e2 245 overrides = scm_make_weak_key_hash_table (SCM_UNDEFINED);
f3cf9421 246 arity_overrides = scm_make_weak_key_hash_table (SCM_UNDEFINED);
a0599745 247#include "libguile/procprop.x"
0f2d19dd
JB
248}
249
89e00824
ML
250
251/*
252 Local Variables:
253 c-file-style: "gnu"
254 End:
255*/