*** empty log message ***
[bpt/guile.git] / libguile / eval.c
CommitLineData
d0b07b5d 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,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
0f2d19dd
JB
18\f
19
6dbd0af5
MD
20/* This file is read twice in order to produce debugging versions of
21 * scm_ceval and scm_apply. These functions, scm_deval and
22 * scm_dapply, are produced when we define the preprocessor macro
23 * DEVAL. The file is divided into sections which are treated
24 * differently with respect to DEVAL. The heads of these sections are
25 * marked with the string "SECTION:".
26 */
27
6dbd0af5 28/* SECTION: This code is compiled once.
0f2d19dd
JB
29 */
30
3d05f2e0
RB
31#if HAVE_CONFIG_H
32# include <config.h>
33#endif
0f2d19dd 34
3d05f2e0
RB
35#include "libguile/__scm.h"
36
37#ifndef DEVAL
d16332b3 38
48b96f4b
JB
39/* AIX requires this to be the first thing in the file. The #pragma
40 directive is indented so pre-ANSI compilers will ignore it, rather
41 than choke on it. */
5862b540 42#ifndef __GNUC__
48b96f4b
JB
43# if HAVE_ALLOCA_H
44# include <alloca.h>
45# else
46# ifdef _AIX
ac13d9d2 47# pragma alloca
48b96f4b
JB
48# else
49# ifndef alloca /* predefined by HP cc +Olibcalls */
50char *alloca ();
51# endif
52# endif
53# endif
54#endif
55
a0599745
MD
56#include "libguile/_scm.h"
57#include "libguile/debug.h"
09074dbf 58#include "libguile/dynwind.h"
a0599745
MD
59#include "libguile/alist.h"
60#include "libguile/eq.h"
61#include "libguile/continuations.h"
756414cf 62#include "libguile/futures.h"
a0599745
MD
63#include "libguile/throw.h"
64#include "libguile/smob.h"
65#include "libguile/macros.h"
66#include "libguile/procprop.h"
67#include "libguile/hashtab.h"
68#include "libguile/hash.h"
69#include "libguile/srcprop.h"
70#include "libguile/stackchk.h"
71#include "libguile/objects.h"
72#include "libguile/async.h"
73#include "libguile/feature.h"
74#include "libguile/modules.h"
75#include "libguile/ports.h"
76#include "libguile/root.h"
77#include "libguile/vectors.h"
549e6ec6 78#include "libguile/fluids.h"
f12745b6 79#include "libguile/goops.h"
a513ead3 80#include "libguile/values.h"
a0599745
MD
81
82#include "libguile/validate.h"
83#include "libguile/eval.h"
c96d76b8 84#include "libguile/lang.h"
89efbff4 85
0f2d19dd
JB
86\f
87
d0624e39
DH
88/* {Ilocs}
89 *
90 * Ilocs are memoized references to variables in local environment frames.
91 * They are represented as three values: The relative offset of the
92 * environment frame, the number of the binding within that frame, and a
93 * boolean value indicating whether the binding is the last binding in the
94 * frame.
95 */
96#define SCM_ILOC00 SCM_MAKE_ITAG8(0L, scm_tc8_iloc)
97#define SCM_IDINC (0x00100000L)
98#define SCM_IDSTMSK (-SCM_IDINC)
99#define SCM_MAKE_ILOC(frame_nr, binding_nr, last_p) \
100 SCM_PACK ( \
101 ((frame_nr) << 8) \
102 + ((binding_nr) << 20) \
103 + ((last_p) ? SCM_ICDR : 0) \
104 + scm_tc8_iloc )
105
106#if (SCM_DEBUG_DEBUGGING_SUPPORT == 1)
107
108SCM scm_dbg_make_iloc (SCM frame, SCM binding, SCM cdrp);
109SCM_DEFINE (scm_dbg_make_iloc, "dbg-make-iloc", 3, 0, 0,
110 (SCM frame, SCM binding, SCM cdrp),
111 "Return a new iloc with frame offset @var{frame}, binding\n"
112 "offset @var{binding} and the cdr flag @var{cdrp}.")
113#define FUNC_NAME s_scm_dbg_make_iloc
114{
115 SCM_VALIDATE_INUM (1, frame);
116 SCM_VALIDATE_INUM (2, binding);
117 return SCM_MAKE_ILOC (SCM_INUM (frame),
118 SCM_INUM (binding),
119 !SCM_FALSEP (cdrp));
120}
121#undef FUNC_NAME
122
123SCM scm_dbg_iloc_p (SCM obj);
124SCM_DEFINE (scm_dbg_iloc_p, "dbg-iloc?", 1, 0, 0,
125 (SCM obj),
126 "Return @code{#t} if @var{obj} is an iloc.")
127#define FUNC_NAME s_scm_dbg_iloc_p
128{
129 return SCM_BOOL (SCM_ILOCP (obj));
130}
131#undef FUNC_NAME
132
133#endif
134
135\f
136
17fa3fcf
DH
137#define SCM_VALIDATE_NON_EMPTY_COMBINATION(x) \
138 do { \
139 if (SCM_EQ_P ((x), SCM_EOL)) \
e90c3a89 140 scm_misc_error (NULL, s_expression, SCM_EOL); \
17fa3fcf
DH
141 } while (0)
142
143\f
144
6dbd0af5
MD
145/* The evaluator contains a plethora of EVAL symbols.
146 * This is an attempt at explanation.
147 *
148 * The following macros should be used in code which is read twice
149 * (where the choice of evaluator is hard soldered):
150 *
151 * SCM_CEVAL is the symbol used within one evaluator to call itself.
152 * Originally, it is defined to scm_ceval, but is redefined to
153 * scm_deval during the second pass.
154 *
6cb702da 155 * SCM_EVALIM is used when it is known that the expression is an
6dbd0af5
MD
156 * immediate. (This macro never calls an evaluator.)
157 *
158 * EVALCAR evaluates the car of an expression.
159 *
6dbd0af5
MD
160 * The following macros should be used in code which is read once
161 * (where the choice of evaluator is dynamic):
162 *
6cb702da 163 * SCM_XEVAL takes care of immediates without calling an evaluator. It
6dbd0af5
MD
164 * then calls scm_ceval *or* scm_deval, depending on the debugging
165 * mode.
166 *
6cb702da 167 * SCM_XEVALCAR corresponds to EVALCAR, but uses scm_ceval *or* scm_deval
6dbd0af5
MD
168 * depending on the debugging mode.
169 *
170 * The main motivation for keeping this plethora is efficiency
171 * together with maintainability (=> locality of code).
172 */
173
6cb702da 174#define SCM_CEVAL scm_ceval
0f2d19dd 175
e90c3a89
DH
176#define SCM_EVALIM2(x) \
177 ((SCM_EQ_P ((x), SCM_EOL) \
178 ? scm_misc_error (NULL, s_expression, SCM_EOL), 0 \
179 : 0), \
180 (x))
181
182#define SCM_EVALIM(x, env) (SCM_ILOCP (x) \
183 ? *scm_ilookup ((x), env) \
184 : SCM_EVALIM2(x))
185
186#define SCM_XEVAL(x, env) (SCM_IMP (x) \
187 ? SCM_EVALIM2(x) \
188 : (*scm_ceval_ptr) ((x), (env)))
189
190#define SCM_XEVALCAR(x, env) (SCM_IMP (SCM_CAR (x)) \
191 ? SCM_EVALIM (SCM_CAR (x), env) \
192 : (SCM_SYMBOLP (SCM_CAR (x)) \
193 ? *scm_lookupcar (x, env, 1) \
194 : (*scm_ceval_ptr) (SCM_CAR (x), env)))
195
8c494e99 196#define EVALCAR(x, env) (SCM_IMP (SCM_CAR (x)) \
904a077d 197 ? SCM_EVALIM (SCM_CAR (x), env) \
680516ba
DH
198 : (SCM_SYMBOLP (SCM_CAR (x)) \
199 ? *scm_lookupcar (x, env, 1) \
200 : SCM_CEVAL (SCM_CAR (x), env)))
0f2d19dd 201
28d52ebb 202SCM_REC_MUTEX (source_mutex);
9bc4701c 203
12841895 204
e90c3a89
DH
205static const char s_expression[] = "missing or extra expression";
206static const char s_test[] = "bad test";
207static const char s_body[] = "bad body";
208static const char s_bindings[] = "bad bindings";
209static const char s_duplicate_bindings[] = "duplicate bindings";
210static const char s_variable[] = "bad variable";
211static const char s_clauses[] = "bad or missing clauses";
212static const char s_formals[] = "bad formals";
213static const char s_duplicate_formals[] = "duplicate formals";
214static const char s_splicing[] = "bad (non-list) result for unquote-splicing";
215
216
12841895
DH
217/* Lookup a given local variable in an environment. The local variable is
218 * given as an iloc, that is a triple <frame, binding, last?>, where frame
219 * indicates the relative number of the environment frame (counting upwards
220 * from the innermost environment frame), binding indicates the number of the
221 * binding within the frame, and last? (which is extracted from the iloc using
222 * the macro SCM_ICDRP) indicates whether the binding forms the binding at the
223 * very end of the improper list of bindings. */
0f2d19dd 224SCM *
6e8d25a6 225scm_ilookup (SCM iloc, SCM env)
0f2d19dd 226{
12841895
DH
227 unsigned int frame_nr = SCM_IFRAME (iloc);
228 unsigned int binding_nr = SCM_IDIST (iloc);
229 SCM frames = env;
230 SCM bindings;
231
232 for (; 0 != frame_nr; --frame_nr)
233 frames = SCM_CDR (frames);
234
235 bindings = SCM_CAR (frames);
236 for (; 0 != binding_nr; --binding_nr)
237 bindings = SCM_CDR (bindings);
238
0f2d19dd 239 if (SCM_ICDRP (iloc))
12841895
DH
240 return SCM_CDRLOC (bindings);
241 return SCM_CARLOC (SCM_CDR (bindings));
0f2d19dd 242}
0f2d19dd 243
12841895 244
f8769b1d
MV
245/* The Lookup Car Race
246 - by Eva Luator
247
248 Memoization of variables and special forms is done while executing
249 the code for the first time. As long as there is only one thread
250 everything is fine, but as soon as two threads execute the same
251 code concurrently `for the first time' they can come into conflict.
252
253 This memoization includes rewriting variable references into more
254 efficient forms and expanding macros. Furthermore, macro expansion
255 includes `compiling' special forms like `let', `cond', etc. into
256 tree-code instructions.
257
258 There shouldn't normally be a problem with memoizing local and
904a077d 259 global variable references (into ilocs and variables), because all
f8769b1d
MV
260 threads will mutate the code in *exactly* the same way and (if I
261 read the C code correctly) it is not possible to observe a half-way
262 mutated cons cell. The lookup procedure can handle this
263 transparently without any critical sections.
264
265 It is different with macro expansion, because macro expansion
266 happens outside of the lookup procedure and can't be
904a077d
MV
267 undone. Therefore the lookup procedure can't cope with it. It has
268 to indicate failure when it detects a lost race and hope that the
269 caller can handle it. Luckily, it turns out that this is the case.
f8769b1d 270
904a077d 271 An example to illustrate this: Suppose that the following form will
f8769b1d
MV
272 be memoized concurrently by two threads
273
274 (let ((x 12)) x)
275
276 Let's first examine the lookup of X in the body. The first thread
277 decides that it has to find the symbol "x" in the environment and
278 starts to scan it. Then the other thread takes over and actually
279 overtakes the first. It looks up "x" and substitutes an
280 appropriate iloc for it. Now the first thread continues and
281 completes its lookup. It comes to exactly the same conclusions as
282 the second one and could - without much ado - just overwrite the
283 iloc with the same iloc.
284
285 But let's see what will happen when the race occurs while looking
286 up the symbol "let" at the start of the form. It could happen that
287 the second thread interrupts the lookup of the first thread and not
904a077d
MV
288 only substitutes a variable for it but goes right ahead and
289 replaces it with the compiled form (#@let* (x 12) x). Now, when
290 the first thread completes its lookup, it would replace the #@let*
291 with a variable containing the "let" binding, effectively reverting
292 the form to (let (x 12) x). This is wrong. It has to detect that
293 it has lost the race and the evaluator has to reconsider the
294 changed form completely.
f8769b1d
MV
295
296 This race condition could be resolved with some kind of traffic
297 light (like mutexes) around scm_lookupcar, but I think that it is
298 best to avoid them in this case. They would serialize memoization
299 completely and because lookup involves calling arbitrary Scheme
300 code (via the lookup-thunk), threads could be blocked for an
301 arbitrary amount of time or even deadlock. But with the current
302 solution a lot of unnecessary work is potentially done. */
303
9aa82b39 304/* SCM_LOOKUPCAR1 is what SCM_LOOKUPCAR used to be but is allowed to
f8769b1d
MV
305 return NULL to indicate a failed lookup due to some race conditions
306 between threads. This only happens when VLOC is the first cell of
307 a special form that will eventually be memoized (like `let', etc.)
308 In that case the whole lookup is bogus and the caller has to
309 reconsider the complete special form.
310
311 SCM_LOOKUPCAR is still there, of course. It just calls
de513fa0 312 SCM_LOOKUPCAR1 and aborts on receiving NULL. So SCM_LOOKUPCAR
f8769b1d
MV
313 should only be called when it is known that VLOC is not the first
314 pair of a special form. Otherwise, use SCM_LOOKUPCAR1 and check
26d5b9b4
MD
315 for NULL. I think I've found the only places where this
316 applies. */
f8769b1d 317
f25f761d
GH
318SCM_SYMBOL (scm_unbound_variable_key, "unbound-variable");
319
8ecf1f13 320static SCM *
26d5b9b4 321scm_lookupcar1 (SCM vloc, SCM genv, int check)
0f2d19dd
JB
322{
323 SCM env = genv;
e3173f93 324 register SCM *al, fl, var = SCM_CAR (vloc);
0f2d19dd 325 register SCM iloc = SCM_ILOC00;
0f2d19dd
JB
326 for (; SCM_NIMP (env); env = SCM_CDR (env))
327 {
790071cd 328 if (!SCM_CONSP (SCM_CAR (env)))
0f2d19dd 329 break;
a23afe53 330 al = SCM_CARLOC (env);
0f2d19dd
JB
331 for (fl = SCM_CAR (*al); SCM_NIMP (fl); fl = SCM_CDR (fl))
332 {
01f11e02 333 if (!SCM_CONSP (fl))
33b97402 334 {
cf498326 335 if (SCM_EQ_P (fl, var))
0f2d19dd 336 {
cf498326 337 if (! SCM_EQ_P (SCM_CAR (vloc), var))
f8769b1d 338 goto race;
3201d763 339 SCM_SET_CELL_WORD_0 (vloc, SCM_UNPACK (iloc) + SCM_ICDR);
a23afe53 340 return SCM_CDRLOC (*al);
0f2d19dd 341 }
33b97402
MD
342 else
343 break;
344 }
a23afe53 345 al = SCM_CDRLOC (*al);
cf498326 346 if (SCM_EQ_P (SCM_CAR (fl), var))
0f2d19dd 347 {
0f2d19dd
JB
348 if (SCM_UNBNDP (SCM_CAR (*al)))
349 {
350 env = SCM_EOL;
351 goto errout;
352 }
c6772927 353 if (!SCM_EQ_P (SCM_CAR (vloc), var))
f8769b1d 354 goto race;
a23afe53 355 SCM_SETCAR (vloc, iloc);
a23afe53 356 return SCM_CARLOC (*al);
0f2d19dd 357 }
3201d763 358 iloc = SCM_PACK (SCM_UNPACK (iloc) + SCM_IDINC);
0f2d19dd 359 }
3201d763 360 iloc = SCM_PACK ((~SCM_IDSTMSK) & (SCM_UNPACK(iloc) + SCM_IFRINC));
0f2d19dd
JB
361 }
362 {
86d31dfe 363 SCM top_thunk, real_var;
790071cd 364 if (SCM_NIMP (env))
0f2d19dd 365 {
86d31dfe
MV
366 top_thunk = SCM_CAR (env); /* env now refers to a
367 top level env thunk */
0f2d19dd
JB
368 env = SCM_CDR (env);
369 }
370 else
371 top_thunk = SCM_BOOL_F;
86d31dfe
MV
372 real_var = scm_sym2var (var, top_thunk, SCM_BOOL_F);
373 if (SCM_FALSEP (real_var))
0f2d19dd 374 goto errout;
86d31dfe 375
01f11e02 376 if (!SCM_NULLP (env) || SCM_UNBNDP (SCM_VARIABLE_REF (real_var)))
86d31dfe
MV
377 {
378 errout:
86d31dfe
MV
379 if (check)
380 {
381 if (SCM_NULLP (env))
382 scm_error (scm_unbound_variable_key, NULL,
383 "Unbound variable: ~S",
8ea46249 384 scm_list_1 (var), SCM_BOOL_F);
86d31dfe
MV
385 else
386 scm_misc_error (NULL, "Damaged environment: ~S",
8ea46249 387 scm_list_1 (var));
86d31dfe
MV
388 }
389 else
390 {
391 /* A variable could not be found, but we shall
392 not throw an error. */
393 static SCM undef_object = SCM_UNDEFINED;
394 return &undef_object;
395 }
09e4d064 396 }
86d31dfe 397
c6772927 398 if (!SCM_EQ_P (SCM_CAR (vloc), var))
86d31dfe
MV
399 {
400 /* Some other thread has changed the very cell we are working
401 on. In effect, it must have done our job or messed it up
402 completely. */
403 race:
404 var = SCM_CAR (vloc);
d22a0ea1
MV
405 if (SCM_VARIABLEP (var))
406 return SCM_VARIABLE_LOC (var);
86d31dfe
MV
407 if (SCM_ITAG7 (var) == SCM_ITAG7 (SCM_ILOC00))
408 return scm_ilookup (var, genv);
904a077d 409 /* We can't cope with anything else than variables and ilocs. When
86d31dfe
MV
410 a special form has been memoized (i.e. `let' into `#@let') we
411 return NULL and expect the calling function to do the right
412 thing. For the evaluator, this means going back and redoing
413 the dispatch on the car of the form. */
414 return NULL;
415 }
f8769b1d 416
d22a0ea1 417 SCM_SETCAR (vloc, real_var);
86d31dfe
MV
418 return SCM_VARIABLE_LOC (real_var);
419 }
0f2d19dd
JB
420}
421
f8769b1d 422SCM *
6e8d25a6 423scm_lookupcar (SCM vloc, SCM genv, int check)
f8769b1d 424{
26d5b9b4 425 SCM *loc = scm_lookupcar1 (vloc, genv, check);
f8769b1d
MV
426 if (loc == NULL)
427 abort ();
428 return loc;
429}
f8769b1d 430
0f2d19dd 431#define unmemocar scm_unmemocar
1cc91f1b 432
86d31dfe
MV
433SCM_SYMBOL (sym_three_question_marks, "???");
434
0f2d19dd 435SCM
6e8d25a6 436scm_unmemocar (SCM form, SCM env)
0f2d19dd 437{
302c12b4 438 if (!SCM_CONSP (form))
0f2d19dd 439 return form;
302c12b4 440 else
d22a0ea1 441 {
302c12b4
DH
442 SCM c = SCM_CAR (form);
443 if (SCM_VARIABLEP (c))
444 {
445 SCM sym = scm_module_reverse_lookup (scm_env_module (env), c);
446 if (SCM_FALSEP (sym))
447 sym = sym_three_question_marks;
448 SCM_SETCAR (form, sym);
449 }
302c12b4
DH
450 else if (SCM_ILOCP (c))
451 {
452 unsigned long int ir;
453
454 for (ir = SCM_IFRAME (c); ir != 0; --ir)
455 env = SCM_CDR (env);
456 env = SCM_CAAR (env);
457 for (ir = SCM_IDIST (c); ir != 0; --ir)
458 env = SCM_CDR (env);
459 SCM_SETCAR (form, SCM_ICDRP (c) ? env : SCM_CAR (env));
460 }
302c12b4
DH
461 return form;
462 }
0f2d19dd
JB
463}
464
1cc91f1b 465
0f2d19dd 466SCM
6e8d25a6 467scm_eval_car (SCM pair, SCM env)
0f2d19dd 468{
6cb702da 469 return SCM_XEVALCAR (pair, env);
0f2d19dd
JB
470}
471
472\f
473/*
474 * The following rewrite expressions and
475 * some memoized forms have different syntax
476 */
477
85db4a2c
DH
478SCM_GLOBAL_SYMBOL (scm_sym_arrow, "=>");
479SCM_GLOBAL_SYMBOL (scm_sym_else, "else");
480SCM_GLOBAL_SYMBOL (scm_sym_unquote, "unquote");
481SCM_GLOBAL_SYMBOL (scm_sym_uq_splicing, "unquote-splicing");
81123e6d 482
85db4a2c
DH
483SCM_GLOBAL_SYMBOL (scm_sym_enter_frame, "enter-frame");
484SCM_GLOBAL_SYMBOL (scm_sym_apply_frame, "apply-frame");
485SCM_GLOBAL_SYMBOL (scm_sym_exit_frame, "exit-frame");
486SCM_GLOBAL_SYMBOL (scm_sym_trace, "trace");
0f2d19dd 487
0f2d19dd 488
26d5b9b4
MD
489/* Check that the body denoted by XORIG is valid and rewrite it into
490 its internal form. The internal form of a body is just the body
491 itself, but prefixed with an ISYM that denotes to what kind of
492 outer construct this body belongs. A lambda body starts with
493 SCM_IM_LAMBDA, for example, a body of a let starts with SCM_IM_LET,
494 etc. The one exception is a body that belongs to a letrec that has
495 been formed by rewriting internal defines: it starts with
496 SCM_IM_DEFINE. */
497
498/* XXX - Besides controlling the rewriting of internal defines, the
499 additional ISYM could be used for improved error messages.
500 This is not done yet. */
501
502static SCM
6e8d25a6 503scm_m_body (SCM op, SCM xorig, const char *what)
26d5b9b4 504{
e90c3a89 505 SCM_ASSYNT (scm_ilength (xorig) >= 1, s_body, what);
26d5b9b4
MD
506
507 /* Don't add another ISYM if one is present already. */
508 if (SCM_ISYMP (SCM_CAR (xorig)))
509 return xorig;
510
511 /* Retain possible doc string. */
44d3cb0d 512 if (!SCM_CONSP (SCM_CAR (xorig)))
26d5b9b4 513 {
8ea46249 514 if (!SCM_NULLP (SCM_CDR (xorig)))
26d5b9b4 515 return scm_cons (SCM_CAR (xorig),
8ea46249 516 scm_m_body (op, SCM_CDR (xorig), what));
26d5b9b4
MD
517 return xorig;
518 }
519
ab66ae47 520 return scm_cons (op, xorig);
26d5b9b4
MD
521}
522
1cc91f1b 523
9fbee57e 524/* Start of the memoizers for the standard R5RS builtin macros. */
0f2d19dd
JB
525
526
3b88ed2a 527SCM_SYNTAX (s_and, "and", scm_i_makbimacro, scm_m_and);
8ea46249 528SCM_GLOBAL_SYMBOL (scm_sym_and, s_and);
1cc91f1b 529
8ea46249 530SCM
e81d98ec 531scm_m_and (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 532{
c014a02e 533 long len = scm_ilength (SCM_CDR (xorig));
e90c3a89 534 SCM_ASSYNT (len >= 0, s_test, s_and);
0f2d19dd 535 if (len >= 1)
3a3111a8 536 return scm_cons (SCM_IM_AND, SCM_CDR (xorig));
0f2d19dd
JB
537 else
538 return SCM_BOOL_T;
539}
540
1cc91f1b 541
3b88ed2a 542SCM_SYNTAX (s_begin, "begin", scm_i_makbimacro, scm_m_begin);
9fbee57e 543SCM_GLOBAL_SYMBOL (scm_sym_begin, s_begin);
8ea46249
DH
544
545SCM
9fbee57e 546scm_m_begin (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 547{
e90c3a89 548 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) >= 0, s_expression, s_begin);
9fbee57e 549 return scm_cons (SCM_IM_BEGIN, SCM_CDR (xorig));
0f2d19dd
JB
550}
551
552
3b88ed2a 553SCM_SYNTAX (s_case, "case", scm_i_makbimacro, scm_m_case);
8ea46249 554SCM_GLOBAL_SYMBOL (scm_sym_case, s_case);
1cc91f1b 555
8ea46249 556SCM
e81d98ec 557scm_m_case (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 558{
8ea46249
DH
559 SCM clauses;
560 SCM cdrx = SCM_CDR (xorig);
e90c3a89 561 SCM_ASSYNT (scm_ilength (cdrx) >= 2, s_clauses, s_case);
8ea46249
DH
562 clauses = SCM_CDR (cdrx);
563 while (!SCM_NULLP (clauses))
0f2d19dd 564 {
8ea46249 565 SCM clause = SCM_CAR (clauses);
e90c3a89 566 SCM_ASSYNT (scm_ilength (clause) >= 2, s_clauses, s_case);
8ea46249
DH
567 SCM_ASSYNT (scm_ilength (SCM_CAR (clause)) >= 0
568 || (SCM_EQ_P (scm_sym_else, SCM_CAR (clause))
569 && SCM_NULLP (SCM_CDR (clauses))),
e90c3a89 570 s_clauses, s_case);
8ea46249 571 clauses = SCM_CDR (clauses);
0f2d19dd 572 }
3a3111a8 573 return scm_cons (SCM_IM_CASE, cdrx);
0f2d19dd
JB
574}
575
576
3b88ed2a 577SCM_SYNTAX (s_cond, "cond", scm_i_makbimacro, scm_m_cond);
8ea46249 578SCM_GLOBAL_SYMBOL (scm_sym_cond, s_cond);
1cc91f1b 579
8ea46249 580SCM
e81d98ec 581scm_m_cond (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 582{
8ea46249
DH
583 SCM cdrx = SCM_CDR (xorig);
584 SCM clauses = cdrx;
e90c3a89 585 SCM_ASSYNT (scm_ilength (clauses) >= 1, s_clauses, s_cond);
8ea46249 586 while (!SCM_NULLP (clauses))
0f2d19dd 587 {
8ea46249
DH
588 SCM clause = SCM_CAR (clauses);
589 long len = scm_ilength (clause);
e90c3a89 590 SCM_ASSYNT (len >= 1, s_clauses, s_cond);
8ea46249 591 if (SCM_EQ_P (scm_sym_else, SCM_CAR (clause)))
0f2d19dd 592 {
8ea46249
DH
593 int last_clause_p = SCM_NULLP (SCM_CDR (clauses));
594 SCM_ASSYNT (len >= 2 && last_clause_p, "bad ELSE clause", s_cond);
0f2d19dd 595 }
8ea46249
DH
596 else if (len >= 2 && SCM_EQ_P (scm_sym_arrow, SCM_CADR (clause)))
597 {
598 SCM_ASSYNT (len > 2, "missing recipient", s_cond);
599 SCM_ASSYNT (len == 3, "bad recipient", s_cond);
600 }
601 clauses = SCM_CDR (clauses);
0f2d19dd 602 }
3a3111a8 603 return scm_cons (SCM_IM_COND, cdrx);
0f2d19dd
JB
604}
605
1cc91f1b 606
3b88ed2a 607SCM_SYNTAX(s_define, "define", scm_i_makbimacro, scm_m_define);
9fbee57e 608SCM_GLOBAL_SYMBOL(scm_sym_define, s_define);
5280aaca 609
9fbee57e
DH
610/* Guile provides an extension to R5RS' define syntax to represent function
611 * currying in a compact way. With this extension, it is allowed to write
612 * (define <nested-variable> <body>), where <nested-variable> has of one of
613 * the forms (<nested-variable> <formals>), (<nested-variable> . <formal>),
614 * (<variable> <formals>) or (<variable> . <formal>). As in R5RS, <formals>
615 * should be either a sequence of zero or more variables, or a sequence of one
616 * or more variables followed by a space-delimited period and another
617 * variable. Each level of argument nesting wraps the <body> within another
618 * lambda expression. For example, the following forms are allowed, each one
619 * followed by an equivalent, more explicit implementation.
620 * Example 1:
621 * (define ((a b . c) . d) <body>) is equivalent to
622 * (define a (lambda (b . c) (lambda d <body>)))
623 * Example 2:
624 * (define (((a) b) c . d) <body>) is equivalent to
625 * (define a (lambda () (lambda (b) (lambda (c . d) <body>))))
626 */
627/* Dirk:FIXME:: We should provide an implementation for 'define' in the R5RS
628 * module that does not implement this extension. */
629SCM
630scm_m_define (SCM x, SCM env)
5280aaca 631{
9fbee57e
DH
632 SCM name;
633 x = SCM_CDR (x);
e90c3a89 634 SCM_ASSYNT (scm_ilength (x) >= 2, s_expression, s_define);
9fbee57e
DH
635 name = SCM_CAR (x);
636 x = SCM_CDR (x);
637 while (SCM_CONSP (name))
5280aaca 638 {
9fbee57e
DH
639 /* This while loop realizes function currying by variable nesting. */
640 SCM formals = SCM_CDR (name);
641 x = scm_list_1 (scm_cons2 (scm_sym_lambda, formals, x));
642 name = SCM_CAR (name);
5280aaca 643 }
e90c3a89
DH
644 SCM_ASSYNT (SCM_SYMBOLP (name), s_variable, s_define);
645 SCM_ASSYNT (scm_ilength (x) == 1, s_expression, s_define);
9fbee57e 646 if (SCM_TOP_LEVEL (env))
0f2d19dd 647 {
9fbee57e
DH
648 SCM var;
649 x = scm_eval_car (x, env);
650 if (SCM_REC_PROCNAMES_P)
651 {
652 SCM tmp = x;
653 while (SCM_MACROP (tmp))
654 tmp = SCM_MACRO_CODE (tmp);
655 if (SCM_CLOSUREP (tmp)
656 /* Only the first definition determines the name. */
657 && SCM_FALSEP (scm_procedure_property (tmp, scm_sym_name)))
658 scm_set_procedure_property_x (tmp, scm_sym_name, name);
659 }
660 var = scm_sym2var (name, scm_env_top_level (env), SCM_BOOL_T);
661 SCM_VARIABLE_SET (var, x);
662 return SCM_UNSPECIFIED;
26d5b9b4 663 }
9fbee57e
DH
664 else
665 return scm_cons2 (SCM_IM_DEFINE, name, x);
0f2d19dd
JB
666}
667
668
3b88ed2a 669SCM_SYNTAX (s_delay, "delay", scm_i_makbimacro, scm_m_delay);
9fbee57e 670SCM_GLOBAL_SYMBOL (scm_sym_delay, s_delay);
1cc91f1b 671
9fbee57e
DH
672/* Promises are implemented as closures with an empty parameter list. Thus,
673 * (delay <expression>) is transformed into (#@delay '() <expression>), where
674 * the empty list represents the empty parameter list. This representation
675 * allows for easy creation of the closure during evaluation. */
8ea46249 676SCM
9fbee57e 677scm_m_delay (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 678{
e90c3a89 679 SCM_ASSYNT (scm_ilength (xorig) == 2, s_expression, s_delay);
9fbee57e 680 return scm_cons2 (SCM_IM_DELAY, SCM_EOL, SCM_CDR (xorig));
0f2d19dd
JB
681}
682
8ea46249 683
302c12b4
DH
684/* DO gets the most radically altered syntax. The order of the vars is
685 * reversed here. In contrast, the order of the inits and steps is reversed
686 * during the evaluation:
687
0f2d19dd
JB
688 (do ((<var1> <init1> <step1>)
689 (<var2> <init2>)
690 ... )
691 (<test> <return>)
692 <body>)
302c12b4 693
0f2d19dd 694 ;; becomes
302c12b4 695
e681d187
DH
696 (#@do (<init1> <init2> ... <initn>)
697 (varn ... var2 var1)
0f2d19dd
JB
698 (<test> <return>)
699 (<body>)
700 <step1> <step2> ... <stepn>) ;; missing steps replaced by var
302c12b4 701 */
0f2d19dd 702
3b88ed2a 703SCM_SYNTAX(s_do, "do", scm_i_makbimacro, scm_m_do);
2f0d1375 704SCM_GLOBAL_SYMBOL(scm_sym_do, s_do);
1cc91f1b 705
0f2d19dd 706SCM
e81d98ec 707scm_m_do (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 708{
8ea46249
DH
709 SCM bindings;
710 SCM x = SCM_CDR (xorig);
711 SCM vars = SCM_EOL;
712 SCM inits = SCM_EOL;
713 SCM *initloc = &inits;
714 SCM steps = SCM_EOL;
715 SCM *steploc = &steps;
e90c3a89 716 SCM_ASSYNT (scm_ilength (x) >= 2, s_test, "do");
8ea46249 717 bindings = SCM_CAR (x);
e90c3a89 718 SCM_ASSYNT (scm_ilength (bindings) >= 0, s_bindings, "do");
8ea46249 719 while (!SCM_NULLP (bindings))
0f2d19dd 720 {
302c12b4
DH
721 SCM binding = SCM_CAR (bindings);
722 long len = scm_ilength (binding);
e90c3a89 723 SCM_ASSYNT (len == 2 || len == 3, s_bindings, "do");
302c12b4
DH
724 {
725 SCM name = SCM_CAR (binding);
726 SCM init = SCM_CADR (binding);
727 SCM step = (len == 2) ? name : SCM_CADDR (binding);
e90c3a89 728 SCM_ASSYNT (SCM_SYMBOLP (name), s_variable, "do");
302c12b4
DH
729 vars = scm_cons (name, vars);
730 *initloc = scm_list_1 (init);
731 initloc = SCM_CDRLOC (*initloc);
732 *steploc = scm_list_1 (step);
733 steploc = SCM_CDRLOC (*steploc);
734 bindings = SCM_CDR (bindings);
735 }
0f2d19dd
JB
736 }
737 x = SCM_CDR (x);
e90c3a89 738 SCM_ASSYNT (scm_ilength (SCM_CAR (x)) >= 1, s_test, "do");
0f2d19dd 739 x = scm_cons2 (SCM_CAR (x), SCM_CDR (x), steps);
e681d187 740 x = scm_cons2 (inits, vars, x);
3a3111a8 741 return scm_cons (SCM_IM_DO, x);
0f2d19dd
JB
742}
743
b8229a3b 744
3b88ed2a 745SCM_SYNTAX (s_if, "if", scm_i_makbimacro, scm_m_if);
9fbee57e 746SCM_GLOBAL_SYMBOL (scm_sym_if, s_if);
b8229a3b 747
9fbee57e
DH
748SCM
749scm_m_if (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 750{
9fbee57e 751 long len = scm_ilength (SCM_CDR (xorig));
e90c3a89 752 SCM_ASSYNT (len >= 2 && len <= 3, s_expression, s_if);
9fbee57e 753 return scm_cons (SCM_IM_IF, SCM_CDR (xorig));
0f2d19dd
JB
754}
755
302c12b4 756
3b88ed2a 757SCM_SYNTAX (s_lambda, "lambda", scm_i_makbimacro, scm_m_lambda);
9fbee57e 758SCM_GLOBAL_SYMBOL (scm_sym_lambda, s_lambda);
0f2d19dd 759
9fbee57e
DH
760/* Return true if OBJ is `eq?' to one of the elements of LIST or to the
761 * cdr of the last cons. (Thus, LIST is not required to be a proper
762 * list and OBJ can also be found in the improper ending.) */
763static int
764scm_c_improper_memq (SCM obj, SCM list)
5cb22e96 765{
9fbee57e
DH
766 for (; SCM_CONSP (list); list = SCM_CDR (list))
767 {
768 if (SCM_EQ_P (SCM_CAR (list), obj))
769 return 1;
770 }
771 return SCM_EQ_P (list, obj);
5cb22e96
DH
772}
773
28d52ebb 774SCM
9fbee57e 775scm_m_lambda (SCM xorig, SCM env SCM_UNUSED)
28d52ebb 776{
9fbee57e
DH
777 SCM formals;
778 SCM x = SCM_CDR (xorig);
28d52ebb 779
e90c3a89 780 SCM_ASSYNT (SCM_CONSP (x), s_formals, s_lambda);
1cc91f1b 781
9fbee57e
DH
782 formals = SCM_CAR (x);
783 while (SCM_CONSP (formals))
0f2d19dd 784 {
9fbee57e 785 SCM formal = SCM_CAR (formals);
e90c3a89 786 SCM_ASSYNT (SCM_SYMBOLP (formal), s_formals, s_lambda);
9fbee57e 787 if (scm_c_improper_memq (formal, SCM_CDR (formals)))
e90c3a89 788 scm_misc_error (s_lambda, s_duplicate_formals, SCM_EOL);
9fbee57e 789 formals = SCM_CDR (formals);
0f2d19dd 790 }
9fbee57e 791 if (!SCM_NULLP (formals) && !SCM_SYMBOLP (formals))
e90c3a89 792 scm_misc_error (s_lambda, s_formals, SCM_EOL);
9fbee57e
DH
793
794 return scm_cons2 (SCM_IM_LAMBDA, SCM_CAR (x),
795 scm_m_body (SCM_IM_LAMBDA, SCM_CDR (x), s_lambda));
0f2d19dd 796}
6dbd0af5 797
0f2d19dd 798
302c12b4
DH
799/* The bindings ((v1 i1) (v2 i2) ... (vn in)) are transformed to the lists
800 * (vn ... v2 v1) and (i1 i2 ... in). That is, the list of variables is
801 * reversed here, the list of inits gets reversed during evaluation. */
802static void
803transform_bindings (SCM bindings, SCM *rvarloc, SCM *initloc, const char *what)
0f2d19dd 804{
302c12b4
DH
805 SCM rvars = SCM_EOL;
806 *rvarloc = SCM_EOL;
807 *initloc = SCM_EOL;
808
e90c3a89 809 SCM_ASSYNT (scm_ilength (bindings) >= 1, s_bindings, what);
0f2d19dd 810
0f2d19dd
JB
811 do
812 {
302c12b4 813 SCM binding = SCM_CAR (bindings);
e90c3a89
DH
814 SCM_ASSYNT (scm_ilength (binding) == 2, s_bindings, what);
815 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (binding)), s_variable, what);
302c12b4 816 if (scm_c_improper_memq (SCM_CAR (binding), rvars))
e90c3a89 817 scm_misc_error (what, s_duplicate_bindings, SCM_EOL);
302c12b4
DH
818 rvars = scm_cons (SCM_CAR (binding), rvars);
819 *initloc = scm_list_1 (SCM_CADR (binding));
a23afe53 820 initloc = SCM_CDRLOC (*initloc);
302c12b4 821 bindings = SCM_CDR (bindings);
0f2d19dd 822 }
302c12b4 823 while (!SCM_NULLP (bindings));
26d5b9b4 824
302c12b4 825 *rvarloc = rvars;
0f2d19dd
JB
826}
827
302c12b4 828
3b88ed2a 829SCM_SYNTAX(s_let, "let", scm_i_makbimacro, scm_m_let);
2f0d1375 830SCM_GLOBAL_SYMBOL(scm_sym_let, s_let);
b8229a3b 831
302c12b4 832SCM
6e8d25a6 833scm_m_let (SCM xorig, SCM env)
0f2d19dd 834{
302c12b4
DH
835 SCM x = SCM_CDR (xorig);
836 SCM temp;
837
e90c3a89 838 SCM_ASSYNT (SCM_CONSP (x), s_bindings, s_let);
302c12b4
DH
839 temp = SCM_CAR (x);
840 if (SCM_NULLP (temp)
841 || (scm_ilength (temp) == 1 && SCM_CONSP (SCM_CAR (temp))))
26d5b9b4
MD
842 {
843 /* null or single binding, let* is faster */
3096b33f 844 SCM bindings = temp;
302c12b4 845 SCM body = scm_m_body (SCM_IM_LET, SCM_CDR (x), s_let);
3096b33f 846 return scm_m_letstar (scm_cons2 (SCM_CAR (xorig), bindings, body), env);
26d5b9b4 847 }
302c12b4 848 else if (SCM_CONSP (temp))
26d5b9b4 849 {
3096b33f
DH
850 /* plain let */
851 SCM bindings = temp;
302c12b4 852 SCM rvars, inits, body;
3096b33f 853 transform_bindings (bindings, &rvars, &inits, "let");
302c12b4
DH
854 body = scm_m_body (SCM_IM_LET, SCM_CDR (x), "let");
855 return scm_cons2 (SCM_IM_LET, rvars, scm_cons (inits, body));
26d5b9b4 856 }
302c12b4
DH
857 else
858 {
859 /* named let: Transform (let name ((var init) ...) body ...) into
860 * ((letrec ((name (lambda (var ...) body ...))) name) init ...) */
26d5b9b4 861
302c12b4
DH
862 SCM name = temp;
863 SCM vars = SCM_EOL;
864 SCM *varloc = &vars;
865 SCM inits = SCM_EOL;
866 SCM *initloc = &inits;
867 SCM bindings;
868
e90c3a89 869 SCM_ASSYNT (SCM_SYMBOLP (name), s_bindings, s_let);
302c12b4 870 x = SCM_CDR (x);
e90c3a89 871 SCM_ASSYNT (SCM_CONSP (x), s_bindings, s_let);
302c12b4 872 bindings = SCM_CAR (x);
e90c3a89 873 SCM_ASSYNT (scm_ilength (bindings) >= 0, s_bindings, s_let);
302c12b4
DH
874 while (!SCM_NULLP (bindings))
875 { /* vars and inits both in order */
876 SCM binding = SCM_CAR (bindings);
e90c3a89
DH
877 SCM_ASSYNT (scm_ilength (binding) == 2, s_bindings, s_let);
878 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (binding)), s_variable, s_let);
302c12b4
DH
879 *varloc = scm_list_1 (SCM_CAR (binding));
880 varloc = SCM_CDRLOC (*varloc);
881 *initloc = scm_list_1 (SCM_CADR (binding));
882 initloc = SCM_CDRLOC (*initloc);
883 bindings = SCM_CDR (bindings);
884 }
26d5b9b4 885
302c12b4
DH
886 {
887 SCM lambda_body = scm_m_body (SCM_IM_LET, SCM_CDR (x), "let");
888 SCM lambda_form = scm_cons2 (scm_sym_lambda, vars, lambda_body);
889 SCM rvar = scm_list_1 (name);
890 SCM init = scm_list_1 (lambda_form);
891 SCM body = scm_m_body (SCM_IM_LET, scm_list_1 (name), "let");
892 SCM letrec = scm_cons2 (SCM_IM_LETREC, rvar, scm_cons (init, body));
893 return scm_cons (letrec, inits);
894 }
895 }
0f2d19dd
JB
896}
897
898
3b88ed2a 899SCM_SYNTAX (s_letstar, "let*", scm_i_makbimacro, scm_m_letstar);
9fbee57e 900SCM_GLOBAL_SYMBOL (scm_sym_letstar, s_letstar);
1cc91f1b 901
9fbee57e
DH
902/* (let* ((v1 i1) (v2 i2) ...) body) with variables v1 .. vk and initializers
903 * i1 .. ik is transformed into the form (#@let* (v1 i1 v2 i2 ...) body*). */
904SCM
905scm_m_letstar (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 906{
9fbee57e
DH
907 SCM bindings;
908 SCM x = SCM_CDR (xorig);
909 SCM vars = SCM_EOL;
910 SCM *varloc = &vars;
0f2d19dd 911
e90c3a89 912 SCM_ASSYNT (SCM_CONSP (x), s_bindings, s_letstar);
9fbee57e
DH
913
914 bindings = SCM_CAR (x);
e90c3a89 915 SCM_ASSYNT (scm_ilength (bindings) >= 0, s_bindings, s_letstar);
9fbee57e
DH
916 while (!SCM_NULLP (bindings))
917 {
918 SCM binding = SCM_CAR (bindings);
e90c3a89
DH
919 SCM_ASSYNT (scm_ilength (binding) == 2, s_bindings, s_letstar);
920 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (binding)), s_variable, s_letstar);
9fbee57e
DH
921 *varloc = scm_list_2 (SCM_CAR (binding), SCM_CADR (binding));
922 varloc = SCM_CDRLOC (SCM_CDR (*varloc));
923 bindings = SCM_CDR (bindings);
924 }
925
926 return scm_cons2 (SCM_IM_LETSTAR, vars,
927 scm_m_body (SCM_IM_LETSTAR, SCM_CDR (x), s_letstar));
928}
b8229a3b 929
0f2d19dd 930
3b88ed2a 931SCM_SYNTAX(s_letrec, "letrec", scm_i_makbimacro, scm_m_letrec);
9fbee57e 932SCM_GLOBAL_SYMBOL(scm_sym_letrec, s_letrec);
1cc91f1b 933
0f2d19dd 934SCM
9fbee57e 935scm_m_letrec (SCM xorig, SCM env)
0f2d19dd 936{
9fbee57e 937 SCM x = SCM_CDR (xorig);
e90c3a89 938 SCM_ASSYNT (SCM_CONSP (x), s_bindings, s_letrec);
9fbee57e
DH
939
940 if (SCM_NULLP (SCM_CAR (x)))
941 {
942 /* null binding, let* faster */
943 SCM body = scm_m_body (SCM_IM_LETREC, SCM_CDR (x), s_letrec);
944 return scm_m_letstar (scm_cons2 (SCM_CAR (xorig), SCM_EOL, body), env);
945 }
946 else
947 {
948 SCM rvars, inits, body;
949 transform_bindings (SCM_CAR (x), &rvars, &inits, "letrec");
950 body = scm_m_body (SCM_IM_LETREC, SCM_CDR (x), "letrec");
951 return scm_cons2 (SCM_IM_LETREC, rvars, scm_cons (inits, body));
952 }
0f2d19dd
JB
953}
954
73b64342 955
3b88ed2a 956SCM_SYNTAX (s_or, "or", scm_i_makbimacro, scm_m_or);
9fbee57e 957SCM_GLOBAL_SYMBOL (scm_sym_or, s_or);
73b64342
MD
958
959SCM
9fbee57e 960scm_m_or (SCM xorig, SCM env SCM_UNUSED)
73b64342 961{
c014a02e 962 long len = scm_ilength (SCM_CDR (xorig));
e90c3a89 963 SCM_ASSYNT (len >= 0, s_test, s_or);
9fbee57e
DH
964 if (len >= 1)
965 return scm_cons (SCM_IM_OR, SCM_CDR (xorig));
966 else
967 return SCM_BOOL_F;
73b64342
MD
968}
969
73b64342 970
9fbee57e
DH
971SCM_SYNTAX (s_quasiquote, "quasiquote", scm_makacro, scm_m_quasiquote);
972SCM_GLOBAL_SYMBOL (scm_sym_quasiquote, s_quasiquote);
973
974/* Internal function to handle a quasiquotation: 'form' is the parameter in
975 * the call (quasiquotation form), 'env' is the environment where unquoted
976 * expressions will be evaluated, and 'depth' is the current quasiquotation
977 * nesting level and is known to be greater than zero. */
978static SCM
979iqq (SCM form, SCM env, unsigned long int depth)
73b64342 980{
9fbee57e 981 if (SCM_CONSP (form))
c96d76b8 982 {
9fbee57e
DH
983 SCM tmp = SCM_CAR (form);
984 if (SCM_EQ_P (tmp, scm_sym_quasiquote))
985 {
986 SCM args = SCM_CDR (form);
e90c3a89 987 SCM_ASSYNT (scm_ilength (args) == 1, s_expression, s_quasiquote);
9fbee57e
DH
988 return scm_list_2 (tmp, iqq (SCM_CAR (args), env, depth + 1));
989 }
990 else if (SCM_EQ_P (tmp, scm_sym_unquote))
991 {
992 SCM args = SCM_CDR (form);
e90c3a89 993 SCM_ASSYNT (scm_ilength (args) == 1, s_expression, s_quasiquote);
9fbee57e
DH
994 if (depth - 1 == 0)
995 return scm_eval_car (args, env);
996 else
997 return scm_list_2 (tmp, iqq (SCM_CAR (args), env, depth - 1));
998 }
999 else if (SCM_CONSP (tmp)
1000 && SCM_EQ_P (SCM_CAR (tmp), scm_sym_uq_splicing))
1001 {
1002 SCM args = SCM_CDR (tmp);
e90c3a89 1003 SCM_ASSYNT (scm_ilength (args) == 1, s_expression, s_quasiquote);
9fbee57e
DH
1004 if (depth - 1 == 0)
1005 {
1006 SCM list = scm_eval_car (args, env);
1007 SCM rest = SCM_CDR (form);
1008 SCM_ASSYNT (scm_ilength (list) >= 0, s_splicing, s_quasiquote);
1009 return scm_append (scm_list_2 (list, iqq (rest, env, depth)));
1010 }
1011 else
1012 return scm_cons (iqq (SCM_CAR (form), env, depth - 1),
1013 iqq (SCM_CDR (form), env, depth));
1014 }
1015 else
1016 return scm_cons (iqq (SCM_CAR (form), env, depth),
1017 iqq (SCM_CDR (form), env, depth));
1018 }
1019 else if (SCM_VECTORP (form))
c96d76b8 1020 {
9fbee57e
DH
1021 size_t i = SCM_VECTOR_LENGTH (form);
1022 SCM const *const data = SCM_VELTS (form);
1023 SCM tmp = SCM_EOL;
1024 while (i != 0)
1025 tmp = scm_cons (data[--i], tmp);
1026 scm_remember_upto_here_1 (form);
1027 return scm_vector (iqq (tmp, env, depth));
c96d76b8 1028 }
9fbee57e
DH
1029 else
1030 return form;
1031}
1032
1033SCM
1034scm_m_quasiquote (SCM xorig, SCM env)
1035{
1036 SCM x = SCM_CDR (xorig);
e90c3a89 1037 SCM_ASSYNT (scm_ilength (x) == 1, s_expression, s_quasiquote);
9fbee57e
DH
1038 return iqq (SCM_CAR (x), env, 1);
1039}
1040
1041
3b88ed2a 1042SCM_SYNTAX (s_quote, "quote", scm_i_makbimacro, scm_m_quote);
9fbee57e
DH
1043SCM_GLOBAL_SYMBOL (scm_sym_quote, s_quote);
1044
1045SCM
1046scm_m_quote (SCM xorig, SCM env SCM_UNUSED)
1047{
e90c3a89 1048 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1, s_expression, s_quote);
9fbee57e
DH
1049 return scm_cons (SCM_IM_QUOTE, SCM_CDR (xorig));
1050}
1051
1052
1053/* Will go into the RnRS module when Guile is factorized.
3b88ed2a 1054SCM_SYNTAX (s_set_x, "set!", scm_i_makbimacro, scm_m_set_x); */
9fbee57e
DH
1055static const char s_set_x[] = "set!";
1056SCM_GLOBAL_SYMBOL (scm_sym_set_x, s_set_x);
1057
1058SCM
1059scm_m_set_x (SCM xorig, SCM env SCM_UNUSED)
1060{
1061 SCM x = SCM_CDR (xorig);
e90c3a89
DH
1062 SCM_ASSYNT (scm_ilength (x) == 2, s_expression, s_set_x);
1063 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (x)), s_variable, s_set_x);
9fbee57e
DH
1064 return scm_cons (SCM_IM_SET_X, x);
1065}
1066
1067
1068/* Start of the memoizers for non-R5RS builtin macros. */
1069
1070
3b88ed2a 1071SCM_SYNTAX (s_atapply, "@apply", scm_i_makbimacro, scm_m_apply);
9fbee57e
DH
1072SCM_GLOBAL_SYMBOL (scm_sym_atapply, s_atapply);
1073SCM_GLOBAL_SYMBOL (scm_sym_apply, s_atapply + 1);
1074
1075SCM
1076scm_m_apply (SCM xorig, SCM env SCM_UNUSED)
1077{
e90c3a89 1078 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 2, s_expression, s_atapply);
9fbee57e 1079 return scm_cons (SCM_IM_APPLY, SCM_CDR (xorig));
73b64342
MD
1080}
1081
c96d76b8 1082
2e171178
MV
1083/* (@bind ((var exp) ...) body ...)
1084
1085 This will assign the values of the `exp's to the global variables
1086 named by `var's (symbols, not evaluated), creating them if they
1087 don't exist, executes body, and then restores the previous values of
1088 the `var's. Additionally, whenever control leaves body, the values
1089 of the `var's are saved and restored when control returns. It is an
1090 error when a symbol appears more than once among the `var's.
1091 All `exp's are evaluated before any `var' is set.
1092
c96d76b8 1093 Think of this as `let' for dynamic scope.
2e171178
MV
1094
1095 It is memoized into (#@bind ((var ...) . (reversed-val ...)) body ...).
1096
1097 XXX - also implement `@bind*'.
1098*/
1099
3b88ed2a 1100SCM_SYNTAX (s_atbind, "@bind", scm_i_makbimacro, scm_m_atbind);
73b64342
MD
1101
1102SCM
1103scm_m_atbind (SCM xorig, SCM env)
1104{
1105 SCM x = SCM_CDR (xorig);
2e171178 1106 SCM top_level = scm_env_top_level (env);
311f6782 1107 SCM vars = SCM_EOL, var;
2e171178
MV
1108 SCM exps = SCM_EOL;
1109
e90c3a89 1110 SCM_ASSYNT (scm_ilength (x) > 1, s_expression, s_atbind);
73b64342 1111
73b64342
MD
1112 x = SCM_CAR (x);
1113 while (SCM_NIMP (x))
1114 {
2e171178
MV
1115 SCM rest;
1116 SCM sym_exp = SCM_CAR (x);
e90c3a89
DH
1117 SCM_ASSYNT (scm_ilength (sym_exp) == 2, s_bindings, s_atbind);
1118 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (sym_exp)), s_bindings, s_atbind);
73b64342 1119 x = SCM_CDR (x);
2e171178 1120 for (rest = x; SCM_NIMP (rest); rest = SCM_CDR (rest))
8ea46249 1121 if (SCM_EQ_P (SCM_CAR (sym_exp), SCM_CAAR (rest)))
e90c3a89 1122 scm_misc_error (s_atbind, s_duplicate_bindings, SCM_EOL);
311f6782
MV
1123 /* The first call to scm_sym2var will look beyond the current
1124 module, while the second call wont. */
1125 var = scm_sym2var (SCM_CAR (sym_exp), top_level, SCM_BOOL_F);
1126 if (SCM_FALSEP (var))
1127 var = scm_sym2var (SCM_CAR (sym_exp), top_level, SCM_BOOL_T);
1128 vars = scm_cons (var, vars);
2e171178 1129 exps = scm_cons (SCM_CADR (sym_exp), exps);
73b64342 1130 }
2e171178
MV
1131 return scm_cons (SCM_IM_BIND,
1132 scm_cons (scm_cons (scm_reverse_x (vars, SCM_EOL), exps),
1133 SCM_CDDR (xorig)));
73b64342 1134}
73b64342 1135
b0c5d67b 1136
3b88ed2a 1137SCM_SYNTAX(s_atcall_cc, "@call-with-current-continuation", scm_i_makbimacro, scm_m_cont);
9fbee57e
DH
1138SCM_GLOBAL_SYMBOL(scm_sym_atcall_cc, s_atcall_cc);
1139
1140
1141SCM
1142scm_m_cont (SCM xorig, SCM env SCM_UNUSED)
b0c5d67b 1143{
9fbee57e 1144 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1,
e90c3a89 1145 s_expression, s_atcall_cc);
9fbee57e 1146 return scm_cons (SCM_IM_CONT, SCM_CDR (xorig));
b0c5d67b 1147}
b0c5d67b
DH
1148
1149
3b88ed2a 1150SCM_SYNTAX (s_at_call_with_values, "@call-with-values", scm_i_makbimacro, scm_m_at_call_with_values);
9fbee57e 1151SCM_GLOBAL_SYMBOL(scm_sym_at_call_with_values, s_at_call_with_values);
b0c5d67b
DH
1152
1153SCM
9fbee57e 1154scm_m_at_call_with_values (SCM xorig, SCM env SCM_UNUSED)
b0c5d67b 1155{
9fbee57e 1156 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 2,
e90c3a89 1157 s_expression, s_at_call_with_values);
9fbee57e 1158 return scm_cons (SCM_IM_CALL_WITH_VALUES, SCM_CDR (xorig));
b0c5d67b 1159}
b0c5d67b
DH
1160
1161
3b88ed2a 1162SCM_SYNTAX (s_future, "future", scm_i_makbimacro, scm_m_future);
9fbee57e 1163SCM_GLOBAL_SYMBOL (scm_sym_future, s_future);
a513ead3 1164
9fbee57e
DH
1165/* Like promises, futures are implemented as closures with an empty
1166 * parameter list. Thus, (future <expression>) is transformed into
1167 * (#@future '() <expression>), where the empty list represents the
1168 * empty parameter list. This representation allows for easy creation
1169 * of the closure during evaluation. */
a513ead3 1170SCM
9fbee57e 1171scm_m_future (SCM xorig, SCM env SCM_UNUSED)
a513ead3 1172{
e90c3a89 1173 SCM_ASSYNT (scm_ilength (xorig) == 2, s_expression, s_future);
9fbee57e 1174 return scm_cons2 (SCM_IM_FUTURE, SCM_EOL, SCM_CDR (xorig));
a513ead3
MV
1175}
1176
9fbee57e 1177
3b88ed2a 1178SCM_SYNTAX (s_gset_x, "set!", scm_i_makbimacro, scm_m_generalized_set_x);
9fbee57e
DH
1179SCM_SYMBOL (scm_sym_setter, "setter");
1180
1181SCM
1182scm_m_generalized_set_x (SCM xorig, SCM env SCM_UNUSED)
1183{
1184 SCM x = SCM_CDR (xorig);
e90c3a89 1185 SCM_ASSYNT (2 == scm_ilength (x), s_expression, s_set_x);
9fbee57e
DH
1186 if (SCM_SYMBOLP (SCM_CAR (x)))
1187 return scm_cons (SCM_IM_SET_X, x);
1188 else if (SCM_CONSP (SCM_CAR (x)))
1189 return scm_cons (scm_list_2 (scm_sym_setter, SCM_CAAR (x)),
1190 scm_append (scm_list_2 (SCM_CDAR (x), SCM_CDR (x))));
1191 else
e90c3a89 1192 scm_misc_error (s_set_x, s_variable, SCM_EOL);
9fbee57e
DH
1193}
1194
1195
a4aa2134 1196static const char* s_atslot_ref = "@slot-ref";
9fbee57e 1197
a4aa2134
DH
1198/* @slot-ref is bound privately in the (oop goops) module from goops.c. As
1199 * soon as the module system allows us to more freely create bindings in
1200 * arbitrary modules during the startup phase, the code from goops.c should be
1201 * moved here. */
9fbee57e
DH
1202SCM
1203scm_m_atslot_ref (SCM xorig, SCM env SCM_UNUSED)
1204#define FUNC_NAME s_atslot_ref
1205{
1206 SCM x = SCM_CDR (xorig);
e90c3a89 1207 SCM_ASSYNT (scm_ilength (x) == 2, s_expression, FUNC_NAME);
9fbee57e
DH
1208 SCM_VALIDATE_INUM (SCM_ARG2, SCM_CADR (x));
1209 return scm_cons (SCM_IM_SLOT_REF, x);
1210}
1211#undef FUNC_NAME
1212
1213
a4aa2134 1214static const char* s_atslot_set_x = "@slot-set!";
9fbee57e 1215
a4aa2134
DH
1216/* @slot-set! is bound privately in the (oop goops) module from goops.c. As
1217 * soon as the module system allows us to more freely create bindings in
1218 * arbitrary modules during the startup phase, the code from goops.c should be
1219 * moved here. */
9fbee57e
DH
1220SCM
1221scm_m_atslot_set_x (SCM xorig, SCM env SCM_UNUSED)
1222#define FUNC_NAME s_atslot_set_x
1223{
1224 SCM x = SCM_CDR (xorig);
e90c3a89 1225 SCM_ASSYNT (scm_ilength (x) == 3, s_expression, FUNC_NAME);
9fbee57e
DH
1226 SCM_VALIDATE_INUM (SCM_ARG2, SCM_CADR (x));
1227 return scm_cons (SCM_IM_SLOT_SET_X, x);
1228}
1229#undef FUNC_NAME
1230
1231
1232#if SCM_ENABLE_ELISP
1233
3b88ed2a 1234SCM_SYNTAX (s_nil_cond, "nil-cond", scm_i_makbimacro, scm_m_nil_cond);
9fbee57e
DH
1235
1236SCM
1237scm_m_nil_cond (SCM xorig, SCM env SCM_UNUSED)
1238{
1239 long len = scm_ilength (SCM_CDR (xorig));
e90c3a89 1240 SCM_ASSYNT (len >= 1 && (len & 1) == 1, s_expression, "nil-cond");
9fbee57e
DH
1241 return scm_cons (SCM_IM_NIL_COND, SCM_CDR (xorig));
1242}
1243
1244
3b88ed2a 1245SCM_SYNTAX (s_atfop, "@fop", scm_i_makbimacro, scm_m_atfop);
9fbee57e
DH
1246
1247SCM
1248scm_m_atfop (SCM xorig, SCM env SCM_UNUSED)
1249{
1250 SCM x = SCM_CDR (xorig), var;
e90c3a89 1251 SCM_ASSYNT (scm_ilength (x) >= 1, s_expression, "@fop");
9fbee57e
DH
1252 var = scm_symbol_fref (SCM_CAR (x));
1253 /* Passing the symbol name as the `subr' arg here isn't really
1254 right, but without it it can be very difficult to work out from
1255 the error message which function definition was missing. In any
1256 case, we shouldn't really use SCM_ASSYNT here at all, but instead
1257 something equivalent to (signal void-function (list SYM)) in
1258 Elisp. */
1259 SCM_ASSYNT (SCM_VARIABLEP (var),
1260 "Symbol's function definition is void",
1261 SCM_SYMBOL_CHARS (SCM_CAR (x)));
1262 /* Support `defalias'. */
1263 while (SCM_SYMBOLP (SCM_VARIABLE_REF (var)))
1264 {
1265 var = scm_symbol_fref (SCM_VARIABLE_REF (var));
1266 SCM_ASSYNT (SCM_VARIABLEP (var),
1267 "Symbol's function definition is void",
1268 SCM_SYMBOL_CHARS (SCM_CAR (x)));
1269 }
1270 /* Use `var' here rather than `SCM_VARIABLE_REF (var)' because the
1271 former allows for automatically picking up redefinitions of the
1272 corresponding symbol. */
1273 SCM_SETCAR (x, var);
1274 /* If the variable contains a procedure, leave the
1275 `transformer-macro' in place so that the procedure's arguments
1276 get properly transformed, and change the initial @fop to
1277 SCM_IM_APPLY. */
1278 if (!SCM_MACROP (SCM_VARIABLE_REF (var)))
1279 {
1280 SCM_SETCAR (xorig, SCM_IM_APPLY);
1281 return xorig;
1282 }
1283 /* Otherwise (the variable contains a macro), the arguments should
1284 not be transformed, so cut the `transformer-macro' out and return
1285 the resulting expression starting with the variable. */
1286 SCM_SETCDR (x, SCM_CDADR (x));
1287 return x;
1288}
1289
1290#endif /* SCM_ENABLE_ELISP */
1291
1292
f58c472a
DH
1293/* Start of the memoizers for deprecated macros. */
1294
1295
1296#if (SCM_ENABLE_DEPRECATED == 1)
1297
1298SCM_SYNTAX (s_undefine, "undefine", scm_makacro, scm_m_undefine);
1299
1300SCM
1301scm_m_undefine (SCM x, SCM env)
1302{
1303 SCM arg1 = x;
1304 x = SCM_CDR (x);
1305 SCM_ASSYNT (SCM_TOP_LEVEL (env), "bad placement ", s_undefine);
1306 SCM_ASSYNT (SCM_CONSP (x) && SCM_NULLP (SCM_CDR (x)),
e90c3a89 1307 s_expression, s_undefine);
f58c472a 1308 x = SCM_CAR (x);
e90c3a89 1309 SCM_ASSYNT (SCM_SYMBOLP (x), s_variable, s_undefine);
f58c472a
DH
1310 arg1 = scm_sym2var (x, scm_env_top_level (env), SCM_BOOL_F);
1311 SCM_ASSYNT (!SCM_FALSEP (arg1) && !SCM_UNBNDP (SCM_VARIABLE_REF (arg1)),
1312 "variable already unbound ", s_undefine);
1313 SCM_VARIABLE_SET (arg1, SCM_UNDEFINED);
1314#ifdef SICP
1315 return x;
1316#else
1317 return SCM_UNSPECIFIED;
1318#endif
1319}
1320
1321#endif
1322
1323
26d5b9b4
MD
1324SCM
1325scm_m_expand_body (SCM xorig, SCM env)
1326{
22a52da1 1327 SCM x = SCM_CDR (xorig), defs = SCM_EOL;
26d5b9b4
MD
1328 char *what = SCM_ISYMCHARS (SCM_CAR (xorig)) + 2;
1329
1330 while (SCM_NIMP (x))
1331 {
22a52da1
DH
1332 SCM form = SCM_CAR (x);
1333 if (!SCM_CONSP (form))
26d5b9b4
MD
1334 break;
1335 if (!SCM_SYMBOLP (SCM_CAR (form)))
1336 break;
22a52da1 1337
3a3111a8
MD
1338 form = scm_macroexp (scm_cons_source (form,
1339 SCM_CAR (form),
1340 SCM_CDR (form)),
1341 env);
26d5b9b4 1342
cf498326 1343 if (SCM_EQ_P (SCM_IM_DEFINE, SCM_CAR (form)))
26d5b9b4
MD
1344 {
1345 defs = scm_cons (SCM_CDR (form), defs);
22a52da1 1346 x = SCM_CDR (x);
26d5b9b4 1347 }
22a52da1 1348 else if (!SCM_IMP (defs))
26d5b9b4
MD
1349 {
1350 break;
1351 }
cf498326 1352 else if (SCM_EQ_P (SCM_IM_BEGIN, SCM_CAR (form)))
26d5b9b4 1353 {
8ea46249 1354 x = scm_append (scm_list_2 (SCM_CDR (form), SCM_CDR (x)));
26d5b9b4
MD
1355 }
1356 else
1357 {
22a52da1 1358 x = scm_cons (form, SCM_CDR (x));
26d5b9b4
MD
1359 break;
1360 }
1361 }
1362
302c12b4 1363 if (!SCM_NULLP (defs))
26d5b9b4 1364 {
302c12b4
DH
1365 SCM rvars, inits, body, letrec;
1366 transform_bindings (defs, &rvars, &inits, what);
1367 body = scm_m_body (SCM_IM_DEFINE, x, what);
1368 letrec = scm_cons2 (SCM_IM_LETREC, rvars, scm_cons (inits, body));
1369 SCM_SETCAR (xorig, letrec);
1370 SCM_SETCDR (xorig, SCM_EOL);
1371 }
1372 else
1373 {
e90c3a89 1374 SCM_ASSYNT (SCM_CONSP (x), s_body, what);
302c12b4
DH
1375 SCM_SETCAR (xorig, SCM_CAR (x));
1376 SCM_SETCDR (xorig, SCM_CDR (x));
26d5b9b4 1377 }
26d5b9b4
MD
1378
1379 return xorig;
1380}
1381
1382SCM
1383scm_macroexp (SCM x, SCM env)
1384{
86d31dfe 1385 SCM res, proc, orig_sym;
26d5b9b4
MD
1386
1387 /* Don't bother to produce error messages here. We get them when we
1388 eventually execute the code for real. */
1389
1390 macro_tail:
86d31dfe
MV
1391 orig_sym = SCM_CAR (x);
1392 if (!SCM_SYMBOLP (orig_sym))
26d5b9b4
MD
1393 return x;
1394
26d5b9b4
MD
1395 {
1396 SCM *proc_ptr = scm_lookupcar1 (x, env, 0);
1397 if (proc_ptr == NULL)
1398 {
1399 /* We have lost the race. */
1400 goto macro_tail;
1401 }
1402 proc = *proc_ptr;
1403 }
26d5b9b4
MD
1404
1405 /* Only handle memoizing macros. `Acros' and `macros' are really
1406 special forms and should not be evaluated here. */
1407
3b88ed2a
DH
1408 if (!SCM_MACROP (proc)
1409 || (SCM_MACRO_TYPE (proc) != 2 && !SCM_BUILTIN_MACRO_P (proc)))
26d5b9b4
MD
1410 return x;
1411
86d31dfe 1412 SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of lookupcar */
fdc28395 1413 res = scm_call_2 (SCM_MACRO_CODE (proc), x, env);
26d5b9b4
MD
1414
1415 if (scm_ilength (res) <= 0)
8ea46249 1416 res = scm_list_2 (SCM_IM_BEGIN, res);
26d5b9b4 1417
26d5b9b4
MD
1418 SCM_DEFER_INTS;
1419 SCM_SETCAR (x, SCM_CAR (res));
1420 SCM_SETCDR (x, SCM_CDR (res));
1421 SCM_ALLOW_INTS;
1422
1423 goto macro_tail;
1424}
73b64342 1425
a44a9715
DH
1426#define SCM_BIT7(x) (127 & SCM_UNPACK (x))
1427
1428/* A function object to implement "apply" for non-closure functions. */
1429static SCM f_apply;
1430/* An endless list consisting of #<undefined> objects: */
1431static SCM undefineds;
1432
6dbd0af5
MD
1433/* scm_unmemocopy takes a memoized expression together with its
1434 * environment and rewrites it to its original form. Thus, it is the
1435 * inversion of the rewrite rules above. The procedure is not
1436 * optimized for speed. It's used in scm_iprin1 when printing the
220ff1eb
MD
1437 * code of a closure, in scm_procedure_source, in display_frame when
1438 * generating the source for a stackframe in a backtrace, and in
1439 * display_expression.
86d31dfe 1440 *
c96d76b8 1441 * Unmemoizing is not a reliable process. You cannot in general
86d31dfe
MV
1442 * expect to get the original source back.
1443 *
1444 * However, GOOPS currently relies on this for method compilation.
1445 * This ought to change.
26d5b9b4
MD
1446 */
1447
8ea46249
DH
1448static SCM
1449build_binding_list (SCM names, SCM inits)
1450{
1451 SCM bindings = SCM_EOL;
1452 while (!SCM_NULLP (names))
1453 {
1454 SCM binding = scm_list_2 (SCM_CAR (names), SCM_CAR (inits));
1455 bindings = scm_cons (binding, bindings);
1456 names = SCM_CDR (names);
1457 inits = SCM_CDR (inits);
1458 }
1459 return bindings;
1460}
1461
6dbd0af5 1462static SCM
1bbd0b84 1463unmemocopy (SCM x, SCM env)
6dbd0af5
MD
1464{
1465 SCM ls, z;
6dbd0af5 1466 SCM p;
8c494e99 1467 if (!SCM_CONSP (x))
6dbd0af5 1468 return x;
6dbd0af5 1469 p = scm_whash_lookup (scm_source_whash, x);
8ea46249 1470 switch (SCM_ITAG7 (SCM_CAR (x)))
6dbd0af5 1471 {
1b43d24c 1472 case SCM_BIT7 (SCM_IM_AND):
2f0d1375 1473 ls = z = scm_cons (scm_sym_and, SCM_UNSPECIFIED);
6dbd0af5 1474 break;
1b43d24c 1475 case SCM_BIT7 (SCM_IM_BEGIN):
2f0d1375 1476 ls = z = scm_cons (scm_sym_begin, SCM_UNSPECIFIED);
6dbd0af5 1477 break;
1b43d24c 1478 case SCM_BIT7 (SCM_IM_CASE):
2f0d1375 1479 ls = z = scm_cons (scm_sym_case, SCM_UNSPECIFIED);
6dbd0af5 1480 break;
1b43d24c 1481 case SCM_BIT7 (SCM_IM_COND):
2f0d1375 1482 ls = z = scm_cons (scm_sym_cond, SCM_UNSPECIFIED);
6dbd0af5 1483 break;
1b43d24c 1484 case SCM_BIT7 (SCM_IM_DO):
6dbd0af5 1485 {
e681d187
DH
1486 /* format: (#@do (i1 ... ik) (nk nk-1 ...) (test) (body) s1 ... sk),
1487 * where ix is an initializer for a local variable, nx is the name of
8ea46249
DH
1488 * the local variable, test is the test clause of the do loop, body is
1489 * the body of the do loop and sx are the step clauses for the local
1490 * variables. */
1491 SCM names, inits, test, memoized_body, steps, bindings;
1492
6dbd0af5 1493 x = SCM_CDR (x);
8ea46249 1494 inits = scm_reverse (unmemocopy (SCM_CAR (x), env));
e681d187
DH
1495 x = SCM_CDR (x);
1496 names = SCM_CAR (x);
821f18a4 1497 env = SCM_EXTEND_ENV (names, SCM_EOL, env);
6dbd0af5 1498 x = SCM_CDR (x);
8ea46249
DH
1499 test = unmemocopy (SCM_CAR (x), env);
1500 x = SCM_CDR (x);
1501 memoized_body = SCM_CAR (x);
1502 x = SCM_CDR (x);
1503 steps = scm_reverse (unmemocopy (x, env));
1504
26d5b9b4 1505 /* build transformed binding list */
8ea46249
DH
1506 bindings = SCM_EOL;
1507 while (!SCM_NULLP (names))
6dbd0af5 1508 {
8ea46249
DH
1509 SCM name = SCM_CAR (names);
1510 SCM init = SCM_CAR (inits);
1511 SCM step = SCM_CAR (steps);
1512 step = SCM_EQ_P (step, name) ? SCM_EOL : scm_list_1 (step);
1513
1514 bindings = scm_cons (scm_cons2 (name, init, step), bindings);
1515
1516 names = SCM_CDR (names);
1517 inits = SCM_CDR (inits);
1518 steps = SCM_CDR (steps);
6dbd0af5 1519 }
8ea46249
DH
1520 z = scm_cons (test, SCM_UNSPECIFIED);
1521 ls = scm_cons2 (scm_sym_do, bindings, z);
1522
1523 x = scm_cons (SCM_BOOL_F, memoized_body);
1524 break;
1525 }
1b43d24c 1526 case SCM_BIT7 (SCM_IM_IF):
8ea46249
DH
1527 ls = z = scm_cons (scm_sym_if, SCM_UNSPECIFIED);
1528 break;
1b43d24c 1529 case SCM_BIT7 (SCM_IM_LET):
8ea46249
DH
1530 {
1531 /* format: (#@let (nk nk-1 ...) (i1 ... ik) b1 ...),
1532 * where nx is the name of a local variable, ix is an initializer for
1533 * the local variable and by are the body clauses. */
1534 SCM names, inits, bindings;
1535
1536 x = SCM_CDR (x);
1537 names = SCM_CAR (x);
1538 x = SCM_CDR (x);
1539 inits = scm_reverse (unmemocopy (SCM_CAR (x), env));
821f18a4 1540 env = SCM_EXTEND_ENV (names, SCM_EOL, env);
8ea46249
DH
1541
1542 bindings = build_binding_list (names, inits);
1543 z = scm_cons (bindings, SCM_UNSPECIFIED);
1544 ls = scm_cons (scm_sym_let, z);
1545 break;
1546 }
1b43d24c 1547 case SCM_BIT7 (SCM_IM_LETREC):
8ea46249
DH
1548 {
1549 /* format: (#@letrec (nk nk-1 ...) (i1 ... ik) b1 ...),
1550 * where nx is the name of a local variable, ix is an initializer for
1551 * the local variable and by are the body clauses. */
1552 SCM names, inits, bindings;
1553
1554 x = SCM_CDR (x);
1555 names = SCM_CAR (x);
821f18a4 1556 env = SCM_EXTEND_ENV (names, SCM_EOL, env);
8ea46249
DH
1557 x = SCM_CDR (x);
1558 inits = scm_reverse (unmemocopy (SCM_CAR (x), env));
1559
1560 bindings = build_binding_list (names, inits);
1561 z = scm_cons (bindings, SCM_UNSPECIFIED);
1562 ls = scm_cons (scm_sym_letrec, z);
6dbd0af5
MD
1563 break;
1564 }
1b43d24c 1565 case SCM_BIT7 (SCM_IM_LETSTAR):
6dbd0af5
MD
1566 {
1567 SCM b, y;
1568 x = SCM_CDR (x);
1569 b = SCM_CAR (x);
1570 y = SCM_EOL;
1571 if SCM_IMP (b)
1572 {
821f18a4 1573 env = SCM_EXTEND_ENV (SCM_EOL, SCM_EOL, env);
6dbd0af5
MD
1574 goto letstar;
1575 }
1576 y = z = scm_acons (SCM_CAR (b),
1577 unmemocar (
8ea46249 1578 scm_cons (unmemocopy (SCM_CADR (b), env), SCM_EOL), env),
6dbd0af5 1579 SCM_UNSPECIFIED);
821f18a4 1580 env = SCM_EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
8ea46249 1581 b = SCM_CDDR (b);
6dbd0af5
MD
1582 if (SCM_IMP (b))
1583 {
1584 SCM_SETCDR (y, SCM_EOL);
05b15362
DH
1585 z = scm_cons (y, SCM_UNSPECIFIED);
1586 ls = scm_cons (scm_sym_let, z);
6dbd0af5
MD
1587 break;
1588 }
1589 do
1590 {
a23afe53
MD
1591 SCM_SETCDR (z, scm_acons (SCM_CAR (b),
1592 unmemocar (
8ea46249 1593 scm_list_1 (unmemocopy (SCM_CADR (b), env)), env),
a23afe53
MD
1594 SCM_UNSPECIFIED));
1595 z = SCM_CDR (z);
821f18a4 1596 env = SCM_EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
8ea46249 1597 b = SCM_CDDR (b);
6dbd0af5 1598 }
ff467021 1599 while (SCM_NIMP (b));
a23afe53 1600 SCM_SETCDR (z, SCM_EOL);
6dbd0af5 1601 letstar:
05b15362
DH
1602 z = scm_cons (y, SCM_UNSPECIFIED);
1603 ls = scm_cons (scm_sym_letstar, z);
6dbd0af5
MD
1604 break;
1605 }
1b43d24c 1606 case SCM_BIT7 (SCM_IM_OR):
2f0d1375 1607 ls = z = scm_cons (scm_sym_or, SCM_UNSPECIFIED);
6dbd0af5 1608 break;
1b43d24c 1609 case SCM_BIT7 (SCM_IM_LAMBDA):
6dbd0af5 1610 x = SCM_CDR (x);
8ea46249
DH
1611 z = scm_cons (SCM_CAR (x), SCM_UNSPECIFIED);
1612 ls = scm_cons (scm_sym_lambda, z);
821f18a4 1613 env = SCM_EXTEND_ENV (SCM_CAR (x), SCM_EOL, env);
6dbd0af5 1614 break;
1b43d24c 1615 case SCM_BIT7 (SCM_IM_QUOTE):
2f0d1375 1616 ls = z = scm_cons (scm_sym_quote, SCM_UNSPECIFIED);
6dbd0af5 1617 break;
1b43d24c 1618 case SCM_BIT7 (SCM_IM_SET_X):
89efbff4 1619 ls = z = scm_cons (scm_sym_set_x, SCM_UNSPECIFIED);
6dbd0af5 1620 break;
1b43d24c 1621 case SCM_BIT7 (SCM_MAKISYM (0)):
6dbd0af5 1622 z = SCM_CAR (x);
ff467021 1623 switch (SCM_ISYMNUM (z))
6dbd0af5 1624 {
22f2cf2d
DH
1625 case (SCM_ISYMNUM (SCM_IM_DEFINE)):
1626 {
1627 SCM n;
1628 x = SCM_CDR (x);
1629 n = SCM_CAR (x);
1630 z = scm_cons (n, SCM_UNSPECIFIED);
1631 ls = scm_cons (scm_sym_define, z);
1632 if (!SCM_NULLP (env))
1633 env = scm_cons (scm_cons (scm_cons (n, SCM_CAAR (env)),
1634 SCM_CDAR (env)),
1635 SCM_CDR (env));
1636 break;
1637 }
6dbd0af5 1638 case (SCM_ISYMNUM (SCM_IM_APPLY)):
2f0d1375 1639 ls = z = scm_cons (scm_sym_atapply, SCM_UNSPECIFIED);
6dbd0af5
MD
1640 goto loop;
1641 case (SCM_ISYMNUM (SCM_IM_CONT)):
2f0d1375 1642 ls = z = scm_cons (scm_sym_atcall_cc, SCM_UNSPECIFIED);
6dbd0af5 1643 goto loop;
a570e93a
MD
1644 case (SCM_ISYMNUM (SCM_IM_DELAY)):
1645 ls = z = scm_cons (scm_sym_delay, SCM_UNSPECIFIED);
1646 x = SCM_CDR (x);
1647 goto loop;
28d52ebb 1648 case (SCM_ISYMNUM (SCM_IM_FUTURE)):
ebf9b47c 1649 ls = z = scm_cons (scm_sym_future, SCM_UNSPECIFIED);
28d52ebb
MD
1650 x = SCM_CDR (x);
1651 goto loop;
a513ead3
MV
1652 case (SCM_ISYMNUM (SCM_IM_CALL_WITH_VALUES)):
1653 ls = z = scm_cons (scm_sym_at_call_with_values, SCM_UNSPECIFIED);
1654 goto loop;
6dbd0af5 1655 default:
fa888178 1656 /* appease the Sun compiler god: */ ;
6dbd0af5 1657 }
6dbd0af5
MD
1658 default:
1659 ls = z = unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env),
1660 SCM_UNSPECIFIED),
1661 env);
1662 }
1663loop:
8c494e99
DH
1664 x = SCM_CDR (x);
1665 while (SCM_CONSP (x))
a23afe53 1666 {
8c494e99
DH
1667 SCM form = SCM_CAR (x);
1668 if (!SCM_ISYMP (form))
1669 {
1670 SCM copy = scm_cons (unmemocopy (form, env), SCM_UNSPECIFIED);
1671 SCM_SETCDR (z, unmemocar (copy, env));
1672 z = SCM_CDR (z);
1673 }
1674 x = SCM_CDR (x);
a23afe53
MD
1675 }
1676 SCM_SETCDR (z, x);
01f11e02 1677 if (!SCM_FALSEP (p))
6dbd0af5 1678 scm_whash_insert (scm_source_whash, ls, p);
6dbd0af5
MD
1679 return ls;
1680}
1681
1cc91f1b 1682
6dbd0af5 1683SCM
6e8d25a6 1684scm_unmemocopy (SCM x, SCM env)
6dbd0af5 1685{
01f11e02 1686 if (!SCM_NULLP (env))
6dbd0af5
MD
1687 /* Make a copy of the lowest frame to protect it from
1688 modifications by SCM_IM_DEFINE */
1689 return unmemocopy (x, scm_cons (SCM_CAR (env), SCM_CDR (env)));
1690 else
1691 return unmemocopy (x, env);
1692}
1693
1cc91f1b 1694
0f2d19dd 1695int
6e8d25a6 1696scm_badargsp (SCM formals, SCM args)
0f2d19dd 1697{
6a0f6ff3 1698 while (!SCM_NULLP (formals))
0f2d19dd 1699 {
01f11e02 1700 if (!SCM_CONSP (formals))
ff467021 1701 return 0;
6a0f6ff3 1702 if (SCM_NULLP (args))
ff467021 1703 return 1;
0f2d19dd
JB
1704 formals = SCM_CDR (formals);
1705 args = SCM_CDR (args);
1706 }
01f11e02 1707 return !SCM_NULLP (args) ? 1 : 0;
0f2d19dd 1708}
a392ee15 1709
0f2d19dd 1710\f
6dbd0af5 1711SCM
6e8d25a6 1712scm_eval_args (SCM l, SCM env, SCM proc)
6dbd0af5 1713{
680ed4a8 1714 SCM results = SCM_EOL, *lloc = &results, res;
904a077d 1715 while (SCM_CONSP (l))
6dbd0af5 1716 {
680ed4a8 1717 res = EVALCAR (l, env);
904a077d 1718
8ea46249 1719 *lloc = scm_list_1 (res);
a23afe53 1720 lloc = SCM_CDRLOC (*lloc);
6dbd0af5
MD
1721 l = SCM_CDR (l);
1722 }
22a52da1 1723 if (!SCM_NULLP (l))
904a077d 1724 scm_wrong_num_args (proc);
680ed4a8 1725 return results;
6dbd0af5 1726}
c4ac4d88 1727
d0b07b5d 1728
9de33deb
MD
1729SCM
1730scm_eval_body (SCM code, SCM env)
1731{
1732 SCM next;
1733 again:
01f11e02
DH
1734 next = SCM_CDR (code);
1735 while (!SCM_NULLP (next))
9de33deb
MD
1736 {
1737 if (SCM_IMP (SCM_CAR (code)))
1738 {
1739 if (SCM_ISYMP (SCM_CAR (code)))
1740 {
28d52ebb 1741 scm_rec_mutex_lock (&source_mutex);
9bc4701c
MD
1742 /* check for race condition */
1743 if (SCM_ISYMP (SCM_CAR (code)))
1744 code = scm_m_expand_body (code, env);
28d52ebb 1745 scm_rec_mutex_unlock (&source_mutex);
9de33deb
MD
1746 goto again;
1747 }
1748 }
1749 else
1750 SCM_XEVAL (SCM_CAR (code), env);
1751 code = next;
01f11e02 1752 next = SCM_CDR (code);
9de33deb
MD
1753 }
1754 return SCM_XEVALCAR (code, env);
1755}
1756
0f2d19dd
JB
1757#endif /* !DEVAL */
1758
6dbd0af5
MD
1759
1760/* SECTION: This code is specific for the debugging support. One
1761 * branch is read when DEVAL isn't defined, the other when DEVAL is
1762 * defined.
1763 */
1764
1765#ifndef DEVAL
1766
1767#define SCM_APPLY scm_apply
1768#define PREP_APPLY(proc, args)
1769#define ENTER_APPLY
ddea3325 1770#define RETURN(x) do { return x; } while (0)
b7ff98dd
MD
1771#ifdef STACK_CHECKING
1772#ifndef NO_CEVAL_STACK_CHECKING
1773#define EVAL_STACK_CHECKING
1774#endif
6dbd0af5
MD
1775#endif
1776
1777#else /* !DEVAL */
1778
0f2d19dd
JB
1779#undef SCM_CEVAL
1780#define SCM_CEVAL scm_deval /* Substitute all uses of scm_ceval */
1781#undef SCM_APPLY
1782#define SCM_APPLY scm_dapply
6dbd0af5
MD
1783#undef PREP_APPLY
1784#define PREP_APPLY(p, l) \
1785{ ++debug.info; debug.info->a.proc = p; debug.info->a.args = l; }
1786#undef ENTER_APPLY
1787#define ENTER_APPLY \
d3a6bc94 1788do { \
b7ff98dd 1789 SCM_SET_ARGSREADY (debug);\
5132eef0 1790 if (scm_check_apply_p && SCM_TRAPS_P)\
b7ff98dd 1791 if (SCM_APPLY_FRAME_P || (SCM_TRACE_P && PROCTRACEP (proc)))\
6dbd0af5 1792 {\
156dcb09 1793 SCM tmp, tail = SCM_BOOL(SCM_TRACED_FRAME_P (debug)); \
c6a4fbce 1794 SCM_SET_TRACED_FRAME (debug); \
d95c0b76 1795 SCM_TRAPS_P = 0;\
b7ff98dd 1796 if (SCM_CHEAPTRAPS_P)\
6dbd0af5 1797 {\
c0ab1b8d 1798 tmp = scm_make_debugobj (&debug);\
d95c0b76 1799 scm_call_3 (SCM_APPLY_FRAME_HDLR, scm_sym_apply_frame, tmp, tail);\
b6d75948 1800 }\
6dbd0af5
MD
1801 else\
1802 {\
5f144b10
GH
1803 int first;\
1804 tmp = scm_make_continuation (&first);\
1805 if (first)\
d95c0b76 1806 scm_call_3 (SCM_APPLY_FRAME_HDLR, scm_sym_apply_frame, tmp, tail);\
6dbd0af5 1807 }\
d95c0b76 1808 SCM_TRAPS_P = 1;\
6dbd0af5 1809 }\
d3a6bc94 1810} while (0)
0f2d19dd 1811#undef RETURN
ddea3325 1812#define RETURN(e) do { proc = (e); goto exit; } while (0)
b7ff98dd
MD
1813#ifdef STACK_CHECKING
1814#ifndef EVAL_STACK_CHECKING
1815#define EVAL_STACK_CHECKING
1816#endif
6dbd0af5
MD
1817#endif
1818
1819/* scm_ceval_ptr points to the currently selected evaluator.
1820 * *fixme*: Although efficiency is important here, this state variable
1821 * should probably not be a global. It should be related to the
1822 * current repl.
1823 */
1824
1cc91f1b 1825
1bbd0b84 1826SCM (*scm_ceval_ptr) (SCM x, SCM env);
0f2d19dd 1827
1646d37b 1828/* scm_last_debug_frame contains a pointer to the last debugging
6dbd0af5
MD
1829 * information stack frame. It is accessed very often from the
1830 * debugging evaluator, so it should probably not be indirectly
1831 * addressed. Better to save and restore it from the current root at
1832 * any stack swaps.
1833 */
1834
6dbd0af5
MD
1835/* scm_debug_eframe_size is the number of slots available for pseudo
1836 * stack frames at each real stack frame.
1837 */
1838
c014a02e 1839long scm_debug_eframe_size;
6dbd0af5 1840
b7ff98dd 1841int scm_debug_mode, scm_check_entry_p, scm_check_apply_p, scm_check_exit_p;
6dbd0af5 1842
c014a02e 1843long scm_eval_stack;
a74145b8 1844
92c2555f 1845scm_t_option scm_eval_opts[] = {
a74145b8 1846 { SCM_OPTION_INTEGER, "stack", 22000, "Size of thread stacks (in machine words)." }
33b97402
MD
1847};
1848
92c2555f 1849scm_t_option scm_debug_opts[] = {
b7ff98dd
MD
1850 { SCM_OPTION_BOOLEAN, "cheap", 1,
1851 "*Flyweight representation of the stack at traps." },
1852 { SCM_OPTION_BOOLEAN, "breakpoints", 0, "*Check for breakpoints." },
1853 { SCM_OPTION_BOOLEAN, "trace", 0, "*Trace mode." },
1854 { SCM_OPTION_BOOLEAN, "procnames", 1,
1855 "Record procedure names at definition." },
1856 { SCM_OPTION_BOOLEAN, "backwards", 0,
1857 "Display backtrace in anti-chronological order." },
274dc5fd 1858 { SCM_OPTION_INTEGER, "width", 79, "Maximal width of backtrace." },
4e646a03
MD
1859 { SCM_OPTION_INTEGER, "indent", 10, "Maximal indentation in backtrace." },
1860 { SCM_OPTION_INTEGER, "frames", 3,
b7ff98dd 1861 "Maximum number of tail-recursive frames in backtrace." },
4e646a03
MD
1862 { SCM_OPTION_INTEGER, "maxdepth", 1000,
1863 "Maximal number of stored backtrace frames." },
1864 { SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." },
11f77bfc
MD
1865 { SCM_OPTION_BOOLEAN, "backtrace", 0, "Show backtrace on error." },
1866 { SCM_OPTION_BOOLEAN, "debug", 0, "Use the debugging evaluator." },
863e833b 1867 { SCM_OPTION_INTEGER, "stack", 20000, "Stack size limit (measured in words; 0 = no check)." },
d95c0b76 1868 { SCM_OPTION_SCM, "show-file-name", (unsigned long)SCM_BOOL_T, "Show file names and line numbers in backtraces when not `#f'. A value of `base' displays only base names, while `#t' displays full names."}
6dbd0af5
MD
1869};
1870
92c2555f 1871scm_t_option scm_evaluator_trap_table[] = {
b6d75948 1872 { SCM_OPTION_BOOLEAN, "traps", 0, "Enable evaluator traps." },
b7ff98dd
MD
1873 { SCM_OPTION_BOOLEAN, "enter-frame", 0, "Trap when eval enters new frame." },
1874 { SCM_OPTION_BOOLEAN, "apply-frame", 0, "Trap when entering apply." },
d95c0b76
NJ
1875 { SCM_OPTION_BOOLEAN, "exit-frame", 0, "Trap when exiting eval or apply." },
1876 { SCM_OPTION_SCM, "enter-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for enter-frame traps." },
1877 { SCM_OPTION_SCM, "apply-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for apply-frame traps." },
1878 { SCM_OPTION_SCM, "exit-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for exit-frame traps." }
6dbd0af5
MD
1879};
1880
a1ec6916 1881SCM_DEFINE (scm_eval_options_interface, "eval-options-interface", 0, 1, 0,
1bbd0b84 1882 (SCM setting),
b3f26b14
MG
1883 "Option interface for the evaluation options. Instead of using\n"
1884 "this procedure directly, use the procedures @code{eval-enable},\n"
3939e9df 1885 "@code{eval-disable}, @code{eval-set!} and @code{eval-options}.")
1bbd0b84 1886#define FUNC_NAME s_scm_eval_options_interface
33b97402
MD
1887{
1888 SCM ans;
1889 SCM_DEFER_INTS;
1890 ans = scm_options (setting,
1891 scm_eval_opts,
1892 SCM_N_EVAL_OPTIONS,
1bbd0b84 1893 FUNC_NAME);
a74145b8 1894 scm_eval_stack = SCM_EVAL_STACK * sizeof (void *);
33b97402
MD
1895 SCM_ALLOW_INTS;
1896 return ans;
1897}
1bbd0b84 1898#undef FUNC_NAME
33b97402 1899
d0b07b5d 1900
a1ec6916 1901SCM_DEFINE (scm_evaluator_traps, "evaluator-traps-interface", 0, 1, 0,
1bbd0b84 1902 (SCM setting),
b3f26b14 1903 "Option interface for the evaluator trap options.")
1bbd0b84 1904#define FUNC_NAME s_scm_evaluator_traps
33b97402
MD
1905{
1906 SCM ans;
1907 SCM_DEFER_INTS;
1908 ans = scm_options (setting,
1909 scm_evaluator_trap_table,
1910 SCM_N_EVALUATOR_TRAPS,
1bbd0b84 1911 FUNC_NAME);
33b97402 1912 SCM_RESET_DEBUG_MODE;
bfc69694 1913 SCM_ALLOW_INTS;
33b97402
MD
1914 return ans;
1915}
1bbd0b84 1916#undef FUNC_NAME
33b97402 1917
d0b07b5d 1918
24933780 1919static SCM
a392ee15 1920deval_args (SCM l, SCM env, SCM proc, SCM *lloc)
0f2d19dd 1921{
680ed4a8 1922 SCM *results = lloc, res;
904a077d 1923 while (SCM_CONSP (l))
0f2d19dd 1924 {
680ed4a8 1925 res = EVALCAR (l, env);
904a077d 1926
8ea46249 1927 *lloc = scm_list_1 (res);
a23afe53 1928 lloc = SCM_CDRLOC (*lloc);
0f2d19dd
JB
1929 l = SCM_CDR (l);
1930 }
22a52da1 1931 if (!SCM_NULLP (l))
904a077d 1932 scm_wrong_num_args (proc);
680ed4a8 1933 return *results;
0f2d19dd
JB
1934}
1935
6dbd0af5
MD
1936#endif /* !DEVAL */
1937
1938
a392ee15 1939/* SECTION: This code is compiled twice.
6dbd0af5
MD
1940 */
1941
a392ee15 1942
d9d39d76 1943/* Update the toplevel environment frame ENV so that it refers to the
a392ee15 1944 * current module. */
d9d39d76
MV
1945#define UPDATE_TOPLEVEL_ENV(env) \
1946 do { \
1947 SCM p = scm_current_module_lookup_closure (); \
d0b07b5d 1948 if (p != SCM_CAR (env)) \
d9d39d76
MV
1949 env = scm_top_level_env (p); \
1950 } while (0)
1951
6dbd0af5 1952
a392ee15
DH
1953/* This is the evaluator. Like any real monster, it has three heads:
1954 *
1955 * scm_ceval is the non-debugging evaluator, scm_deval is the debugging
1956 * version. Both are implemented using a common code base, using the
1957 * following mechanism: SCM_CEVAL is a macro, which is either defined to
1958 * scm_ceval or scm_deval. Thus, there is no function SCM_CEVAL, but the code
1959 * for SCM_CEVAL actually compiles to either scm_ceval or scm_deval. When
1960 * SCM_CEVAL is defined to scm_ceval, it is known that the macro DEVAL is not
1961 * defined. When SCM_CEVAL is defined to scm_deval, then the macro DEVAL is
1962 * known to be defined. Thus, in SCM_CEVAL parts for the debugging evaluator
1963 * are enclosed within #ifdef DEVAL ... #endif.
1964 *
1965 * All three (scm_ceval, scm_deval and their common implementation SCM_CEVAL)
1966 * take two input parameters, x and env: x is a single expression to be
1967 * evalutated. env is the environment in which bindings are searched.
1968 *
1969 * x is known to be a cell (i. e. a pair or any other non-immediate). Since x
1970 * is a single expression, it is necessarily in a tail position. If x is just
1971 * a call to another function like in the expression (foo exp1 exp2 ...), the
1972 * realization of that call therefore _must_not_ increase stack usage (the
1973 * evaluation of exp1, exp2 etc., however, may do so). This is realized by
1974 * making extensive use of 'goto' statements within the evaluator: The gotos
1975 * replace recursive calls to SCM_CEVAL, thus re-using the same stack frame
1976 * that SCM_CEVAL was already using. If, however, x represents some form that
1977 * requires to evaluate a sequence of expressions like (begin exp1 exp2 ...),
1978 * then recursive calls to SCM_CEVAL are performed for all but the last
1979 * expression of that sequence. */
6dbd0af5 1980
0f2d19dd 1981#if 0
0f2d19dd 1982SCM
1bbd0b84 1983scm_ceval (SCM x, SCM env)
0f2d19dd
JB
1984{}
1985#endif
1cc91f1b 1986
a392ee15 1987#if 0
0f2d19dd 1988SCM
1bbd0b84 1989scm_deval (SCM x, SCM env)
0f2d19dd
JB
1990{}
1991#endif
1992
6dbd0af5 1993SCM
1bbd0b84 1994SCM_CEVAL (SCM x, SCM env)
0f2d19dd 1995{
42030fb2 1996 SCM proc, arg1;
6dbd0af5 1997#ifdef DEVAL
92c2555f
MV
1998 scm_t_debug_frame debug;
1999 scm_t_debug_info *debug_info_end;
1646d37b 2000 debug.prev = scm_last_debug_frame;
020c890c 2001 debug.status = 0;
04b6c081 2002 /*
92c2555f 2003 * The debug.vect contains twice as much scm_t_debug_info frames as the
04b6c081
MD
2004 * user has specified with (debug-set! frames <n>).
2005 *
2006 * Even frames are eval frames, odd frames are apply frames.
2007 */
92c2555f 2008 debug.vect = (scm_t_debug_info *) alloca (scm_debug_eframe_size
a392ee15 2009 * sizeof (scm_t_debug_info));
c0ab1b8d
JB
2010 debug.info = debug.vect;
2011 debug_info_end = debug.vect + scm_debug_eframe_size;
2012 scm_last_debug_frame = &debug;
6dbd0af5 2013#endif
b7ff98dd 2014#ifdef EVAL_STACK_CHECKING
79f55b7c 2015 if (scm_stack_checking_enabled_p && SCM_STACK_OVERFLOW_P (&proc))
6dbd0af5 2016 {
b7ff98dd 2017#ifdef DEVAL
6dbd0af5
MD
2018 debug.info->e.exp = x;
2019 debug.info->e.env = env;
b7ff98dd 2020#endif
6dbd0af5
MD
2021 scm_report_stack_overflow ();
2022 }
2023#endif
6a0f6ff3 2024
6dbd0af5
MD
2025#ifdef DEVAL
2026 goto start;
2027#endif
6a0f6ff3 2028
6dbd0af5
MD
2029loop:
2030#ifdef DEVAL
b7ff98dd
MD
2031 SCM_CLEAR_ARGSREADY (debug);
2032 if (SCM_OVERFLOWP (debug))
6dbd0af5 2033 --debug.info;
04b6c081
MD
2034 /*
2035 * In theory, this should be the only place where it is necessary to
2036 * check for space in debug.vect since both eval frames and
2037 * available space are even.
2038 *
2039 * For this to be the case, however, it is necessary that primitive
2040 * special forms which jump back to `loop', `begin' or some similar
680516ba 2041 * label call PREP_APPLY.
04b6c081 2042 */
c0ab1b8d 2043 else if (++debug.info >= debug_info_end)
6dbd0af5 2044 {
b7ff98dd 2045 SCM_SET_OVERFLOW (debug);
6dbd0af5
MD
2046 debug.info -= 2;
2047 }
6a0f6ff3 2048
6dbd0af5
MD
2049start:
2050 debug.info->e.exp = x;
2051 debug.info->e.env = env;
5132eef0
DH
2052 if (scm_check_entry_p && SCM_TRAPS_P)
2053 {
bc76d628
DH
2054 if (SCM_ENTER_FRAME_P
2055 || (SCM_BREAKPOINTS_P && scm_c_source_property_breakpoint_p (x)))
5132eef0 2056 {
bc76d628
DH
2057 SCM stackrep;
2058 SCM tail = SCM_BOOL (SCM_TAILRECP (debug));
5132eef0
DH
2059 SCM_SET_TAILREC (debug);
2060 if (SCM_CHEAPTRAPS_P)
bc76d628 2061 stackrep = scm_make_debugobj (&debug);
5132eef0
DH
2062 else
2063 {
2064 int first;
2065 SCM val = scm_make_continuation (&first);
2066
2067 if (first)
bc76d628 2068 stackrep = val;
5132eef0
DH
2069 else
2070 {
2071 x = val;
2072 if (SCM_IMP (x))
2073 RETURN (x);
2074 else
2075 /* This gives the possibility for the debugger to
2076 modify the source expression before evaluation. */
2077 goto dispatch;
2078 }
2079 }
2080 SCM_TRAPS_P = 0;
2081 scm_call_4 (SCM_ENTER_FRAME_HDLR,
2082 scm_sym_enter_frame,
bc76d628 2083 stackrep,
5132eef0
DH
2084 tail,
2085 scm_unmemocopy (x, env));
2086 SCM_TRAPS_P = 1;
2087 }
2088 }
6dbd0af5 2089#endif
f8769b1d 2090dispatch:
9cb5124f 2091 SCM_TICK;
0f2d19dd
JB
2092 switch (SCM_TYP7 (x))
2093 {
28b06554 2094 case scm_tc7_symbol:
a392ee15 2095 /* Only happens when called at top level. */
0f2d19dd 2096 x = scm_cons (x, SCM_UNDEFINED);
ddea3325 2097 RETURN (*scm_lookupcar (x, env, 1));
0f2d19dd 2098
1b43d24c 2099 case SCM_BIT7 (SCM_IM_AND):
0f2d19dd 2100 x = SCM_CDR (x);
302c12b4
DH
2101 while (!SCM_NULLP (SCM_CDR (x)))
2102 {
38ace99e
DH
2103 SCM test_result = EVALCAR (x, env);
2104 if (SCM_FALSEP (test_result) || SCM_NILP (test_result))
0f2d19dd 2105 RETURN (SCM_BOOL_F);
302c12b4
DH
2106 else
2107 x = SCM_CDR (x);
2108 }
6dbd0af5 2109 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2110 goto carloop;
2111
1b43d24c 2112 case SCM_BIT7 (SCM_IM_BEGIN):
e050d4f8
DH
2113 x = SCM_CDR (x);
2114 if (SCM_NULLP (x))
b8113bc8
MV
2115 RETURN (SCM_UNSPECIFIED);
2116
6dbd0af5 2117 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2118
2119 begin:
4163eb72
MV
2120 /* If we are on toplevel with a lookup closure, we need to sync
2121 with the current module. */
22a52da1 2122 if (SCM_CONSP (env) && !SCM_CONSP (SCM_CAR (env)))
4163eb72 2123 {
d9d39d76 2124 UPDATE_TOPLEVEL_ENV (env);
302c12b4 2125 while (!SCM_NULLP (SCM_CDR (x)))
4163eb72 2126 {
5280aaca 2127 EVALCAR (x, env);
d9d39d76 2128 UPDATE_TOPLEVEL_ENV (env);
302c12b4 2129 x = SCM_CDR (x);
4163eb72 2130 }
5280aaca 2131 goto carloop;
4163eb72
MV
2132 }
2133 else
5280aaca
MV
2134 goto nontoplevel_begin;
2135
5280aaca 2136 nontoplevel_begin:
302c12b4 2137 while (!SCM_NULLP (SCM_CDR (x)))
0f2d19dd 2138 {
6a0f6ff3
DH
2139 SCM form = SCM_CAR (x);
2140 if (SCM_IMP (form))
26d5b9b4 2141 {
6a0f6ff3 2142 if (SCM_ISYMP (form))
26d5b9b4 2143 {
28d52ebb 2144 scm_rec_mutex_lock (&source_mutex);
9bc4701c
MD
2145 /* check for race condition */
2146 if (SCM_ISYMP (SCM_CAR (x)))
2147 x = scm_m_expand_body (x, env);
28d52ebb 2148 scm_rec_mutex_unlock (&source_mutex);
5280aaca 2149 goto nontoplevel_begin;
26d5b9b4 2150 }
4163eb72 2151 else
6a0f6ff3 2152 SCM_VALIDATE_NON_EMPTY_COMBINATION (form);
26d5b9b4 2153 }
5280aaca 2154 else
6a0f6ff3 2155 SCM_CEVAL (form, env);
302c12b4 2156 x = SCM_CDR (x);
0f2d19dd 2157 }
5280aaca 2158
6a0f6ff3
DH
2159 carloop:
2160 {
2161 /* scm_eval last form in list */
2162 SCM last_form = SCM_CAR (x);
0f2d19dd 2163
6a0f6ff3
DH
2164 if (SCM_CONSP (last_form))
2165 {
2166 /* This is by far the most frequent case. */
2167 x = last_form;
2168 goto loop; /* tail recurse */
2169 }
2170 else if (SCM_IMP (last_form))
2171 RETURN (SCM_EVALIM (last_form, env));
2172 else if (SCM_VARIABLEP (last_form))
2173 RETURN (SCM_VARIABLE_REF (last_form));
2174 else if (SCM_SYMBOLP (last_form))
2175 RETURN (*scm_lookupcar (x, env, 1));
2176 else
2177 RETURN (last_form);
2178 }
0f2d19dd
JB
2179
2180
1b43d24c 2181 case SCM_BIT7 (SCM_IM_CASE):
0f2d19dd 2182 x = SCM_CDR (x);
6a0f6ff3
DH
2183 {
2184 SCM key = EVALCAR (x, env);
2185 x = SCM_CDR (x);
2186 while (!SCM_NULLP (x))
2187 {
2188 SCM clause = SCM_CAR (x);
2189 SCM labels = SCM_CAR (clause);
2190 if (SCM_EQ_P (labels, scm_sym_else))
2191 {
2192 x = SCM_CDR (clause);
2193 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2194 goto begin;
2195 }
2196 while (!SCM_NULLP (labels))
2197 {
2198 SCM label = SCM_CAR (labels);
2199 if (SCM_EQ_P (label, key) || !SCM_FALSEP (scm_eqv_p (label, key)))
2200 {
2201 x = SCM_CDR (clause);
2202 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2203 goto begin;
2204 }
2205 labels = SCM_CDR (labels);
2206 }
2207 x = SCM_CDR (x);
2208 }
2209 }
ddea3325 2210 RETURN (SCM_UNSPECIFIED);
0f2d19dd
JB
2211
2212
1b43d24c 2213 case SCM_BIT7 (SCM_IM_COND):
8ea46249
DH
2214 x = SCM_CDR (x);
2215 while (!SCM_NULLP (x))
0f2d19dd 2216 {
e5cb71a0
DH
2217 SCM clause = SCM_CAR (x);
2218 if (SCM_EQ_P (SCM_CAR (clause), scm_sym_else))
8ea46249 2219 {
e5cb71a0 2220 x = SCM_CDR (clause);
8ea46249
DH
2221 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2222 goto begin;
2223 }
e5cb71a0 2224 else
0f2d19dd 2225 {
dff98306
DH
2226 arg1 = EVALCAR (clause, env);
2227 if (!SCM_FALSEP (arg1) && !SCM_NILP (arg1))
6dbd0af5 2228 {
e5cb71a0
DH
2229 x = SCM_CDR (clause);
2230 if (SCM_NULLP (x))
dff98306 2231 RETURN (arg1);
e5cb71a0
DH
2232 else if (!SCM_EQ_P (SCM_CAR (x), scm_sym_arrow))
2233 {
2234 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2235 goto begin;
2236 }
2237 else
2238 {
2239 proc = SCM_CDR (x);
2240 proc = EVALCAR (proc, env);
dff98306 2241 PREP_APPLY (proc, scm_list_1 (arg1));
e5cb71a0 2242 ENTER_APPLY;
ddd8f927 2243 goto evap1;
e5cb71a0 2244 }
6dbd0af5 2245 }
e5cb71a0 2246 x = SCM_CDR (x);
0f2d19dd
JB
2247 }
2248 }
ddea3325 2249 RETURN (SCM_UNSPECIFIED);
0f2d19dd
JB
2250
2251
1b43d24c 2252 case SCM_BIT7 (SCM_IM_DO):
0f2d19dd 2253 x = SCM_CDR (x);
e5cb71a0
DH
2254 {
2255 /* Compute the initialization values and the initial environment. */
e681d187 2256 SCM init_forms = SCM_CAR (x);
e5cb71a0
DH
2257 SCM init_values = SCM_EOL;
2258 while (!SCM_NULLP (init_forms))
2259 {
2260 init_values = scm_cons (EVALCAR (init_forms, env), init_values);
2261 init_forms = SCM_CDR (init_forms);
2262 }
e681d187 2263 x = SCM_CDR (x);
821f18a4 2264 env = SCM_EXTEND_ENV (SCM_CAR (x), init_values, env);
e5cb71a0 2265 }
e681d187 2266 x = SCM_CDR (x);
e5cb71a0
DH
2267 {
2268 SCM test_form = SCM_CAR (x);
2269 SCM body_forms = SCM_CADR (x);
2270 SCM step_forms = SCM_CDDR (x);
2271
2272 SCM test_result = EVALCAR (test_form, env);
2273
2274 while (SCM_FALSEP (test_result) || SCM_NILP (test_result))
2275 {
0f2d19dd 2276 {
e5cb71a0
DH
2277 /* Evaluate body forms. */
2278 SCM temp_forms;
2279 for (temp_forms = body_forms;
2280 !SCM_NULLP (temp_forms);
2281 temp_forms = SCM_CDR (temp_forms))
2282 {
2283 SCM form = SCM_CAR (temp_forms);
2284 /* Dirk:FIXME: We only need to eval forms, that may have a
2285 * side effect here. This is only true for forms that start
2286 * with a pair. All others are just constants. However,
2287 * since in the common case there is no constant expression
2288 * in a body of a do form, we just check for immediates here
2289 * and have SCM_CEVAL take care of other cases. In the long
2290 * run it would make sense to get rid of this test and have
2291 * the macro transformer of 'do' eliminate all forms that
2292 * have no sideeffect. */
2293 if (!SCM_IMP (form))
2294 SCM_CEVAL (form, env);
2295 }
0f2d19dd 2296 }
e5cb71a0
DH
2297
2298 {
2299 /* Evaluate the step expressions. */
2300 SCM temp_forms;
2301 SCM step_values = SCM_EOL;
2302 for (temp_forms = step_forms;
2303 !SCM_NULLP (temp_forms);
2304 temp_forms = SCM_CDR (temp_forms))
2305 {
2306 SCM value = EVALCAR (temp_forms, env);
2307 step_values = scm_cons (value, step_values);
2308 }
821f18a4
DH
2309 env = SCM_EXTEND_ENV (SCM_CAAR (env),
2310 step_values,
2311 SCM_CDR (env));
e5cb71a0
DH
2312 }
2313
2314 test_result = EVALCAR (test_form, env);
2315 }
2316 }
2317 x = SCM_CDAR (x);
0f2d19dd 2318 if (SCM_NULLP (x))
6dbd0af5
MD
2319 RETURN (SCM_UNSPECIFIED);
2320 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
5280aaca 2321 goto nontoplevel_begin;
0f2d19dd
JB
2322
2323
1b43d24c 2324 case SCM_BIT7 (SCM_IM_IF):
0f2d19dd 2325 x = SCM_CDR (x);
38ace99e
DH
2326 {
2327 SCM test_result = EVALCAR (x, env);
2328 if (!SCM_FALSEP (test_result) && !SCM_NILP (test_result))
2329 x = SCM_CDR (x);
2330 else
2331 {
2332 x = SCM_CDDR (x);
2333 if (SCM_NULLP (x))
2334 RETURN (SCM_UNSPECIFIED);
2335 }
2336 }
6dbd0af5 2337 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2338 goto carloop;
2339
2340
1b43d24c 2341 case SCM_BIT7 (SCM_IM_LET):
0f2d19dd 2342 x = SCM_CDR (x);
38ace99e
DH
2343 {
2344 SCM init_forms = SCM_CADR (x);
2345 SCM init_values = SCM_EOL;
2346 do
2347 {
2348 init_values = scm_cons (EVALCAR (init_forms, env), init_values);
2349 init_forms = SCM_CDR (init_forms);
2350 }
2351 while (!SCM_NULLP (init_forms));
821f18a4 2352 env = SCM_EXTEND_ENV (SCM_CAR (x), init_values, env);
38ace99e 2353 }
e050d4f8
DH
2354 x = SCM_CDDR (x);
2355 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2356 goto nontoplevel_begin;
0f2d19dd
JB
2357
2358
1b43d24c 2359 case SCM_BIT7 (SCM_IM_LETREC):
0f2d19dd 2360 x = SCM_CDR (x);
821f18a4 2361 env = SCM_EXTEND_ENV (SCM_CAR (x), undefineds, env);
0f2d19dd 2362 x = SCM_CDR (x);
38ace99e
DH
2363 {
2364 SCM init_forms = SCM_CAR (x);
2365 SCM init_values = SCM_EOL;
2366 do
2367 {
2368 init_values = scm_cons (EVALCAR (init_forms, env), init_values);
2369 init_forms = SCM_CDR (init_forms);
2370 }
2371 while (!SCM_NULLP (init_forms));
2372 SCM_SETCDR (SCM_CAR (env), init_values);
2373 }
e050d4f8
DH
2374 x = SCM_CDR (x);
2375 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2376 goto nontoplevel_begin;
0f2d19dd
JB
2377
2378
1b43d24c 2379 case SCM_BIT7 (SCM_IM_LETSTAR):
0f2d19dd 2380 x = SCM_CDR (x);
302c12b4
DH
2381 {
2382 SCM bindings = SCM_CAR (x);
2383 if (SCM_NULLP (bindings))
821f18a4 2384 env = SCM_EXTEND_ENV (SCM_EOL, SCM_EOL, env);
302c12b4
DH
2385 else
2386 {
2387 do
2388 {
2389 SCM name = SCM_CAR (bindings);
2390 SCM init = SCM_CDR (bindings);
821f18a4 2391 env = SCM_EXTEND_ENV (name, EVALCAR (init, env), env);
302c12b4
DH
2392 bindings = SCM_CDR (init);
2393 }
2394 while (!SCM_NULLP (bindings));
2395 }
2396 }
e050d4f8
DH
2397 x = SCM_CDR (x);
2398 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2399 goto nontoplevel_begin;
0f2d19dd 2400
302c12b4 2401
1b43d24c 2402 case SCM_BIT7 (SCM_IM_OR):
0f2d19dd 2403 x = SCM_CDR (x);
302c12b4 2404 while (!SCM_NULLP (SCM_CDR (x)))
0f2d19dd 2405 {
302c12b4 2406 SCM val = EVALCAR (x, env);
c96d76b8 2407 if (!SCM_FALSEP (val) && !SCM_NILP (val))
302c12b4
DH
2408 RETURN (val);
2409 else
2410 x = SCM_CDR (x);
0f2d19dd 2411 }
6dbd0af5 2412 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2413 goto carloop;
2414
2415
1b43d24c 2416 case SCM_BIT7 (SCM_IM_LAMBDA):
0f2d19dd
JB
2417 RETURN (scm_closure (SCM_CDR (x), env));
2418
2419
1b43d24c 2420 case SCM_BIT7 (SCM_IM_QUOTE):
8ea46249 2421 RETURN (SCM_CADR (x));
0f2d19dd
JB
2422
2423
1b43d24c 2424 case SCM_BIT7 (SCM_IM_SET_X):
0f2d19dd 2425 x = SCM_CDR (x);
38ace99e
DH
2426 {
2427 SCM *location;
2428 SCM variable = SCM_CAR (x);
e050d4f8 2429 if (SCM_ILOCP (variable))
38ace99e 2430 location = scm_ilookup (variable, env);
3063e30a 2431 else if (SCM_VARIABLEP (variable))
e050d4f8 2432 location = SCM_VARIABLE_LOC (variable);
38ace99e
DH
2433 else /* (SCM_SYMBOLP (variable)) is known to be true */
2434 location = scm_lookupcar (x, env, 1);
2435 x = SCM_CDR (x);
2436 *location = EVALCAR (x, env);
2437 }
0f2d19dd 2438 RETURN (SCM_UNSPECIFIED);
0f2d19dd
JB
2439
2440
0f2d19dd 2441 /* new syntactic forms go here. */
1b43d24c 2442 case SCM_BIT7 (SCM_MAKISYM (0)):
0f2d19dd 2443 proc = SCM_CAR (x);
a392ee15 2444 switch (SCM_ISYMNUM (proc))
0f2d19dd 2445 {
3f04400d
DH
2446
2447
22f2cf2d
DH
2448 case (SCM_ISYMNUM (SCM_IM_DEFINE)):
2449 /* Top level defines are handled directly by the memoizer and thus
2450 * will never generate memoized code with SCM_IM_DEFINE. Internal
2451 * defines which occur at valid positions will be transformed into
2452 * letrec expressions. Thus, whenever the executor detects
2453 * SCM_IM_DEFINE, this must come from an internal definition at an
2454 * illegal position. */
2455 scm_misc_error (NULL, "Bad define placement", SCM_EOL);
2456
2457
0f2d19dd 2458 case (SCM_ISYMNUM (SCM_IM_APPLY)):
e910e9d2
DH
2459 x = SCM_CDR (x);
2460 proc = EVALCAR (x, env);
2461 PREP_APPLY (proc, SCM_EOL);
2462 x = SCM_CDR (x);
2463 arg1 = EVALCAR (x, env);
9a069bdd
DH
2464
2465 apply_proc:
2466 /* Go here to tail-apply a procedure. PROC is the procedure and
2467 * ARG1 is the list of arguments. PREP_APPLY must have been called
2468 * before jumping to apply_proc. */
0f2d19dd
JB
2469 if (SCM_CLOSUREP (proc))
2470 {
9a069bdd 2471 SCM formals = SCM_CLOSURE_FORMALS (proc);
6dbd0af5 2472#ifdef DEVAL
9a069bdd 2473 debug.info->a.args = arg1;
6dbd0af5 2474#endif
9a069bdd
DH
2475 if (scm_badargsp (formals, arg1))
2476 scm_wrong_num_args (proc);
2477 ENTER_APPLY;
2478 /* Copy argument list */
2479 if (SCM_NULL_OR_NIL_P (arg1))
2480 env = SCM_EXTEND_ENV (formals, SCM_EOL, SCM_ENV (proc));
2481 else
2482 {
2483 SCM args = scm_list_1 (SCM_CAR (arg1));
2484 SCM tail = args;
2485 arg1 = SCM_CDR (arg1);
2486 while (!SCM_NULL_OR_NIL_P (arg1))
2487 {
2488 SCM new_tail = scm_list_1 (SCM_CAR (arg1));
2489 SCM_SETCDR (tail, new_tail);
2490 tail = new_tail;
2491 arg1 = SCM_CDR (arg1);
2492 }
2493 env = SCM_EXTEND_ENV (formals, args, SCM_ENV (proc));
2494 }
2495
2496 x = SCM_CLOSURE_BODY (proc);
2497 goto nontoplevel_begin;
0f2d19dd 2498 }
3f04400d
DH
2499 else
2500 {
e910e9d2
DH
2501 ENTER_APPLY;
2502 RETURN (SCM_APPLY (proc, arg1, SCM_EOL));
3f04400d
DH
2503 }
2504
0f2d19dd
JB
2505
2506 case (SCM_ISYMNUM (SCM_IM_CONT)):
5f144b10
GH
2507 {
2508 int first;
2509 SCM val = scm_make_continuation (&first);
2510
e050d4f8 2511 if (!first)
5f144b10 2512 RETURN (val);
e050d4f8
DH
2513 else
2514 {
2515 arg1 = val;
2516 proc = SCM_CDR (x);
2517 proc = scm_eval_car (proc, env);
e050d4f8
DH
2518 PREP_APPLY (proc, scm_list_1 (arg1));
2519 ENTER_APPLY;
e050d4f8
DH
2520 goto evap1;
2521 }
5f144b10 2522 }
e050d4f8 2523
0f2d19dd 2524
a570e93a 2525 case (SCM_ISYMNUM (SCM_IM_DELAY)):
ddea3325 2526 RETURN (scm_makprom (scm_closure (SCM_CDR (x), env)));
a570e93a 2527
e050d4f8 2528
28d52ebb
MD
2529 case (SCM_ISYMNUM (SCM_IM_FUTURE)):
2530 RETURN (scm_i_make_future (scm_closure (SCM_CDR (x), env)));
2531
2532
c8e1d354
MD
2533 /* PLACEHOLDER for case (SCM_ISYMNUM (SCM_IM_DISPATCH)): The
2534 following code (type_dispatch) is intended to be the tail
2535 of the case clause for the internal macro
2536 SCM_IM_DISPATCH. Please don't remove it from this
2537 location without discussing it with Mikael
2538 <djurfeldt@nada.kth.se> */
2539
f12745b6
DH
2540 /* The type dispatch code is duplicated below
2541 * (c.f. objects.c:scm_mcache_compute_cmethod) since that
2542 * cuts down execution time for type dispatch to 50%. */
dff98306 2543 type_dispatch: /* inputs: x, arg1 */
f12745b6
DH
2544 /* Type dispatch means to determine from the types of the function
2545 * arguments (i. e. the 'signature' of the call), which method from
2546 * a generic function is to be called. This process of selecting
2547 * the right method takes some time. To speed it up, guile uses
2548 * caching: Together with the macro call to dispatch the signatures
2549 * of some previous calls to that generic function from the same
2550 * place are stored (in the code!) in a cache that we call the
2551 * 'method cache'. This is done since it is likely, that
2552 * consecutive calls to dispatch from that position in the code will
2553 * have the same signature. Thus, the type dispatch works as
2554 * follows: First, determine a hash value from the signature of the
2555 * actual arguments. Second, use this hash value as an index to
2556 * find that same signature in the method cache stored at this
2557 * position in the code. If found, you have also found the
2558 * corresponding method that belongs to that signature. If the
2559 * signature is not found in the method cache, you have to perform a
2560 * full search over all signatures stored with the generic
2561 * function. */
2562 {
2563 unsigned long int specializers;
2564 unsigned long int hash_value;
2565 unsigned long int cache_end_pos;
2566 unsigned long int mask;
2567 SCM method_cache;
2568
2569 {
2570 SCM z = SCM_CDDR (x);
2571 SCM tmp = SCM_CADR (z);
2572 specializers = SCM_INUM (SCM_CAR (z));
2573
2574 /* Compute a hash value for searching the method cache. There
2575 * are two variants for computing the hash value, a (rather)
2576 * complicated one, and a simple one. For the complicated one
2577 * explained below, tmp holds a number that is used in the
2578 * computation. */
2579 if (SCM_INUMP (tmp))
2580 {
2581 /* Use the signature of the actual arguments to determine
2582 * the hash value. This is done as follows: Each class has
2583 * an array of random numbers, that are determined when the
2584 * class is created. The integer 'hashset' is an index into
2585 * that array of random numbers. Now, from all classes that
2586 * are part of the signature of the actual arguments, the
2587 * random numbers at index 'hashset' are taken and summed
2588 * up, giving the hash value. The value of 'hashset' is
2589 * stored at the call to dispatch. This allows to have
2590 * different 'formulas' for calculating the hash value at
2591 * different places where dispatch is called. This allows
2592 * to optimize the hash formula at every individual place
2593 * where dispatch is called, such that hopefully the hash
2594 * value that is computed will directly point to the right
2595 * method in the method cache. */
2596 unsigned long int hashset = SCM_INUM (tmp);
2597 unsigned long int counter = specializers + 1;
dff98306 2598 SCM tmp_arg = arg1;
f12745b6
DH
2599 hash_value = 0;
2600 while (!SCM_NULLP (tmp_arg) && counter != 0)
61364ba6 2601 {
f12745b6
DH
2602 SCM class = scm_class_of (SCM_CAR (tmp_arg));
2603 hash_value += SCM_INSTANCE_HASH (class, hashset);
2604 tmp_arg = SCM_CDR (tmp_arg);
2605 counter--;
61364ba6 2606 }
f12745b6
DH
2607 z = SCM_CDDR (z);
2608 method_cache = SCM_CADR (z);
2609 mask = SCM_INUM (SCM_CAR (z));
2610 hash_value &= mask;
2611 cache_end_pos = hash_value;
2612 }
2613 else
2614 {
2615 /* This method of determining the hash value is much
2616 * simpler: Set the hash value to zero and just perform a
2617 * linear search through the method cache. */
2618 method_cache = tmp;
2619 mask = (unsigned long int) ((long) -1);
2620 hash_value = 0;
2621 cache_end_pos = SCM_VECTOR_LENGTH (method_cache);
2622 }
2623 }
61364ba6 2624
f12745b6
DH
2625 {
2626 /* Search the method cache for a method with a matching
2627 * signature. Start the search at position 'hash_value'. The
2628 * hashing implementation uses linear probing for conflict
2629 * resolution, that is, if the signature in question is not
2630 * found at the starting index in the hash table, the next table
2631 * entry is tried, and so on, until in the worst case the whole
2632 * cache has been searched, but still the signature has not been
2633 * found. */
2634 SCM z;
2635 do
2636 {
dff98306 2637 SCM args = arg1; /* list of arguments */
f12745b6
DH
2638 z = SCM_VELTS (method_cache)[hash_value];
2639 while (!SCM_NULLP (args))
61364ba6
MD
2640 {
2641 /* More arguments than specifiers => CLASS != ENV */
f12745b6
DH
2642 SCM class_of_arg = scm_class_of (SCM_CAR (args));
2643 if (!SCM_EQ_P (class_of_arg, SCM_CAR (z)))
61364ba6 2644 goto next_method;
f12745b6 2645 args = SCM_CDR (args);
61364ba6
MD
2646 z = SCM_CDR (z);
2647 }
f12745b6
DH
2648 /* Fewer arguments than specifiers => CAR != ENV */
2649 if (SCM_NULLP (SCM_CAR (z)) || SCM_CONSP (SCM_CAR (z)))
2650 goto apply_cmethod;
2651 next_method:
2652 hash_value = (hash_value + 1) & mask;
2653 } while (hash_value != cache_end_pos);
2654
2655 /* No appropriate method was found in the cache. */
dff98306 2656 z = scm_memoize_method (x, arg1);
f12745b6 2657
dff98306 2658 apply_cmethod: /* inputs: z, arg1 */
f12745b6
DH
2659 {
2660 SCM formals = SCM_CMETHOD_FORMALS (z);
821f18a4 2661 env = SCM_EXTEND_ENV (formals, arg1, SCM_CMETHOD_ENV (z));
f12745b6
DH
2662 x = SCM_CMETHOD_BODY (z);
2663 goto nontoplevel_begin;
2664 }
2665 }
61364ba6 2666 }
73b64342 2667
1d15ecd3 2668
ca4be6ea
MD
2669 case (SCM_ISYMNUM (SCM_IM_SLOT_REF)):
2670 x = SCM_CDR (x);
1d15ecd3
DH
2671 {
2672 SCM instance = EVALCAR (x, env);
2673 unsigned long int slot = SCM_INUM (SCM_CADR (x));
2674 RETURN (SCM_PACK (SCM_STRUCT_DATA (instance) [slot]));
2675 }
2676
2677
ca4be6ea
MD
2678 case (SCM_ISYMNUM (SCM_IM_SLOT_SET_X)):
2679 x = SCM_CDR (x);
1d15ecd3
DH
2680 {
2681 SCM instance = EVALCAR (x, env);
2682 unsigned long int slot = SCM_INUM (SCM_CADR (x));
2683 SCM value = EVALCAR (SCM_CDDR (x), env);
2684 SCM_STRUCT_DATA (instance) [slot] = SCM_UNPACK (value);
2685 RETURN (SCM_UNSPECIFIED);
2686 }
2687
c96d76b8 2688
22721140 2689#if SCM_ENABLE_ELISP
ca4be6ea 2690
73b64342 2691 case (SCM_ISYMNUM (SCM_IM_NIL_COND)):
1d15ecd3
DH
2692 {
2693 SCM test_form = SCM_CDR (x);
2694 x = SCM_CDR (test_form);
2695 while (!SCM_NULL_OR_NIL_P (x))
2696 {
2697 SCM test_result = EVALCAR (test_form, env);
2698 if (!(SCM_FALSEP (test_result)
2699 || SCM_NULL_OR_NIL_P (test_result)))
2700 {
2701 if (SCM_EQ_P (SCM_CAR (x), SCM_UNSPECIFIED))
2702 RETURN (test_result);
2703 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2704 goto carloop;
2705 }
2706 else
2707 {
2708 test_form = SCM_CDR (x);
2709 x = SCM_CDR (test_form);
2710 }
2711 }
2712 x = test_form;
2713 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2714 goto carloop;
2715 }
73b64342 2716
c96d76b8 2717#endif /* SCM_ENABLE_ELISP */
73b64342
MD
2718
2719 case (SCM_ISYMNUM (SCM_IM_BIND)):
2e171178
MV
2720 {
2721 SCM vars, exps, vals;
73b64342 2722
2e171178
MV
2723 x = SCM_CDR (x);
2724 vars = SCM_CAAR (x);
2725 exps = SCM_CDAR (x);
2726
2727 vals = SCM_EOL;
2728
2729 while (SCM_NIMP (exps))
2730 {
2731 vals = scm_cons (EVALCAR (exps, env), vals);
2732 exps = SCM_CDR (exps);
2733 }
2734
2735 scm_swap_bindings (vars, vals);
2736 scm_dynwinds = scm_acons (vars, vals, scm_dynwinds);
1d15ecd3
DH
2737
2738 /* Ignore all but the last evaluation result. */
2739 for (x = SCM_CDR (x); !SCM_NULLP (SCM_CDR (x)); x = SCM_CDR (x))
2e171178 2740 {
1d15ecd3
DH
2741 if (SCM_CONSP (SCM_CAR (x)))
2742 SCM_CEVAL (SCM_CAR (x), env);
2e171178
MV
2743 }
2744 proc = EVALCAR (x, env);
73b64342 2745
2e171178
MV
2746 scm_dynwinds = SCM_CDR (scm_dynwinds);
2747 scm_swap_bindings (vars, vals);
73b64342 2748
ddea3325 2749 RETURN (proc);
2e171178 2750 }
c96d76b8 2751
1d15ecd3 2752
a513ead3
MV
2753 case (SCM_ISYMNUM (SCM_IM_CALL_WITH_VALUES)):
2754 {
9a069bdd
DH
2755 SCM producer;
2756
2757 x = SCM_CDR (x);
2758 producer = EVALCAR (x, env);
2759 x = SCM_CDR (x);
2760 proc = EVALCAR (x, env); /* proc is the consumer. */
2761 arg1 = SCM_APPLY (producer, SCM_EOL, SCM_EOL);
dff98306
DH
2762 if (SCM_VALUESP (arg1))
2763 arg1 = scm_struct_ref (arg1, SCM_INUM0);
a513ead3 2764 else
dff98306 2765 arg1 = scm_list_1 (arg1);
9a069bdd
DH
2766 PREP_APPLY (proc, arg1);
2767 goto apply_proc;
a513ead3
MV
2768 }
2769
b7798e10 2770
0f2d19dd 2771 default:
ddd8f927 2772 goto evapply;
0f2d19dd
JB
2773 }
2774
2775 default:
2776 proc = x;
ddd8f927 2777 goto evapply;
0f2d19dd
JB
2778 case scm_tc7_vector:
2779 case scm_tc7_wvect:
22721140 2780#if SCM_HAVE_ARRAYS
0f2d19dd
JB
2781 case scm_tc7_bvect:
2782 case scm_tc7_byvect:
2783 case scm_tc7_svect:
2784 case scm_tc7_ivect:
2785 case scm_tc7_uvect:
2786 case scm_tc7_fvect:
2787 case scm_tc7_dvect:
2788 case scm_tc7_cvect:
3d05f2e0 2789#if SCM_SIZEOF_LONG_LONG != 0
0f2d19dd 2790 case scm_tc7_llvect:
afe5177e 2791#endif
0f2d19dd 2792#endif
534c55a9 2793 case scm_tc7_number:
0f2d19dd 2794 case scm_tc7_string:
0f2d19dd
JB
2795 case scm_tc7_smob:
2796 case scm_tcs_closures:
224822be 2797 case scm_tc7_cclo:
89efbff4 2798 case scm_tc7_pws:
0f2d19dd 2799 case scm_tcs_subrs:
904a077d 2800 case scm_tcs_struct:
0f2d19dd
JB
2801 RETURN (x);
2802
d22a0ea1 2803 case scm_tc7_variable:
a130e982 2804 RETURN (SCM_VARIABLE_REF(x));
d22a0ea1 2805
1b43d24c 2806 case SCM_BIT7 (SCM_ILOC00):
0f2d19dd 2807 proc = *scm_ilookup (SCM_CAR (x), env);
ddd8f927 2808 goto checkmacro;
b7798e10 2809
0f2d19dd 2810 case scm_tcs_cons_nimcar:
e050d4f8 2811 if (SCM_SYMBOLP (SCM_CAR (x)))
0f2d19dd 2812 {
e050d4f8 2813 SCM orig_sym = SCM_CAR (x);
b7798e10
DH
2814 {
2815 SCM *location = scm_lookupcar1 (x, env, 1);
2816 if (location == NULL)
2817 {
2818 /* we have lost the race, start again. */
2819 goto dispatch;
2820 }
2821 proc = *location;
2822 }
f8769b1d 2823
22a52da1 2824 if (SCM_MACROP (proc))
0f2d19dd 2825 {
86d31dfe
MV
2826 SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of
2827 lookupcar */
e050d4f8 2828 handle_a_macro: /* inputs: x, env, proc */
368bf056 2829#ifdef DEVAL
7c354052
MD
2830 /* Set a flag during macro expansion so that macro
2831 application frames can be deleted from the backtrace. */
2832 SCM_SET_MACROEXP (debug);
368bf056 2833#endif
dff98306 2834 arg1 = SCM_APPLY (SCM_MACRO_CODE (proc), x,
f8769b1d
MV
2835 scm_cons (env, scm_listofnull));
2836
7c354052
MD
2837#ifdef DEVAL
2838 SCM_CLEAR_MACROEXP (debug);
2839#endif
22a52da1 2840 switch (SCM_MACRO_TYPE (proc))
0f2d19dd 2841 {
3b88ed2a 2842 case 3:
0f2d19dd 2843 case 2:
dff98306
DH
2844 if (scm_ilength (arg1) <= 0)
2845 arg1 = scm_list_2 (SCM_IM_BEGIN, arg1);
6dbd0af5 2846#ifdef DEVAL
22a52da1 2847 if (!SCM_CLOSUREP (SCM_MACRO_CODE (proc)))
6dbd0af5 2848 {
6dbd0af5 2849 SCM_DEFER_INTS;
dff98306
DH
2850 SCM_SETCAR (x, SCM_CAR (arg1));
2851 SCM_SETCDR (x, SCM_CDR (arg1));
6dbd0af5
MD
2852 SCM_ALLOW_INTS;
2853 goto dispatch;
2854 }
2855 /* Prevent memoizing of debug info expression. */
6203706f
MD
2856 debug.info->e.exp = scm_cons_source (debug.info->e.exp,
2857 SCM_CAR (x),
2858 SCM_CDR (x));
6dbd0af5 2859#endif
0f2d19dd 2860 SCM_DEFER_INTS;
dff98306
DH
2861 SCM_SETCAR (x, SCM_CAR (arg1));
2862 SCM_SETCDR (x, SCM_CDR (arg1));
0f2d19dd 2863 SCM_ALLOW_INTS;
680516ba
DH
2864 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2865 goto loop;
3063e30a 2866#if SCM_ENABLE_DEPRECATED == 1
0f2d19dd 2867 case 1:
680516ba
DH
2868 x = arg1;
2869 if (SCM_NIMP (x))
2870 {
2871 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2872 goto loop;
2873 }
2874 else
2875 RETURN (arg1);
3063e30a 2876#endif
0f2d19dd 2877 case 0:
dff98306 2878 RETURN (arg1);
0f2d19dd
JB
2879 }
2880 }
2881 }
2882 else
2883 proc = SCM_CEVAL (SCM_CAR (x), env);
bd987b8e 2884
ddd8f927
DH
2885 checkmacro:
2886 if (SCM_MACROP (proc))
0f2d19dd 2887 goto handle_a_macro;
0f2d19dd
JB
2888 }
2889
2890
e050d4f8 2891evapply: /* inputs: x, proc */
6dbd0af5
MD
2892 PREP_APPLY (proc, SCM_EOL);
2893 if (SCM_NULLP (SCM_CDR (x))) {
2894 ENTER_APPLY;
89efbff4 2895 evap0:
ddd8f927 2896 SCM_ASRTGO (!SCM_IMP (proc), badfun);
0f2d19dd
JB
2897 switch (SCM_TYP7 (proc))
2898 { /* no arguments given */
2899 case scm_tc7_subr_0:
2900 RETURN (SCM_SUBRF (proc) ());
2901 case scm_tc7_subr_1o:
2902 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED));
2903 case scm_tc7_lsubr:
2904 RETURN (SCM_SUBRF (proc) (SCM_EOL));
2905 case scm_tc7_rpsubr:
2906 RETURN (SCM_BOOL_T);
2907 case scm_tc7_asubr:
2908 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED));
0717dfd8 2909 case scm_tc7_smob:
68b06924 2910 if (!SCM_SMOB_APPLICABLE_P (proc))
0717dfd8 2911 goto badfun;
68b06924 2912 RETURN (SCM_SMOB_APPLY_0 (proc));
0f2d19dd 2913 case scm_tc7_cclo:
dff98306 2914 arg1 = proc;
0f2d19dd 2915 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
2916#ifdef DEVAL
2917 debug.info->a.proc = proc;
dff98306 2918 debug.info->a.args = scm_list_1 (arg1);
6dbd0af5 2919#endif
0f2d19dd 2920 goto evap1;
89efbff4
MD
2921 case scm_tc7_pws:
2922 proc = SCM_PROCEDURE (proc);
2923#ifdef DEVAL
2924 debug.info->a.proc = proc;
2925#endif
002f1a5d
MD
2926 if (!SCM_CLOSUREP (proc))
2927 goto evap0;
ddd8f927 2928 /* fallthrough */
0f2d19dd 2929 case scm_tcs_closures:
ddd8f927
DH
2930 {
2931 const SCM formals = SCM_CLOSURE_FORMALS (proc);
2932 if (SCM_CONSP (formals))
2933 goto umwrongnumargs;
2934 x = SCM_CLOSURE_BODY (proc);
2935 env = SCM_EXTEND_ENV (formals, SCM_EOL, SCM_ENV (proc));
2936 goto nontoplevel_begin;
2937 }
904a077d 2938 case scm_tcs_struct:
195847fa
MD
2939 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2940 {
2941 x = SCM_ENTITY_PROCEDURE (proc);
dff98306 2942 arg1 = SCM_EOL;
195847fa
MD
2943 goto type_dispatch;
2944 }
2ca0d207 2945 else if (SCM_I_OPERATORP (proc))
da7f71d7 2946 {
dff98306 2947 arg1 = proc;
195847fa
MD
2948 proc = (SCM_I_ENTITYP (proc)
2949 ? SCM_ENTITY_PROCEDURE (proc)
2950 : SCM_OPERATOR_PROCEDURE (proc));
da7f71d7 2951#ifdef DEVAL
195847fa 2952 debug.info->a.proc = proc;
dff98306 2953 debug.info->a.args = scm_list_1 (arg1);
da7f71d7 2954#endif
ddd8f927 2955 goto evap1;
da7f71d7 2956 }
2ca0d207
DH
2957 else
2958 goto badfun;
0f2d19dd
JB
2959 case scm_tc7_subr_1:
2960 case scm_tc7_subr_2:
2961 case scm_tc7_subr_2o:
14b18ed6 2962 case scm_tc7_dsubr:
0f2d19dd
JB
2963 case scm_tc7_cxr:
2964 case scm_tc7_subr_3:
2965 case scm_tc7_lsubr_2:
2966 umwrongnumargs:
2967 unmemocar (x, env);
f5bf2977 2968 scm_wrong_num_args (proc);
0f2d19dd 2969 default:
ddd8f927
DH
2970 badfun:
2971 scm_misc_error (NULL, "Wrong type to apply: ~S", scm_list_1 (proc));
0f2d19dd 2972 }
6dbd0af5 2973 }
0f2d19dd
JB
2974
2975 /* must handle macros by here */
2976 x = SCM_CDR (x);
dff98306
DH
2977 if (SCM_CONSP (x))
2978 arg1 = EVALCAR (x, env);
680ed4a8 2979 else
ab1f1094 2980 scm_wrong_num_args (proc);
6dbd0af5 2981#ifdef DEVAL
dff98306 2982 debug.info->a.args = scm_list_1 (arg1);
6dbd0af5 2983#endif
0f2d19dd 2984 x = SCM_CDR (x);
42030fb2
DH
2985 {
2986 SCM arg2;
2987 if (SCM_NULLP (x))
2988 {
2989 ENTER_APPLY;
2990 evap1: /* inputs: proc, arg1 */
ddd8f927 2991 SCM_ASRTGO (!SCM_IMP (proc), badfun);
42030fb2
DH
2992 switch (SCM_TYP7 (proc))
2993 { /* have one argument in arg1 */
2994 case scm_tc7_subr_2o:
2995 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED));
2996 case scm_tc7_subr_1:
2997 case scm_tc7_subr_1o:
2998 RETURN (SCM_SUBRF (proc) (arg1));
14b18ed6
DH
2999 case scm_tc7_dsubr:
3000 if (SCM_INUMP (arg1))
3001 {
3002 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
3003 }
3004 else if (SCM_REALP (arg1))
3005 {
3006 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
3007 }
3008 else if (SCM_BIGP (arg1))
3009 {
3010 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_i_big2dbl (arg1))));
3011 }
3012 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
3013 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
42030fb2 3014 case scm_tc7_cxr:
42030fb2 3015 {
14b18ed6
DH
3016 unsigned char pattern = (scm_t_bits) SCM_SUBRF (proc);
3017 do
3018 {
3019 SCM_ASSERT (SCM_CONSP (arg1), arg1, SCM_ARG1,
3020 SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
3021 arg1 = (pattern & 1) ? SCM_CAR (arg1) : SCM_CDR (arg1);
3022 pattern >>= 2;
3023 } while (pattern);
42030fb2 3024 RETURN (arg1);
0f2d19dd 3025 }
42030fb2
DH
3026 case scm_tc7_rpsubr:
3027 RETURN (SCM_BOOL_T);
3028 case scm_tc7_asubr:
3029 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED));
3030 case scm_tc7_lsubr:
0f2d19dd 3031#ifdef DEVAL
42030fb2 3032 RETURN (SCM_SUBRF (proc) (debug.info->a.args));
0f2d19dd 3033#else
42030fb2 3034 RETURN (SCM_SUBRF (proc) (scm_list_1 (arg1)));
0f2d19dd 3035#endif
42030fb2
DH
3036 case scm_tc7_smob:
3037 if (!SCM_SMOB_APPLICABLE_P (proc))
3038 goto badfun;
3039 RETURN (SCM_SMOB_APPLY_1 (proc, arg1));
3040 case scm_tc7_cclo:
3041 arg2 = arg1;
3042 arg1 = proc;
3043 proc = SCM_CCLO_SUBR (proc);
6dbd0af5 3044#ifdef DEVAL
42030fb2
DH
3045 debug.info->a.args = scm_cons (arg1, debug.info->a.args);
3046 debug.info->a.proc = proc;
6dbd0af5 3047#endif
42030fb2
DH
3048 goto evap2;
3049 case scm_tc7_pws:
3050 proc = SCM_PROCEDURE (proc);
89efbff4 3051#ifdef DEVAL
42030fb2 3052 debug.info->a.proc = proc;
89efbff4 3053#endif
42030fb2
DH
3054 if (!SCM_CLOSUREP (proc))
3055 goto evap1;
ddd8f927 3056 /* fallthrough */
42030fb2 3057 case scm_tcs_closures:
ddd8f927
DH
3058 {
3059 /* clos1: */
3060 const SCM formals = SCM_CLOSURE_FORMALS (proc);
3061 if (SCM_NULLP (formals)
3062 || (SCM_CONSP (formals) && SCM_CONSP (SCM_CDR (formals))))
3063 goto umwrongnumargs;
3064 x = SCM_CLOSURE_BODY (proc);
0f2d19dd 3065#ifdef DEVAL
ddd8f927
DH
3066 env = SCM_EXTEND_ENV (formals,
3067 debug.info->a.args,
3068 SCM_ENV (proc));
0f2d19dd 3069#else
ddd8f927
DH
3070 env = SCM_EXTEND_ENV (formals,
3071 scm_list_1 (arg1),
3072 SCM_ENV (proc));
0f2d19dd 3073#endif
ddd8f927
DH
3074 goto nontoplevel_begin;
3075 }
42030fb2
DH
3076 case scm_tcs_struct:
3077 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3078 {
3079 x = SCM_ENTITY_PROCEDURE (proc);
f3d2630a 3080#ifdef DEVAL
42030fb2 3081 arg1 = debug.info->a.args;
f3d2630a 3082#else
42030fb2 3083 arg1 = scm_list_1 (arg1);
f3d2630a 3084#endif
42030fb2
DH
3085 goto type_dispatch;
3086 }
2ca0d207 3087 else if (SCM_I_OPERATORP (proc))
42030fb2
DH
3088 {
3089 arg2 = arg1;
3090 arg1 = proc;
3091 proc = (SCM_I_ENTITYP (proc)
3092 ? SCM_ENTITY_PROCEDURE (proc)
3093 : SCM_OPERATOR_PROCEDURE (proc));
0c32d76c 3094#ifdef DEVAL
42030fb2
DH
3095 debug.info->a.args = scm_cons (arg1, debug.info->a.args);
3096 debug.info->a.proc = proc;
0c32d76c 3097#endif
ddd8f927 3098 goto evap2;
42030fb2 3099 }
2ca0d207
DH
3100 else
3101 goto badfun;
42030fb2
DH
3102 case scm_tc7_subr_2:
3103 case scm_tc7_subr_0:
3104 case scm_tc7_subr_3:
3105 case scm_tc7_lsubr_2:
ab1f1094 3106 scm_wrong_num_args (proc);
42030fb2
DH
3107 default:
3108 goto badfun;
3109 }
3110 }
42030fb2
DH
3111 if (SCM_CONSP (x))
3112 arg2 = EVALCAR (x, env);
3113 else
ab1f1094 3114 scm_wrong_num_args (proc);
bd987b8e 3115
42030fb2 3116 { /* have two or more arguments */
6dbd0af5 3117#ifdef DEVAL
42030fb2 3118 debug.info->a.args = scm_list_2 (arg1, arg2);
6dbd0af5 3119#endif
42030fb2
DH
3120 x = SCM_CDR (x);
3121 if (SCM_NULLP (x)) {
3122 ENTER_APPLY;
3123 evap2:
ddd8f927 3124 SCM_ASRTGO (!SCM_IMP (proc), badfun);
42030fb2
DH
3125 switch (SCM_TYP7 (proc))
3126 { /* have two arguments */
3127 case scm_tc7_subr_2:
3128 case scm_tc7_subr_2o:
3129 RETURN (SCM_SUBRF (proc) (arg1, arg2));
3130 case scm_tc7_lsubr:
0f2d19dd 3131#ifdef DEVAL
42030fb2 3132 RETURN (SCM_SUBRF (proc) (debug.info->a.args));
6dbd0af5 3133#else
42030fb2
DH
3134 RETURN (SCM_SUBRF (proc) (scm_list_2 (arg1, arg2)));
3135#endif
3136 case scm_tc7_lsubr_2:
3137 RETURN (SCM_SUBRF (proc) (arg1, arg2, SCM_EOL));
3138 case scm_tc7_rpsubr:
3139 case scm_tc7_asubr:
3140 RETURN (SCM_SUBRF (proc) (arg1, arg2));
3141 case scm_tc7_smob:
3142 if (!SCM_SMOB_APPLICABLE_P (proc))
3143 goto badfun;
3144 RETURN (SCM_SMOB_APPLY_2 (proc, arg1, arg2));
3145 cclon:
3146 case scm_tc7_cclo:
0f2d19dd 3147#ifdef DEVAL
42030fb2
DH
3148 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
3149 scm_cons (proc, debug.info->a.args),
3150 SCM_EOL));
0f2d19dd 3151#else
42030fb2
DH
3152 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
3153 scm_cons2 (proc, arg1,
3154 scm_cons (arg2,
3155 scm_eval_args (x,
3156 env,
3157 proc))),
3158 SCM_EOL));
3159#endif
3160 case scm_tcs_struct:
3161 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3162 {
3163 x = SCM_ENTITY_PROCEDURE (proc);
3164#ifdef DEVAL
3165 arg1 = debug.info->a.args;
3166#else
3167 arg1 = scm_list_2 (arg1, arg2);
6dbd0af5 3168#endif
42030fb2
DH
3169 goto type_dispatch;
3170 }
2ca0d207 3171 else if (SCM_I_OPERATORP (proc))
42030fb2
DH
3172 {
3173 operatorn:
f3d2630a 3174#ifdef DEVAL
42030fb2
DH
3175 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
3176 ? SCM_ENTITY_PROCEDURE (proc)
3177 : SCM_OPERATOR_PROCEDURE (proc),
3178 scm_cons (proc, debug.info->a.args),
3179 SCM_EOL));
f3d2630a 3180#else
42030fb2
DH
3181 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
3182 ? SCM_ENTITY_PROCEDURE (proc)
3183 : SCM_OPERATOR_PROCEDURE (proc),
3184 scm_cons2 (proc, arg1,
3185 scm_cons (arg2,
3186 scm_eval_args (x,
3187 env,
3188 proc))),
3189 SCM_EOL));
f3d2630a 3190#endif
42030fb2 3191 }
2ca0d207
DH
3192 else
3193 goto badfun;
42030fb2 3194 case scm_tc7_subr_0:
14b18ed6 3195 case scm_tc7_dsubr:
42030fb2
DH
3196 case scm_tc7_cxr:
3197 case scm_tc7_subr_1o:
3198 case scm_tc7_subr_1:
3199 case scm_tc7_subr_3:
ab1f1094 3200 scm_wrong_num_args (proc);
42030fb2 3201 default:
9b07e212 3202 goto badfun;
42030fb2
DH
3203 case scm_tc7_pws:
3204 proc = SCM_PROCEDURE (proc);
3205#ifdef DEVAL
3206 debug.info->a.proc = proc;
3207#endif
3208 if (!SCM_CLOSUREP (proc))
3209 goto evap2;
ddd8f927 3210 /* fallthrough */
42030fb2 3211 case scm_tcs_closures:
ddd8f927
DH
3212 {
3213 /* clos2: */
3214 const SCM formals = SCM_CLOSURE_FORMALS (proc);
3215 if (SCM_NULLP (formals)
3216 || (SCM_CONSP (formals)
3217 && (SCM_NULLP (SCM_CDR (formals))
3218 || (SCM_CONSP (SCM_CDR (formals))
3219 && SCM_CONSP (SCM_CDDR (formals))))))
3220 goto umwrongnumargs;
0c32d76c 3221#ifdef DEVAL
ddd8f927
DH
3222 env = SCM_EXTEND_ENV (formals,
3223 debug.info->a.args,
3224 SCM_ENV (proc));
195847fa 3225#else
ddd8f927
DH
3226 env = SCM_EXTEND_ENV (formals,
3227 scm_list_2 (arg1, arg2),
3228 SCM_ENV (proc));
195847fa 3229#endif
ddd8f927
DH
3230 x = SCM_CLOSURE_BODY (proc);
3231 goto nontoplevel_begin;
3232 }
42030fb2
DH
3233 }
3234 }
42030fb2 3235 if (!SCM_CONSP (x))
ab1f1094 3236 scm_wrong_num_args (proc);
42030fb2
DH
3237#ifdef DEVAL
3238 debug.info->a.args = scm_cons2 (arg1, arg2,
3239 deval_args (x, env, proc,
3240 SCM_CDRLOC (SCM_CDR (debug.info->a.args))));
3241#endif
3242 ENTER_APPLY;
3243 evap3:
ddd8f927 3244 SCM_ASRTGO (!SCM_IMP (proc), badfun);
42030fb2
DH
3245 switch (SCM_TYP7 (proc))
3246 { /* have 3 or more arguments */
3247#ifdef DEVAL
6dbd0af5 3248 case scm_tc7_subr_3:
ab1f1094
DH
3249 if (!SCM_NULLP (SCM_CDR (x)))
3250 scm_wrong_num_args (proc);
3251 else
3252 RETURN (SCM_SUBRF (proc) (arg1, arg2,
3253 SCM_CADDR (debug.info->a.args)));
42030fb2
DH
3254 case scm_tc7_asubr:
3255 arg1 = SCM_SUBRF(proc)(arg1, arg2);
3256 arg2 = SCM_CDDR (debug.info->a.args);
3257 do
3258 {
3259 arg1 = SCM_SUBRF(proc)(arg1, SCM_CAR (arg2));
3260 arg2 = SCM_CDR (arg2);
3261 }
3262 while (SCM_NIMP (arg2));
3263 RETURN (arg1);
3264 case scm_tc7_rpsubr:
3265 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, arg2)))
3266 RETURN (SCM_BOOL_F);
3267 arg1 = SCM_CDDR (debug.info->a.args);
3268 do
3269 {
3270 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, SCM_CAR (arg1))))
3271 RETURN (SCM_BOOL_F);
3272 arg2 = SCM_CAR (arg1);
3273 arg1 = SCM_CDR (arg1);
3274 }
3275 while (SCM_NIMP (arg1));
3276 RETURN (SCM_BOOL_T);
3277 case scm_tc7_lsubr_2:
3278 RETURN (SCM_SUBRF (proc) (arg1, arg2,
3279 SCM_CDDR (debug.info->a.args)));
3280 case scm_tc7_lsubr:
3281 RETURN (SCM_SUBRF (proc) (debug.info->a.args));
3282 case scm_tc7_smob:
3283 if (!SCM_SMOB_APPLICABLE_P (proc))
3284 goto badfun;
3285 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, arg2,
3286 SCM_CDDR (debug.info->a.args)));
3287 case scm_tc7_cclo:
3288 goto cclon;
002f1a5d
MD
3289 case scm_tc7_pws:
3290 proc = SCM_PROCEDURE (proc);
002f1a5d 3291 debug.info->a.proc = proc;
002f1a5d 3292 if (!SCM_CLOSUREP (proc))
42030fb2 3293 goto evap3;
ddd8f927 3294 /* fallthrough */
6dbd0af5 3295 case scm_tcs_closures:
ddd8f927
DH
3296 {
3297 const SCM formals = SCM_CLOSURE_FORMALS (proc);
3298 if (SCM_NULLP (formals)
3299 || (SCM_CONSP (formals)
3300 && (SCM_NULLP (SCM_CDR (formals))
3301 || (SCM_CONSP (SCM_CDR (formals))
3302 && scm_badargsp (SCM_CDDR (formals), x)))))
3303 goto umwrongnumargs;
3304 SCM_SET_ARGSREADY (debug);
3305 env = SCM_EXTEND_ENV (formals,
3306 debug.info->a.args,
3307 SCM_ENV (proc));
3308 x = SCM_CLOSURE_BODY (proc);
3309 goto nontoplevel_begin;
3310 }
6dbd0af5 3311#else /* DEVAL */
42030fb2 3312 case scm_tc7_subr_3:
ab1f1094
DH
3313 if (!SCM_NULLP (SCM_CDR (x)))
3314 scm_wrong_num_args (proc);
3315 else
3316 RETURN (SCM_SUBRF (proc) (arg1, arg2, EVALCAR (x, env)));
42030fb2
DH
3317 case scm_tc7_asubr:
3318 arg1 = SCM_SUBRF (proc) (arg1, arg2);
3319 do
3320 {
3321 arg1 = SCM_SUBRF(proc)(arg1, EVALCAR(x, env));
3322 x = SCM_CDR(x);
3323 }
3324 while (SCM_NIMP (x));
3325 RETURN (arg1);
3326 case scm_tc7_rpsubr:
3327 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, arg2)))
3328 RETURN (SCM_BOOL_F);
3329 do
3330 {
3331 arg1 = EVALCAR (x, env);
3332 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, arg1)))
3333 RETURN (SCM_BOOL_F);
3334 arg2 = arg1;
3335 x = SCM_CDR (x);
3336 }
3337 while (SCM_NIMP (x));
3338 RETURN (SCM_BOOL_T);
3339 case scm_tc7_lsubr_2:
3340 RETURN (SCM_SUBRF (proc) (arg1, arg2, scm_eval_args (x, env, proc)));
3341 case scm_tc7_lsubr:
3342 RETURN (SCM_SUBRF (proc) (scm_cons2 (arg1,
3343 arg2,
3344 scm_eval_args (x, env, proc))));
3345 case scm_tc7_smob:
3346 if (!SCM_SMOB_APPLICABLE_P (proc))
3347 goto badfun;
3348 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, arg2,
3349 scm_eval_args (x, env, proc)));
3350 case scm_tc7_cclo:
3351 goto cclon;
3352 case scm_tc7_pws:
3353 proc = SCM_PROCEDURE (proc);
3354 if (!SCM_CLOSUREP (proc))
3355 goto evap3;
ddd8f927
DH
3356 /* fallthrough */
3357 case scm_tcs_closures:
da7f71d7 3358 {
ddd8f927 3359 const SCM formals = SCM_CLOSURE_FORMALS (proc);
42030fb2
DH
3360 if (SCM_NULLP (formals)
3361 || (SCM_CONSP (formals)
3362 && (SCM_NULLP (SCM_CDR (formals))
3363 || (SCM_CONSP (SCM_CDR (formals))
3364 && scm_badargsp (SCM_CDDR (formals), x)))))
3365 goto umwrongnumargs;
ddd8f927
DH
3366 env = SCM_EXTEND_ENV (formals,
3367 scm_cons2 (arg1,
3368 arg2,
3369 scm_eval_args (x, env, proc)),
3370 SCM_ENV (proc));
3371 x = SCM_CLOSURE_BODY (proc);
3372 goto nontoplevel_begin;
da7f71d7 3373 }
0f2d19dd 3374#endif /* DEVAL */
42030fb2
DH
3375 case scm_tcs_struct:
3376 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3377 {
f3d2630a 3378#ifdef DEVAL
42030fb2 3379 arg1 = debug.info->a.args;
f3d2630a 3380#else
42030fb2 3381 arg1 = scm_cons2 (arg1, arg2, scm_eval_args (x, env, proc));
f3d2630a 3382#endif
42030fb2
DH
3383 x = SCM_ENTITY_PROCEDURE (proc);
3384 goto type_dispatch;
3385 }
2ca0d207 3386 else if (SCM_I_OPERATORP (proc))
42030fb2 3387 goto operatorn;
2ca0d207
DH
3388 else
3389 goto badfun;
42030fb2
DH
3390 case scm_tc7_subr_2:
3391 case scm_tc7_subr_1o:
3392 case scm_tc7_subr_2o:
3393 case scm_tc7_subr_0:
14b18ed6 3394 case scm_tc7_dsubr:
42030fb2
DH
3395 case scm_tc7_cxr:
3396 case scm_tc7_subr_1:
ab1f1094 3397 scm_wrong_num_args (proc);
42030fb2 3398 default:
9b07e212 3399 goto badfun;
42030fb2
DH
3400 }
3401 }
0f2d19dd
JB
3402 }
3403#ifdef DEVAL
6dbd0af5 3404exit:
5132eef0 3405 if (scm_check_exit_p && SCM_TRAPS_P)
b7ff98dd 3406 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 3407 {
b7ff98dd
MD
3408 SCM_CLEAR_TRACED_FRAME (debug);
3409 if (SCM_CHEAPTRAPS_P)
dff98306 3410 arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
3411 else
3412 {
5f144b10
GH
3413 int first;
3414 SCM val = scm_make_continuation (&first);
e050d4f8 3415
5f144b10 3416 if (first)
dff98306 3417 arg1 = val;
5f144b10 3418 else
6dbd0af5 3419 {
5f144b10 3420 proc = val;
6dbd0af5
MD
3421 goto ret;
3422 }
3423 }
d95c0b76 3424 SCM_TRAPS_P = 0;
dff98306 3425 scm_call_3 (SCM_EXIT_FRAME_HDLR, scm_sym_exit_frame, arg1, proc);
d95c0b76 3426 SCM_TRAPS_P = 1;
6dbd0af5
MD
3427 }
3428ret:
1646d37b 3429 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
3430 return proc;
3431#endif
3432}
3433
6dbd0af5
MD
3434
3435/* SECTION: This code is compiled once.
3436 */
3437
0f2d19dd
JB
3438#ifndef DEVAL
3439
fdc28395 3440\f
d0b07b5d 3441
fdc28395
KN
3442/* Simple procedure calls
3443 */
3444
3445SCM
3446scm_call_0 (SCM proc)
3447{
3448 return scm_apply (proc, SCM_EOL, SCM_EOL);
3449}
3450
3451SCM
3452scm_call_1 (SCM proc, SCM arg1)
3453{
3454 return scm_apply (proc, arg1, scm_listofnull);
3455}
3456
3457SCM
3458scm_call_2 (SCM proc, SCM arg1, SCM arg2)
3459{
3460 return scm_apply (proc, arg1, scm_cons (arg2, scm_listofnull));
3461}
3462
3463SCM
3464scm_call_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)
3465{
3466 return scm_apply (proc, arg1, scm_cons2 (arg2, arg3, scm_listofnull));
3467}
3468
d95c0b76
NJ
3469SCM
3470scm_call_4 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4)
3471{
3472 return scm_apply (proc, arg1, scm_cons2 (arg2, arg3,
3473 scm_cons (arg4, scm_listofnull)));
3474}
3475
fdc28395
KN
3476/* Simple procedure applies
3477 */
3478
3479SCM
3480scm_apply_0 (SCM proc, SCM args)
3481{
3482 return scm_apply (proc, args, SCM_EOL);
3483}
3484
3485SCM
3486scm_apply_1 (SCM proc, SCM arg1, SCM args)
3487{
3488 return scm_apply (proc, scm_cons (arg1, args), SCM_EOL);
3489}
3490
3491SCM
3492scm_apply_2 (SCM proc, SCM arg1, SCM arg2, SCM args)
3493{
3494 return scm_apply (proc, scm_cons2 (arg1, arg2, args), SCM_EOL);
3495}
3496
3497SCM
3498scm_apply_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM args)
3499{
3500 return scm_apply (proc, scm_cons (arg1, scm_cons2 (arg2, arg3, args)),
3501 SCM_EOL);
3502}
3503
82a2622a 3504/* This code processes the arguments to apply:
b145c172
JB
3505
3506 (apply PROC ARG1 ... ARGS)
3507
82a2622a
JB
3508 Given a list (ARG1 ... ARGS), this function conses the ARG1
3509 ... arguments onto the front of ARGS, and returns the resulting
3510 list. Note that ARGS is a list; thus, the argument to this
3511 function is a list whose last element is a list.
3512
3513 Apply calls this function, and applies PROC to the elements of the
b145c172
JB
3514 result. apply:nconc2last takes care of building the list of
3515 arguments, given (ARG1 ... ARGS).
3516
82a2622a
JB
3517 Rather than do new consing, apply:nconc2last destroys its argument.
3518 On that topic, this code came into my care with the following
3519 beautifully cryptic comment on that topic: "This will only screw
3520 you if you do (scm_apply scm_apply '( ... ))" If you know what
3521 they're referring to, send me a patch to this comment. */
b145c172 3522
3b3b36dd 3523SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
b3f26b14
MG
3524 (SCM lst),
3525 "Given a list (@var{arg1} @dots{} @var{args}), this function\n"
3526 "conses the @var{arg1} @dots{} arguments onto the front of\n"
3527 "@var{args}, and returns the resulting list. Note that\n"
3528 "@var{args} is a list; thus, the argument to this function is\n"
3529 "a list whose last element is a list.\n"
3530 "Note: Rather than do new consing, @code{apply:nconc2last}\n"
3531 "destroys its argument, so use with care.")
1bbd0b84 3532#define FUNC_NAME s_scm_nconc2last
0f2d19dd
JB
3533{
3534 SCM *lloc;
34d19ef6 3535 SCM_VALIDATE_NONEMPTYLIST (1, lst);
0f2d19dd 3536 lloc = &lst;
c96d76b8
NJ
3537 while (!SCM_NULLP (SCM_CDR (*lloc))) /* Perhaps should be
3538 SCM_NULL_OR_NIL_P, but not
3539 needed in 99.99% of cases,
3540 and it could seriously hurt
3541 performance. - Neil */
a23afe53 3542 lloc = SCM_CDRLOC (*lloc);
1bbd0b84 3543 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
0f2d19dd
JB
3544 *lloc = SCM_CAR (*lloc);
3545 return lst;
3546}
1bbd0b84 3547#undef FUNC_NAME
0f2d19dd
JB
3548
3549#endif /* !DEVAL */
3550
6dbd0af5
MD
3551
3552/* SECTION: When DEVAL is defined this code yields scm_dapply.
3553 * It is compiled twice.
3554 */
3555
0f2d19dd 3556#if 0
0f2d19dd 3557SCM
6e8d25a6 3558scm_apply (SCM proc, SCM arg1, SCM args)
0f2d19dd
JB
3559{}
3560#endif
3561
3562#if 0
0f2d19dd 3563SCM
6e8d25a6 3564scm_dapply (SCM proc, SCM arg1, SCM args)
d0b07b5d 3565{}
0f2d19dd
JB
3566#endif
3567
1cc91f1b 3568
82a2622a
JB
3569/* Apply a function to a list of arguments.
3570
3571 This function is exported to the Scheme level as taking two
3572 required arguments and a tail argument, as if it were:
3573 (lambda (proc arg1 . args) ...)
3574 Thus, if you just have a list of arguments to pass to a procedure,
3575 pass the list as ARG1, and '() for ARGS. If you have some fixed
3576 args, pass the first as ARG1, then cons any remaining fixed args
3577 onto the front of your argument list, and pass that as ARGS. */
3578
0f2d19dd 3579SCM
1bbd0b84 3580SCM_APPLY (SCM proc, SCM arg1, SCM args)
0f2d19dd 3581{
0f2d19dd 3582#ifdef DEVAL
92c2555f
MV
3583 scm_t_debug_frame debug;
3584 scm_t_debug_info debug_vect_body;
1646d37b 3585 debug.prev = scm_last_debug_frame;
b7ff98dd 3586 debug.status = SCM_APPLYFRAME;
c0ab1b8d 3587 debug.vect = &debug_vect_body;
6dbd0af5
MD
3588 debug.vect[0].a.proc = proc;
3589 debug.vect[0].a.args = SCM_EOL;
1646d37b 3590 scm_last_debug_frame = &debug;
0f2d19dd 3591#else
b7ff98dd 3592 if (SCM_DEBUGGINGP)
0f2d19dd 3593 return scm_dapply (proc, arg1, args);
0f2d19dd
JB
3594#endif
3595
3596 SCM_ASRTGO (SCM_NIMP (proc), badproc);
82a2622a
JB
3597
3598 /* If ARGS is the empty list, then we're calling apply with only two
3599 arguments --- ARG1 is the list of arguments for PROC. Whatever
3600 the case, futz with things so that ARG1 is the first argument to
3601 give to PROC (or SCM_UNDEFINED if no args), and ARGS contains the
30000774
JB
3602 rest.
3603
3604 Setting the debug apply frame args this way is pretty messy.
3605 Perhaps we should store arg1 and args directly in the frame as
3606 received, and let scm_frame_arguments unpack them, because that's
3607 a relatively rare operation. This works for now; if the Guile
3608 developer archives are still around, see Mikael's post of
3609 11-Apr-97. */
0f2d19dd
JB
3610 if (SCM_NULLP (args))
3611 {
3612 if (SCM_NULLP (arg1))
30000774
JB
3613 {
3614 arg1 = SCM_UNDEFINED;
3615#ifdef DEVAL
3616 debug.vect[0].a.args = SCM_EOL;
3617#endif
3618 }
0f2d19dd
JB
3619 else
3620 {
30000774
JB
3621#ifdef DEVAL
3622 debug.vect[0].a.args = arg1;
3623#endif
0f2d19dd
JB
3624 args = SCM_CDR (arg1);
3625 arg1 = SCM_CAR (arg1);
3626 }
3627 }
3628 else
3629 {
0f2d19dd 3630 args = scm_nconc2last (args);
30000774
JB
3631#ifdef DEVAL
3632 debug.vect[0].a.args = scm_cons (arg1, args);
3633#endif
0f2d19dd 3634 }
0f2d19dd 3635#ifdef DEVAL
b6d75948 3636 if (SCM_ENTER_FRAME_P && SCM_TRAPS_P)
6dbd0af5
MD
3637 {
3638 SCM tmp;
b7ff98dd 3639 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 3640 tmp = scm_make_debugobj (&debug);
6dbd0af5
MD
3641 else
3642 {
5f144b10
GH
3643 int first;
3644
3645 tmp = scm_make_continuation (&first);
3646 if (!first)
6dbd0af5
MD
3647 goto entap;
3648 }
d95c0b76
NJ
3649 SCM_TRAPS_P = 0;
3650 scm_call_2 (SCM_ENTER_FRAME_HDLR, scm_sym_enter_frame, tmp);
3651 SCM_TRAPS_P = 1;
6dbd0af5
MD
3652 }
3653entap:
3654 ENTER_APPLY;
3655#endif
6dbd0af5 3656tail:
0f2d19dd
JB
3657 switch (SCM_TYP7 (proc))
3658 {
3659 case scm_tc7_subr_2o:
3660 args = SCM_NULLP (args) ? SCM_UNDEFINED : SCM_CAR (args);
ddea3325 3661 RETURN (SCM_SUBRF (proc) (arg1, args));
0f2d19dd 3662 case scm_tc7_subr_2:
ab1f1094
DH
3663 if (SCM_NULLP (args) || !SCM_NULLP (SCM_CDR (args)))
3664 scm_wrong_num_args (proc);
0f2d19dd 3665 args = SCM_CAR (args);
ddea3325 3666 RETURN (SCM_SUBRF (proc) (arg1, args));
0f2d19dd 3667 case scm_tc7_subr_0:
ab1f1094
DH
3668 if (!SCM_UNBNDP (arg1))
3669 scm_wrong_num_args (proc);
3670 else
3671 RETURN (SCM_SUBRF (proc) ());
0f2d19dd 3672 case scm_tc7_subr_1:
ab1f1094
DH
3673 if (SCM_UNBNDP (arg1))
3674 scm_wrong_num_args (proc);
0f2d19dd 3675 case scm_tc7_subr_1o:
ab1f1094
DH
3676 if (!SCM_NULLP (args))
3677 scm_wrong_num_args (proc);
3678 else
3679 RETURN (SCM_SUBRF (proc) (arg1));
14b18ed6
DH
3680 case scm_tc7_dsubr:
3681 if (SCM_UNBNDP (arg1) || !SCM_NULLP (args))
3682 scm_wrong_num_args (proc);
3683 if (SCM_INUMP (arg1))
3684 {
3685 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
3686 }
3687 else if (SCM_REALP (arg1))
3688 {
3689 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
3690 }
3691 else if (SCM_BIGP (arg1))
3692 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_i_big2dbl (arg1))));
3693 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
3694 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
0f2d19dd 3695 case scm_tc7_cxr:
ab1f1094
DH
3696 if (SCM_UNBNDP (arg1) || !SCM_NULLP (args))
3697 scm_wrong_num_args (proc);
0f2d19dd 3698 {
14b18ed6
DH
3699 unsigned char pattern = (scm_t_bits) SCM_SUBRF (proc);
3700 do
3701 {
3702 SCM_ASSERT (SCM_CONSP (arg1), arg1, SCM_ARG1,
3703 SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
3704 arg1 = (pattern & 1) ? SCM_CAR (arg1) : SCM_CDR (arg1);
3705 pattern >>= 2;
3706 } while (pattern);
3707 RETURN (arg1);
0f2d19dd
JB
3708 }
3709 case scm_tc7_subr_3:
ab1f1094
DH
3710 if (SCM_NULLP (args)
3711 || SCM_NULLP (SCM_CDR (args))
3712 || !SCM_NULLP (SCM_CDDR (args)))
3713 scm_wrong_num_args (proc);
3714 else
3715 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CADR (args)));
0f2d19dd
JB
3716 case scm_tc7_lsubr:
3717#ifdef DEVAL
ddea3325 3718 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args));
0f2d19dd 3719#else
ddea3325 3720 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args)));
0f2d19dd
JB
3721#endif
3722 case scm_tc7_lsubr_2:
ab1f1094
DH
3723 if (!SCM_CONSP (args))
3724 scm_wrong_num_args (proc);
3725 else
3726 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CDR (args)));
0f2d19dd
JB
3727 case scm_tc7_asubr:
3728 if (SCM_NULLP (args))
ddea3325 3729 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED));
0f2d19dd
JB
3730 while (SCM_NIMP (args))
3731 {
3732 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3733 arg1 = SCM_SUBRF (proc) (arg1, SCM_CAR (args));
3734 args = SCM_CDR (args);
3735 }
3736 RETURN (arg1);
3737 case scm_tc7_rpsubr:
3738 if (SCM_NULLP (args))
3739 RETURN (SCM_BOOL_T);
3740 while (SCM_NIMP (args))
3741 {
3742 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3743 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, SCM_CAR (args))))
3744 RETURN (SCM_BOOL_F);
3745 arg1 = SCM_CAR (args);
3746 args = SCM_CDR (args);
3747 }
3748 RETURN (SCM_BOOL_T);
3749 case scm_tcs_closures:
3750#ifdef DEVAL
6dbd0af5 3751 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args);
0f2d19dd
JB
3752#else
3753 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args));
3754#endif
726d810a 3755 if (scm_badargsp (SCM_CLOSURE_FORMALS (proc), arg1))
ab1f1094 3756 scm_wrong_num_args (proc);
1609038c
MD
3757
3758 /* Copy argument list */
3759 if (SCM_IMP (arg1))
3760 args = arg1;
3761 else
3762 {
3763 SCM tl = args = scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED);
05b15362 3764 for (arg1 = SCM_CDR (arg1); SCM_CONSP (arg1); arg1 = SCM_CDR (arg1))
1609038c 3765 {
05b15362 3766 SCM_SETCDR (tl, scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED));
1609038c
MD
3767 tl = SCM_CDR (tl);
3768 }
3769 SCM_SETCDR (tl, arg1);
3770 }
3771
821f18a4
DH
3772 args = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3773 args,
3774 SCM_ENV (proc));
f9450cdb 3775 proc = SCM_CLOSURE_BODY (proc);
e791c18f 3776 again:
05b15362
DH
3777 arg1 = SCM_CDR (proc);
3778 while (!SCM_NULLP (arg1))
2ddb0920
MD
3779 {
3780 if (SCM_IMP (SCM_CAR (proc)))
3781 {
3782 if (SCM_ISYMP (SCM_CAR (proc)))
3783 {
28d52ebb 3784 scm_rec_mutex_lock (&source_mutex);
9bc4701c
MD
3785 /* check for race condition */
3786 if (SCM_ISYMP (SCM_CAR (proc)))
3787 proc = scm_m_expand_body (proc, args);
28d52ebb 3788 scm_rec_mutex_unlock (&source_mutex);
e791c18f 3789 goto again;
2ddb0920 3790 }
5280aaca 3791 else
17fa3fcf 3792 SCM_VALIDATE_NON_EMPTY_COMBINATION (SCM_CAR (proc));
2ddb0920
MD
3793 }
3794 else
e791c18f
MD
3795 SCM_CEVAL (SCM_CAR (proc), args);
3796 proc = arg1;
05b15362 3797 arg1 = SCM_CDR (proc);
2ddb0920 3798 }
e791c18f 3799 RETURN (EVALCAR (proc, args));
0717dfd8 3800 case scm_tc7_smob:
68b06924 3801 if (!SCM_SMOB_APPLICABLE_P (proc))
0717dfd8 3802 goto badproc;
afa38f6e 3803 if (SCM_UNBNDP (arg1))
ddea3325 3804 RETURN (SCM_SMOB_APPLY_0 (proc));
afa38f6e 3805 else if (SCM_NULLP (args))
ddea3325 3806 RETURN (SCM_SMOB_APPLY_1 (proc, arg1));
0717dfd8 3807 else if (SCM_NULLP (SCM_CDR (args)))
ddea3325 3808 RETURN (SCM_SMOB_APPLY_2 (proc, arg1, SCM_CAR (args)));
0717dfd8 3809 else
68b06924 3810 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, SCM_CAR (args), SCM_CDR (args)));
0f2d19dd
JB
3811 case scm_tc7_cclo:
3812#ifdef DEVAL
6dbd0af5
MD
3813 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3814 arg1 = proc;
3815 proc = SCM_CCLO_SUBR (proc);
3816 debug.vect[0].a.proc = proc;
3817 debug.vect[0].a.args = scm_cons (arg1, args);
0f2d19dd
JB
3818#else
3819 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
0f2d19dd
JB
3820 arg1 = proc;
3821 proc = SCM_CCLO_SUBR (proc);
6dbd0af5 3822#endif
0f2d19dd 3823 goto tail;
89efbff4
MD
3824 case scm_tc7_pws:
3825 proc = SCM_PROCEDURE (proc);
3826#ifdef DEVAL
3827 debug.vect[0].a.proc = proc;
3828#endif
3829 goto tail;
904a077d 3830 case scm_tcs_struct:
f3d2630a
MD
3831 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3832 {
3833#ifdef DEVAL
3834 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3835#else
3836 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3837#endif
195847fa 3838 RETURN (scm_apply_generic (proc, args));
f3d2630a 3839 }
2ca0d207 3840 else if (SCM_I_OPERATORP (proc))
da7f71d7 3841 {
504d99c5 3842 /* operator */
da7f71d7
MD
3843#ifdef DEVAL
3844 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3845#else
3846 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3847#endif
3848 arg1 = proc;
195847fa
MD
3849 proc = (SCM_I_ENTITYP (proc)
3850 ? SCM_ENTITY_PROCEDURE (proc)
3851 : SCM_OPERATOR_PROCEDURE (proc));
da7f71d7
MD
3852#ifdef DEVAL
3853 debug.vect[0].a.proc = proc;
3854 debug.vect[0].a.args = scm_cons (arg1, args);
3855#endif
195847fa
MD
3856 if (SCM_NIMP (proc))
3857 goto tail;
3858 else
3859 goto badproc;
da7f71d7 3860 }
2ca0d207
DH
3861 else
3862 goto badproc;
0f2d19dd
JB
3863 default:
3864 badproc:
db4b4ca6 3865 scm_wrong_type_arg ("apply", SCM_ARG1, proc);
0f2d19dd
JB
3866 }
3867#ifdef DEVAL
6dbd0af5 3868exit:
5132eef0 3869 if (scm_check_exit_p && SCM_TRAPS_P)
b7ff98dd 3870 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 3871 {
b7ff98dd
MD
3872 SCM_CLEAR_TRACED_FRAME (debug);
3873 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 3874 arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
3875 else
3876 {
5f144b10
GH
3877 int first;
3878 SCM val = scm_make_continuation (&first);
3879
3880 if (first)
3881 arg1 = val;
3882 else
6dbd0af5 3883 {
5f144b10 3884 proc = val;
6dbd0af5
MD
3885 goto ret;
3886 }
3887 }
d95c0b76
NJ
3888 SCM_TRAPS_P = 0;
3889 scm_call_3 (SCM_EXIT_FRAME_HDLR, scm_sym_exit_frame, arg1, proc);
3890 SCM_TRAPS_P = 1;
6dbd0af5
MD
3891 }
3892ret:
1646d37b 3893 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
3894 return proc;
3895#endif
3896}
3897
6dbd0af5
MD
3898
3899/* SECTION: The rest of this file is only read once.
3900 */
3901
0f2d19dd
JB
3902#ifndef DEVAL
3903
504d99c5
MD
3904/* Trampolines
3905 *
3906 * Trampolines make it possible to move procedure application dispatch
3907 * outside inner loops. The motivation was clean implementation of
3908 * efficient replacements of R5RS primitives in SRFI-1.
3909 *
3910 * The semantics is clear: scm_trampoline_N returns an optimized
3911 * version of scm_call_N (or NULL if the procedure isn't applicable
3912 * on N args).
3913 *
3914 * Applying the optimization to map and for-each increased efficiency
3915 * noticeably. For example, (map abs ls) is now 8 times faster than
3916 * before.
3917 */
3918
756414cf
MD
3919static SCM
3920call_subr0_0 (SCM proc)
3921{
3922 return SCM_SUBRF (proc) ();
3923}
3924
3925static SCM
3926call_subr1o_0 (SCM proc)
3927{
3928 return SCM_SUBRF (proc) (SCM_UNDEFINED);
3929}
3930
3931static SCM
3932call_lsubr_0 (SCM proc)
3933{
3934 return SCM_SUBRF (proc) (SCM_EOL);
3935}
3936
3937SCM
3938scm_i_call_closure_0 (SCM proc)
3939{
6a3f13f0
DH
3940 const SCM env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3941 SCM_EOL,
3942 SCM_ENV (proc));
3943 const SCM result = scm_eval_body (SCM_CLOSURE_BODY (proc), env);
d0b07b5d 3944 return result;
756414cf
MD
3945}
3946
3947scm_t_trampoline_0
3948scm_trampoline_0 (SCM proc)
3949{
3950 if (SCM_IMP (proc))
d0b07b5d 3951 return NULL;
756414cf
MD
3952 if (SCM_DEBUGGINGP)
3953 return scm_call_0;
3954 switch (SCM_TYP7 (proc))
3955 {
3956 case scm_tc7_subr_0:
3957 return call_subr0_0;
3958 case scm_tc7_subr_1o:
3959 return call_subr1o_0;
3960 case scm_tc7_lsubr:
3961 return call_lsubr_0;
3962 case scm_tcs_closures:
3963 {
3964 SCM formals = SCM_CLOSURE_FORMALS (proc);
4b612c5b 3965 if (SCM_NULLP (formals) || !SCM_CONSP (formals))
756414cf
MD
3966 return scm_i_call_closure_0;
3967 else
d0b07b5d 3968 return NULL;
756414cf
MD
3969 }
3970 case scm_tcs_struct:
3971 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3972 return scm_call_generic_0;
2ca0d207
DH
3973 else if (SCM_I_OPERATORP (proc))
3974 return scm_call_0;
3975 return NULL;
756414cf
MD
3976 case scm_tc7_smob:
3977 if (SCM_SMOB_APPLICABLE_P (proc))
3978 return SCM_SMOB_DESCRIPTOR (proc).apply_0;
3979 else
d0b07b5d 3980 return NULL;
756414cf
MD
3981 case scm_tc7_asubr:
3982 case scm_tc7_rpsubr:
3983 case scm_tc7_cclo:
3984 case scm_tc7_pws:
3985 return scm_call_0;
3986 default:
d0b07b5d 3987 return NULL; /* not applicable on one arg */
756414cf
MD
3988 }
3989}
3990
504d99c5
MD
3991static SCM
3992call_subr1_1 (SCM proc, SCM arg1)
3993{
3994 return SCM_SUBRF (proc) (arg1);
3995}
3996
9ed24633
MD
3997static SCM
3998call_subr2o_1 (SCM proc, SCM arg1)
3999{
4000 return SCM_SUBRF (proc) (arg1, SCM_UNDEFINED);
4001}
4002
504d99c5
MD
4003static SCM
4004call_lsubr_1 (SCM proc, SCM arg1)
4005{
4006 return SCM_SUBRF (proc) (scm_list_1 (arg1));
4007}
4008
4009static SCM
4010call_dsubr_1 (SCM proc, SCM arg1)
4011{
4012 if (SCM_INUMP (arg1))
4013 {
4014 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
4015 }
4016 else if (SCM_REALP (arg1))
4017 {
4018 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
4019 }
504d99c5
MD
4020 else if (SCM_BIGP (arg1))
4021 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_i_big2dbl (arg1))));
504d99c5
MD
4022 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
4023 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
4024}
4025
4026static SCM
4027call_cxr_1 (SCM proc, SCM arg1)
4028{
14b18ed6
DH
4029 unsigned char pattern = (scm_t_bits) SCM_SUBRF (proc);
4030 do
4031 {
4032 SCM_ASSERT (SCM_CONSP (arg1), arg1, SCM_ARG1,
4033 SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
4034 arg1 = (pattern & 1) ? SCM_CAR (arg1) : SCM_CDR (arg1);
4035 pattern >>= 2;
4036 } while (pattern);
4037 return arg1;
504d99c5
MD
4038}
4039
4040static SCM
4041call_closure_1 (SCM proc, SCM arg1)
4042{
6a3f13f0
DH
4043 const SCM env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
4044 scm_list_1 (arg1),
4045 SCM_ENV (proc));
4046 const SCM result = scm_eval_body (SCM_CLOSURE_BODY (proc), env);
d0b07b5d 4047 return result;
504d99c5
MD
4048}
4049
4050scm_t_trampoline_1
4051scm_trampoline_1 (SCM proc)
4052{
4053 if (SCM_IMP (proc))
d0b07b5d 4054 return NULL;
504d99c5
MD
4055 if (SCM_DEBUGGINGP)
4056 return scm_call_1;
4057 switch (SCM_TYP7 (proc))
4058 {
4059 case scm_tc7_subr_1:
4060 case scm_tc7_subr_1o:
4061 return call_subr1_1;
9ed24633
MD
4062 case scm_tc7_subr_2o:
4063 return call_subr2o_1;
504d99c5
MD
4064 case scm_tc7_lsubr:
4065 return call_lsubr_1;
14b18ed6
DH
4066 case scm_tc7_dsubr:
4067 return call_dsubr_1;
504d99c5 4068 case scm_tc7_cxr:
14b18ed6 4069 return call_cxr_1;
504d99c5
MD
4070 case scm_tcs_closures:
4071 {
4072 SCM formals = SCM_CLOSURE_FORMALS (proc);
4b612c5b
MD
4073 if (!SCM_NULLP (formals)
4074 && (!SCM_CONSP (formals) || !SCM_CONSP (SCM_CDR (formals))))
504d99c5
MD
4075 return call_closure_1;
4076 else
d0b07b5d 4077 return NULL;
504d99c5
MD
4078 }
4079 case scm_tcs_struct:
4080 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
4081 return scm_call_generic_1;
2ca0d207
DH
4082 else if (SCM_I_OPERATORP (proc))
4083 return scm_call_1;
4084 return NULL;
504d99c5
MD
4085 case scm_tc7_smob:
4086 if (SCM_SMOB_APPLICABLE_P (proc))
4087 return SCM_SMOB_DESCRIPTOR (proc).apply_1;
4088 else
d0b07b5d 4089 return NULL;
504d99c5
MD
4090 case scm_tc7_asubr:
4091 case scm_tc7_rpsubr:
4092 case scm_tc7_cclo:
4093 case scm_tc7_pws:
4094 return scm_call_1;
4095 default:
d0b07b5d 4096 return NULL; /* not applicable on one arg */
504d99c5
MD
4097 }
4098}
4099
4100static SCM
4101call_subr2_2 (SCM proc, SCM arg1, SCM arg2)
4102{
4103 return SCM_SUBRF (proc) (arg1, arg2);
4104}
4105
9ed24633
MD
4106static SCM
4107call_lsubr2_2 (SCM proc, SCM arg1, SCM arg2)
4108{
4109 return SCM_SUBRF (proc) (arg1, arg2, SCM_EOL);
4110}
4111
504d99c5
MD
4112static SCM
4113call_lsubr_2 (SCM proc, SCM arg1, SCM arg2)
4114{
4115 return SCM_SUBRF (proc) (scm_list_2 (arg1, arg2));
4116}
4117
4118static SCM
4119call_closure_2 (SCM proc, SCM arg1, SCM arg2)
4120{
6a3f13f0
DH
4121 const SCM env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
4122 scm_list_2 (arg1, arg2),
4123 SCM_ENV (proc));
4124 const SCM result = scm_eval_body (SCM_CLOSURE_BODY (proc), env);
d0b07b5d 4125 return result;
504d99c5
MD
4126}
4127
4128scm_t_trampoline_2
4129scm_trampoline_2 (SCM proc)
4130{
4131 if (SCM_IMP (proc))
d0b07b5d 4132 return NULL;
504d99c5
MD
4133 if (SCM_DEBUGGINGP)
4134 return scm_call_2;
4135 switch (SCM_TYP7 (proc))
4136 {
4137 case scm_tc7_subr_2:
4138 case scm_tc7_subr_2o:
4139 case scm_tc7_rpsubr:
4140 case scm_tc7_asubr:
4141 return call_subr2_2;
9ed24633
MD
4142 case scm_tc7_lsubr_2:
4143 return call_lsubr2_2;
504d99c5
MD
4144 case scm_tc7_lsubr:
4145 return call_lsubr_2;
4146 case scm_tcs_closures:
4147 {
4148 SCM formals = SCM_CLOSURE_FORMALS (proc);
4b612c5b
MD
4149 if (!SCM_NULLP (formals)
4150 && (!SCM_CONSP (formals)
4151 || (!SCM_NULLP (SCM_CDR (formals))
4152 && (!SCM_CONSP (SCM_CDR (formals))
4153 || !SCM_CONSP (SCM_CDDR (formals))))))
504d99c5
MD
4154 return call_closure_2;
4155 else
d0b07b5d 4156 return NULL;
504d99c5
MD
4157 }
4158 case scm_tcs_struct:
4159 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
4160 return scm_call_generic_2;
2ca0d207
DH
4161 else if (SCM_I_OPERATORP (proc))
4162 return scm_call_2;
4163 return NULL;
504d99c5
MD
4164 case scm_tc7_smob:
4165 if (SCM_SMOB_APPLICABLE_P (proc))
4166 return SCM_SMOB_DESCRIPTOR (proc).apply_2;
4167 else
d0b07b5d 4168 return NULL;
504d99c5
MD
4169 case scm_tc7_cclo:
4170 case scm_tc7_pws:
4171 return scm_call_2;
4172 default:
d0b07b5d 4173 return NULL; /* not applicable on two args */
504d99c5
MD
4174 }
4175}
4176
d9c393f5
JB
4177/* Typechecking for multi-argument MAP and FOR-EACH.
4178
47c3f06d 4179 Verify that each element of the vector ARGV, except for the first,
d9c393f5 4180 is a proper list whose length is LEN. Attribute errors to WHO,
47c3f06d 4181 and claim that the i'th element of ARGV is WHO's i+2'th argument. */
d9c393f5 4182static inline void
47c3f06d 4183check_map_args (SCM argv,
c014a02e 4184 long len,
47c3f06d
MD
4185 SCM gf,
4186 SCM proc,
4187 SCM args,
4188 const char *who)
d9c393f5 4189{
34d19ef6 4190 SCM const *ve = SCM_VELTS (argv);
c014a02e 4191 long i;
d9c393f5 4192
b5c2579a 4193 for (i = SCM_VECTOR_LENGTH (argv) - 1; i >= 1; i--)
d9c393f5 4194 {
c014a02e 4195 long elt_len = scm_ilength (ve[i]);
d9c393f5
JB
4196
4197 if (elt_len < 0)
47c3f06d
MD
4198 {
4199 if (gf)
4200 scm_apply_generic (gf, scm_cons (proc, args));
4201 else
4202 scm_wrong_type_arg (who, i + 2, ve[i]);
4203 }
d9c393f5
JB
4204
4205 if (elt_len != len)
504d99c5 4206 scm_out_of_range_pos (who, ve[i], SCM_MAKINUM (i + 2));
d9c393f5
JB
4207 }
4208
5d2b97cd 4209 scm_remember_upto_here_1 (argv);
d9c393f5
JB
4210}
4211
4212
47c3f06d 4213SCM_GPROC (s_map, "map", 2, 0, 1, scm_map, g_map);
1cc91f1b 4214
368bf056
MD
4215/* Note: Currently, scm_map applies PROC to the argument list(s)
4216 sequentially, starting with the first element(s). This is used in
8878f040 4217 evalext.c where the Scheme procedure `map-in-order', which guarantees
368bf056 4218 sequential behaviour, is implemented using scm_map. If the
8878f040 4219 behaviour changes, we need to update `map-in-order'.
368bf056
MD
4220*/
4221
0f2d19dd 4222SCM
1bbd0b84 4223scm_map (SCM proc, SCM arg1, SCM args)
af45e3b0 4224#define FUNC_NAME s_map
0f2d19dd 4225{
c014a02e 4226 long i, len;
0f2d19dd
JB
4227 SCM res = SCM_EOL;
4228 SCM *pres = &res;
34d19ef6 4229 SCM const *ve = &args; /* Keep args from being optimized away. */
0f2d19dd 4230
d9c393f5 4231 len = scm_ilength (arg1);
47c3f06d
MD
4232 SCM_GASSERTn (len >= 0,
4233 g_map, scm_cons2 (proc, arg1, args), SCM_ARG2, s_map);
af45e3b0 4234 SCM_VALIDATE_REST_ARGUMENT (args);
0f2d19dd
JB
4235 if (SCM_NULLP (args))
4236 {
504d99c5
MD
4237 scm_t_trampoline_1 call = scm_trampoline_1 (proc);
4238 SCM_GASSERT2 (call, g_map, proc, arg1, SCM_ARG1, s_map);
4239 while (SCM_NIMP (arg1))
4240 {
4241 *pres = scm_list_1 (call (proc, SCM_CAR (arg1)));
4242 pres = SCM_CDRLOC (*pres);
4243 arg1 = SCM_CDR (arg1);
4244 }
4245 return res;
4246 }
4247 if (SCM_NULLP (SCM_CDR (args)))
4248 {
4249 SCM arg2 = SCM_CAR (args);
4250 int len2 = scm_ilength (arg2);
4251 scm_t_trampoline_2 call = scm_trampoline_2 (proc);
4252 SCM_GASSERTn (call,
4253 g_map, scm_cons2 (proc, arg1, args), SCM_ARG1, s_map);
4254 SCM_GASSERTn (len2 >= 0,
4255 g_map, scm_cons2 (proc, arg1, args), SCM_ARG3, s_map);
4256 if (len2 != len)
4257 SCM_OUT_OF_RANGE (3, arg2);
0f2d19dd
JB
4258 while (SCM_NIMP (arg1))
4259 {
504d99c5 4260 *pres = scm_list_1 (call (proc, SCM_CAR (arg1), SCM_CAR (arg2)));
a23afe53 4261 pres = SCM_CDRLOC (*pres);
0f2d19dd 4262 arg1 = SCM_CDR (arg1);
504d99c5 4263 arg2 = SCM_CDR (arg2);
0f2d19dd
JB
4264 }
4265 return res;
4266 }
05b15362
DH
4267 arg1 = scm_cons (arg1, args);
4268 args = scm_vector (arg1);
0f2d19dd 4269 ve = SCM_VELTS (args);
47c3f06d 4270 check_map_args (args, len, g_map, proc, arg1, s_map);
0f2d19dd
JB
4271 while (1)
4272 {
4273 arg1 = SCM_EOL;
b5c2579a 4274 for (i = SCM_VECTOR_LENGTH (args) - 1; i >= 0; i--)
0f2d19dd 4275 {
d9c393f5
JB
4276 if (SCM_IMP (ve[i]))
4277 return res;
0f2d19dd 4278 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
34d19ef6 4279 SCM_VECTOR_SET (args, i, SCM_CDR (ve[i]));
0f2d19dd 4280 }
8ea46249 4281 *pres = scm_list_1 (scm_apply (proc, arg1, SCM_EOL));
a23afe53 4282 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
4283 }
4284}
af45e3b0 4285#undef FUNC_NAME
0f2d19dd
JB
4286
4287
47c3f06d 4288SCM_GPROC (s_for_each, "for-each", 2, 0, 1, scm_for_each, g_for_each);
1cc91f1b 4289
0f2d19dd 4290SCM
1bbd0b84 4291scm_for_each (SCM proc, SCM arg1, SCM args)
af45e3b0 4292#define FUNC_NAME s_for_each
0f2d19dd 4293{
34d19ef6 4294 SCM const *ve = &args; /* Keep args from being optimized away. */
c014a02e 4295 long i, len;
d9c393f5 4296 len = scm_ilength (arg1);
47c3f06d
MD
4297 SCM_GASSERTn (len >= 0, g_for_each, scm_cons2 (proc, arg1, args),
4298 SCM_ARG2, s_for_each);
af45e3b0 4299 SCM_VALIDATE_REST_ARGUMENT (args);
c96d76b8 4300 if (SCM_NULLP (args))
0f2d19dd 4301 {
504d99c5
MD
4302 scm_t_trampoline_1 call = scm_trampoline_1 (proc);
4303 SCM_GASSERT2 (call, g_for_each, proc, arg1, SCM_ARG1, s_for_each);
4304 while (SCM_NIMP (arg1))
4305 {
4306 call (proc, SCM_CAR (arg1));
4307 arg1 = SCM_CDR (arg1);
4308 }
4309 return SCM_UNSPECIFIED;
4310 }
4311 if (SCM_NULLP (SCM_CDR (args)))
4312 {
4313 SCM arg2 = SCM_CAR (args);
4314 int len2 = scm_ilength (arg2);
4315 scm_t_trampoline_2 call = scm_trampoline_2 (proc);
4316 SCM_GASSERTn (call, g_for_each,
4317 scm_cons2 (proc, arg1, args), SCM_ARG1, s_for_each);
4318 SCM_GASSERTn (len2 >= 0, g_for_each,
4319 scm_cons2 (proc, arg1, args), SCM_ARG3, s_for_each);
4320 if (len2 != len)
4321 SCM_OUT_OF_RANGE (3, arg2);
c96d76b8 4322 while (SCM_NIMP (arg1))
0f2d19dd 4323 {
504d99c5 4324 call (proc, SCM_CAR (arg1), SCM_CAR (arg2));
0f2d19dd 4325 arg1 = SCM_CDR (arg1);
504d99c5 4326 arg2 = SCM_CDR (arg2);
0f2d19dd
JB
4327 }
4328 return SCM_UNSPECIFIED;
4329 }
05b15362
DH
4330 arg1 = scm_cons (arg1, args);
4331 args = scm_vector (arg1);
0f2d19dd 4332 ve = SCM_VELTS (args);
47c3f06d 4333 check_map_args (args, len, g_for_each, proc, arg1, s_for_each);
0f2d19dd
JB
4334 while (1)
4335 {
4336 arg1 = SCM_EOL;
b5c2579a 4337 for (i = SCM_VECTOR_LENGTH (args) - 1; i >= 0; i--)
0f2d19dd 4338 {
c96d76b8
NJ
4339 if (SCM_IMP (ve[i]))
4340 return SCM_UNSPECIFIED;
0f2d19dd 4341 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
34d19ef6 4342 SCM_VECTOR_SET (args, i, SCM_CDR (ve[i]));
0f2d19dd
JB
4343 }
4344 scm_apply (proc, arg1, SCM_EOL);
4345 }
4346}
af45e3b0 4347#undef FUNC_NAME
0f2d19dd 4348
1cc91f1b 4349
0f2d19dd 4350SCM
6e8d25a6 4351scm_closure (SCM code, SCM env)
0f2d19dd 4352{
16d4699b
MV
4353 SCM z;
4354 SCM closcar = scm_cons (code, SCM_EOL);
228a24ef 4355 z = scm_cell (SCM_UNPACK (closcar) + scm_tc3_closure, (scm_t_bits) env);
16d4699b 4356 scm_remember_upto_here (closcar);
0f2d19dd
JB
4357 return z;
4358}
4359
4360
92c2555f 4361scm_t_bits scm_tc16_promise;
1cc91f1b 4362
0f2d19dd 4363SCM
6e8d25a6 4364scm_makprom (SCM code)
0f2d19dd 4365{
28d52ebb
MD
4366 SCM_RETURN_NEWSMOB2 (scm_tc16_promise,
4367 SCM_UNPACK (code),
4368 scm_make_rec_mutex ());
0f2d19dd
JB
4369}
4370
28d52ebb
MD
4371static size_t
4372promise_free (SCM promise)
4373{
4374 scm_rec_mutex_free (SCM_PROMISE_MUTEX (promise));
4375 return 0;
4376}
1cc91f1b 4377
0f2d19dd 4378static int
e841c3e0 4379promise_print (SCM exp, SCM port, scm_print_state *pstate)
0f2d19dd 4380{
19402679 4381 int writingp = SCM_WRITINGP (pstate);
b7f3516f 4382 scm_puts ("#<promise ", port);
19402679 4383 SCM_SET_WRITINGP (pstate, 1);
28d52ebb 4384 scm_iprin1 (SCM_PROMISE_DATA (exp), port, pstate);
19402679 4385 SCM_SET_WRITINGP (pstate, writingp);
b7f3516f 4386 scm_putc ('>', port);
0f2d19dd
JB
4387 return !0;
4388}
4389
3b3b36dd 4390SCM_DEFINE (scm_force, "force", 1, 0, 0,
28d52ebb 4391 (SCM promise),
67e8151b
MG
4392 "If the promise @var{x} has not been computed yet, compute and\n"
4393 "return @var{x}, otherwise just return the previously computed\n"
4394 "value.")
1bbd0b84 4395#define FUNC_NAME s_scm_force
0f2d19dd 4396{
28d52ebb
MD
4397 SCM_VALIDATE_SMOB (1, promise, promise);
4398 scm_rec_mutex_lock (SCM_PROMISE_MUTEX (promise));
4399 if (!SCM_PROMISE_COMPUTED_P (promise))
0f2d19dd 4400 {
28d52ebb
MD
4401 SCM ans = scm_call_0 (SCM_PROMISE_DATA (promise));
4402 if (!SCM_PROMISE_COMPUTED_P (promise))
0f2d19dd 4403 {
28d52ebb
MD
4404 SCM_SET_PROMISE_DATA (promise, ans);
4405 SCM_SET_PROMISE_COMPUTED (promise);
0f2d19dd
JB
4406 }
4407 }
28d52ebb
MD
4408 scm_rec_mutex_unlock (SCM_PROMISE_MUTEX (promise));
4409 return SCM_PROMISE_DATA (promise);
0f2d19dd 4410}
1bbd0b84 4411#undef FUNC_NAME
0f2d19dd 4412
445f675c 4413
a1ec6916 4414SCM_DEFINE (scm_promise_p, "promise?", 1, 0, 0,
67e8151b 4415 (SCM obj),
b380b885 4416 "Return true if @var{obj} is a promise, i.e. a delayed computation\n"
7a095584 4417 "(@pxref{Delayed evaluation,,,r5rs.info,The Revised^5 Report on Scheme}).")
1bbd0b84 4418#define FUNC_NAME s_scm_promise_p
0f2d19dd 4419{
67e8151b 4420 return SCM_BOOL (SCM_TYP16_PREDICATE (scm_tc16_promise, obj));
0f2d19dd 4421}
1bbd0b84 4422#undef FUNC_NAME
0f2d19dd 4423
445f675c 4424
a1ec6916 4425SCM_DEFINE (scm_cons_source, "cons-source", 3, 0, 0,
1bbd0b84 4426 (SCM xorig, SCM x, SCM y),
11768c04
NJ
4427 "Create and return a new pair whose car and cdr are @var{x} and @var{y}.\n"
4428 "Any source properties associated with @var{xorig} are also associated\n"
4429 "with the new pair.")
1bbd0b84 4430#define FUNC_NAME s_scm_cons_source
26d5b9b4
MD
4431{
4432 SCM p, z;
16d4699b 4433 z = scm_cons (x, y);
26d5b9b4
MD
4434 /* Copy source properties possibly associated with xorig. */
4435 p = scm_whash_lookup (scm_source_whash, xorig);
445f675c 4436 if (!SCM_IMP (p))
26d5b9b4
MD
4437 scm_whash_insert (scm_source_whash, z, p);
4438 return z;
4439}
1bbd0b84 4440#undef FUNC_NAME
26d5b9b4 4441
445f675c 4442
a1ec6916 4443SCM_DEFINE (scm_copy_tree, "copy-tree", 1, 0, 0,
1bbd0b84 4444 (SCM obj),
b380b885
MD
4445 "Recursively copy the data tree that is bound to @var{obj}, and return a\n"
4446 "pointer to the new data structure. @code{copy-tree} recurses down the\n"
4447 "contents of both pairs and vectors (since both cons cells and vector\n"
4448 "cells may point to arbitrary objects), and stops recursing when it hits\n"
4449 "any other object.")
1bbd0b84 4450#define FUNC_NAME s_scm_copy_tree
0f2d19dd
JB
4451{
4452 SCM ans, tl;
26d5b9b4 4453 if (SCM_IMP (obj))
ff467021 4454 return obj;
3910272e
MD
4455 if (SCM_VECTORP (obj))
4456 {
c014a02e 4457 unsigned long i = SCM_VECTOR_LENGTH (obj);
00ffa0e7 4458 ans = scm_c_make_vector (i, SCM_UNSPECIFIED);
3910272e 4459 while (i--)
34d19ef6 4460 SCM_VECTOR_SET (ans, i, scm_copy_tree (SCM_VELTS (obj)[i]));
3910272e
MD
4461 return ans;
4462 }
01f11e02 4463 if (!SCM_CONSP (obj))
0f2d19dd 4464 return obj;
26d5b9b4
MD
4465 ans = tl = scm_cons_source (obj,
4466 scm_copy_tree (SCM_CAR (obj)),
4467 SCM_UNSPECIFIED);
05b15362 4468 for (obj = SCM_CDR (obj); SCM_CONSP (obj); obj = SCM_CDR (obj))
a23afe53
MD
4469 {
4470 SCM_SETCDR (tl, scm_cons (scm_copy_tree (SCM_CAR (obj)),
4471 SCM_UNSPECIFIED));
4472 tl = SCM_CDR (tl);
4473 }
4474 SCM_SETCDR (tl, obj);
0f2d19dd
JB
4475 return ans;
4476}
1bbd0b84 4477#undef FUNC_NAME
0f2d19dd 4478
1cc91f1b 4479
4163eb72
MV
4480/* We have three levels of EVAL here:
4481
4482 - scm_i_eval (exp, env)
4483
4484 evaluates EXP in environment ENV. ENV is a lexical environment
4485 structure as used by the actual tree code evaluator. When ENV is
4486 a top-level environment, then changes to the current module are
a513ead3 4487 tracked by updating ENV so that it continues to be in sync with
4163eb72
MV
4488 the current module.
4489
4490 - scm_primitive_eval (exp)
4491
4492 evaluates EXP in the top-level environment as determined by the
4493 current module. This is done by constructing a suitable
4494 environment and calling scm_i_eval. Thus, changes to the
4495 top-level module are tracked normally.
4496
4497 - scm_eval (exp, mod)
4498
a513ead3 4499 evaluates EXP while MOD is the current module. This is done by
4163eb72
MV
4500 setting the current module to MOD, invoking scm_primitive_eval on
4501 EXP, and then restoring the current module to the value it had
4502 previously. That is, while EXP is evaluated, changes to the
4503 current module are tracked, but these changes do not persist when
4504 scm_eval returns.
4505
4506 For each level of evals, there are two variants, distinguished by a
4507 _x suffix: the ordinary variant does not modify EXP while the _x
4508 variant can destructively modify EXP into something completely
4509 unintelligible. A Scheme data structure passed as EXP to one of the
4510 _x variants should not ever be used again for anything. So when in
4511 doubt, use the ordinary variant.
4512
4513*/
4514
0f2d19dd 4515SCM
68d8be66 4516scm_i_eval_x (SCM exp, SCM env)
0f2d19dd 4517{
68d8be66 4518 return SCM_XEVAL (exp, env);
0f2d19dd
JB
4519}
4520
68d8be66
MD
4521SCM
4522scm_i_eval (SCM exp, SCM env)
4523{
26fb6390 4524 exp = scm_copy_tree (exp);
e37a4fba 4525 return SCM_XEVAL (exp, env);
68d8be66
MD
4526}
4527
4528SCM
4163eb72 4529scm_primitive_eval_x (SCM exp)
0f2d19dd 4530{
a513ead3 4531 SCM env;
bcdab802 4532 SCM transformer = scm_current_module_transformer ();
a513ead3 4533 if (SCM_NIMP (transformer))
fdc28395 4534 exp = scm_call_1 (transformer, exp);
a513ead3 4535 env = scm_top_level_env (scm_current_module_lookup_closure ());
4163eb72 4536 return scm_i_eval_x (exp, env);
0f2d19dd
JB
4537}
4538
4163eb72
MV
4539SCM_DEFINE (scm_primitive_eval, "primitive-eval", 1, 0, 0,
4540 (SCM exp),
2069af38 4541 "Evaluate @var{exp} in the top-level environment specified by\n"
4163eb72
MV
4542 "the current module.")
4543#define FUNC_NAME s_scm_primitive_eval
4544{
a513ead3 4545 SCM env;
bcdab802 4546 SCM transformer = scm_current_module_transformer ();
a513ead3 4547 if (SCM_NIMP (transformer))
fdc28395 4548 exp = scm_call_1 (transformer, exp);
a513ead3 4549 env = scm_top_level_env (scm_current_module_lookup_closure ());
4163eb72
MV
4550 return scm_i_eval (exp, env);
4551}
4552#undef FUNC_NAME
4553
68d8be66
MD
4554/* Eval does not take the second arg optionally. This is intentional
4555 * in order to be R5RS compatible, and to prepare for the new module
4556 * system, where we would like to make the choice of evaluation
4163eb72 4557 * environment explicit. */
549e6ec6 4558
09074dbf
DH
4559static void
4560change_environment (void *data)
4561{
4562 SCM pair = SCM_PACK (data);
4563 SCM new_module = SCM_CAR (pair);
aa767bc5 4564 SCM old_module = scm_current_module ();
09074dbf 4565 SCM_SETCDR (pair, old_module);
aa767bc5 4566 scm_set_current_module (new_module);
09074dbf
DH
4567}
4568
4569
09074dbf
DH
4570static void
4571restore_environment (void *data)
4572{
4573 SCM pair = SCM_PACK (data);
4574 SCM old_module = SCM_CDR (pair);
aa767bc5 4575 SCM new_module = scm_current_module ();
2e9c835d 4576 SCM_SETCAR (pair, new_module);
aa767bc5 4577 scm_set_current_module (old_module);
09074dbf
DH
4578}
4579
4163eb72
MV
4580static SCM
4581inner_eval_x (void *data)
4582{
4583 return scm_primitive_eval_x (SCM_PACK(data));
4584}
4585
4586SCM
4587scm_eval_x (SCM exp, SCM module)
4588#define FUNC_NAME "eval!"
4589{
4590 SCM_VALIDATE_MODULE (2, module);
4591
4592 return scm_internal_dynamic_wind
4593 (change_environment, inner_eval_x, restore_environment,
4594 (void *) SCM_UNPACK (exp),
4595 (void *) SCM_UNPACK (scm_cons (module, SCM_BOOL_F)));
4596}
4597#undef FUNC_NAME
4598
4599static SCM
4600inner_eval (void *data)
4601{
4602 return scm_primitive_eval (SCM_PACK(data));
4603}
09074dbf 4604
68d8be66 4605SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
4163eb72
MV
4606 (SCM exp, SCM module),
4607 "Evaluate @var{exp}, a list representing a Scheme expression,\n"
4608 "in the top-level environment specified by @var{module}.\n"
8f85c0c6 4609 "While @var{exp} is evaluated (using @code{primitive-eval}),\n"
4163eb72
MV
4610 "@var{module} is made the current module. The current module\n"
4611 "is reset to its previous value when @var{eval} returns.")
1bbd0b84 4612#define FUNC_NAME s_scm_eval
0f2d19dd 4613{
4163eb72 4614 SCM_VALIDATE_MODULE (2, module);
09074dbf
DH
4615
4616 return scm_internal_dynamic_wind
4617 (change_environment, inner_eval, restore_environment,
4163eb72
MV
4618 (void *) SCM_UNPACK (exp),
4619 (void *) SCM_UNPACK (scm_cons (module, SCM_BOOL_F)));
0f2d19dd 4620}
1bbd0b84 4621#undef FUNC_NAME
0f2d19dd 4622
6dbd0af5
MD
4623
4624/* At this point, scm_deval and scm_dapply are generated.
4625 */
4626
a44a9715
DH
4627#define DEVAL
4628#include "eval.c"
0f2d19dd 4629
1cc91f1b 4630
0f2d19dd
JB
4631void
4632scm_init_eval ()
0f2d19dd 4633{
33b97402
MD
4634 scm_init_opts (scm_evaluator_traps,
4635 scm_evaluator_trap_table,
4636 SCM_N_EVALUATOR_TRAPS);
4637 scm_init_opts (scm_eval_options_interface,
4638 scm_eval_opts,
4639 SCM_N_EVAL_OPTIONS);
4640
f99c9c28
MD
4641 scm_tc16_promise = scm_make_smob_type ("promise", 0);
4642 scm_set_smob_mark (scm_tc16_promise, scm_markcdr);
28d52ebb 4643 scm_set_smob_free (scm_tc16_promise, promise_free);
e841c3e0 4644 scm_set_smob_print (scm_tc16_promise, promise_print);
b8229a3b 4645
a44a9715
DH
4646 undefineds = scm_list_1 (SCM_UNDEFINED);
4647 SCM_SETCDR (undefineds, undefineds);
4648 scm_permanent_object (undefineds);
7c33806a 4649
a44a9715 4650 scm_listofnull = scm_list_1 (SCM_EOL);
0f2d19dd 4651
a44a9715
DH
4652 f_apply = scm_c_define_subr ("apply", scm_tc7_lsubr_2, scm_apply);
4653 scm_permanent_object (f_apply);
86d31dfe 4654
a0599745 4655#include "libguile/eval.x"
86d31dfe 4656
25eaf21a 4657 scm_add_feature ("delay");
0f2d19dd 4658}
0f2d19dd 4659
6dbd0af5 4660#endif /* !DEVAL */
89e00824
ML
4661
4662/*
4663 Local Variables:
4664 c-file-style: "gnu"
4665 End:
4666*/