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