latin1 strings in vm error messages
[bpt/guile.git] / libguile / eval.c
CommitLineData
4a655e50 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011
434f2f7a 2 * Free Software Foundation, Inc.
0f2d19dd 3 *
73be1d9e 4 * This library is free software; you can redistribute it and/or
53befeb7
NJ
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation; either version 3 of
7 * the License, or (at your option) any later version.
0f2d19dd 8 *
53befeb7
NJ
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
0f2d19dd 13 *
73be1d9e
MV
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
53befeb7
NJ
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA
73be1d9e 18 */
1bbd0b84 19
0f2d19dd
JB
20\f
21
dbb605f5 22#ifdef HAVE_CONFIG_H
3d05f2e0
RB
23# include <config.h>
24#endif
0f2d19dd 25
f7439099 26#include <alloca.h>
3d05f2e0 27
f7439099 28#include "libguile/__scm.h"
48b96f4b 29
a0599745 30#include "libguile/_scm.h"
21628685
DH
31#include "libguile/alist.h"
32#include "libguile/async.h"
33#include "libguile/continuations.h"
747022e4 34#include "libguile/control.h"
a0599745 35#include "libguile/debug.h"
328dc9a3 36#include "libguile/deprecation.h"
09074dbf 37#include "libguile/dynwind.h"
a0599745 38#include "libguile/eq.h"
a310a1d1 39#include "libguile/expand.h"
21628685
DH
40#include "libguile/feature.h"
41#include "libguile/fluids.h"
21628685
DH
42#include "libguile/goops.h"
43#include "libguile/hash.h"
44#include "libguile/hashtab.h"
4610b011 45#include "libguile/list.h"
a0599745 46#include "libguile/macros.h"
b7742c6b 47#include "libguile/memoize.h"
a0599745
MD
48#include "libguile/modules.h"
49#include "libguile/ports.h"
7e6e6b37 50#include "libguile/print.h"
21628685 51#include "libguile/procprop.h"
4abef68f 52#include "libguile/programs.h"
a0599745 53#include "libguile/root.h"
21628685
DH
54#include "libguile/smob.h"
55#include "libguile/srcprop.h"
56#include "libguile/stackchk.h"
57#include "libguile/strings.h"
9de87eea 58#include "libguile/threads.h"
21628685
DH
59#include "libguile/throw.h"
60#include "libguile/validate.h"
a513ead3 61#include "libguile/values.h"
21628685 62#include "libguile/vectors.h"
4abef68f 63#include "libguile/vm.h"
a0599745 64
a0599745 65#include "libguile/eval.h"
0ee05b85 66#include "libguile/private-options.h"
89efbff4 67
0f2d19dd
JB
68\f
69
0ee05b85 70
b7742c6b 71/* We have three levels of EVAL here:
609a8b86 72
b7742c6b 73 - eval (exp, env)
89bff2fc 74
b7742c6b
AW
75 evaluates EXP in environment ENV. ENV is a lexical environment
76 structure as used by the actual tree code evaluator. When ENV is
77 a top-level environment, then changes to the current module are
78 tracked by updating ENV so that it continues to be in sync with
79 the current module.
e6729603 80
b7742c6b 81 - scm_primitive_eval (exp)
e6729603 82
b7742c6b
AW
83 evaluates EXP in the top-level environment as determined by the
84 current module. This is done by constructing a suitable
85 environment and calling eval. Thus, changes to the
86 top-level module are tracked normally.
e6729603 87
b7742c6b 88 - scm_eval (exp, mod)
e6729603 89
b7742c6b
AW
90 evaluates EXP while MOD is the current module. This is done
91 by setting the current module to MOD_OR_STATE, invoking
92 scm_primitive_eval on EXP, and then restoring the current module
93 to the value it had previously. That is, while EXP is evaluated,
94 changes to the current module (or dynamic state) are tracked,
95 but these changes do not persist when scm_eval returns.
e6729603 96
b7742c6b 97*/
e6729603 98
e6729603 99
314b8716
AW
100/* Boot closures. We only see these when compiling eval.scm, because once
101 eval.scm is in the house, closures are standard VM closures.
102 */
103
104static scm_t_bits scm_tc16_boot_closure;
105#define RETURN_BOOT_CLOSURE(code, env) SCM_RETURN_NEWSMOB2 (scm_tc16_boot_closure, (code), (env))
106#define BOOT_CLOSURE_P(obj) SCM_TYP16_PREDICATE (scm_tc16_boot_closure, (obj))
107#define BOOT_CLOSURE_CODE(x) SCM_SMOB_OBJECT (x)
108#define BOOT_CLOSURE_ENV(x) SCM_SMOB_OBJECT_2 (x)
8f9c5b58
AW
109#define BOOT_CLOSURE_BODY(x) CAR (BOOT_CLOSURE_CODE (x))
110#define BOOT_CLOSURE_NUM_REQUIRED_ARGS(x) SCM_I_INUM (CADR (BOOT_CLOSURE_CODE (x)))
111#define BOOT_CLOSURE_IS_FIXED(x) scm_is_null (CDDR (BOOT_CLOSURE_CODE (x)))
112/* NB: One may only call the following accessors if the closure is not FIXED. */
113#define BOOT_CLOSURE_HAS_REST_ARGS(x) scm_is_true (CADDR (BOOT_CLOSURE_CODE (x)))
114#define BOOT_CLOSURE_IS_REST(x) scm_is_null (CDDDR (BOOT_CLOSURE_CODE (x)))
115/* NB: One may only call the following accessors if the closure is not REST. */
116#define BOOT_CLOSURE_IS_FULL(x) (1)
dc3e203e
AW
117#define BOOT_CLOSURE_PARSE_FULL(fu_,body,nargs,rest,nopt,kw,inits,alt) \
118 do { SCM fu = fu_; \
119 body = CAR (fu); fu = CDR (fu); \
120 \
121 rest = kw = alt = SCM_BOOL_F; \
122 inits = SCM_EOL; \
123 nopt = 0; \
124 \
125 nreq = SCM_I_INUM (CAR (fu)); fu = CDR (fu); \
126 if (scm_is_pair (fu)) \
127 { \
128 rest = CAR (fu); fu = CDR (fu); \
129 if (scm_is_pair (fu)) \
130 { \
131 nopt = SCM_I_INUM (CAR (fu)); fu = CDR (fu); \
132 kw = CAR (fu); fu = CDR (fu); \
133 inits = CAR (fu); fu = CDR (fu); \
134 alt = CAR (fu); \
135 } \
136 } \
d8a071fc 137 } while (0)
7572ee52
AW
138static void prepare_boot_closure_env_for_apply (SCM proc, SCM args,
139 SCM *out_body, SCM *out_env);
140static void prepare_boot_closure_env_for_eval (SCM proc, unsigned int argc,
141 SCM exps, SCM *out_body,
142 SCM *inout_env);
314b8716
AW
143
144
b7742c6b
AW
145#define CAR(x) SCM_CAR(x)
146#define CDR(x) SCM_CDR(x)
147#define CAAR(x) SCM_CAAR(x)
148#define CADR(x) SCM_CADR(x)
149#define CDAR(x) SCM_CDAR(x)
150#define CDDR(x) SCM_CDDR(x)
151#define CADDR(x) SCM_CADDR(x)
152#define CDDDR(x) SCM_CDDDR(x)
e6729603
DH
153
154
b7742c6b 155SCM_SYMBOL (scm_unbound_variable_key, "unbound-variable");
e6729603 156
b7742c6b 157static void error_used_before_defined (void)
d0624e39 158{
b7742c6b
AW
159 scm_error (scm_unbound_variable_key, NULL,
160 "Variable used before given a value", SCM_EOL, SCM_BOOL_F);
d0624e39 161}
d0624e39 162
d8a071fc
AW
163static void error_invalid_keyword (SCM proc)
164{
4a655e50 165 scm_error_scm (scm_from_latin1_symbol ("keyword-argument-error"), proc,
d8a071fc
AW
166 scm_from_locale_string ("Invalid keyword"), SCM_EOL,
167 SCM_BOOL_F);
168}
169
170static void error_unrecognized_keyword (SCM proc)
171{
4a655e50 172 scm_error_scm (scm_from_latin1_symbol ("keyword-argument-error"), proc,
d8a071fc
AW
173 scm_from_locale_string ("Unrecognized keyword"), SCM_EOL,
174 SCM_BOOL_F);
175}
176
177
b7742c6b 178/* the environment:
3149a5b6 179 (VAL ... . MOD)
b7742c6b
AW
180 If MOD is #f, it means the environment was captured before modules were
181 booted.
182 If MOD is the literal value '(), we are evaluating at the top level, and so
183 should track changes to the current module. You have to be careful in this
184 case, because further lexical contours should capture the current module.
185*/
186#define CAPTURE_ENV(env) \
187 ((env == SCM_EOL) ? scm_current_module () : \
188 ((env == SCM_BOOL_F) ? scm_the_root_module () : env))
6f81708a
DH
189
190static SCM
b7742c6b 191eval (SCM x, SCM env)
6f81708a 192{
b7742c6b
AW
193 SCM mx;
194 SCM proc = SCM_UNDEFINED, args = SCM_EOL;
b7ecadca 195 unsigned int argc;
6f81708a 196
b7742c6b
AW
197 loop:
198 SCM_TICK;
199 if (!SCM_MEMOIZED_P (x))
200 abort ();
201
202 mx = SCM_MEMOIZED_ARGS (x);
203 switch (SCM_MEMOIZED_TAG (x))
204 {
205 case SCM_M_BEGIN:
206 for (; !scm_is_null (CDR (mx)); mx = CDR (mx))
207 eval (CAR (mx), env);
208 x = CAR (mx);
209 goto loop;
210
211 case SCM_M_IF:
212 if (scm_is_true (eval (CAR (mx), env)))
213 x = CADR (mx);
6f81708a 214 else
b7742c6b
AW
215 x = CDDR (mx);
216 goto loop;
5fb64383 217
b7742c6b
AW
218 case SCM_M_LET:
219 {
220 SCM inits = CAR (mx);
221 SCM new_env = CAPTURE_ENV (env);
222 for (; scm_is_pair (inits); inits = CDR (inits))
223 new_env = scm_cons (eval (CAR (inits), env), new_env);
224 env = new_env;
225 x = CDR (mx);
226 goto loop;
227 }
228
229 case SCM_M_LAMBDA:
314b8716 230 RETURN_BOOT_CLOSURE (mx, CAPTURE_ENV (env));
5fb64383 231
b7742c6b
AW
232 case SCM_M_QUOTE:
233 return mx;
0f2d19dd 234
b7742c6b
AW
235 case SCM_M_DEFINE:
236 scm_define (CAR (mx), eval (CDR (mx), env));
237 return SCM_UNSPECIFIED;
212e58ed 238
d69531e2
AW
239 case SCM_M_DYNWIND:
240 {
241 SCM in, out, res, old_winds;
242 in = eval (CAR (mx), env);
243 out = eval (CDDR (mx), env);
244 scm_call_0 (in);
245 old_winds = scm_i_dynwinds ();
246 scm_i_set_dynwinds (scm_acons (in, out, old_winds));
247 res = eval (CADR (mx), env);
248 scm_i_set_dynwinds (old_winds);
249 scm_call_0 (out);
250 return res;
251 }
252
bb0229b5
AW
253 case SCM_M_WITH_FLUIDS:
254 {
255 long i, len;
256 SCM *fluidv, *valuesv, walk, wf, res;
257 len = scm_ilength (CAR (mx));
258 fluidv = alloca (sizeof (SCM)*len);
259 for (i = 0, walk = CAR (mx); i < len; i++, walk = CDR (walk))
260 fluidv[i] = eval (CAR (walk), env);
261 valuesv = alloca (sizeof (SCM)*len);
262 for (i = 0, walk = CADR (mx); i < len; i++, walk = CDR (walk))
263 valuesv[i] = eval (CAR (walk), env);
264
265 wf = scm_i_make_with_fluids (len, fluidv, valuesv);
266 scm_i_swap_with_fluids (wf, SCM_I_CURRENT_THREAD->dynamic_state);
267 scm_i_set_dynwinds (scm_cons (wf, scm_i_dynwinds ()));
268 res = eval (CDDR (mx), env);
269 scm_i_swap_with_fluids (wf, SCM_I_CURRENT_THREAD->dynamic_state);
270 scm_i_set_dynwinds (CDR (scm_i_dynwinds ()));
271
272 return res;
273 }
274
b7742c6b
AW
275 case SCM_M_APPLY:
276 /* Evaluate the procedure to be applied. */
277 proc = eval (CAR (mx), env);
278 /* Evaluate the argument holding the list of arguments */
279 args = eval (CADR (mx), env);
280
281 apply_proc:
282 /* Go here to tail-apply a procedure. PROC is the procedure and
283 * ARGS is the list of arguments. */
314b8716 284 if (BOOT_CLOSURE_P (proc))
b7742c6b 285 {
7572ee52 286 prepare_boot_closure_env_for_apply (proc, args, &x, &env);
b7742c6b
AW
287 goto loop;
288 }
289 else
ea9f4f4b 290 return scm_call_with_vm (scm_the_vm (), proc, args);
212e58ed 291
b7742c6b
AW
292 case SCM_M_CALL:
293 /* Evaluate the procedure to be applied. */
294 proc = eval (CAR (mx), env);
b7ecadca 295 argc = SCM_I_INUM (CADR (mx));
9331f91c 296 mx = CDDR (mx);
212e58ed 297
314b8716 298 if (BOOT_CLOSURE_P (proc))
5fa0939c 299 {
7572ee52 300 prepare_boot_closure_env_for_eval (proc, argc, mx, &x, &env);
b7742c6b 301 goto loop;
5fa0939c 302 }
b7742c6b
AW
303 else
304 {
e2cf8eb9 305 SCM *argv;
b7ecadca
LC
306 unsigned int i;
307
e2cf8eb9 308 argv = alloca (argc * sizeof (SCM));
b7ecadca
LC
309 for (i = 0; i < argc; i++, mx = CDR (mx))
310 argv[i] = eval (CAR (mx), env);
311
312 return scm_c_vm_run (scm_the_vm (), proc, argv, argc);
b7742c6b 313 }
b7ecadca 314
b7742c6b 315 case SCM_M_CONT:
babfc7b2 316 return scm_i_call_with_current_continuation (eval (mx, env));
212e58ed 317
b7742c6b
AW
318 case SCM_M_CALL_WITH_VALUES:
319 {
320 SCM producer;
321 SCM v;
322
323 producer = eval (CAR (mx), env);
324 proc = eval (CDR (mx), env); /* proc is the consumer. */
ea9f4f4b 325 v = scm_call_with_vm (scm_the_vm (), producer, SCM_EOL);
b7742c6b
AW
326 if (SCM_VALUESP (v))
327 args = scm_struct_ref (v, SCM_INUM0);
328 else
329 args = scm_list_1 (v);
330 goto apply_proc;
331 }
26d5b9b4 332
b7742c6b
AW
333 case SCM_M_LEXICAL_REF:
334 {
335 int n;
336 SCM ret;
337 for (n = SCM_I_INUM (mx); n; n--)
338 env = CDR (env);
339 ret = CAR (env);
340 if (SCM_UNLIKELY (SCM_UNBNDP (ret)))
341 /* we don't know what variable, though, because we don't have its
342 name */
343 error_used_before_defined ();
344 return ret;
345 }
1cc91f1b 346
b7742c6b
AW
347 case SCM_M_LEXICAL_SET:
348 {
349 int n;
350 SCM val = eval (CDR (mx), env);
351 for (n = SCM_I_INUM (CAR (mx)); n; n--)
352 env = CDR (env);
353 SCM_SETCAR (env, val);
354 return SCM_UNSPECIFIED;
355 }
910b5125 356
b7742c6b
AW
357 case SCM_M_TOPLEVEL_REF:
358 if (SCM_VARIABLEP (mx))
359 return SCM_VARIABLE_REF (mx);
360 else
57d23e25 361 {
b7742c6b 362 while (scm_is_pair (env))
f3a8d1b7 363 env = CDR (env);
3149a5b6
AW
364 return SCM_VARIABLE_REF
365 (scm_memoize_variable_access_x (x, CAPTURE_ENV (env)));
57d23e25 366 }
57d23e25 367
b7742c6b
AW
368 case SCM_M_TOPLEVEL_SET:
369 {
370 SCM var = CAR (mx);
371 SCM val = eval (CDR (mx), env);
372 if (SCM_VARIABLEP (var))
373 {
374 SCM_VARIABLE_SET (var, val);
375 return SCM_UNSPECIFIED;
376 }
377 else
378 {
379 while (scm_is_pair (env))
f3a8d1b7 380 env = CDR (env);
3149a5b6
AW
381 SCM_VARIABLE_SET
382 (scm_memoize_variable_access_x (x, CAPTURE_ENV (env)),
383 val);
b7742c6b
AW
384 return SCM_UNSPECIFIED;
385 }
386 }
910b5125 387
b7742c6b
AW
388 case SCM_M_MODULE_REF:
389 if (SCM_VARIABLEP (mx))
390 return SCM_VARIABLE_REF (mx);
910b5125 391 else
3149a5b6
AW
392 return SCM_VARIABLE_REF
393 (scm_memoize_variable_access_x (x, SCM_BOOL_F));
910b5125 394
b7742c6b
AW
395 case SCM_M_MODULE_SET:
396 if (SCM_VARIABLEP (CDR (mx)))
910b5125 397 {
b7742c6b
AW
398 SCM_VARIABLE_SET (CDR (mx), eval (CAR (mx), env));
399 return SCM_UNSPECIFIED;
400 }
401 else
402 {
3149a5b6
AW
403 SCM_VARIABLE_SET
404 (scm_memoize_variable_access_x (x, SCM_BOOL_F),
405 eval (CAR (mx), env));
b7742c6b 406 return SCM_UNSPECIFIED;
910b5125 407 }
910b5125 408
747022e4
AW
409 case SCM_M_PROMPT:
410 {
7112a34d
AW
411 SCM vm, res;
412 /* We need the prompt and handler values after a longjmp case,
413 so make sure they are volatile. */
414 volatile SCM handler, prompt;
747022e4 415
d2964315
AW
416 vm = scm_the_vm ();
417 prompt = scm_c_make_prompt (eval (CAR (mx), env), SCM_VM_DATA (vm)->fp,
418 SCM_VM_DATA (vm)->sp, SCM_VM_DATA (vm)->ip,
adbdfd6d 419 0, -1, scm_i_dynwinds ());
747022e4
AW
420 handler = eval (CDDR (mx), env);
421 scm_i_set_dynwinds (scm_cons (prompt, scm_i_dynwinds ()));
422
423 if (SCM_PROMPT_SETJMP (prompt))
424 {
b8af64db 425 /* The prompt exited nonlocally. */
747022e4 426 proc = handler;
572eef50 427 args = scm_i_prompt_pop_abort_args_x (scm_the_vm ());
747022e4
AW
428 goto apply_proc;
429 }
430
431 res = eval (CADR (mx), env);
432 scm_i_set_dynwinds (CDR (scm_i_dynwinds ()));
433 return res;
434 }
435
b7742c6b
AW
436 default:
437 abort ();
438 }
910b5125
DH
439}
440
b7742c6b 441\f
2a6f7afe 442
b7742c6b
AW
443/* Simple procedure calls
444 */
2a6f7afe 445
b7742c6b
AW
446SCM
447scm_call_0 (SCM proc)
448{
bf5a05f2 449 return scm_c_vm_run (scm_the_vm (), proc, NULL, 0);
0f2d19dd
JB
450}
451
b7742c6b
AW
452SCM
453scm_call_1 (SCM proc, SCM arg1)
212e58ed 454{
bf5a05f2 455 return scm_c_vm_run (scm_the_vm (), proc, &arg1, 1);
b7742c6b 456}
212e58ed 457
b7742c6b
AW
458SCM
459scm_call_2 (SCM proc, SCM arg1, SCM arg2)
460{
bf5a05f2
AW
461 SCM args[] = { arg1, arg2 };
462 return scm_c_vm_run (scm_the_vm (), proc, args, 2);
212e58ed
DH
463}
464
b7742c6b
AW
465SCM
466scm_call_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)
0f2d19dd 467{
bf5a05f2
AW
468 SCM args[] = { arg1, arg2, arg3 };
469 return scm_c_vm_run (scm_the_vm (), proc, args, 3);
0f2d19dd
JB
470}
471
b7742c6b
AW
472SCM
473scm_call_4 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4)
212e58ed 474{
bf5a05f2
AW
475 SCM args[] = { arg1, arg2, arg3, arg4 };
476 return scm_c_vm_run (scm_the_vm (), proc, args, 4);
212e58ed
DH
477}
478
f32e67be
AW
479SCM
480scm_call_5 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5)
481{
482 SCM args[] = { arg1, arg2, arg3, arg4, arg5 };
483 return scm_c_vm_run (scm_the_vm (), proc, args, 5);
484}
485
486SCM
487scm_call_6 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
488 SCM arg6)
489{
490 SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6 };
491 return scm_c_vm_run (scm_the_vm (), proc, args, 6);
492}
493
86fd6dff
AW
494SCM
495scm_call_n (SCM proc, SCM *argv, size_t nargs)
496{
497 return scm_c_vm_run (scm_the_vm (), proc, argv, nargs);
498}
499
b7742c6b 500/* Simple procedure applies
9fbee57e 501 */
cc56ba80 502
b7742c6b
AW
503SCM
504scm_apply_0 (SCM proc, SCM args)
505{
506 return scm_apply (proc, args, SCM_EOL);
0f572ba7
DH
507}
508
b7742c6b
AW
509SCM
510scm_apply_1 (SCM proc, SCM arg1, SCM args)
0f572ba7 511{
b7742c6b 512 return scm_apply (proc, scm_cons (arg1, args), SCM_EOL);
8ae95199
DH
513}
514
b7742c6b
AW
515SCM
516scm_apply_2 (SCM proc, SCM arg1, SCM arg2, SCM args)
0f2d19dd 517{
b7742c6b 518 return scm_apply (proc, scm_cons2 (arg1, arg2, args), SCM_EOL);
0f2d19dd
JB
519}
520
b7742c6b
AW
521SCM
522scm_apply_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM args)
212e58ed 523{
b7742c6b
AW
524 return scm_apply (proc, scm_cons (arg1, scm_cons2 (arg2, arg3, args)),
525 SCM_EOL);
212e58ed
DH
526}
527
b7742c6b 528/* This code processes the arguments to apply:
8ea46249 529
b7742c6b 530 (apply PROC ARG1 ... ARGS)
302c12b4 531
b7742c6b
AW
532 Given a list (ARG1 ... ARGS), this function conses the ARG1
533 ... arguments onto the front of ARGS, and returns the resulting
534 list. Note that ARGS is a list; thus, the argument to this
535 function is a list whose last element is a list.
302c12b4 536
b7742c6b
AW
537 Apply calls this function, and applies PROC to the elements of the
538 result. apply:nconc2last takes care of building the list of
539 arguments, given (ARG1 ... ARGS).
a954ce1d 540
b7742c6b
AW
541 Rather than do new consing, apply:nconc2last destroys its argument.
542 On that topic, this code came into my care with the following
543 beautifully cryptic comment on that topic: "This will only screw
544 you if you do (scm_apply scm_apply '( ... ))" If you know what
545 they're referring to, send me a patch to this comment. */
0f2d19dd 546
b7742c6b
AW
547SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
548 (SCM lst),
549 "Given a list (@var{arg1} @dots{} @var{args}), this function\n"
550 "conses the @var{arg1} @dots{} arguments onto the front of\n"
551 "@var{args}, and returns the resulting list. Note that\n"
552 "@var{args} is a list; thus, the argument to this function is\n"
553 "a list whose last element is a list.\n"
554 "Note: Rather than do new consing, @code{apply:nconc2last}\n"
555 "destroys its argument, so use with care.")
556#define FUNC_NAME s_scm_nconc2last
212e58ed 557{
b7742c6b
AW
558 SCM *lloc;
559 SCM_VALIDATE_NONEMPTYLIST (1, lst);
560 lloc = &lst;
b6b84131 561 while (!scm_is_null (SCM_CDR (*lloc)))
b7742c6b
AW
562 lloc = SCM_CDRLOC (*lloc);
563 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
564 *lloc = SCM_CAR (*lloc);
565 return lst;
212e58ed 566}
b7742c6b 567#undef FUNC_NAME
212e58ed 568
b8229a3b
MS
569
570
b7742c6b 571/* Typechecking for multi-argument MAP and FOR-EACH.
0f2d19dd 572
b7742c6b
AW
573 Verify that each element of the vector ARGV, except for the first,
574 is a proper list whose length is LEN. Attribute errors to WHO,
575 and claim that the i'th element of ARGV is WHO's i+2'th argument. */
576static inline void
577check_map_args (SCM argv,
578 long len,
579 SCM gf,
580 SCM proc,
581 SCM args,
582 const char *who)
212e58ed 583{
b7742c6b 584 long i;
0f2d19dd 585
b7742c6b 586 for (i = SCM_SIMPLE_VECTOR_LENGTH (argv) - 1; i >= 1; i--)
9fbee57e 587 {
b7742c6b
AW
588 SCM elt = SCM_SIMPLE_VECTOR_REF (argv, i);
589 long elt_len = scm_ilength (elt);
5cb22e96 590
b7742c6b
AW
591 if (elt_len < 0)
592 {
593 if (gf)
594 scm_apply_generic (gf, scm_cons (proc, args));
595 else
596 scm_wrong_type_arg (who, i + 2, elt);
597 }
1cc91f1b 598
b7742c6b
AW
599 if (elt_len != len)
600 scm_out_of_range_pos (who, elt, scm_from_long (i + 2));
0f2d19dd 601 }
0f2d19dd 602}
6dbd0af5 603
212e58ed 604
b7742c6b 605SCM_GPROC (s_map, "map", 2, 0, 1, scm_map, g_map);
212e58ed 606
b7742c6b
AW
607/* Note: Currently, scm_map applies PROC to the argument list(s)
608 sequentially, starting with the first element(s). This is used in
609 evalext.c where the Scheme procedure `map-in-order', which guarantees
610 sequential behaviour, is implemented using scm_map. If the
611 behaviour changes, we need to update `map-in-order'.
612*/
0f2d19dd 613
b7742c6b
AW
614SCM
615scm_map (SCM proc, SCM arg1, SCM args)
616#define FUNC_NAME s_map
0f2d19dd 617{
b7742c6b
AW
618 long i, len;
619 SCM res = SCM_EOL;
620 SCM *pres = &res;
0f2d19dd 621
b7742c6b
AW
622 len = scm_ilength (arg1);
623 SCM_GASSERTn (len >= 0,
624 g_map, scm_cons2 (proc, arg1, args), SCM_ARG2, s_map);
625 SCM_VALIDATE_REST_ARGUMENT (args);
626 if (scm_is_null (args))
0f2d19dd 627 {
b7742c6b
AW
628 SCM_GASSERT2 (scm_is_true (scm_procedure_p (proc)), g_map, proc, arg1, SCM_ARG1, s_map);
629 while (SCM_NIMP (arg1))
630 {
631 *pres = scm_list_1 (scm_call_1 (proc, SCM_CAR (arg1)));
632 pres = SCM_CDRLOC (*pres);
633 arg1 = SCM_CDR (arg1);
634 }
635 return res;
0f2d19dd 636 }
b7742c6b
AW
637 if (scm_is_null (SCM_CDR (args)))
638 {
639 SCM arg2 = SCM_CAR (args);
640 int len2 = scm_ilength (arg2);
641 SCM_GASSERTn (scm_is_true (scm_procedure_p (proc)), g_map,
642 scm_cons2 (proc, arg1, args), SCM_ARG1, s_map);
643 SCM_GASSERTn (len2 >= 0,
644 g_map, scm_cons2 (proc, arg1, args), SCM_ARG3, s_map);
645 if (len2 != len)
646 SCM_OUT_OF_RANGE (3, arg2);
647 while (SCM_NIMP (arg1))
648 {
649 *pres = scm_list_1 (scm_call_2 (proc, SCM_CAR (arg1), SCM_CAR (arg2)));
650 pres = SCM_CDRLOC (*pres);
651 arg1 = SCM_CDR (arg1);
652 arg2 = SCM_CDR (arg2);
653 }
654 return res;
655 }
656 arg1 = scm_cons (arg1, args);
657 args = scm_vector (arg1);
658 check_map_args (args, len, g_map, proc, arg1, s_map);
659 while (1)
d6754c23 660 {
b7742c6b
AW
661 arg1 = SCM_EOL;
662 for (i = SCM_SIMPLE_VECTOR_LENGTH (args) - 1; i >= 0; i--)
663 {
664 SCM elt = SCM_SIMPLE_VECTOR_REF (args, i);
665 if (SCM_IMP (elt))
666 return res;
667 arg1 = scm_cons (SCM_CAR (elt), arg1);
668 SCM_SIMPLE_VECTOR_SET (args, i, SCM_CDR (elt));
669 }
670 *pres = scm_list_1 (scm_apply (proc, arg1, SCM_EOL));
671 pres = SCM_CDRLOC (*pres);
d6754c23 672 }
0f2d19dd 673}
b7742c6b 674#undef FUNC_NAME
0f2d19dd 675
302c12b4 676
b7742c6b 677SCM_GPROC (s_for_each, "for-each", 2, 0, 1, scm_for_each, g_for_each);
d6754c23 678
b7742c6b
AW
679SCM
680scm_for_each (SCM proc, SCM arg1, SCM args)
681#define FUNC_NAME s_for_each
0f2d19dd 682{
b7742c6b
AW
683 long i, len;
684 len = scm_ilength (arg1);
685 SCM_GASSERTn (len >= 0, g_for_each, scm_cons2 (proc, arg1, args),
686 SCM_ARG2, s_for_each);
687 SCM_VALIDATE_REST_ARGUMENT (args);
688 if (scm_is_null (args))
26d5b9b4 689 {
b7742c6b
AW
690 SCM_GASSERT2 (scm_is_true (scm_procedure_p (proc)), g_for_each,
691 proc, arg1, SCM_ARG1, s_for_each);
692 while (SCM_NIMP (arg1))
693 {
694 scm_call_1 (proc, SCM_CAR (arg1));
695 arg1 = SCM_CDR (arg1);
696 }
697 return SCM_UNSPECIFIED;
26d5b9b4 698 }
b7742c6b 699 if (scm_is_null (SCM_CDR (args)))
26d5b9b4 700 {
b7742c6b
AW
701 SCM arg2 = SCM_CAR (args);
702 int len2 = scm_ilength (arg2);
703 SCM_GASSERTn (scm_is_true (scm_procedure_p (proc)), g_for_each,
704 scm_cons2 (proc, arg1, args), SCM_ARG1, s_for_each);
705 SCM_GASSERTn (len2 >= 0, g_for_each,
706 scm_cons2 (proc, arg1, args), SCM_ARG3, s_for_each);
707 if (len2 != len)
708 SCM_OUT_OF_RANGE (3, arg2);
709 while (SCM_NIMP (arg1))
710 {
711 scm_call_2 (proc, SCM_CAR (arg1), SCM_CAR (arg2));
712 arg1 = SCM_CDR (arg1);
713 arg2 = SCM_CDR (arg2);
714 }
715 return SCM_UNSPECIFIED;
26d5b9b4 716 }
b7742c6b
AW
717 arg1 = scm_cons (arg1, args);
718 args = scm_vector (arg1);
719 check_map_args (args, len, g_for_each, proc, arg1, s_for_each);
720 while (1)
302c12b4 721 {
b7742c6b
AW
722 arg1 = SCM_EOL;
723 for (i = SCM_SIMPLE_VECTOR_LENGTH (args) - 1; i >= 0; i--)
71560395 724 {
b7742c6b
AW
725 SCM elt = SCM_SIMPLE_VECTOR_REF (args, i);
726 if (SCM_IMP (elt))
727 return SCM_UNSPECIFIED;
728 arg1 = scm_cons (SCM_CAR (elt), arg1);
729 SCM_SIMPLE_VECTOR_SET (args, i, SCM_CDR (elt));
730 }
731 scm_apply (proc, arg1, SCM_EOL);
732 }
733}
734#undef FUNC_NAME
71560395 735
71560395 736
5f161164
AW
737static SCM
738scm_c_primitive_eval (SCM exp)
b7742c6b 739{
a310a1d1 740 if (!SCM_EXPANDED_P (exp))
4f692ace 741 exp = scm_call_1 (scm_current_module_transformer (), exp);
a310a1d1 742 return eval (scm_memoize_expression (exp), SCM_EOL);
b7742c6b 743}
5f161164
AW
744
745static SCM var_primitive_eval;
746SCM
747scm_primitive_eval (SCM exp)
748{
749 return scm_c_vm_run (scm_the_vm (), scm_variable_ref (var_primitive_eval),
750 &exp, 1);
751}
71560395 752
b7742c6b
AW
753
754/* Eval does not take the second arg optionally. This is intentional
755 * in order to be R5RS compatible, and to prepare for the new module
756 * system, where we would like to make the choice of evaluation
757 * environment explicit. */
758
759SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
760 (SCM exp, SCM module_or_state),
761 "Evaluate @var{exp}, a list representing a Scheme expression,\n"
762 "in the top-level environment specified by\n"
763 "@var{module_or_state}.\n"
764 "While @var{exp} is evaluated (using @code{primitive-eval}),\n"
765 "@var{module_or_state} is made the current module when\n"
766 "it is a module, or the current dynamic state when it is\n"
767 "a dynamic state."
768 "Example: (eval '(+ 1 2) (interaction-environment))")
769#define FUNC_NAME s_scm_eval
770{
771 SCM res;
772
773 scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
774 if (scm_is_dynamic_state (module_or_state))
775 scm_dynwind_current_dynamic_state (module_or_state);
776 else if (scm_module_system_booted_p)
777 {
778 SCM_VALIDATE_MODULE (2, module_or_state);
779 scm_dynwind_current_module (module_or_state);
71560395 780 }
b7742c6b 781 /* otherwise if the module system isn't booted, ignore the module arg */
71560395 782
b7742c6b
AW
783 res = scm_primitive_eval (exp);
784
785 scm_dynwind_end ();
786 return res;
787}
788#undef FUNC_NAME
71560395
AW
789
790
b7742c6b 791static SCM f_apply;
71560395
AW
792
793/* Apply a function to a list of arguments.
794
795 This function is exported to the Scheme level as taking two
796 required arguments and a tail argument, as if it were:
797 (lambda (proc arg1 . args) ...)
798 Thus, if you just have a list of arguments to pass to a procedure,
799 pass the list as ARG1, and '() for ARGS. If you have some fixed
800 args, pass the first as ARG1, then cons any remaining fixed args
801 onto the front of your argument list, and pass that as ARGS. */
802
803SCM
804scm_apply (SCM proc, SCM arg1, SCM args)
805{
b7742c6b 806 /* Fix things up so that args contains all args. */
71560395 807 if (scm_is_null (args))
b7742c6b 808 args = arg1;
71560395 809 else
b7742c6b 810 args = scm_cons_star (arg1, args);
71560395 811
ea9f4f4b 812 return scm_call_with_vm (scm_the_vm (), proc, args);
b7742c6b 813}
434f2f7a 814
7572ee52
AW
815static void
816prepare_boot_closure_env_for_apply (SCM proc, SCM args,
817 SCM *out_body, SCM *out_env)
314b8716 818{
8f9c5b58
AW
819 int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (proc);
820 SCM env = BOOT_CLOSURE_ENV (proc);
dc3e203e 821
8f9c5b58
AW
822 if (BOOT_CLOSURE_IS_FIXED (proc)
823 || (BOOT_CLOSURE_IS_REST (proc)
824 && !BOOT_CLOSURE_HAS_REST_ARGS (proc)))
825 {
826 if (SCM_UNLIKELY (scm_ilength (args) != nreq))
827 scm_wrong_num_args (proc);
828 for (; scm_is_pair (args); args = CDR (args))
829 env = scm_cons (CAR (args), env);
7572ee52
AW
830 *out_body = BOOT_CLOSURE_BODY (proc);
831 *out_env = env;
8f9c5b58
AW
832 }
833 else if (BOOT_CLOSURE_IS_REST (proc))
314b8716
AW
834 {
835 if (SCM_UNLIKELY (scm_ilength (args) < nreq))
8f9c5b58 836 scm_wrong_num_args (proc);
314b8716 837 for (; nreq; nreq--, args = CDR (args))
8f9c5b58
AW
838 env = scm_cons (CAR (args), env);
839 env = scm_cons (args, env);
7572ee52
AW
840 *out_body = BOOT_CLOSURE_BODY (proc);
841 *out_env = env;
314b8716
AW
842 }
843 else
d8a071fc
AW
844 {
845 int i, argc, nreq, nopt;
846 SCM body, rest, kw, inits, alt;
dc3e203e 847 SCM mx = BOOT_CLOSURE_CODE (proc);
d8a071fc 848
7572ee52 849 loop:
dc3e203e 850 BOOT_CLOSURE_PARSE_FULL (mx, body, nargs, rest, nopt, kw, inits, alt);
d8a071fc
AW
851
852 argc = scm_ilength (args);
853 if (argc < nreq)
854 {
855 if (scm_is_true (alt))
7572ee52 856 {
dc3e203e 857 mx = alt;
7572ee52
AW
858 goto loop;
859 }
d8a071fc
AW
860 else
861 scm_wrong_num_args (proc);
862 }
863 if (scm_is_false (kw) && argc > nreq + nopt && scm_is_false (rest))
864 {
865 if (scm_is_true (alt))
7572ee52 866 {
dc3e203e 867 mx = alt;
7572ee52
AW
868 goto loop;
869 }
d8a071fc
AW
870 else
871 scm_wrong_num_args (proc);
872 }
873
874 for (i = 0; i < nreq; i++, args = CDR (args))
875 env = scm_cons (CAR (args), env);
876
877 if (scm_is_false (kw))
878 {
879 /* Optional args (possibly), but no keyword args. */
880 for (; i < argc && i < nreq + nopt;
881 i++, args = CDR (args))
882 {
883 env = scm_cons (CAR (args), env);
884 inits = CDR (inits);
885 }
886
887 for (; i < nreq + nopt; i++, inits = CDR (inits))
888 env = scm_cons (eval (CAR (inits), env), env);
889
890 if (scm_is_true (rest))
891 env = scm_cons (args, env);
892 }
893 else
894 {
895 SCM aok;
896
897 aok = CAR (kw);
898 kw = CDR (kw);
899
900 /* Keyword args. As before, but stop at the first keyword. */
901 for (; i < argc && i < nreq + nopt && !scm_is_keyword (CAR (args));
902 i++, args = CDR (args), inits = CDR (inits))
903 env = scm_cons (CAR (args), env);
904
905 for (; i < nreq + nopt; i++, inits = CDR (inits))
906 env = scm_cons (eval (CAR (inits), env), env);
907
908 if (scm_is_true (rest))
909 {
910 env = scm_cons (args, env);
911 i++;
912 }
913
914 /* Now fill in env with unbound values, limn the rest of the args for
915 keywords, and fill in unbound values with their inits. */
916 {
917 int imax = i - 1;
918 int kw_start_idx = i;
919 SCM walk, k, v;
920 for (walk = kw; scm_is_pair (walk); walk = CDR (walk))
921 if (SCM_I_INUM (CDAR (walk)) > imax)
922 imax = SCM_I_INUM (CDAR (walk));
923 for (; i <= imax; i++)
924 env = scm_cons (SCM_UNDEFINED, env);
925
926 if (scm_is_pair (args) && scm_is_pair (CDR (args)))
927 for (; scm_is_pair (args) && scm_is_pair (CDR (args));
928 args = CDR (args))
929 {
930 k = CAR (args); v = CADR (args);
931 if (!scm_is_keyword (k))
932 {
933 if (scm_is_true (rest))
934 continue;
935 else
936 break;
937 }
938 for (walk = kw; scm_is_pair (walk); walk = CDR (walk))
939 if (scm_is_eq (k, CAAR (walk)))
940 {
941 /* Well... ok, list-set! isn't the nicest interface, but
942 hey. */
943 int iset = imax - SCM_I_INUM (CDAR (walk));
944 scm_list_set_x (env, SCM_I_MAKINUM (iset), v);
945 args = CDR (args);
946 break;
947 }
948 if (scm_is_null (walk) && scm_is_false (aok))
949 error_unrecognized_keyword (proc);
950 }
951 if (scm_is_pair (args) && scm_is_false (rest))
952 error_invalid_keyword (proc);
953
954 /* Now fill in unbound values, evaluating init expressions in their
955 appropriate environment. */
956 for (i = imax - kw_start_idx; scm_is_pair (inits); i--, inits = CDR (inits))
957 {
958 SCM tail = scm_list_tail (env, SCM_I_MAKINUM (i));
959 if (SCM_UNBNDP (CAR (tail)))
960 SCM_SETCAR (tail, eval (CAR (inits), CDR (tail)));
961 }
962 }
963 }
8f9c5b58 964
dc3e203e 965 *out_body = body;
7572ee52
AW
966 *out_env = env;
967 }
8f9c5b58
AW
968}
969
7572ee52 970static void
8f9c5b58 971prepare_boot_closure_env_for_eval (SCM proc, unsigned int argc,
7572ee52 972 SCM exps, SCM *out_body, SCM *inout_env)
8f9c5b58
AW
973{
974 int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (proc);
975 SCM new_env = BOOT_CLOSURE_ENV (proc);
976 if (BOOT_CLOSURE_IS_FIXED (proc)
977 || (BOOT_CLOSURE_IS_REST (proc)
978 && !BOOT_CLOSURE_HAS_REST_ARGS (proc)))
314b8716 979 {
8f9c5b58 980 for (; scm_is_pair (exps); exps = CDR (exps), nreq--)
7572ee52 981 new_env = scm_cons (eval (CAR (exps), *inout_env), new_env);
8f9c5b58
AW
982 if (SCM_UNLIKELY (nreq != 0))
983 scm_wrong_num_args (proc);
7572ee52
AW
984 *out_body = BOOT_CLOSURE_BODY (proc);
985 *inout_env = new_env;
314b8716 986 }
8f9c5b58
AW
987 else if (BOOT_CLOSURE_IS_REST (proc))
988 {
989 if (SCM_UNLIKELY (argc < nreq))
990 scm_wrong_num_args (proc);
991 for (; nreq; nreq--, exps = CDR (exps))
7572ee52 992 new_env = scm_cons (eval (CAR (exps), *inout_env), new_env);
8f9c5b58
AW
993 {
994 SCM rest = SCM_EOL;
995 for (; scm_is_pair (exps); exps = CDR (exps))
7572ee52 996 rest = scm_cons (eval (CAR (exps), *inout_env), rest);
8f9c5b58
AW
997 new_env = scm_cons (scm_reverse (rest),
998 new_env);
999 }
7572ee52
AW
1000 *out_body = BOOT_CLOSURE_BODY (proc);
1001 *inout_env = new_env;
8f9c5b58
AW
1002 }
1003 else
d8a071fc
AW
1004 {
1005 SCM args = SCM_EOL;
1006 for (; scm_is_pair (exps); exps = CDR (exps))
7572ee52
AW
1007 args = scm_cons (eval (CAR (exps), *inout_env), args);
1008 args = scm_reverse_x (args, SCM_UNDEFINED);
1009 prepare_boot_closure_env_for_apply (proc, args, out_body, inout_env);
d8a071fc 1010 }
8f9c5b58
AW
1011}
1012
1013static SCM
1014boot_closure_apply (SCM closure, SCM args)
1015{
7572ee52
AW
1016 SCM body, env;
1017 prepare_boot_closure_env_for_apply (closure, args, &body, &env);
1018 return eval (body, env);
314b8716
AW
1019}
1020
1021static int
1022boot_closure_print (SCM closure, SCM port, scm_print_state *pstate)
1023{
1024 SCM args;
1025 scm_puts ("#<boot-closure ", port);
3d27ef4b 1026 scm_uintprint ((scm_t_bits)SCM2PTR (closure), 16, port);
314b8716
AW
1027 scm_putc (' ', port);
1028 args = scm_make_list (scm_from_int (BOOT_CLOSURE_NUM_REQUIRED_ARGS (closure)),
4a655e50 1029 scm_from_latin1_symbol ("_"));
8f9c5b58 1030 if (!BOOT_CLOSURE_IS_FIXED (closure) && BOOT_CLOSURE_HAS_REST_ARGS (closure))
4a655e50 1031 args = scm_cons_star (scm_from_latin1_symbol ("_"), args);
7572ee52 1032 /* FIXME: optionals and rests */
314b8716
AW
1033 scm_display (args, port);
1034 scm_putc ('>', port);
1035 return 1;
1036}
1037
0f2d19dd
JB
1038void
1039scm_init_eval ()
0f2d19dd 1040{
5f161164
AW
1041 SCM primitive_eval;
1042
df9ca8d8 1043 f_apply = scm_c_define_gsubr ("apply", 2, 0, 1, scm_apply);
86d31dfe 1044
314b8716
AW
1045 scm_tc16_boot_closure = scm_make_smob_type ("boot-closure", 0);
1046 scm_set_smob_apply (scm_tc16_boot_closure, boot_closure_apply, 0, 0, 1);
1047 scm_set_smob_print (scm_tc16_boot_closure, boot_closure_print);
1048
5f161164
AW
1049 primitive_eval = scm_c_make_gsubr ("primitive-eval", 1, 0, 0,
1050 scm_c_primitive_eval);
1051 var_primitive_eval = scm_define (SCM_SUBR_NAME (primitive_eval),
1052 primitive_eval);
1053
a0599745 1054#include "libguile/eval.x"
0f2d19dd 1055}
0f2d19dd 1056
89e00824
ML
1057/*
1058 Local Variables:
1059 c-file-style: "gnu"
1060 End:
1061*/
62560650 1062