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