Greg's smob patch
[bpt/guile.git] / libguile / variable.c
1 /* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program 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
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
40 * If you do not wish that, delete this exception notice. */
41 \f
42
43 #include <stdio.h>
44 #include "_scm.h"
45 #include "eq.h"
46 #include "genio.h"
47 #include "smob.h"
48
49 #include "variable.h"
50 \f
51
52 static int prin_var SCM_P ((SCM exp, SCM port, scm_print_state *pstate));
53
54 static int
55 prin_var (exp, port, pstate)
56 SCM exp;
57 SCM port;
58 scm_print_state *pstate;
59 {
60 scm_puts ("#<variable ", port);
61 scm_intprint(exp, 16, port);
62 {
63 SCM val_cell;
64 val_cell = SCM_CDR(exp);
65 if (SCM_CAR (val_cell) != SCM_UNDEFINED)
66 {
67 scm_puts (" name: ", port);
68 scm_iprin1 (SCM_CAR (val_cell), port, pstate);
69 }
70 scm_puts (" binding: ", port);
71 scm_iprin1 (SCM_CDR (val_cell), port, pstate);
72 }
73 scm_putc('>', port);
74 return 1;
75 }
76
77
78 static SCM scm_markvar SCM_P ((SCM ptr));
79
80 static SCM
81 scm_markvar (ptr)
82 SCM ptr;
83 {
84 return SCM_CDR (ptr);
85 }
86
87 static SCM var_equal SCM_P ((SCM var1, SCM var2));
88
89 static SCM
90 var_equal (var1, var2)
91 SCM var1;
92 SCM var2;
93 {
94 return scm_equal_p (SCM_CDR (var1), SCM_CDR (var2));
95 }
96
97 int scm_tc16_variable;
98 \f
99
100 static SCM anonymous_variable_sym;
101
102
103 static SCM make_vcell_variable SCM_P ((SCM vcell));
104
105 static SCM
106 make_vcell_variable (vcell)
107 SCM vcell;
108 {
109 SCM_RETURN_NEWSMOB (scm_tc16_variable, vcell);
110 }
111
112 SCM_PROC(s_make_variable, "make-variable", 1, 1, 0, scm_make_variable);
113
114 SCM
115 scm_make_variable (init, name_hint)
116 SCM init;
117 SCM name_hint;
118 {
119 SCM val_cell;
120
121 if (name_hint == SCM_UNDEFINED)
122 name_hint = anonymous_variable_sym;
123
124 SCM_NEWCELL(val_cell);
125 SCM_DEFER_INTS;
126 SCM_SETCAR (val_cell, name_hint);
127 SCM_SETCDR (val_cell, init);
128 SCM_ALLOW_INTS;
129 return make_vcell_variable (val_cell);
130 }
131
132
133 SCM_PROC(s_make_undefined_variable, "make-undefined-variable", 0, 1, 0, scm_make_undefined_variable);
134
135 SCM
136 scm_make_undefined_variable (name_hint)
137 SCM name_hint;
138 {
139 SCM vcell;
140
141 if (name_hint == SCM_UNDEFINED)
142 name_hint = anonymous_variable_sym;
143
144 SCM_NEWCELL (vcell);
145 SCM_DEFER_INTS;
146 SCM_SETCAR (vcell, name_hint);
147 SCM_SETCDR (vcell, SCM_UNDEFINED);
148 SCM_ALLOW_INTS;
149 return make_vcell_variable (vcell);
150 }
151
152
153 SCM_PROC(s_variable_p, "variable?", 1, 0, 0, scm_variable_p);
154
155 SCM
156 scm_variable_p (obj)
157 SCM obj;
158 {
159 return ( (SCM_NIMP(obj) && SCM_VARIABLEP (obj))
160 ? SCM_BOOL_T
161 : SCM_BOOL_F);
162 }
163
164
165 SCM_PROC(s_variable_ref, "variable-ref", 1, 0, 0, scm_variable_ref);
166
167 SCM
168 scm_variable_ref (var)
169 SCM var;
170 {
171 SCM_ASSERT (SCM_NIMP(var) && SCM_VARIABLEP(var), var, SCM_ARG1, s_variable_ref);
172 return SCM_CDR (SCM_CDR (var));
173 }
174
175
176
177 SCM_PROC(s_variable_set_x, "variable-set!", 2, 0, 0, scm_variable_set_x);
178
179 SCM
180 scm_variable_set_x (var, val)
181 SCM var;
182 SCM val;
183 {
184 SCM_ASSERT (SCM_NIMP(var) && SCM_VARIABLEP (var), var, SCM_ARG1, s_variable_set_x);
185 SCM_SETCDR (SCM_CDR (var), val);
186 return SCM_UNSPECIFIED;
187 }
188
189
190 SCM_PROC(s_builtin_variable, "builtin-variable", 1, 0, 0, scm_builtin_variable);
191
192 SCM
193 scm_builtin_variable (name)
194 SCM name;
195 {
196 SCM vcell;
197 SCM var_slot;
198
199 SCM_ASSERT (SCM_NIMP (name) && SCM_SYMBOLP (name), name, SCM_ARG1, s_builtin_variable);
200 vcell = scm_sym2vcell (name, SCM_BOOL_F, SCM_BOOL_T);
201 if (vcell == SCM_BOOL_F)
202 return SCM_BOOL_F;
203
204 scm_intern_symbol (scm_symhash_vars, name);
205 var_slot = scm_sym2ovcell (name, scm_symhash_vars);
206
207 SCM_DEFER_INTS;
208 if ( SCM_IMP (SCM_CDR (var_slot))
209 || (SCM_VARVCELL (var_slot) != vcell))
210 SCM_SETCDR (var_slot, make_vcell_variable (vcell));
211 SCM_ALLOW_INTS;
212
213 return SCM_CDR (var_slot);
214 }
215
216
217 SCM_PROC(s_variable_bound_p, "variable-bound?", 1, 0, 0, scm_variable_bound_p);
218
219 SCM
220 scm_variable_bound_p (var)
221 SCM var;
222 {
223 SCM_ASSERT (SCM_NIMP(var) && SCM_VARIABLEP (var), var, SCM_ARG1, s_variable_bound_p);
224 return (SCM_UNBNDP (SCM_CDR (SCM_VARVCELL (var)))
225 ? SCM_BOOL_F
226 : SCM_BOOL_T);
227 }
228
229
230
231
232 void
233 scm_init_variable ()
234 {
235 scm_tc16_variable = scm_make_smob_type_mfpe ("variable", 0,
236 scm_markvar, NULL, prin_var, var_equal);
237 anonymous_variable_sym = SCM_CAR (scm_sysintern ("anonymous-variable", SCM_UNDEFINED));
238 #include "variable.x"
239 }
240