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