Changed license terms to the plain LGPL thru-out.
[bpt/guile.git] / libguile / procprop.c
CommitLineData
a48d60b1 1/* Copyright (C) 1995,1996,1998,2000,2001, 2003 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
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
1bbd0b84 17
1bbd0b84 18
0f2d19dd
JB
19\f
20
a0599745
MD
21#include "libguile/_scm.h"
22
23#include "libguile/alist.h"
24#include "libguile/eval.h"
25#include "libguile/procs.h"
26#include "libguile/gsubr.h"
27#include "libguile/objects.h"
5540e847 28#include "libguile/smob.h"
a0599745
MD
29#include "libguile/root.h"
30#include "libguile/vectors.h"
31
32#include "libguile/validate.h"
33#include "libguile/procprop.h"
0f2d19dd
JB
34\f
35
c083a529 36SCM_GLOBAL_SYMBOL (scm_sym_system_procedure, "system-procedure");
67e60655
MD
37SCM_GLOBAL_SYMBOL (scm_sym_arity, "arity");
38
08906709
MD
39SCM
40scm_i_procedure_arity (SCM proc)
67e60655
MD
41{
42 int a = 0, o = 0, r = 0;
08906709
MD
43 if (SCM_IMP (proc))
44 return SCM_BOOL_F;
67e60655
MD
45 loop:
46 switch (SCM_TYP7 (proc))
47 {
48 case scm_tc7_subr_1o:
49 o = 1;
50 case scm_tc7_subr_0:
51 break;
52 case scm_tc7_subr_2o:
53 o = 1;
54 case scm_tc7_subr_1:
55 case scm_tc7_cxr:
67e60655
MD
56 a += 1;
57 break;
58 case scm_tc7_subr_2:
59 a += 2;
60 break;
61 case scm_tc7_subr_3:
62 a += 3;
63 break;
64 case scm_tc7_asubr:
65 case scm_tc7_rpsubr:
66 case scm_tc7_lsubr:
67 r = 1;
91517e28 68 break;
67e60655
MD
69 case scm_tc7_lsubr_2:
70 a += 2;
91517e28 71 r = 1;
67e60655 72 break;
5540e847 73 case scm_tc7_smob:
68b06924 74 if (SCM_SMOB_APPLICABLE_P (proc))
362306b9
DH
75 {
76 int type = SCM_SMOB_DESCRIPTOR (proc).gsubr_type;
77 a += SCM_GSUBR_REQ (type);
78 o = SCM_GSUBR_OPT (type);
79 r = SCM_GSUBR_REST (type);
80 break;
81 }
82 else
83 {
5540e847 84 return SCM_BOOL_F;
362306b9
DH
85 }
86 case scm_tc7_cclo:
87 if (SCM_EQ_P (SCM_CCLO_SUBR (proc), scm_f_gsubr_apply))
67e60655 88 {
362306b9 89 int type = SCM_INUM (SCM_GSUBR_TYPE (proc));
08906709 90 a += SCM_GSUBR_REQ (type);
67e60655
MD
91 o = SCM_GSUBR_OPT (type);
92 r = SCM_GSUBR_REST (type);
93 break;
94 }
362306b9
DH
95 else
96 {
97 proc = SCM_CCLO_SUBR (proc);
98 a -= 1;
99 goto loop;
100 }
dec118c8
MD
101 case scm_tc7_pws:
102 proc = SCM_PROCEDURE (proc);
103 goto loop;
67e60655 104 case scm_tcs_closures:
726d810a
DH
105 proc = SCM_CLOSURE_FORMALS (proc);
106 if (SCM_NULLP (proc))
67e60655 107 break;
0c95b57d 108 while (SCM_CONSP (proc))
67e60655
MD
109 {
110 ++a;
111 proc = SCM_CDR (proc);
112 }
726d810a 113 if (!SCM_NULLP (proc))
67e60655
MD
114 r = 1;
115 break;
904a077d 116 case scm_tcs_struct:
815ce8d5
MD
117 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
118 {
119 r = 1;
120 break;
121 }
122 else if (!SCM_I_OPERATORP (proc))
08906709 123 return SCM_BOOL_F;
815ce8d5
MD
124 proc = (SCM_I_ENTITYP (proc)
125 ? SCM_ENTITY_PROCEDURE (proc)
126 : SCM_OPERATOR_PROCEDURE (proc));
127 a -= 1;
128 goto loop;
08906709
MD
129 default:
130 return SCM_BOOL_F;
67e60655 131 }
1afff620 132 return scm_list_3 (SCM_MAKINUM (a), SCM_MAKINUM (o), SCM_BOOL(r));
67e60655
MD
133}
134
0f2d19dd 135static SCM
1bbd0b84 136scm_stand_in_scm_proc(SCM proc)
0f2d19dd
JB
137{
138 SCM answer;
a48d60b1 139 answer = scm_assq (proc, scm_stand_in_procs);
54778cd3 140 if (SCM_FALSEP (answer))
0f2d19dd 141 {
1afff620 142 answer = scm_closure (scm_list_2 (SCM_EOL, SCM_BOOL_F), SCM_EOL);
e0c08f17 143 scm_stand_in_procs = scm_acons (proc, answer, scm_stand_in_procs);
0f2d19dd
JB
144 }
145 else
146 answer = SCM_CDR (answer);
147 return answer;
148}
149
3b3b36dd 150SCM_DEFINE (scm_procedure_properties, "procedure-properties", 1, 0, 0,
1bbd0b84 151 (SCM proc),
b380b885 152 "Return @var{obj}'s property list.")
1bbd0b84 153#define FUNC_NAME s_scm_procedure_properties
0f2d19dd 154{
34d19ef6 155 SCM_VALIDATE_PROC (1, proc);
67e60655 156 return scm_acons (scm_sym_arity, scm_i_procedure_arity (proc),
0c95b57d 157 SCM_PROCPROPS (SCM_CLOSUREP (proc)
67e60655
MD
158 ? proc
159 : scm_stand_in_scm_proc (proc)));
0f2d19dd 160}
1bbd0b84 161#undef FUNC_NAME
0f2d19dd 162
3b3b36dd 163SCM_DEFINE (scm_set_procedure_properties_x, "set-procedure-properties!", 2, 0, 0,
1bbd0b84 164 (SCM proc, SCM new_val),
b380b885 165 "Set @var{obj}'s property list to @var{alist}.")
1bbd0b84 166#define FUNC_NAME s_scm_set_procedure_properties_x
0f2d19dd 167{
0c95b57d 168 if (!SCM_CLOSUREP (proc))
0f2d19dd 169 proc = scm_stand_in_scm_proc(proc);
34d19ef6 170 SCM_VALIDATE_CLOSURE (1, proc);
a6c64c3c 171 SCM_SETPROCPROPS (proc, new_val);
0f2d19dd
JB
172 return SCM_UNSPECIFIED;
173}
1bbd0b84 174#undef FUNC_NAME
0f2d19dd 175
3b3b36dd 176SCM_DEFINE (scm_procedure_property, "procedure-property", 2, 0, 0,
1bbd0b84 177 (SCM p, SCM k),
b380b885 178 "Return the property of @var{obj} with name @var{key}.")
1bbd0b84 179#define FUNC_NAME s_scm_procedure_property
0f2d19dd
JB
180{
181 SCM assoc;
54778cd3 182 if (SCM_EQ_P (k, scm_sym_arity))
08906709
MD
183 {
184 SCM arity;
185 SCM_ASSERT (SCM_NFALSEP (arity = scm_i_procedure_arity (p)),
1bbd0b84 186 p, SCM_ARG1, FUNC_NAME);
08906709
MD
187 return arity;
188 }
34d19ef6 189 SCM_VALIDATE_PROC (1, p);
67e60655 190 assoc = scm_sloppy_assq (k,
0c95b57d 191 SCM_PROCPROPS (SCM_CLOSUREP (p)
67e60655
MD
192 ? p
193 : scm_stand_in_scm_proc (p)));
0f2d19dd
JB
194 return (SCM_NIMP (assoc) ? SCM_CDR (assoc) : SCM_BOOL_F);
195}
1bbd0b84 196#undef FUNC_NAME
0f2d19dd 197
3b3b36dd 198SCM_DEFINE (scm_set_procedure_property_x, "set-procedure-property!", 3, 0, 0,
1bbd0b84 199 (SCM p, SCM k, SCM v),
b380b885
MD
200 "In @var{obj}'s property list, set the property named @var{key} to\n"
201 "@var{value}.")
1bbd0b84 202#define FUNC_NAME s_scm_set_procedure_property_x
0f2d19dd
JB
203{
204 SCM assoc;
0c95b57d 205 if (!SCM_CLOSUREP (p))
0f2d19dd 206 p = scm_stand_in_scm_proc(p);
34d19ef6 207 SCM_VALIDATE_CLOSURE (1, p);
54778cd3 208 if (SCM_EQ_P (k, scm_sym_arity))
1bbd0b84 209 SCM_MISC_ERROR ("arity is a read-only property", SCM_EOL);
0f2d19dd
JB
210 assoc = scm_sloppy_assq (k, SCM_PROCPROPS (p));
211 if (SCM_NIMP (assoc))
212 SCM_SETCDR (assoc, v);
213 else
a6c64c3c 214 SCM_SETPROCPROPS (p, scm_acons (k, v, SCM_PROCPROPS (p)));
0f2d19dd
JB
215 return SCM_UNSPECIFIED;
216}
1bbd0b84 217#undef FUNC_NAME
0f2d19dd
JB
218
219\f
220
1cc91f1b 221
0f2d19dd
JB
222void
223scm_init_procprop ()
0f2d19dd 224{
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*/