fold objects.[ch] into goops.[ch]
[bpt/guile.git] / libguile / eval.c
CommitLineData
e20d7001 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009
434f2f7a 2 * Free Software Foundation, Inc.
0f2d19dd 3 *
73be1d9e 4 * This library is free software; you can redistribute it and/or
53befeb7
NJ
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation; either version 3 of
7 * the License, or (at your option) any later version.
0f2d19dd 8 *
53befeb7
NJ
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
73be1d9e
MV
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
0f2d19dd 13 *
73be1d9e
MV
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
53befeb7
NJ
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 * 02110-1301 USA
73be1d9e 18 */
1bbd0b84 19
0f2d19dd
JB
20\f
21
6dbd0af5 22/* SECTION: This code is compiled once.
0f2d19dd
JB
23 */
24
dbb605f5 25#ifdef HAVE_CONFIG_H
3d05f2e0
RB
26# include <config.h>
27#endif
0f2d19dd 28
f7439099 29#include <alloca.h>
3d05f2e0 30
f7439099 31#include "libguile/__scm.h"
48b96f4b 32
e7313a9d 33#include <assert.h>
a0599745 34#include "libguile/_scm.h"
21628685
DH
35#include "libguile/alist.h"
36#include "libguile/async.h"
37#include "libguile/continuations.h"
a0599745 38#include "libguile/debug.h"
328dc9a3 39#include "libguile/deprecation.h"
09074dbf 40#include "libguile/dynwind.h"
a0599745 41#include "libguile/eq.h"
21628685
DH
42#include "libguile/feature.h"
43#include "libguile/fluids.h"
21628685
DH
44#include "libguile/goops.h"
45#include "libguile/hash.h"
46#include "libguile/hashtab.h"
47#include "libguile/lang.h"
4610b011 48#include "libguile/list.h"
a0599745 49#include "libguile/macros.h"
a0599745
MD
50#include "libguile/modules.h"
51#include "libguile/ports.h"
7e6e6b37 52#include "libguile/print.h"
21628685 53#include "libguile/procprop.h"
4abef68f 54#include "libguile/programs.h"
a0599745 55#include "libguile/root.h"
21628685
DH
56#include "libguile/smob.h"
57#include "libguile/srcprop.h"
58#include "libguile/stackchk.h"
59#include "libguile/strings.h"
9de87eea 60#include "libguile/threads.h"
21628685
DH
61#include "libguile/throw.h"
62#include "libguile/validate.h"
a513ead3 63#include "libguile/values.h"
21628685 64#include "libguile/vectors.h"
4abef68f 65#include "libguile/vm.h"
a0599745 66
a0599745 67#include "libguile/eval.h"
0ee05b85 68#include "libguile/private-options.h"
89efbff4 69
0f2d19dd
JB
70\f
71
0ee05b85 72
212e58ed 73static SCM unmemoize_exprs (SCM expr, SCM env);
0f572ba7 74static SCM canonicalize_define (SCM expr);
e5156567 75static SCM *scm_lookupcar1 (SCM vloc, SCM genv, int check);
212e58ed 76static SCM unmemoize_builtin_macro (SCM expr, SCM env);
0ee05b85
HWN
77static void ceval_letrec_inits (SCM env, SCM init_forms, SCM **init_values_eol);
78static SCM ceval (SCM x, SCM env);
79static SCM deval (SCM x, SCM env);
0f572ba7
DH
80
81\f
82
e6729603
DH
83/* {Syntax Errors}
84 *
85 * This section defines the message strings for the syntax errors that can be
86 * detected during memoization and the functions and macros that shall be
87 * called by the memoizer code to signal syntax errors. */
88
89
90/* Syntax errors that can be detected during memoization: */
91
92/* Circular or improper lists do not form valid scheme expressions. If a
93 * circular list or an improper list is detected in a place where a scheme
94 * expression is expected, a 'Bad expression' error is signalled. */
95static const char s_bad_expression[] = "Bad expression";
96
89bff2fc
DH
97/* If a form is detected that holds a different number of expressions than are
98 * required in that context, a 'Missing or extra expression' error is
99 * signalled. */
100static const char s_expression[] = "Missing or extra expression in";
101
cc56ba80 102/* If a form is detected that holds less expressions than are required in that
8ae95199 103 * context, a 'Missing expression' error is signalled. */
cc56ba80
DH
104static const char s_missing_expression[] = "Missing expression in";
105
609a8b86 106/* If a form is detected that holds more expressions than are allowed in that
8ae95199 107 * context, an 'Extra expression' error is signalled. */
609a8b86
DH
108static const char s_extra_expression[] = "Extra expression in";
109
89bff2fc
DH
110/* The empty combination '()' is not allowed as an expression in scheme. If
111 * it is detected in a place where an expression is expected, an 'Illegal
112 * empty combination' error is signalled. Note: If you encounter this error
113 * message, it is very likely that you intended to denote the empty list. To
114 * do so, you need to quote the empty list like (quote ()) or '(). */
115static const char s_empty_combination[] = "Illegal empty combination";
116
c86c440b
DH
117/* A body may hold an arbitrary number of internal defines, followed by a
118 * non-empty sequence of expressions. If a body with an empty sequence of
119 * expressions is detected, a 'Missing body expression' error is signalled.
120 */
121static const char s_missing_body_expression[] = "Missing body expression in";
122
123/* A body may hold an arbitrary number of internal defines, followed by a
124 * non-empty sequence of expressions. Each the definitions and the
125 * expressions may be grouped arbitraryly with begin, but it is not allowed to
126 * mix definitions and expressions. If a define form in a body mixes
127 * definitions and expressions, a 'Mixed definitions and expressions' error is
6bff1368 128 * signalled. */
c86c440b 129static const char s_mixed_body_forms[] = "Mixed definitions and expressions in";
6bff1368
DH
130/* Definitions are only allowed on the top level and at the start of a body.
131 * If a definition is detected anywhere else, a 'Bad define placement' error
132 * is signalled. */
133static const char s_bad_define[] = "Bad define placement";
c86c440b 134
2a6f7afe
DH
135/* Case or cond expressions must have at least one clause. If a case or cond
136 * expression without any clauses is detected, a 'Missing clauses' error is
137 * signalled. */
138static const char s_missing_clauses[] = "Missing clauses";
139
609a8b86
DH
140/* If there is an 'else' clause in a case or a cond statement, it must be the
141 * last clause. If after the 'else' case clause further clauses are detected,
142 * a 'Misplaced else clause' error is signalled. */
143static const char s_misplaced_else_clause[] = "Misplaced else clause";
144
2a6f7afe
DH
145/* If a case clause is detected that is not in the format
146 * (<label(s)> <expression1> <expression2> ...)
147 * a 'Bad case clause' error is signalled. */
148static const char s_bad_case_clause[] = "Bad case clause";
149
2a6f7afe
DH
150/* If a case clause is detected where the <label(s)> element is neither a
151 * proper list nor (in case of the last clause) the syntactic keyword 'else',
152 * a 'Bad case labels' error is signalled. Note: If you encounter this error
153 * for an else-clause which seems to be syntactically correct, check if 'else'
154 * is really a syntactic keyword in that context. If 'else' is bound in the
155 * local or global environment, it is not considered a syntactic keyword, but
156 * will be treated as any other variable. */
157static const char s_bad_case_labels[] = "Bad case labels";
158
159/* In a case statement all labels have to be distinct. If in a case statement
160 * a label occurs more than once, a 'Duplicate case label' error is
161 * signalled. */
162static const char s_duplicate_case_label[] = "Duplicate case label";
163
609a8b86
DH
164/* If a cond clause is detected that is not in one of the formats
165 * (<test> <expression1> ...) or (else <expression1> <expression2> ...)
166 * a 'Bad cond clause' error is signalled. */
167static const char s_bad_cond_clause[] = "Bad cond clause";
168
169/* If a cond clause is detected that uses the alternate '=>' form, but does
170 * not hold a recipient element for the test result, a 'Missing recipient'
171 * error is signalled. */
172static const char s_missing_recipient[] = "Missing recipient in";
173
cc56ba80
DH
174/* If in a position where a variable name is required some other object is
175 * detected, a 'Bad variable' error is signalled. */
176static const char s_bad_variable[] = "Bad variable";
177
a954ce1d
DH
178/* Bindings for forms like 'let' and 'do' have to be given in a proper,
179 * possibly empty list. If any other object is detected in a place where a
180 * list of bindings was required, a 'Bad bindings' error is signalled. */
181static const char s_bad_bindings[] = "Bad bindings";
182
183/* Depending on the syntactic context, a binding has to be in the format
184 * (<variable> <expression>) or (<variable> <expression1> <expression2>).
185 * If anything else is detected in a place where a binding was expected, a
186 * 'Bad binding' error is signalled. */
187static const char s_bad_binding[] = "Bad binding";
188
4610b011
DH
189/* Some syntactic forms don't allow variable names to appear more than once in
190 * a list of bindings. If such a situation is nevertheless detected, a
191 * 'Duplicate binding' error is signalled. */
192static const char s_duplicate_binding[] = "Duplicate binding";
193
a954ce1d
DH
194/* If the exit form of a 'do' expression is not in the format
195 * (<test> <expression> ...)
196 * a 'Bad exit clause' error is signalled. */
197static const char s_bad_exit_clause[] = "Bad exit clause";
198
03a3e941
DH
199/* The formal function arguments of a lambda expression have to be either a
200 * single symbol or a non-cyclic list. For anything else a 'Bad formals'
201 * error is signalled. */
202static const char s_bad_formals[] = "Bad formals";
203
204/* If in a lambda expression something else than a symbol is detected at a
205 * place where a formal function argument is required, a 'Bad formal' error is
206 * signalled. */
207static const char s_bad_formal[] = "Bad formal";
208
209/* If in the arguments list of a lambda expression an argument name occurs
210 * more than once, a 'Duplicate formal' error is signalled. */
211static const char s_duplicate_formal[] = "Duplicate formal";
212
6f81708a
DH
213/* If the evaluation of an unquote-splicing expression gives something else
214 * than a proper list, a 'Non-list result for unquote-splicing' error is
215 * signalled. */
216static const char s_splicing[] = "Non-list result for unquote-splicing";
217
9a848baf
DH
218/* If something else than an exact integer is detected as the argument for
219 * @slot-ref and @slot-set!, a 'Bad slot number' error is signalled. */
220static const char s_bad_slot_number[] = "Bad slot number";
221
e6729603
DH
222
223/* Signal a syntax error. We distinguish between the form that caused the
224 * error and the enclosing expression. The error message will print out as
225 * shown in the following pattern. The file name and line number are only
226 * given when they can be determined from the erroneous form or from the
227 * enclosing expression.
228 *
229 * <filename>: In procedure memoization:
230 * <filename>: In file <name>, line <nr>: <error-message> in <expression>. */
231
232SCM_SYMBOL (syntax_error_key, "syntax-error");
233
234/* The prototype is needed to indicate that the function does not return. */
235static void
236syntax_error (const char* const, const SCM, const SCM) SCM_NORETURN;
237
238static void
239syntax_error (const char* const msg, const SCM form, const SCM expr)
240{
cc95e00a 241 SCM msg_string = scm_from_locale_string (msg);
e6729603
DH
242 SCM filename = SCM_BOOL_F;
243 SCM linenr = SCM_BOOL_F;
244 const char *format;
245 SCM args;
246
a61f4e0c 247 if (scm_is_pair (form))
e6729603
DH
248 {
249 filename = scm_source_property (form, scm_sym_filename);
250 linenr = scm_source_property (form, scm_sym_line);
251 }
252
a61f4e0c 253 if (scm_is_false (filename) && scm_is_false (linenr) && scm_is_pair (expr))
e6729603
DH
254 {
255 filename = scm_source_property (expr, scm_sym_filename);
256 linenr = scm_source_property (expr, scm_sym_line);
257 }
258
259 if (!SCM_UNBNDP (expr))
260 {
7888309b 261 if (scm_is_true (filename))
e6729603
DH
262 {
263 format = "In file ~S, line ~S: ~A ~S in expression ~S.";
264 args = scm_list_5 (filename, linenr, msg_string, form, expr);
265 }
7888309b 266 else if (scm_is_true (linenr))
e6729603
DH
267 {
268 format = "In line ~S: ~A ~S in expression ~S.";
269 args = scm_list_4 (linenr, msg_string, form, expr);
270 }
271 else
272 {
273 format = "~A ~S in expression ~S.";
274 args = scm_list_3 (msg_string, form, expr);
275 }
276 }
277 else
278 {
7888309b 279 if (scm_is_true (filename))
e6729603
DH
280 {
281 format = "In file ~S, line ~S: ~A ~S.";
282 args = scm_list_4 (filename, linenr, msg_string, form);
283 }
7888309b 284 else if (scm_is_true (linenr))
e6729603
DH
285 {
286 format = "In line ~S: ~A ~S.";
287 args = scm_list_3 (linenr, msg_string, form);
288 }
289 else
290 {
291 format = "~A ~S.";
292 args = scm_list_2 (msg_string, form);
293 }
294 }
295
296 scm_error (syntax_error_key, "memoization", format, args, SCM_BOOL_F);
297}
298
299
300/* Shortcut macros to simplify syntax error handling. */
9cc37597
LC
301#define ASSERT_SYNTAX(cond, message, form) \
302 { if (SCM_UNLIKELY (!(cond))) \
303 syntax_error (message, form, SCM_UNDEFINED); }
304#define ASSERT_SYNTAX_2(cond, message, form, expr) \
305 { if (SCM_UNLIKELY (!(cond))) \
306 syntax_error (message, form, expr); }
e6729603 307
249bab1c
AW
308static void error_unbound_variable (SCM symbol) SCM_NORETURN;
309static void error_defined_variable (SCM symbol) SCM_NORETURN;
310
e6729603
DH
311\f
312
d0624e39
DH
313/* {Ilocs}
314 *
315 * Ilocs are memoized references to variables in local environment frames.
316 * They are represented as three values: The relative offset of the
317 * environment frame, the number of the binding within that frame, and a
318 * boolean value indicating whether the binding is the last binding in the
319 * frame.
a55c2b68
MV
320 *
321 * Frame numbers have 11 bits, relative offsets have 12 bits.
d0624e39 322 */
7e6e6b37 323
d0624e39 324#define SCM_ILOC00 SCM_MAKE_ITAG8(0L, scm_tc8_iloc)
7e6e6b37
DH
325#define SCM_IFRINC (0x00000100L)
326#define SCM_ICDR (0x00080000L)
d0624e39 327#define SCM_IDINC (0x00100000L)
7e6e6b37
DH
328#define SCM_IFRAME(n) ((long)((SCM_ICDR-SCM_IFRINC)>>8) \
329 & (SCM_UNPACK (n) >> 8))
330#define SCM_IDIST(n) (SCM_UNPACK (n) >> 20)
331#define SCM_ICDRP(n) (SCM_ICDR & SCM_UNPACK (n))
d0624e39 332#define SCM_IDSTMSK (-SCM_IDINC)
a55c2b68
MV
333#define SCM_IFRAMEMAX ((1<<11)-1)
334#define SCM_IDISTMAX ((1<<12)-1)
d0624e39
DH
335#define SCM_MAKE_ILOC(frame_nr, binding_nr, last_p) \
336 SCM_PACK ( \
337 ((frame_nr) << 8) \
338 + ((binding_nr) << 20) \
339 + ((last_p) ? SCM_ICDR : 0) \
340 + scm_tc8_iloc )
341
7e6e6b37
DH
342void
343scm_i_print_iloc (SCM iloc, SCM port)
344{
345 scm_puts ("#@", port);
346 scm_intprint ((long) SCM_IFRAME (iloc), 10, port);
347 scm_putc (SCM_ICDRP (iloc) ? '-' : '+', port);
348 scm_intprint ((long) SCM_IDIST (iloc), 10, port);
349}
350
d0624e39
DH
351#if (SCM_DEBUG_DEBUGGING_SUPPORT == 1)
352
353SCM scm_dbg_make_iloc (SCM frame, SCM binding, SCM cdrp);
90df793f 354
d0624e39
DH
355SCM_DEFINE (scm_dbg_make_iloc, "dbg-make-iloc", 3, 0, 0,
356 (SCM frame, SCM binding, SCM cdrp),
357 "Return a new iloc with frame offset @var{frame}, binding\n"
358 "offset @var{binding} and the cdr flag @var{cdrp}.")
359#define FUNC_NAME s_scm_dbg_make_iloc
360{
c3c97a34
KR
361 return SCM_MAKE_ILOC ((scm_t_bits) scm_to_unsigned_integer (frame, 0, SCM_IFRAMEMAX),
362 (scm_t_bits) scm_to_unsigned_integer (binding, 0, SCM_IDISTMAX),
7888309b 363 scm_is_true (cdrp));
d0624e39
DH
364}
365#undef FUNC_NAME
366
367SCM scm_dbg_iloc_p (SCM obj);
90df793f 368
d0624e39
DH
369SCM_DEFINE (scm_dbg_iloc_p, "dbg-iloc?", 1, 0, 0,
370 (SCM obj),
371 "Return @code{#t} if @var{obj} is an iloc.")
372#define FUNC_NAME s_scm_dbg_iloc_p
373{
7888309b 374 return scm_from_bool (SCM_ILOCP (obj));
d0624e39
DH
375}
376#undef FUNC_NAME
377
378#endif
379
380\f
381
7e6e6b37
DH
382/* {Evaluator byte codes (isyms)}
383 */
384
385#define ISYMNUM(n) (SCM_ITAG8_DATA (n))
386
387/* This table must agree with the list of SCM_IM_ constants in tags.h */
388static const char *const isymnames[] =
389{
390 "#@and",
391 "#@begin",
392 "#@case",
393 "#@cond",
394 "#@do",
395 "#@if",
396 "#@lambda",
397 "#@let",
398 "#@let*",
399 "#@letrec",
400 "#@or",
401 "#@quote",
402 "#@set!",
403 "#@define",
404 "#@apply",
405 "#@call-with-current-continuation",
406 "#@dispatch",
407 "#@slot-ref",
408 "#@slot-set!",
409 "#@delay",
7e6e6b37
DH
410 "#@call-with-values",
411 "#@else",
412 "#@arrow",
413 "#@nil-cond",
414 "#@bind"
415};
416
417void
418scm_i_print_isym (SCM isym, SCM port)
419{
420 const size_t isymnum = ISYMNUM (isym);
421 if (isymnum < (sizeof isymnames / sizeof (char *)))
422 scm_puts (isymnames[isymnum], port);
423 else
424 scm_ipruk ("isym", isym, port);
425}
426
427\f
428
e5156567
DH
429/* The function lookup_symbol is used during memoization: Lookup the symbol in
430 * the environment. If there is no binding for the symbol, SCM_UNDEFINED is
57d23e25
DH
431 * returned. If the symbol is a global variable, the variable object to which
432 * the symbol is bound is returned. Finally, if the symbol is a local
433 * variable the corresponding iloc object is returned. */
6f81708a
DH
434
435/* A helper function for lookup_symbol: Try to find the symbol in the top
436 * level environment frame. The function returns SCM_UNDEFINED if the symbol
57d23e25
DH
437 * is unbound and it returns a variable object if the symbol is a global
438 * variable. */
6f81708a
DH
439static SCM
440lookup_global_symbol (const SCM symbol, const SCM top_level)
441{
442 const SCM variable = scm_sym2var (symbol, top_level, SCM_BOOL_F);
7888309b 443 if (scm_is_false (variable))
57d23e25 444 return SCM_UNDEFINED;
6f81708a 445 else
57d23e25 446 return variable;
6f81708a
DH
447}
448
449static SCM
450lookup_symbol (const SCM symbol, const SCM env)
451{
452 SCM frame_idx;
453 unsigned int frame_nr;
454
455 for (frame_idx = env, frame_nr = 0;
a61f4e0c 456 !scm_is_null (frame_idx);
6f81708a
DH
457 frame_idx = SCM_CDR (frame_idx), ++frame_nr)
458 {
459 const SCM frame = SCM_CAR (frame_idx);
a61f4e0c 460 if (scm_is_pair (frame))
6f81708a
DH
461 {
462 /* frame holds a local environment frame */
463 SCM symbol_idx;
464 unsigned int symbol_nr;
465
466 for (symbol_idx = SCM_CAR (frame), symbol_nr = 0;
a61f4e0c 467 scm_is_pair (symbol_idx);
6f81708a
DH
468 symbol_idx = SCM_CDR (symbol_idx), ++symbol_nr)
469 {
bc36d050 470 if (scm_is_eq (SCM_CAR (symbol_idx), symbol))
6f81708a
DH
471 /* found the symbol, therefore return the iloc */
472 return SCM_MAKE_ILOC (frame_nr, symbol_nr, 0);
473 }
bc36d050 474 if (scm_is_eq (symbol_idx, symbol))
6f81708a
DH
475 /* found the symbol as the last element of the current frame */
476 return SCM_MAKE_ILOC (frame_nr, symbol_nr, 1);
477 }
478 else
479 {
480 /* no more local environment frames */
481 return lookup_global_symbol (symbol, frame);
482 }
483 }
484
485 return lookup_global_symbol (symbol, SCM_BOOL_F);
486}
487
488
489/* Return true if the symbol is - from the point of view of a macro
490 * transformer - a literal in the sense specified in chapter "pattern
491 * language" of R5RS. In the code below, however, we don't match the
492 * definition of R5RS exactly: It returns true if the identifier has no
493 * binding or if it is a syntactic keyword. */
494static int
495literal_p (const SCM symbol, const SCM env)
496{
57d23e25
DH
497 const SCM variable = lookup_symbol (symbol, env);
498 if (SCM_UNBNDP (variable))
499 return 1;
500 if (SCM_VARIABLEP (variable) && SCM_MACROP (SCM_VARIABLE_REF (variable)))
6f81708a
DH
501 return 1;
502 else
503 return 0;
504}
17fa3fcf 505
5fb64383
DH
506
507/* Return true if the expression is self-quoting in the memoized code. Thus,
508 * some other objects (like e. g. vectors) are reported as self-quoting, which
509 * according to R5RS would need to be quoted. */
510static int
511is_self_quoting_p (const SCM expr)
512{
a61f4e0c 513 if (scm_is_pair (expr))
5fb64383 514 return 0;
cc95e00a 515 else if (scm_is_symbol (expr))
5fb64383 516 return 0;
a61f4e0c 517 else if (scm_is_null (expr))
5fb64383
DH
518 return 0;
519 else return 1;
520}
521
0f2d19dd 522
212e58ed
DH
523SCM_SYMBOL (sym_three_question_marks, "???");
524
525static SCM
526unmemoize_expression (const SCM expr, const SCM env)
527{
528 if (SCM_ILOCP (expr))
529 {
530 SCM frame_idx;
531 unsigned long int frame_nr;
532 SCM symbol_idx;
533 unsigned long int symbol_nr;
534
535 for (frame_idx = env, frame_nr = SCM_IFRAME (expr);
536 frame_nr != 0;
537 frame_idx = SCM_CDR (frame_idx), --frame_nr)
538 ;
539 for (symbol_idx = SCM_CAAR (frame_idx), symbol_nr = SCM_IDIST (expr);
540 symbol_nr != 0;
541 symbol_idx = SCM_CDR (symbol_idx), --symbol_nr)
542 ;
543 return SCM_ICDRP (expr) ? symbol_idx : SCM_CAR (symbol_idx);
544 }
545 else if (SCM_VARIABLEP (expr))
546 {
547 const SCM sym = scm_module_reverse_lookup (scm_env_module (env), expr);
7888309b 548 return scm_is_true (sym) ? sym : sym_three_question_marks;
212e58ed 549 }
4057a3e0 550 else if (scm_is_simple_vector (expr))
212e58ed
DH
551 {
552 return scm_list_2 (scm_sym_quote, expr);
553 }
a61f4e0c 554 else if (!scm_is_pair (expr))
212e58ed
DH
555 {
556 return expr;
557 }
558 else if (SCM_ISYMP (SCM_CAR (expr)))
559 {
560 return unmemoize_builtin_macro (expr, env);
561 }
562 else
563 {
564 return unmemoize_exprs (expr, env);
565 }
566}
567
568
569static SCM
570unmemoize_exprs (const SCM exprs, const SCM env)
571{
90df793f 572 SCM r_result = SCM_EOL;
9fcf3cbb 573 SCM expr_idx = exprs;
90df793f
DH
574 SCM um_expr;
575
576 /* Note that due to the current lazy memoizer we may find partially memoized
5fa0939c 577 * code during execution. In such code we have to expect improper lists of
90df793f
DH
578 * expressions: On the one hand, for such code syntax checks have not yet
579 * fully been performed, on the other hand, there may be even legal code
580 * like '(a . b) appear as an improper list of expressions as long as the
581 * quote expression is still in its unmemoized form. For this reason, the
582 * following code handles improper lists of expressions until memoization
583 * and execution have been completely separated. */
a61f4e0c 584 for (; scm_is_pair (expr_idx); expr_idx = SCM_CDR (expr_idx))
212e58ed
DH
585 {
586 const SCM expr = SCM_CAR (expr_idx);
5fa0939c
DH
587
588 /* In partially memoized code, lists of expressions that stem from a
589 * body form may start with an ISYM if the body itself has not yet been
590 * memoized. This isym is just an internal marker to indicate that the
591 * body still needs to be memoized. An isym may occur at the very
592 * beginning of the body or after one or more comment strings. It is
593 * dropped during unmemoization. */
594 if (!SCM_ISYMP (expr))
595 {
596 um_expr = unmemoize_expression (expr, env);
597 r_result = scm_cons (um_expr, r_result);
598 }
90df793f
DH
599 }
600 um_expr = unmemoize_expression (expr_idx, env);
a61f4e0c 601 if (!scm_is_null (r_result))
90df793f
DH
602 {
603 const SCM result = scm_reverse_x (r_result, SCM_UNDEFINED);
604 SCM_SETCDR (r_result, um_expr);
605 return result;
606 }
607 else
608 {
609 return um_expr;
212e58ed 610 }
212e58ed
DH
611}
612
613
34adf7ea
DH
614/* Rewrite the body (which is given as the list of expressions forming the
615 * body) into its internal form. The internal form of a body (<expr> ...) is
616 * just the body itself, but prefixed with an ISYM that denotes to what kind
617 * of outer construct this body belongs: (<ISYM> <expr> ...). A lambda body
618 * starts with SCM_IM_LAMBDA, for example, a body of a let starts with
6bff1368 619 * SCM_IM_LET, etc.
34adf7ea
DH
620 *
621 * It is assumed that the calling expression has already made sure that the
622 * body is a proper list. */
26d5b9b4 623static SCM
430b8401 624m_body (SCM op, SCM exprs)
26d5b9b4 625{
26d5b9b4 626 /* Don't add another ISYM if one is present already. */
34adf7ea
DH
627 if (SCM_ISYMP (SCM_CAR (exprs)))
628 return exprs;
629 else
630 return scm_cons (op, exprs);
26d5b9b4
MD
631}
632
1cc91f1b 633
57d23e25
DH
634/* The function m_expand_body memoizes a proper list of expressions forming a
635 * body. This function takes care of dealing with internal defines and
636 * transforming them into an equivalent letrec expression. The list of
637 * expressions is rewritten in place. */
910b5125 638
57d23e25
DH
639/* This is a helper function for m_expand_body. If the argument expression is
640 * a symbol that denotes a syntactic keyword, the corresponding macro object
641 * is returned, in all other cases the function returns SCM_UNDEFINED. */
910b5125
DH
642static SCM
643try_macro_lookup (const SCM expr, const SCM env)
644{
cc95e00a 645 if (scm_is_symbol (expr))
910b5125 646 {
57d23e25
DH
647 const SCM variable = lookup_symbol (expr, env);
648 if (SCM_VARIABLEP (variable))
649 {
650 const SCM value = SCM_VARIABLE_REF (variable);
651 if (SCM_MACROP (value))
652 return value;
653 }
910b5125 654 }
57d23e25
DH
655
656 return SCM_UNDEFINED;
910b5125
DH
657}
658
659/* This is a helper function for m_expand_body. It expands user macros,
660 * because for the correct translation of a body we need to know whether they
661 * expand to a definition. */
662static SCM
663expand_user_macros (SCM expr, const SCM env)
664{
a61f4e0c 665 while (scm_is_pair (expr))
910b5125
DH
666 {
667 const SCM car_expr = SCM_CAR (expr);
668 const SCM new_car = expand_user_macros (car_expr, env);
669 const SCM value = try_macro_lookup (new_car, env);
670
671 if (SCM_MACROP (value) && SCM_MACRO_TYPE (value) == 2)
672 {
673 /* User macros transform code into code. */
674 expr = scm_call_2 (SCM_MACRO_CODE (value), expr, env);
675 /* We need to reiterate on the transformed code. */
676 }
677 else
678 {
679 /* No user macro: return. */
680 SCM_SETCAR (expr, new_car);
681 return expr;
682 }
683 }
684
685 return expr;
686}
687
688/* This is a helper function for m_expand_body. It determines if a given form
689 * represents an application of a given built-in macro. The built-in macro to
690 * check for is identified by its syntactic keyword. The form is an
691 * application of the given macro if looking up the car of the form in the
692 * given environment actually returns the built-in macro. */
693static int
694is_system_macro_p (const SCM syntactic_keyword, const SCM form, const SCM env)
695{
a61f4e0c 696 if (scm_is_pair (form))
910b5125
DH
697 {
698 const SCM car_form = SCM_CAR (form);
699 const SCM value = try_macro_lookup (car_form, env);
700 if (SCM_BUILTIN_MACRO_P (value))
701 {
702 const SCM macro_name = scm_macro_name (value);
bc36d050 703 return scm_is_eq (macro_name, syntactic_keyword);
910b5125
DH
704 }
705 }
706
707 return 0;
708}
709
4d0949ea
LC
710static SCM
711macroexp (SCM x, SCM env)
712{
713 SCM res, proc, orig_sym;
714
715 /* Don't bother to produce error messages here. We get them when we
716 eventually execute the code for real. */
717
718 macro_tail:
719 orig_sym = SCM_CAR (x);
720 if (!scm_is_symbol (orig_sym))
721 return x;
722
723 {
724 SCM *proc_ptr = scm_lookupcar1 (x, env, 0);
725 if (proc_ptr == NULL)
726 {
727 /* We have lost the race. */
728 goto macro_tail;
729 }
730 proc = *proc_ptr;
731 }
732
733 /* Only handle memoizing macros. `Acros' and `macros' are really
734 special forms and should not be evaluated here. */
735
736 if (!SCM_MACROP (proc)
737 || (SCM_MACRO_TYPE (proc) != 2 && !SCM_BUILTIN_MACRO_P (proc)))
738 return x;
739
740 SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of lookupcar */
741 res = scm_call_2 (SCM_MACRO_CODE (proc), x, env);
742
743 if (scm_ilength (res) <= 0)
744 /* Result of expansion is not a list. */
745 return (scm_list_2 (SCM_IM_BEGIN, res));
746 else
747 {
748 /* njrev: Several queries here: (1) I don't see how it can be
749 correct that the SCM_SETCAR 2 lines below this comment needs
750 protection, but the SCM_SETCAR 6 lines above does not, so
751 something here is probably wrong. (2) macroexp() is now only
752 used in one place - scm_m_generalized_set_x - whereas all other
753 macro expansion happens through expand_user_macros. Therefore
754 (2.1) perhaps macroexp() could be eliminated completely now?
755 (2.2) Does expand_user_macros need any critical section
756 protection? */
757
758 SCM_CRITICAL_SECTION_START;
759 SCM_SETCAR (x, SCM_CAR (res));
760 SCM_SETCDR (x, SCM_CDR (res));
761 SCM_CRITICAL_SECTION_END;
762
763 goto macro_tail;
764 }
765}
766
767\f
768/* Start of the memoizers for the standard R5RS builtin macros. */
769
770static SCM scm_m_quote (SCM xorig, SCM env);
771static SCM scm_m_begin (SCM xorig, SCM env);
772static SCM scm_m_if (SCM xorig, SCM env);
773static SCM scm_m_set_x (SCM xorig, SCM env);
774static SCM scm_m_and (SCM xorig, SCM env);
775static SCM scm_m_or (SCM xorig, SCM env);
776static SCM scm_m_case (SCM xorig, SCM env);
777static SCM scm_m_cond (SCM xorig, SCM env);
778static SCM scm_m_lambda (SCM xorig, SCM env);
779static SCM scm_m_letstar (SCM xorig, SCM env);
780static SCM scm_m_do (SCM xorig, SCM env);
781static SCM scm_m_quasiquote (SCM xorig, SCM env);
782static SCM scm_m_delay (SCM xorig, SCM env);
783static SCM scm_m_generalized_set_x (SCM xorig, SCM env);
4d0949ea
LC
784static SCM scm_m_define (SCM x, SCM env);
785static SCM scm_m_letrec (SCM xorig, SCM env);
786static SCM scm_m_let (SCM xorig, SCM env);
787static SCM scm_m_at (SCM xorig, SCM env);
788static SCM scm_m_atat (SCM xorig, SCM env);
789static SCM scm_m_atslot_ref (SCM xorig, SCM env);
790static SCM scm_m_atslot_set_x (SCM xorig, SCM env);
791static SCM scm_m_apply (SCM xorig, SCM env);
792static SCM scm_m_cont (SCM xorig, SCM env);
793#if SCM_ENABLE_ELISP
794static SCM scm_m_nil_cond (SCM xorig, SCM env);
795static SCM scm_m_atfop (SCM xorig, SCM env);
796#endif /* SCM_ENABLE_ELISP */
797static SCM scm_m_atbind (SCM xorig, SCM env);
798static SCM scm_m_at_call_with_values (SCM xorig, SCM env);
799static SCM scm_m_eval_when (SCM xorig, SCM env);
800
801
9d4bf6d3 802static void
910b5125
DH
803m_expand_body (const SCM forms, const SCM env)
804{
805 /* The first body form can be skipped since it is known to be the ISYM that
806 * was prepended to the body by m_body. */
807 SCM cdr_forms = SCM_CDR (forms);
808 SCM form_idx = cdr_forms;
809 SCM definitions = SCM_EOL;
810 SCM sequence = SCM_EOL;
811
812 /* According to R5RS, the list of body forms consists of two parts: a number
813 * (maybe zero) of definitions, followed by a non-empty sequence of
814 * expressions. Each the definitions and the expressions may be grouped
815 * arbitrarily with begin, but it is not allowed to mix definitions and
816 * expressions. The task of the following loop therefore is to split the
817 * list of body forms into the list of definitions and the sequence of
818 * expressions. */
a61f4e0c 819 while (!scm_is_null (form_idx))
910b5125
DH
820 {
821 const SCM form = SCM_CAR (form_idx);
822 const SCM new_form = expand_user_macros (form, env);
823 if (is_system_macro_p (scm_sym_define, new_form, env))
824 {
825 definitions = scm_cons (new_form, definitions);
826 form_idx = SCM_CDR (form_idx);
827 }
828 else if (is_system_macro_p (scm_sym_begin, new_form, env))
829 {
830 /* We have encountered a group of forms. This has to be either a
831 * (possibly empty) group of (possibly further grouped) definitions,
832 * or a non-empty group of (possibly further grouped)
833 * expressions. */
834 const SCM grouped_forms = SCM_CDR (new_form);
835 unsigned int found_definition = 0;
836 unsigned int found_expression = 0;
837 SCM grouped_form_idx = grouped_forms;
a61f4e0c 838 while (!found_expression && !scm_is_null (grouped_form_idx))
910b5125
DH
839 {
840 const SCM inner_form = SCM_CAR (grouped_form_idx);
841 const SCM new_inner_form = expand_user_macros (inner_form, env);
842 if (is_system_macro_p (scm_sym_define, new_inner_form, env))
843 {
844 found_definition = 1;
845 definitions = scm_cons (new_inner_form, definitions);
846 grouped_form_idx = SCM_CDR (grouped_form_idx);
847 }
848 else if (is_system_macro_p (scm_sym_begin, new_inner_form, env))
849 {
850 const SCM inner_group = SCM_CDR (new_inner_form);
851 grouped_form_idx
852 = scm_append (scm_list_2 (inner_group,
853 SCM_CDR (grouped_form_idx)));
854 }
855 else
856 {
857 /* The group marks the start of the expressions of the body.
858 * We have to make sure that within the same group we have
859 * not encountered a definition before. */
860 ASSERT_SYNTAX (!found_definition, s_mixed_body_forms, form);
861 found_expression = 1;
862 grouped_form_idx = SCM_EOL;
863 }
864 }
865
866 /* We have finished processing the group. If we have not yet
867 * encountered an expression we continue processing the forms of the
868 * body to collect further definition forms. Otherwise, the group
869 * marks the start of the sequence of expressions of the body. */
870 if (!found_expression)
871 {
872 form_idx = SCM_CDR (form_idx);
873 }
874 else
875 {
876 sequence = form_idx;
877 form_idx = SCM_EOL;
878 }
879 }
880 else
881 {
882 /* We have detected a form which is no definition. This marks the
883 * start of the sequence of expressions of the body. */
884 sequence = form_idx;
885 form_idx = SCM_EOL;
886 }
887 }
888
889 /* FIXME: forms does not hold information about the file location. */
a61f4e0c 890 ASSERT_SYNTAX (scm_is_pair (sequence), s_missing_body_expression, cdr_forms);
910b5125 891
a61f4e0c 892 if (!scm_is_null (definitions))
910b5125
DH
893 {
894 SCM definition_idx;
895 SCM letrec_tail;
896 SCM letrec_expression;
897 SCM new_letrec_expression;
910b5125
DH
898
899 SCM bindings = SCM_EOL;
900 for (definition_idx = definitions;
a61f4e0c 901 !scm_is_null (definition_idx);
910b5125
DH
902 definition_idx = SCM_CDR (definition_idx))
903 {
904 const SCM definition = SCM_CAR (definition_idx);
905 const SCM canonical_definition = canonicalize_define (definition);
906 const SCM binding = SCM_CDR (canonical_definition);
907 bindings = scm_cons (binding, bindings);
908 };
909
910 letrec_tail = scm_cons (bindings, sequence);
911 /* FIXME: forms does not hold information about the file location. */
912 letrec_expression = scm_cons_source (forms, scm_sym_letrec, letrec_tail);
913 new_letrec_expression = scm_m_letrec (letrec_expression, env);
9d4bf6d3
MV
914 SCM_SETCAR (forms, new_letrec_expression);
915 SCM_SETCDR (forms, SCM_EOL);
910b5125
DH
916 }
917 else
918 {
919 SCM_SETCAR (forms, SCM_CAR (sequence));
920 SCM_SETCDR (forms, SCM_CDR (sequence));
910b5125
DH
921 }
922}
923
3b88ed2a 924SCM_SYNTAX (s_and, "and", scm_i_makbimacro, scm_m_and);
5f236208 925SCM_GLOBAL_SYMBOL (scm_sym_and, "and");
1cc91f1b 926
4d0949ea 927static SCM
e6729603 928scm_m_and (SCM expr, SCM env SCM_UNUSED)
0f2d19dd 929{
e6729603
DH
930 const SCM cdr_expr = SCM_CDR (expr);
931 const long length = scm_ilength (cdr_expr);
932
933 ASSERT_SYNTAX (length >= 0, s_bad_expression, expr);
934
935 if (length == 0)
936 {
937 /* Special case: (and) is replaced by #t. */
938 return SCM_BOOL_T;
939 }
0f2d19dd 940 else
e6729603
DH
941 {
942 SCM_SETCAR (expr, SCM_IM_AND);
943 return expr;
944 }
0f2d19dd
JB
945}
946
212e58ed
DH
947static SCM
948unmemoize_and (const SCM expr, const SCM env)
949{
950 return scm_cons (scm_sym_and, unmemoize_exprs (SCM_CDR (expr), env));
951}
952
1cc91f1b 953
3b88ed2a 954SCM_SYNTAX (s_begin, "begin", scm_i_makbimacro, scm_m_begin);
5f236208 955SCM_GLOBAL_SYMBOL (scm_sym_begin, "begin");
8ea46249 956
4d0949ea 957static SCM
2a6f7afe 958scm_m_begin (SCM expr, SCM env SCM_UNUSED)
0f2d19dd 959{
2a6f7afe 960 const SCM cdr_expr = SCM_CDR (expr);
21628685
DH
961 /* Dirk:FIXME:: An empty begin clause is not generally allowed by R5RS.
962 * That means, there should be a distinction between uses of begin where an
963 * empty clause is OK and where it is not. */
2a6f7afe
DH
964 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
965
966 SCM_SETCAR (expr, SCM_IM_BEGIN);
967 return expr;
0f2d19dd
JB
968}
969
212e58ed
DH
970static SCM
971unmemoize_begin (const SCM expr, const SCM env)
972{
973 return scm_cons (scm_sym_begin, unmemoize_exprs (SCM_CDR (expr), env));
974}
975
0f2d19dd 976
3b88ed2a 977SCM_SYNTAX (s_case, "case", scm_i_makbimacro, scm_m_case);
5f236208 978SCM_GLOBAL_SYMBOL (scm_sym_case, "case");
6f81708a 979SCM_GLOBAL_SYMBOL (scm_sym_else, "else");
1cc91f1b 980
4d0949ea 981static SCM
2a6f7afe 982scm_m_case (SCM expr, SCM env)
0f2d19dd 983{
8ea46249 984 SCM clauses;
2a6f7afe
DH
985 SCM all_labels = SCM_EOL;
986
987 /* Check, whether 'else is a literal, i. e. not bound to a value. */
988 const int else_literal_p = literal_p (scm_sym_else, env);
989
990 const SCM cdr_expr = SCM_CDR (expr);
991 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
992 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 2, s_missing_clauses, expr);
993
994 clauses = SCM_CDR (cdr_expr);
a61f4e0c 995 while (!scm_is_null (clauses))
0f2d19dd 996 {
2a6f7afe
DH
997 SCM labels;
998
999 const SCM clause = SCM_CAR (clauses);
1000 ASSERT_SYNTAX_2 (scm_ilength (clause) >= 2,
1001 s_bad_case_clause, clause, expr);
1002
1003 labels = SCM_CAR (clause);
a61f4e0c 1004 if (scm_is_pair (labels))
2a6f7afe
DH
1005 {
1006 ASSERT_SYNTAX_2 (scm_ilength (labels) >= 0,
1007 s_bad_case_labels, labels, expr);
26ecfa39 1008 all_labels = scm_append (scm_list_2 (labels, all_labels));
2a6f7afe 1009 }
a61f4e0c 1010 else if (scm_is_null (labels))
58a2510b
DH
1011 {
1012 /* The list of labels is empty. According to R5RS this is allowed.
1013 * It means that the sequence of expressions will never be executed.
1014 * Therefore, as an optimization, we could remove the whole
1015 * clause. */
1016 }
2a6f7afe
DH
1017 else
1018 {
bc36d050 1019 ASSERT_SYNTAX_2 (scm_is_eq (labels, scm_sym_else) && else_literal_p,
2a6f7afe 1020 s_bad_case_labels, labels, expr);
a61f4e0c 1021 ASSERT_SYNTAX_2 (scm_is_null (SCM_CDR (clauses)),
609a8b86 1022 s_misplaced_else_clause, clause, expr);
2a6f7afe
DH
1023 }
1024
1025 /* build the new clause */
bc36d050 1026 if (scm_is_eq (labels, scm_sym_else))
2a6f7afe
DH
1027 SCM_SETCAR (clause, SCM_IM_ELSE);
1028
8ea46249 1029 clauses = SCM_CDR (clauses);
0f2d19dd 1030 }
2a6f7afe
DH
1031
1032 /* Check whether all case labels are distinct. */
a61f4e0c 1033 for (; !scm_is_null (all_labels); all_labels = SCM_CDR (all_labels))
2a6f7afe
DH
1034 {
1035 const SCM label = SCM_CAR (all_labels);
7888309b 1036 ASSERT_SYNTAX_2 (scm_is_false (scm_c_memq (label, SCM_CDR (all_labels))),
4610b011 1037 s_duplicate_case_label, label, expr);
2a6f7afe
DH
1038 }
1039
1040 SCM_SETCAR (expr, SCM_IM_CASE);
1041 return expr;
0f2d19dd
JB
1042}
1043
212e58ed
DH
1044static SCM
1045unmemoize_case (const SCM expr, const SCM env)
1046{
1047 const SCM um_key_expr = unmemoize_expression (SCM_CADR (expr), env);
1048 SCM um_clauses = SCM_EOL;
1049 SCM clause_idx;
1050
1051 for (clause_idx = SCM_CDDR (expr);
a61f4e0c 1052 !scm_is_null (clause_idx);
212e58ed
DH
1053 clause_idx = SCM_CDR (clause_idx))
1054 {
1055 const SCM clause = SCM_CAR (clause_idx);
1056 const SCM labels = SCM_CAR (clause);
1057 const SCM exprs = SCM_CDR (clause);
1058
1059 const SCM um_exprs = unmemoize_exprs (exprs, env);
bc36d050 1060 const SCM um_labels = (scm_is_eq (labels, SCM_IM_ELSE))
212e58ed
DH
1061 ? scm_sym_else
1062 : scm_i_finite_list_copy (labels);
1063 const SCM um_clause = scm_cons (um_labels, um_exprs);
1064
1065 um_clauses = scm_cons (um_clause, um_clauses);
1066 }
1067 um_clauses = scm_reverse_x (um_clauses, SCM_UNDEFINED);
1068
1069 return scm_cons2 (scm_sym_case, um_key_expr, um_clauses);
1070}
1071
0f2d19dd 1072
3b88ed2a 1073SCM_SYNTAX (s_cond, "cond", scm_i_makbimacro, scm_m_cond);
5f236208 1074SCM_GLOBAL_SYMBOL (scm_sym_cond, "cond");
609a8b86 1075SCM_GLOBAL_SYMBOL (scm_sym_arrow, "=>");
1cc91f1b 1076
4d0949ea 1077static SCM
609a8b86 1078scm_m_cond (SCM expr, SCM env)
0f2d19dd 1079{
609a8b86
DH
1080 /* Check, whether 'else or '=> is a literal, i. e. not bound to a value. */
1081 const int else_literal_p = literal_p (scm_sym_else, env);
1082 const int arrow_literal_p = literal_p (scm_sym_arrow, env);
1083
1084 const SCM clauses = SCM_CDR (expr);
1085 SCM clause_idx;
1086
1087 ASSERT_SYNTAX (scm_ilength (clauses) >= 0, s_bad_expression, expr);
1088 ASSERT_SYNTAX (scm_ilength (clauses) >= 1, s_missing_clauses, expr);
1089
1090 for (clause_idx = clauses;
a61f4e0c 1091 !scm_is_null (clause_idx);
609a8b86 1092 clause_idx = SCM_CDR (clause_idx))
0f2d19dd 1093 {
609a8b86
DH
1094 SCM test;
1095
1096 const SCM clause = SCM_CAR (clause_idx);
1097 const long length = scm_ilength (clause);
1098 ASSERT_SYNTAX_2 (length >= 1, s_bad_cond_clause, clause, expr);
1099
1100 test = SCM_CAR (clause);
bc36d050 1101 if (scm_is_eq (test, scm_sym_else) && else_literal_p)
0f2d19dd 1102 {
a61f4e0c 1103 const int last_clause_p = scm_is_null (SCM_CDR (clause_idx));
609a8b86
DH
1104 ASSERT_SYNTAX_2 (length >= 2,
1105 s_bad_cond_clause, clause, expr);
1106 ASSERT_SYNTAX_2 (last_clause_p,
1107 s_misplaced_else_clause, clause, expr);
1108 SCM_SETCAR (clause, SCM_IM_ELSE);
0f2d19dd 1109 }
609a8b86 1110 else if (length >= 2
bc36d050 1111 && scm_is_eq (SCM_CADR (clause), scm_sym_arrow)
609a8b86
DH
1112 && arrow_literal_p)
1113 {
1114 ASSERT_SYNTAX_2 (length > 2, s_missing_recipient, clause, expr);
1115 ASSERT_SYNTAX_2 (length == 3, s_extra_expression, clause, expr);
1116 SCM_SETCAR (SCM_CDR (clause), SCM_IM_ARROW);
8ea46249 1117 }
1fe1fc0a
MV
1118 /* SRFI 61 extended cond */
1119 else if (length >= 3
1120 && scm_is_eq (SCM_CADDR (clause), scm_sym_arrow)
1121 && arrow_literal_p)
1122 {
1123 ASSERT_SYNTAX_2 (length > 3, s_missing_recipient, clause, expr);
1124 ASSERT_SYNTAX_2 (length == 4, s_extra_expression, clause, expr);
1125 SCM_SETCAR (SCM_CDDR (clause), SCM_IM_ARROW);
1126 }
0f2d19dd 1127 }
609a8b86
DH
1128
1129 SCM_SETCAR (expr, SCM_IM_COND);
1130 return expr;
0f2d19dd
JB
1131}
1132
212e58ed
DH
1133static SCM
1134unmemoize_cond (const SCM expr, const SCM env)
1135{
1136 SCM um_clauses = SCM_EOL;
1137 SCM clause_idx;
1138
1139 for (clause_idx = SCM_CDR (expr);
a61f4e0c 1140 !scm_is_null (clause_idx);
212e58ed
DH
1141 clause_idx = SCM_CDR (clause_idx))
1142 {
1143 const SCM clause = SCM_CAR (clause_idx);
1144 const SCM sequence = SCM_CDR (clause);
1145 const SCM test = SCM_CAR (clause);
1146 SCM um_test;
1147 SCM um_sequence;
1148 SCM um_clause;
1149
bc36d050 1150 if (scm_is_eq (test, SCM_IM_ELSE))
212e58ed
DH
1151 um_test = scm_sym_else;
1152 else
1153 um_test = unmemoize_expression (test, env);
1154
a61f4e0c 1155 if (!scm_is_null (sequence) && scm_is_eq (SCM_CAR (sequence),
bc36d050 1156 SCM_IM_ARROW))
212e58ed
DH
1157 {
1158 const SCM target = SCM_CADR (sequence);
1159 const SCM um_target = unmemoize_expression (target, env);
1160 um_sequence = scm_list_2 (scm_sym_arrow, um_target);
1161 }
1162 else
1163 {
1164 um_sequence = unmemoize_exprs (sequence, env);
1165 }
1166
1167 um_clause = scm_cons (um_test, um_sequence);
1168 um_clauses = scm_cons (um_clause, um_clauses);
1169 }
1170 um_clauses = scm_reverse_x (um_clauses, SCM_UNDEFINED);
1171
1172 return scm_cons (scm_sym_cond, um_clauses);
1173}
1174
1cc91f1b 1175
0f572ba7 1176SCM_SYNTAX (s_define, "define", scm_i_makbimacro, scm_m_define);
5f236208 1177SCM_GLOBAL_SYMBOL (scm_sym_define, "define");
5280aaca 1178
9fbee57e
DH
1179/* Guile provides an extension to R5RS' define syntax to represent function
1180 * currying in a compact way. With this extension, it is allowed to write
1181 * (define <nested-variable> <body>), where <nested-variable> has of one of
1182 * the forms (<nested-variable> <formals>), (<nested-variable> . <formal>),
1183 * (<variable> <formals>) or (<variable> . <formal>). As in R5RS, <formals>
1184 * should be either a sequence of zero or more variables, or a sequence of one
1185 * or more variables followed by a space-delimited period and another
1186 * variable. Each level of argument nesting wraps the <body> within another
1187 * lambda expression. For example, the following forms are allowed, each one
1188 * followed by an equivalent, more explicit implementation.
1189 * Example 1:
1190 * (define ((a b . c) . d) <body>) is equivalent to
1191 * (define a (lambda (b . c) (lambda d <body>)))
1192 * Example 2:
1193 * (define (((a) b) c . d) <body>) is equivalent to
1194 * (define a (lambda () (lambda (b) (lambda (c . d) <body>))))
1195 */
1196/* Dirk:FIXME:: We should provide an implementation for 'define' in the R5RS
1197 * module that does not implement this extension. */
0f572ba7
DH
1198static SCM
1199canonicalize_define (const SCM expr)
5280aaca 1200{
cc56ba80
DH
1201 SCM body;
1202 SCM variable;
1203
1204 const SCM cdr_expr = SCM_CDR (expr);
c86c440b 1205 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
cc56ba80
DH
1206 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 2, s_missing_expression, expr);
1207
1208 body = SCM_CDR (cdr_expr);
1209 variable = SCM_CAR (cdr_expr);
a61f4e0c 1210 while (scm_is_pair (variable))
5280aaca 1211 {
cc56ba80
DH
1212 /* This while loop realizes function currying by variable nesting.
1213 * Variable is known to be a nested-variable. In every iteration of the
1214 * loop another level of lambda expression is created, starting with the
4610b011
DH
1215 * innermost one. Note that we don't check for duplicate formals here:
1216 * This will be done by the memoizer of the lambda expression. */
cc56ba80
DH
1217 const SCM formals = SCM_CDR (variable);
1218 const SCM tail = scm_cons (formals, body);
1219
1220 /* Add source properties to each new lambda expression: */
1221 const SCM lambda = scm_cons_source (variable, scm_sym_lambda, tail);
1222
1223 body = scm_list_1 (lambda);
1224 variable = SCM_CAR (variable);
5280aaca 1225 }
cc95e00a 1226 ASSERT_SYNTAX_2 (scm_is_symbol (variable), s_bad_variable, variable, expr);
cc56ba80
DH
1227 ASSERT_SYNTAX (scm_ilength (body) == 1, s_expression, expr);
1228
0f572ba7
DH
1229 SCM_SETCAR (cdr_expr, variable);
1230 SCM_SETCDR (cdr_expr, body);
1231 return expr;
1232}
1233
3dcf3373
LC
1234/* According to Section 5.2.1 of R5RS we first have to make sure that the
1235 variable is bound, and then perform the `(set! variable expression)'
1236 operation. However, EXPRESSION _can_ be evaluated before VARIABLE is
1237 bound. This means that EXPRESSION won't necessarily be able to assign
1238 values to VARIABLE as in `(define foo (begin (set! foo 1) (+ foo 1)))'. */
4d0949ea 1239static SCM
0f572ba7
DH
1240scm_m_define (SCM expr, SCM env)
1241{
6bff1368 1242 ASSERT_SYNTAX (SCM_TOP_LEVEL (env), s_bad_define, expr);
0f572ba7 1243
6bff1368
DH
1244 {
1245 const SCM canonical_definition = canonicalize_define (expr);
1246 const SCM cdr_canonical_definition = SCM_CDR (canonical_definition);
1247 const SCM variable = SCM_CAR (cdr_canonical_definition);
3dcf3373 1248 const SCM value = scm_eval_car (SCM_CDR (cdr_canonical_definition), env);
36245b66
DH
1249 const SCM location
1250 = scm_sym2var (variable, scm_env_top_level (env), SCM_BOOL_T);
6bff1368 1251
6bff1368
DH
1252 if (SCM_REC_PROCNAMES_P)
1253 {
1254 SCM tmp = value;
1255 while (SCM_MACROP (tmp))
1256 tmp = SCM_MACRO_CODE (tmp);
23d72566 1257 if (scm_is_true (scm_procedure_p (tmp))
6bff1368 1258 /* Only the first definition determines the name. */
7888309b 1259 && scm_is_false (scm_procedure_property (tmp, scm_sym_name)))
6bff1368
DH
1260 scm_set_procedure_property_x (tmp, scm_sym_name, variable);
1261 }
0f572ba7 1262
36245b66 1263 SCM_VARIABLE_SET (location, value);
6bff1368
DH
1264
1265 return SCM_UNSPECIFIED;
1266 }
0f2d19dd
JB
1267}
1268
1269
8ae95199
DH
1270/* This is a helper function for forms (<keyword> <expression>) that are
1271 * transformed into (#@<keyword> '() <memoized_expression>) in order to allow
1272 * for easy creation of a thunk (i. e. a closure without arguments) using the
1273 * ('() <memoized_expression>) tail of the memoized form. */
1274static SCM
1275memoize_as_thunk_prototype (const SCM expr, const SCM env SCM_UNUSED)
1276{
1277 const SCM cdr_expr = SCM_CDR (expr);
1278 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
1279 ASSERT_SYNTAX (scm_ilength (cdr_expr) == 1, s_expression, expr);
1280
1281 SCM_SETCDR (expr, scm_cons (SCM_EOL, cdr_expr));
1282
1283 return expr;
1284}
1285
1286
3b88ed2a 1287SCM_SYNTAX (s_delay, "delay", scm_i_makbimacro, scm_m_delay);
5f236208 1288SCM_GLOBAL_SYMBOL (scm_sym_delay, "delay");
1cc91f1b 1289
9fbee57e
DH
1290/* Promises are implemented as closures with an empty parameter list. Thus,
1291 * (delay <expression>) is transformed into (#@delay '() <expression>), where
1292 * the empty list represents the empty parameter list. This representation
1293 * allows for easy creation of the closure during evaluation. */
4d0949ea 1294static SCM
8ae95199 1295scm_m_delay (SCM expr, SCM env)
0f2d19dd 1296{
8ae95199
DH
1297 const SCM new_expr = memoize_as_thunk_prototype (expr, env);
1298 SCM_SETCAR (new_expr, SCM_IM_DELAY);
1299 return new_expr;
0f2d19dd
JB
1300}
1301
212e58ed
DH
1302static SCM
1303unmemoize_delay (const SCM expr, const SCM env)
1304{
1305 const SCM thunk_expr = SCM_CADDR (expr);
acbfb594
NJ
1306 /* A promise is implemented as a closure, and when applying a
1307 closure the evaluator adds a new frame to the environment - even
1308 though, in the case of a promise, the added frame is always
1309 empty. We need to extend the environment here in the same way,
1310 so that any ILOCs in thunk_expr can be unmemoized correctly. */
1311 const SCM new_env = SCM_EXTEND_ENV (SCM_EOL, SCM_EOL, env);
1312 return scm_list_2 (scm_sym_delay, unmemoize_expression (thunk_expr, new_env));
212e58ed
DH
1313}
1314
8ea46249 1315
a954ce1d 1316SCM_SYNTAX(s_do, "do", scm_i_makbimacro, scm_m_do);
5f236208 1317SCM_GLOBAL_SYMBOL(scm_sym_do, "do");
a954ce1d 1318
302c12b4 1319/* DO gets the most radically altered syntax. The order of the vars is
4610b011
DH
1320 * reversed here. During the evaluation this allows for simple consing of the
1321 * results of the inits and steps:
302c12b4 1322
0f2d19dd 1323 (do ((<var1> <init1> <step1>)
a954ce1d
DH
1324 (<var2> <init2>)
1325 ... )
1326 (<test> <return>)
1327 <body>)
302c12b4 1328
0f2d19dd 1329 ;; becomes
302c12b4 1330
e681d187 1331 (#@do (<init1> <init2> ... <initn>)
a954ce1d
DH
1332 (varn ... var2 var1)
1333 (<test> <return>)
1334 (<body>)
1335 <step1> <step2> ... <stepn>) ;; missing steps replaced by var
302c12b4 1336 */
4d0949ea 1337static SCM
a954ce1d 1338scm_m_do (SCM expr, SCM env SCM_UNUSED)
0f2d19dd 1339{
a954ce1d
DH
1340 SCM variables = SCM_EOL;
1341 SCM init_forms = SCM_EOL;
1342 SCM step_forms = SCM_EOL;
1343 SCM binding_idx;
1344 SCM cddr_expr;
1345 SCM exit_clause;
1346 SCM commands;
1347 SCM tail;
1348
1349 const SCM cdr_expr = SCM_CDR (expr);
1350 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
1351 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 2, s_missing_expression, expr);
1352
1353 /* Collect variables, init and step forms. */
1354 binding_idx = SCM_CAR (cdr_expr);
1355 ASSERT_SYNTAX_2 (scm_ilength (binding_idx) >= 0,
1356 s_bad_bindings, binding_idx, expr);
a61f4e0c 1357 for (; !scm_is_null (binding_idx); binding_idx = SCM_CDR (binding_idx))
0f2d19dd 1358 {
a954ce1d
DH
1359 const SCM binding = SCM_CAR (binding_idx);
1360 const long length = scm_ilength (binding);
1361 ASSERT_SYNTAX_2 (length == 2 || length == 3,
1362 s_bad_binding, binding, expr);
1363
302c12b4 1364 {
a954ce1d
DH
1365 const SCM name = SCM_CAR (binding);
1366 const SCM init = SCM_CADR (binding);
1367 const SCM step = (length == 2) ? name : SCM_CADDR (binding);
cc95e00a 1368 ASSERT_SYNTAX_2 (scm_is_symbol (name), s_bad_variable, name, expr);
7888309b 1369 ASSERT_SYNTAX_2 (scm_is_false (scm_c_memq (name, variables)),
4610b011
DH
1370 s_duplicate_binding, name, expr);
1371
a954ce1d
DH
1372 variables = scm_cons (name, variables);
1373 init_forms = scm_cons (init, init_forms);
1374 step_forms = scm_cons (step, step_forms);
302c12b4 1375 }
0f2d19dd 1376 }
a954ce1d
DH
1377 init_forms = scm_reverse_x (init_forms, SCM_UNDEFINED);
1378 step_forms = scm_reverse_x (step_forms, SCM_UNDEFINED);
1379
1380 /* Memoize the test form and the exit sequence. */
1381 cddr_expr = SCM_CDR (cdr_expr);
1382 exit_clause = SCM_CAR (cddr_expr);
1383 ASSERT_SYNTAX_2 (scm_ilength (exit_clause) >= 1,
1384 s_bad_exit_clause, exit_clause, expr);
1385
1386 commands = SCM_CDR (cddr_expr);
1387 tail = scm_cons2 (exit_clause, commands, step_forms);
1388 tail = scm_cons2 (init_forms, variables, tail);
1389 SCM_SETCAR (expr, SCM_IM_DO);
1390 SCM_SETCDR (expr, tail);
1391 return expr;
0f2d19dd
JB
1392}
1393
212e58ed
DH
1394static SCM
1395unmemoize_do (const SCM expr, const SCM env)
1396{
1397 const SCM cdr_expr = SCM_CDR (expr);
1398 const SCM cddr_expr = SCM_CDR (cdr_expr);
1399 const SCM rnames = SCM_CAR (cddr_expr);
1400 const SCM extended_env = SCM_EXTEND_ENV (rnames, SCM_EOL, env);
1401 const SCM cdddr_expr = SCM_CDR (cddr_expr);
1402 const SCM exit_sequence = SCM_CAR (cdddr_expr);
1403 const SCM um_exit_sequence = unmemoize_exprs (exit_sequence, extended_env);
1404 const SCM cddddr_expr = SCM_CDR (cdddr_expr);
1405 const SCM um_body = unmemoize_exprs (SCM_CAR (cddddr_expr), extended_env);
1406
1407 /* build transformed binding list */
1408 SCM um_names = scm_reverse (rnames);
1409 SCM um_inits = unmemoize_exprs (SCM_CAR (cdr_expr), env);
1410 SCM um_steps = unmemoize_exprs (SCM_CDR (cddddr_expr), extended_env);
1411 SCM um_bindings = SCM_EOL;
a61f4e0c 1412 while (!scm_is_null (um_names))
212e58ed
DH
1413 {
1414 const SCM name = SCM_CAR (um_names);
1415 const SCM init = SCM_CAR (um_inits);
1416 SCM step = SCM_CAR (um_steps);
bc36d050 1417 step = scm_is_eq (step, name) ? SCM_EOL : scm_list_1 (step);
212e58ed
DH
1418
1419 um_bindings = scm_cons (scm_cons2 (name, init, step), um_bindings);
1420
1421 um_names = SCM_CDR (um_names);
1422 um_inits = SCM_CDR (um_inits);
1423 um_steps = SCM_CDR (um_steps);
1424 }
1425 um_bindings = scm_reverse_x (um_bindings, SCM_UNDEFINED);
1426
1427 return scm_cons (scm_sym_do,
1428 scm_cons2 (um_bindings, um_exit_sequence, um_body));
1429}
1430
b8229a3b 1431
3b88ed2a 1432SCM_SYNTAX (s_if, "if", scm_i_makbimacro, scm_m_if);
5f236208 1433SCM_GLOBAL_SYMBOL (scm_sym_if, "if");
b8229a3b 1434
4d0949ea 1435static SCM
4610b011 1436scm_m_if (SCM expr, SCM env SCM_UNUSED)
0f2d19dd 1437{
4610b011
DH
1438 const SCM cdr_expr = SCM_CDR (expr);
1439 const long length = scm_ilength (cdr_expr);
1440 ASSERT_SYNTAX (length == 2 || length == 3, s_expression, expr);
1441 SCM_SETCAR (expr, SCM_IM_IF);
1442 return expr;
0f2d19dd
JB
1443}
1444
212e58ed
DH
1445static SCM
1446unmemoize_if (const SCM expr, const SCM env)
1447{
1448 const SCM cdr_expr = SCM_CDR (expr);
1449 const SCM um_condition = unmemoize_expression (SCM_CAR (cdr_expr), env);
1450 const SCM cddr_expr = SCM_CDR (cdr_expr);
1451 const SCM um_then = unmemoize_expression (SCM_CAR (cddr_expr), env);
1452 const SCM cdddr_expr = SCM_CDR (cddr_expr);
1453
a61f4e0c 1454 if (scm_is_null (cdddr_expr))
212e58ed
DH
1455 {
1456 return scm_list_3 (scm_sym_if, um_condition, um_then);
1457 }
1458 else
1459 {
1460 const SCM um_else = unmemoize_expression (SCM_CAR (cdddr_expr), env);
1461 return scm_list_4 (scm_sym_if, um_condition, um_then, um_else);
1462 }
1463}
1464
302c12b4 1465
3b88ed2a 1466SCM_SYNTAX (s_lambda, "lambda", scm_i_makbimacro, scm_m_lambda);
5f236208 1467SCM_GLOBAL_SYMBOL (scm_sym_lambda, "lambda");
0f2d19dd 1468
4610b011
DH
1469/* A helper function for memoize_lambda to support checking for duplicate
1470 * formal arguments: Return true if OBJ is `eq?' to one of the elements of
1471 * LIST or to the cdr of the last cons. Therefore, LIST may have any of the
1472 * forms that a formal argument can have:
1473 * <rest>, (<arg1> ...), (<arg1> ... . <rest>) */
9fbee57e 1474static int
4610b011 1475c_improper_memq (SCM obj, SCM list)
5cb22e96 1476{
a61f4e0c 1477 for (; scm_is_pair (list); list = SCM_CDR (list))
9fbee57e 1478 {
bc36d050 1479 if (scm_is_eq (SCM_CAR (list), obj))
4610b011 1480 return 1;
9fbee57e 1481 }
bc36d050 1482 return scm_is_eq (list, obj);
5cb22e96
DH
1483}
1484
4d0949ea 1485static SCM
03a3e941 1486scm_m_lambda (SCM expr, SCM env SCM_UNUSED)
28d52ebb 1487{
9fbee57e 1488 SCM formals;
03a3e941 1489 SCM formals_idx;
34adf7ea
DH
1490 SCM cddr_expr;
1491 int documentation;
1492 SCM body;
1493 SCM new_body;
03a3e941
DH
1494
1495 const SCM cdr_expr = SCM_CDR (expr);
1496 const long length = scm_ilength (cdr_expr);
1497 ASSERT_SYNTAX (length >= 0, s_bad_expression, expr);
1498 ASSERT_SYNTAX (length >= 2, s_missing_expression, expr);
28d52ebb 1499
03a3e941
DH
1500 /* Before iterating the list of formal arguments, make sure the formals
1501 * actually are given as either a symbol or a non-cyclic list. */
1502 formals = SCM_CAR (cdr_expr);
a61f4e0c 1503 if (scm_is_pair (formals))
03a3e941
DH
1504 {
1505 /* Dirk:FIXME:: We should check for a cyclic list of formals, and if
1506 * detected, report a 'Bad formals' error. */
1507 }
1508 else
1509 {
a61f4e0c 1510 ASSERT_SYNTAX_2 (scm_is_symbol (formals) || scm_is_null (formals),
03a3e941
DH
1511 s_bad_formals, formals, expr);
1512 }
1cc91f1b 1513
03a3e941
DH
1514 /* Now iterate the list of formal arguments to check if all formals are
1515 * symbols, and that there are no duplicates. */
1516 formals_idx = formals;
a61f4e0c 1517 while (scm_is_pair (formals_idx))
0f2d19dd 1518 {
03a3e941
DH
1519 const SCM formal = SCM_CAR (formals_idx);
1520 const SCM next_idx = SCM_CDR (formals_idx);
cc95e00a 1521 ASSERT_SYNTAX_2 (scm_is_symbol (formal), s_bad_formal, formal, expr);
03a3e941
DH
1522 ASSERT_SYNTAX_2 (!c_improper_memq (formal, next_idx),
1523 s_duplicate_formal, formal, expr);
1524 formals_idx = next_idx;
0f2d19dd 1525 }
a61f4e0c 1526 ASSERT_SYNTAX_2 (scm_is_null (formals_idx) || scm_is_symbol (formals_idx),
03a3e941 1527 s_bad_formal, formals_idx, expr);
9fbee57e 1528
34adf7ea
DH
1529 /* Memoize the body. Keep a potential documentation string. */
1530 /* Dirk:FIXME:: We should probably extract the documentation string to
1531 * some external database. Otherwise it will slow down execution, since
1532 * the documentation string will have to be skipped with every execution
1533 * of the closure. */
1534 cddr_expr = SCM_CDR (cdr_expr);
7f9994d9 1535 documentation = (length >= 3 && scm_is_string (SCM_CAR (cddr_expr)));
34adf7ea 1536 body = documentation ? SCM_CDR (cddr_expr) : cddr_expr;
430b8401 1537 new_body = m_body (SCM_IM_LAMBDA, body);
34adf7ea
DH
1538
1539 SCM_SETCAR (expr, SCM_IM_LAMBDA);
1540 if (documentation)
1541 SCM_SETCDR (cddr_expr, new_body);
1542 else
1543 SCM_SETCDR (cdr_expr, new_body);
1544 return expr;
0f2d19dd 1545}
6dbd0af5 1546
212e58ed
DH
1547static SCM
1548unmemoize_lambda (const SCM expr, const SCM env)
1549{
1550 const SCM formals = SCM_CADR (expr);
1551 const SCM body = SCM_CDDR (expr);
1552
1553 const SCM new_env = SCM_EXTEND_ENV (formals, SCM_EOL, env);
1554 const SCM um_formals = scm_i_finite_list_copy (formals);
1555 const SCM um_body = unmemoize_exprs (body, new_env);
1556
1557 return scm_cons2 (scm_sym_lambda, um_formals, um_body);
1558}
1559
0f2d19dd 1560
d6754c23 1561/* Check if the format of the bindings is ((<symbol> <init-form>) ...). */
302c12b4 1562static void
d6754c23 1563check_bindings (const SCM bindings, const SCM expr)
0f2d19dd 1564{
d6754c23 1565 SCM binding_idx;
302c12b4 1566
d6754c23
DH
1567 ASSERT_SYNTAX_2 (scm_ilength (bindings) >= 0,
1568 s_bad_bindings, bindings, expr);
0f2d19dd 1569
d6754c23 1570 binding_idx = bindings;
a61f4e0c 1571 for (; !scm_is_null (binding_idx); binding_idx = SCM_CDR (binding_idx))
0f2d19dd 1572 {
d6754c23
DH
1573 SCM name; /* const */
1574
1575 const SCM binding = SCM_CAR (binding_idx);
1576 ASSERT_SYNTAX_2 (scm_ilength (binding) == 2,
1577 s_bad_binding, binding, expr);
1578
1579 name = SCM_CAR (binding);
cc95e00a 1580 ASSERT_SYNTAX_2 (scm_is_symbol (name), s_bad_variable, name, expr);
0f2d19dd 1581 }
d6754c23 1582}
26d5b9b4 1583
d6754c23
DH
1584
1585/* The bindings, which must have the format ((v1 i1) (v2 i2) ... (vn in)), are
1586 * transformed to the lists (vn ... v2 v1) and (i1 i2 ... in). That is, the
1587 * variables are returned in a list with their order reversed, and the init
1588 * forms are returned in a list in the same order as they are given in the
1589 * bindings. If a duplicate variable name is detected, an error is
1590 * signalled. */
1591static void
1592transform_bindings (
1593 const SCM bindings, const SCM expr,
1594 SCM *const rvarptr, SCM *const initptr )
1595{
1596 SCM rvariables = SCM_EOL;
1597 SCM rinits = SCM_EOL;
1598 SCM binding_idx = bindings;
a61f4e0c 1599 for (; !scm_is_null (binding_idx); binding_idx = SCM_CDR (binding_idx))
d6754c23
DH
1600 {
1601 const SCM binding = SCM_CAR (binding_idx);
1602 const SCM cdr_binding = SCM_CDR (binding);
1603 const SCM name = SCM_CAR (binding);
7888309b 1604 ASSERT_SYNTAX_2 (scm_is_false (scm_c_memq (name, rvariables)),
d6754c23
DH
1605 s_duplicate_binding, name, expr);
1606 rvariables = scm_cons (name, rvariables);
1607 rinits = scm_cons (SCM_CAR (cdr_binding), rinits);
1608 }
1609 *rvarptr = rvariables;
1610 *initptr = scm_reverse_x (rinits, SCM_UNDEFINED);
0f2d19dd
JB
1611}
1612
302c12b4 1613
3b88ed2a 1614SCM_SYNTAX(s_let, "let", scm_i_makbimacro, scm_m_let);
5f236208 1615SCM_GLOBAL_SYMBOL(scm_sym_let, "let");
b8229a3b 1616
d6754c23
DH
1617/* This function is a helper function for memoize_let. It transforms
1618 * (let name ((var init) ...) body ...) into
1619 * ((letrec ((name (lambda (var ...) body ...))) name) init ...)
1620 * and memoizes the expression. It is assumed that the caller has checked
1621 * that name is a symbol and that there are bindings and a body. */
1622static SCM
1623memoize_named_let (const SCM expr, const SCM env SCM_UNUSED)
1624{
1625 SCM rvariables;
1626 SCM variables;
1627 SCM inits;
1628
1629 const SCM cdr_expr = SCM_CDR (expr);
1630 const SCM name = SCM_CAR (cdr_expr);
1631 const SCM cddr_expr = SCM_CDR (cdr_expr);
1632 const SCM bindings = SCM_CAR (cddr_expr);
1633 check_bindings (bindings, expr);
1634
1635 transform_bindings (bindings, expr, &rvariables, &inits);
1636 variables = scm_reverse_x (rvariables, SCM_UNDEFINED);
1637
1638 {
1639 const SCM let_body = SCM_CDR (cddr_expr);
430b8401 1640 const SCM lambda_body = m_body (SCM_IM_LET, let_body);
d6754c23
DH
1641 const SCM lambda_tail = scm_cons (variables, lambda_body);
1642 const SCM lambda_form = scm_cons_source (expr, scm_sym_lambda, lambda_tail);
1643
1644 const SCM rvar = scm_list_1 (name);
1645 const SCM init = scm_list_1 (lambda_form);
430b8401 1646 const SCM body = m_body (SCM_IM_LET, scm_list_1 (name));
d6754c23
DH
1647 const SCM letrec_tail = scm_cons (rvar, scm_cons (init, body));
1648 const SCM letrec_form = scm_cons_source (expr, SCM_IM_LETREC, letrec_tail);
1649 return scm_cons_source (expr, letrec_form, inits);
1650 }
1651}
1652
1653/* (let ((v1 i1) (v2 i2) ...) body) with variables v1 .. vn and initializers
1654 * i1 .. in is transformed to (#@let (vn ... v2 v1) (i1 i2 ...) body). */
4d0949ea 1655static SCM
d6754c23 1656scm_m_let (SCM expr, SCM env)
0f2d19dd 1657{
d6754c23
DH
1658 SCM bindings;
1659
1660 const SCM cdr_expr = SCM_CDR (expr);
1661 const long length = scm_ilength (cdr_expr);
1662 ASSERT_SYNTAX (length >= 0, s_bad_expression, expr);
1663 ASSERT_SYNTAX (length >= 2, s_missing_expression, expr);
302c12b4 1664
d6754c23 1665 bindings = SCM_CAR (cdr_expr);
cc95e00a 1666 if (scm_is_symbol (bindings))
26d5b9b4 1667 {
d6754c23
DH
1668 ASSERT_SYNTAX (length >= 3, s_missing_expression, expr);
1669 return memoize_named_let (expr, env);
26d5b9b4 1670 }
d6754c23
DH
1671
1672 check_bindings (bindings, expr);
a61f4e0c 1673 if (scm_is_null (bindings) || scm_is_null (SCM_CDR (bindings)))
26d5b9b4 1674 {
d6754c23 1675 /* Special case: no bindings or single binding => let* is faster. */
430b8401 1676 const SCM body = m_body (SCM_IM_LET, SCM_CDR (cdr_expr));
d6754c23 1677 return scm_m_letstar (scm_cons2 (SCM_CAR (expr), bindings, body), env);
26d5b9b4 1678 }
302c12b4
DH
1679 else
1680 {
d6754c23
DH
1681 /* plain let */
1682 SCM rvariables;
1683 SCM inits;
1684 transform_bindings (bindings, expr, &rvariables, &inits);
26d5b9b4 1685
302c12b4 1686 {
430b8401 1687 const SCM new_body = m_body (SCM_IM_LET, SCM_CDR (cdr_expr));
d6754c23
DH
1688 const SCM new_tail = scm_cons2 (rvariables, inits, new_body);
1689 SCM_SETCAR (expr, SCM_IM_LET);
1690 SCM_SETCDR (expr, new_tail);
1691 return expr;
302c12b4
DH
1692 }
1693 }
0f2d19dd
JB
1694}
1695
212e58ed
DH
1696static SCM
1697build_binding_list (SCM rnames, SCM rinits)
1698{
1699 SCM bindings = SCM_EOL;
a61f4e0c 1700 while (!scm_is_null (rnames))
212e58ed
DH
1701 {
1702 const SCM binding = scm_list_2 (SCM_CAR (rnames), SCM_CAR (rinits));
1703 bindings = scm_cons (binding, bindings);
1704 rnames = SCM_CDR (rnames);
1705 rinits = SCM_CDR (rinits);
1706 }
1707 return bindings;
1708}
1709
1710static SCM
1711unmemoize_let (const SCM expr, const SCM env)
1712{
1713 const SCM cdr_expr = SCM_CDR (expr);
1714 const SCM um_rnames = SCM_CAR (cdr_expr);
1715 const SCM extended_env = SCM_EXTEND_ENV (um_rnames, SCM_EOL, env);
1716 const SCM cddr_expr = SCM_CDR (cdr_expr);
1717 const SCM um_inits = unmemoize_exprs (SCM_CAR (cddr_expr), env);
1718 const SCM um_rinits = scm_reverse_x (um_inits, SCM_UNDEFINED);
1719 const SCM um_bindings = build_binding_list (um_rnames, um_rinits);
1720 const SCM um_body = unmemoize_exprs (SCM_CDR (cddr_expr), extended_env);
1721
1722 return scm_cons2 (scm_sym_let, um_bindings, um_body);
1723}
1724
1725
1726SCM_SYNTAX(s_letrec, "letrec", scm_i_makbimacro, scm_m_letrec);
5f236208 1727SCM_GLOBAL_SYMBOL(scm_sym_letrec, "letrec");
212e58ed 1728
4d0949ea 1729static SCM
212e58ed
DH
1730scm_m_letrec (SCM expr, SCM env)
1731{
1732 SCM bindings;
1733
1734 const SCM cdr_expr = SCM_CDR (expr);
1735 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
1736 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 2, s_missing_expression, expr);
1737
1738 bindings = SCM_CAR (cdr_expr);
a61f4e0c 1739 if (scm_is_null (bindings))
212e58ed
DH
1740 {
1741 /* no bindings, let* is executed faster */
1742 SCM body = m_body (SCM_IM_LETREC, SCM_CDR (cdr_expr));
1743 return scm_m_letstar (scm_cons2 (SCM_CAR (expr), SCM_EOL, body), env);
1744 }
1745 else
1746 {
1747 SCM rvariables;
1748 SCM inits;
1749 SCM new_body;
1750
1751 check_bindings (bindings, expr);
1752 transform_bindings (bindings, expr, &rvariables, &inits);
1753 new_body = m_body (SCM_IM_LETREC, SCM_CDR (cdr_expr));
1754 return scm_cons2 (SCM_IM_LETREC, rvariables, scm_cons (inits, new_body));
1755 }
1756}
1757
1758static SCM
1759unmemoize_letrec (const SCM expr, const SCM env)
1760{
1761 const SCM cdr_expr = SCM_CDR (expr);
1762 const SCM um_rnames = SCM_CAR (cdr_expr);
1763 const SCM extended_env = SCM_EXTEND_ENV (um_rnames, SCM_EOL, env);
1764 const SCM cddr_expr = SCM_CDR (cdr_expr);
1765 const SCM um_inits = unmemoize_exprs (SCM_CAR (cddr_expr), extended_env);
1766 const SCM um_rinits = scm_reverse_x (um_inits, SCM_UNDEFINED);
1767 const SCM um_bindings = build_binding_list (um_rnames, um_rinits);
1768 const SCM um_body = unmemoize_exprs (SCM_CDR (cddr_expr), extended_env);
1769
1770 return scm_cons2 (scm_sym_letrec, um_bindings, um_body);
1771}
1772
1773
0f2d19dd 1774
3b88ed2a 1775SCM_SYNTAX (s_letstar, "let*", scm_i_makbimacro, scm_m_letstar);
5f236208 1776SCM_GLOBAL_SYMBOL (scm_sym_letstar, "let*");
1cc91f1b 1777
d6754c23
DH
1778/* (let* ((v1 i1) (v2 i2) ...) body) with variables v1 .. vn and initializers
1779 * i1 .. in is transformed into the form (#@let* (v1 i1 v2 i2 ...) body). */
4d0949ea 1780static SCM
d6754c23 1781scm_m_letstar (SCM expr, SCM env SCM_UNUSED)
0f2d19dd 1782{
d6754c23 1783 SCM binding_idx;
d6754c23 1784 SCM new_body;
0f2d19dd 1785
d6754c23
DH
1786 const SCM cdr_expr = SCM_CDR (expr);
1787 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
1788 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 2, s_missing_expression, expr);
9fbee57e 1789
d6754c23
DH
1790 binding_idx = SCM_CAR (cdr_expr);
1791 check_bindings (binding_idx, expr);
1792
461bffb1
DH
1793 /* Transform ((v1 i1) (v2 i2) ...) into (v1 i1 v2 i2 ...). The
1794 * transformation is done in place. At the beginning of one iteration of
1795 * the loop the variable binding_idx holds the form
1796 * P1:( (vn . P2:(in . ())) . P3:( (vn+1 in+1) ... ) ),
1797 * where P1, P2 and P3 indicate the pairs, that are relevant for the
1798 * transformation. P1 and P2 are modified in the loop, P3 remains
1799 * untouched. After the execution of the loop, P1 will hold
1800 * P1:( vn . P2:(in . P3:( (vn+1 in+1) ... )) )
1801 * and binding_idx will hold P3. */
a61f4e0c 1802 while (!scm_is_null (binding_idx))
9fbee57e 1803 {
461bffb1 1804 const SCM cdr_binding_idx = SCM_CDR (binding_idx); /* remember P3 */
d6754c23
DH
1805 const SCM binding = SCM_CAR (binding_idx);
1806 const SCM name = SCM_CAR (binding);
461bffb1
DH
1807 const SCM cdr_binding = SCM_CDR (binding);
1808
1809 SCM_SETCDR (cdr_binding, cdr_binding_idx); /* update P2 */
1810 SCM_SETCAR (binding_idx, name); /* update P1 */
1811 SCM_SETCDR (binding_idx, cdr_binding); /* update P1 */
1812
1813 binding_idx = cdr_binding_idx; /* continue with P3 */
9fbee57e
DH
1814 }
1815
430b8401 1816 new_body = m_body (SCM_IM_LETSTAR, SCM_CDR (cdr_expr));
461bffb1
DH
1817 SCM_SETCAR (expr, SCM_IM_LETSTAR);
1818 /* the bindings have been changed in place */
1819 SCM_SETCDR (cdr_expr, new_body);
1820 return expr;
9fbee57e 1821}
b8229a3b 1822
212e58ed
DH
1823static SCM
1824unmemoize_letstar (const SCM expr, const SCM env)
0f2d19dd 1825{
d6754c23 1826 const SCM cdr_expr = SCM_CDR (expr);
212e58ed
DH
1827 const SCM body = SCM_CDR (cdr_expr);
1828 SCM bindings = SCM_CAR (cdr_expr);
1829 SCM um_bindings = SCM_EOL;
1830 SCM extended_env = env;
1831 SCM um_body;
d6754c23 1832
a61f4e0c 1833 while (!scm_is_null (bindings))
9fbee57e 1834 {
212e58ed
DH
1835 const SCM variable = SCM_CAR (bindings);
1836 const SCM init = SCM_CADR (bindings);
1837 const SCM um_init = unmemoize_expression (init, extended_env);
1838 um_bindings = scm_cons (scm_list_2 (variable, um_init), um_bindings);
1839 extended_env = SCM_EXTEND_ENV (variable, SCM_BOOL_F, extended_env);
1840 bindings = SCM_CDDR (bindings);
9fbee57e 1841 }
212e58ed 1842 um_bindings = scm_reverse_x (um_bindings, SCM_UNDEFINED);
d6754c23 1843
212e58ed
DH
1844 um_body = unmemoize_exprs (body, extended_env);
1845
1846 return scm_cons2 (scm_sym_letstar, um_bindings, um_body);
0f2d19dd
JB
1847}
1848
73b64342 1849
3b88ed2a 1850SCM_SYNTAX (s_or, "or", scm_i_makbimacro, scm_m_or);
5f236208 1851SCM_GLOBAL_SYMBOL (scm_sym_or, "or");
73b64342 1852
4d0949ea 1853static SCM
21628685 1854scm_m_or (SCM expr, SCM env SCM_UNUSED)
73b64342 1855{
21628685
DH
1856 const SCM cdr_expr = SCM_CDR (expr);
1857 const long length = scm_ilength (cdr_expr);
1858
1859 ASSERT_SYNTAX (length >= 0, s_bad_expression, expr);
1860
1861 if (length == 0)
1862 {
1863 /* Special case: (or) is replaced by #f. */
1864 return SCM_BOOL_F;
1865 }
9fbee57e 1866 else
21628685
DH
1867 {
1868 SCM_SETCAR (expr, SCM_IM_OR);
1869 return expr;
1870 }
73b64342
MD
1871}
1872
212e58ed
DH
1873static SCM
1874unmemoize_or (const SCM expr, const SCM env)
1875{
1876 return scm_cons (scm_sym_or, unmemoize_exprs (SCM_CDR (expr), env));
1877}
1878
73b64342 1879
9fbee57e 1880SCM_SYNTAX (s_quasiquote, "quasiquote", scm_makacro, scm_m_quasiquote);
5f236208 1881SCM_GLOBAL_SYMBOL (scm_sym_quasiquote, "quasiquote");
6f81708a
DH
1882SCM_GLOBAL_SYMBOL (scm_sym_unquote, "unquote");
1883SCM_GLOBAL_SYMBOL (scm_sym_uq_splicing, "unquote-splicing");
9fbee57e
DH
1884
1885/* Internal function to handle a quasiquotation: 'form' is the parameter in
1886 * the call (quasiquotation form), 'env' is the environment where unquoted
1887 * expressions will be evaluated, and 'depth' is the current quasiquotation
1888 * nesting level and is known to be greater than zero. */
1889static SCM
1890iqq (SCM form, SCM env, unsigned long int depth)
73b64342 1891{
a61f4e0c 1892 if (scm_is_pair (form))
c96d76b8 1893 {
21628685 1894 const SCM tmp = SCM_CAR (form);
bc36d050 1895 if (scm_is_eq (tmp, scm_sym_quasiquote))
9fbee57e 1896 {
21628685
DH
1897 const SCM args = SCM_CDR (form);
1898 ASSERT_SYNTAX (scm_ilength (args) == 1, s_expression, form);
9fbee57e
DH
1899 return scm_list_2 (tmp, iqq (SCM_CAR (args), env, depth + 1));
1900 }
bc36d050 1901 else if (scm_is_eq (tmp, scm_sym_unquote))
9fbee57e 1902 {
21628685
DH
1903 const SCM args = SCM_CDR (form);
1904 ASSERT_SYNTAX (scm_ilength (args) == 1, s_expression, form);
9fbee57e
DH
1905 if (depth - 1 == 0)
1906 return scm_eval_car (args, env);
1907 else
1908 return scm_list_2 (tmp, iqq (SCM_CAR (args), env, depth - 1));
1909 }
a61f4e0c 1910 else if (scm_is_pair (tmp)
bc36d050 1911 && scm_is_eq (SCM_CAR (tmp), scm_sym_uq_splicing))
9fbee57e 1912 {
21628685
DH
1913 const SCM args = SCM_CDR (tmp);
1914 ASSERT_SYNTAX (scm_ilength (args) == 1, s_expression, form);
9fbee57e
DH
1915 if (depth - 1 == 0)
1916 {
21628685
DH
1917 const SCM list = scm_eval_car (args, env);
1918 const SCM rest = SCM_CDR (form);
1919 ASSERT_SYNTAX_2 (scm_ilength (list) >= 0,
1920 s_splicing, list, form);
9fbee57e
DH
1921 return scm_append (scm_list_2 (list, iqq (rest, env, depth)));
1922 }
1923 else
1924 return scm_cons (iqq (SCM_CAR (form), env, depth - 1),
1925 iqq (SCM_CDR (form), env, depth));
1926 }
1927 else
1928 return scm_cons (iqq (SCM_CAR (form), env, depth),
1929 iqq (SCM_CDR (form), env, depth));
1930 }
4057a3e0
MV
1931 else if (scm_is_vector (form))
1932 return scm_vector (iqq (scm_vector_to_list (form), env, depth));
9fbee57e
DH
1933 else
1934 return form;
1935}
1936
4d0949ea 1937static SCM
21628685 1938scm_m_quasiquote (SCM expr, SCM env)
9fbee57e 1939{
21628685
DH
1940 const SCM cdr_expr = SCM_CDR (expr);
1941 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
1942 ASSERT_SYNTAX (scm_ilength (cdr_expr) == 1, s_expression, expr);
1943 return iqq (SCM_CAR (cdr_expr), env, 1);
9fbee57e
DH
1944}
1945
1946
3b88ed2a 1947SCM_SYNTAX (s_quote, "quote", scm_i_makbimacro, scm_m_quote);
5f236208 1948SCM_GLOBAL_SYMBOL (scm_sym_quote, "quote");
9fbee57e 1949
4d0949ea 1950static SCM
21628685 1951scm_m_quote (SCM expr, SCM env SCM_UNUSED)
9fbee57e 1952{
21628685
DH
1953 SCM quotee;
1954
1955 const SCM cdr_expr = SCM_CDR (expr);
1956 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
1957 ASSERT_SYNTAX (scm_ilength (cdr_expr) == 1, s_expression, expr);
1958 quotee = SCM_CAR (cdr_expr);
5fb64383 1959 if (is_self_quoting_p (quotee))
21628685 1960 return quotee;
e7313a9d 1961
21628685 1962 SCM_SETCAR (expr, SCM_IM_QUOTE);
e7313a9d 1963 SCM_SETCDR (expr, quotee);
21628685 1964 return expr;
9fbee57e
DH
1965}
1966
e7313a9d
DH
1967static SCM
1968unmemoize_quote (const SCM expr, const SCM env SCM_UNUSED)
1969{
1970 return scm_list_2 (scm_sym_quote, SCM_CDR (expr));
1971}
1972
9fbee57e
DH
1973
1974/* Will go into the RnRS module when Guile is factorized.
3b88ed2a 1975SCM_SYNTAX (s_set_x, "set!", scm_i_makbimacro, scm_m_set_x); */
5f236208 1976SCM_GLOBAL_SYMBOL (scm_sym_set_x, "set!");
9fbee57e 1977
4d0949ea 1978static SCM
82b3e2c6 1979scm_m_set_x (SCM expr, SCM env SCM_UNUSED)
9fbee57e 1980{
82b3e2c6 1981 SCM variable;
36245b66 1982 SCM new_variable;
82b3e2c6
DH
1983
1984 const SCM cdr_expr = SCM_CDR (expr);
1985 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
1986 ASSERT_SYNTAX (scm_ilength (cdr_expr) == 2, s_expression, expr);
1987 variable = SCM_CAR (cdr_expr);
36245b66
DH
1988
1989 /* Memoize the variable form. */
cc95e00a 1990 ASSERT_SYNTAX_2 (scm_is_symbol (variable), s_bad_variable, variable, expr);
36245b66 1991 new_variable = lookup_symbol (variable, env);
36245b66
DH
1992 /* Leave the memoization of unbound symbols to lazy memoization: */
1993 if (SCM_UNBNDP (new_variable))
1994 new_variable = variable;
82b3e2c6
DH
1995
1996 SCM_SETCAR (expr, SCM_IM_SET_X);
36245b66 1997 SCM_SETCAR (cdr_expr, new_variable);
82b3e2c6 1998 return expr;
9fbee57e
DH
1999}
2000
212e58ed
DH
2001static SCM
2002unmemoize_set_x (const SCM expr, const SCM env)
2003{
2004 return scm_cons (scm_sym_set_x, unmemoize_exprs (SCM_CDR (expr), env));
2005}
2006
9fbee57e 2007
4d0949ea 2008\f
9fbee57e
DH
2009/* Start of the memoizers for non-R5RS builtin macros. */
2010
2011
249bab1c 2012SCM_SYNTAX (s_at, "@", scm_makmmacro, scm_m_at);
5f236208 2013SCM_GLOBAL_SYMBOL (scm_sym_at, "@");
249bab1c 2014
4d0949ea 2015static SCM
249bab1c
AW
2016scm_m_at (SCM expr, SCM env SCM_UNUSED)
2017{
2018 SCM mod, var;
2019 ASSERT_SYNTAX (scm_ilength (expr) == 3, s_bad_expression, expr);
2020 ASSERT_SYNTAX (scm_ilength (scm_cadr (expr)) > 0, s_bad_expression, expr);
69dd78d7 2021 ASSERT_SYNTAX (scm_is_symbol (scm_caddr (expr)), s_bad_expression, expr);
249bab1c
AW
2022
2023 mod = scm_resolve_module (scm_cadr (expr));
2024 if (scm_is_false (mod))
2025 error_unbound_variable (expr);
2026 var = scm_module_variable (scm_module_public_interface (mod), scm_caddr (expr));
2027 if (scm_is_false (var))
2028 error_unbound_variable (expr);
2029
2030 return var;
2031}
2032
2033SCM_SYNTAX (s_atat, "@@", scm_makmmacro, scm_m_atat);
5f236208 2034SCM_GLOBAL_SYMBOL (scm_sym_atat, "@@");
249bab1c 2035
4d0949ea 2036static SCM
249bab1c
AW
2037scm_m_atat (SCM expr, SCM env SCM_UNUSED)
2038{
2039 SCM mod, var;
2040 ASSERT_SYNTAX (scm_ilength (expr) == 3, s_bad_expression, expr);
2041 ASSERT_SYNTAX (scm_ilength (scm_cadr (expr)) > 0, s_bad_expression, expr);
69dd78d7 2042 ASSERT_SYNTAX (scm_is_symbol (scm_caddr (expr)), s_bad_expression, expr);
249bab1c
AW
2043
2044 mod = scm_resolve_module (scm_cadr (expr));
2045 if (scm_is_false (mod))
2046 error_unbound_variable (expr);
2047 var = scm_module_variable (mod, scm_caddr (expr));
2048 if (scm_is_false (var))
2049 error_unbound_variable (expr);
2050
2051 return var;
2052}
2053
3b88ed2a 2054SCM_SYNTAX (s_atapply, "@apply", scm_i_makbimacro, scm_m_apply);
5f236208
LC
2055SCM_GLOBAL_SYMBOL (scm_sym_atapply, "@apply");
2056SCM_GLOBAL_SYMBOL (scm_sym_apply, "apply");
9fbee57e 2057
4d0949ea 2058static SCM
82b3e2c6 2059scm_m_apply (SCM expr, SCM env SCM_UNUSED)
9fbee57e 2060{
82b3e2c6
DH
2061 const SCM cdr_expr = SCM_CDR (expr);
2062 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
2063 ASSERT_SYNTAX (scm_ilength (cdr_expr) == 2, s_missing_expression, expr);
2e171178 2064
82b3e2c6
DH
2065 SCM_SETCAR (expr, SCM_IM_APPLY);
2066 return expr;
2067}
2e171178 2068
212e58ed
DH
2069static SCM
2070unmemoize_apply (const SCM expr, const SCM env)
2071{
2072 return scm_list_2 (scm_sym_atapply, unmemoize_exprs (SCM_CDR (expr), env));
2073}
2074
2e171178 2075
3b88ed2a 2076SCM_SYNTAX (s_atbind, "@bind", scm_i_makbimacro, scm_m_atbind);
73b64342 2077
82b3e2c6
DH
2078/* FIXME: The following explanation should go into the documentation: */
2079/* (@bind ((var init) ...) body ...) will assign the values of the `init's to
2080 * the global variables named by `var's (symbols, not evaluated), creating
2081 * them if they don't exist, executes body, and then restores the previous
2082 * values of the `var's. Additionally, whenever control leaves body, the
2083 * values of the `var's are saved and restored when control returns. It is an
2084 * error when a symbol appears more than once among the `var's. All `init's
2085 * are evaluated before any `var' is set.
2086 *
2087 * Think of this as `let' for dynamic scope.
2088 */
2089
2090/* (@bind ((var1 exp1) ... (varn expn)) body ...) is memoized into
2091 * (#@bind ((varn ... var1) . (exp1 ... expn)) body ...).
2092 *
2093 * FIXME - also implement `@bind*'.
2094 */
4d0949ea 2095static SCM
82b3e2c6 2096scm_m_atbind (SCM expr, SCM env)
73b64342 2097{
82b3e2c6
DH
2098 SCM bindings;
2099 SCM rvariables;
2100 SCM inits;
2101 SCM variable_idx;
2e171178 2102
82b3e2c6 2103 const SCM top_level = scm_env_top_level (env);
73b64342 2104
82b3e2c6
DH
2105 const SCM cdr_expr = SCM_CDR (expr);
2106 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
2107 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 2, s_missing_expression, expr);
2108 bindings = SCM_CAR (cdr_expr);
2109 check_bindings (bindings, expr);
2110 transform_bindings (bindings, expr, &rvariables, &inits);
2111
2112 for (variable_idx = rvariables;
a61f4e0c 2113 !scm_is_null (variable_idx);
82b3e2c6 2114 variable_idx = SCM_CDR (variable_idx))
73b64342 2115 {
82b3e2c6
DH
2116 /* The first call to scm_sym2var will look beyond the current module,
2117 * while the second call wont. */
2118 const SCM variable = SCM_CAR (variable_idx);
2119 SCM new_variable = scm_sym2var (variable, top_level, SCM_BOOL_F);
7888309b 2120 if (scm_is_false (new_variable))
82b3e2c6
DH
2121 new_variable = scm_sym2var (variable, top_level, SCM_BOOL_T);
2122 SCM_SETCAR (variable_idx, new_variable);
73b64342 2123 }
82b3e2c6
DH
2124
2125 SCM_SETCAR (expr, SCM_IM_BIND);
2126 SCM_SETCAR (cdr_expr, scm_cons (rvariables, inits));
2127 return expr;
73b64342 2128}
73b64342 2129
b0c5d67b 2130
3b88ed2a 2131SCM_SYNTAX(s_atcall_cc, "@call-with-current-continuation", scm_i_makbimacro, scm_m_cont);
5f236208 2132SCM_GLOBAL_SYMBOL(scm_sym_atcall_cc, "@call-with-current-continuation");
9fbee57e 2133
4d0949ea 2134static SCM
da48db62 2135scm_m_cont (SCM expr, SCM env SCM_UNUSED)
b0c5d67b 2136{
da48db62
DH
2137 const SCM cdr_expr = SCM_CDR (expr);
2138 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
2139 ASSERT_SYNTAX (scm_ilength (cdr_expr) == 1, s_expression, expr);
2140
2141 SCM_SETCAR (expr, SCM_IM_CONT);
2142 return expr;
b0c5d67b 2143}
b0c5d67b 2144
212e58ed
DH
2145static SCM
2146unmemoize_atcall_cc (const SCM expr, const SCM env)
2147{
2148 return scm_list_2 (scm_sym_atcall_cc, unmemoize_exprs (SCM_CDR (expr), env));
2149}
2150
b0c5d67b 2151
3b88ed2a 2152SCM_SYNTAX (s_at_call_with_values, "@call-with-values", scm_i_makbimacro, scm_m_at_call_with_values);
5f236208 2153SCM_GLOBAL_SYMBOL(scm_sym_at_call_with_values, "@call-with-values");
b0c5d67b 2154
4d0949ea 2155static SCM
da48db62 2156scm_m_at_call_with_values (SCM expr, SCM env SCM_UNUSED)
b0c5d67b 2157{
da48db62
DH
2158 const SCM cdr_expr = SCM_CDR (expr);
2159 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
2160 ASSERT_SYNTAX (scm_ilength (cdr_expr) == 2, s_expression, expr);
2161
2162 SCM_SETCAR (expr, SCM_IM_CALL_WITH_VALUES);
2163 return expr;
b0c5d67b 2164}
b0c5d67b 2165
212e58ed
DH
2166static SCM
2167unmemoize_at_call_with_values (const SCM expr, const SCM env)
2168{
2169 return scm_list_2 (scm_sym_at_call_with_values,
2170 unmemoize_exprs (SCM_CDR (expr), env));
2171}
2172
9c35c579 2173SCM_SYNTAX (s_eval_when, "eval-when", scm_makmmacro, scm_m_eval_when);
5f236208 2174SCM_GLOBAL_SYMBOL (scm_sym_eval_when, "eval-when");
9c35c579
AW
2175SCM_SYMBOL (sym_eval, "eval");
2176SCM_SYMBOL (sym_load, "load");
2177
2178
4d0949ea 2179static SCM
9c35c579
AW
2180scm_m_eval_when (SCM expr, SCM env SCM_UNUSED)
2181{
b3501b80 2182 ASSERT_SYNTAX (scm_ilength (expr) >= 3, s_bad_expression, expr);
9c35c579
AW
2183 ASSERT_SYNTAX (scm_ilength (scm_cadr (expr)) > 0, s_bad_expression, expr);
2184
2185 if (scm_is_true (scm_memq (sym_eval, scm_cadr (expr)))
2186 || scm_is_true (scm_memq (sym_load, scm_cadr (expr))))
b3501b80 2187 return scm_cons (SCM_IM_BEGIN, scm_cddr (expr));
9c35c579
AW
2188
2189 return scm_list_1 (SCM_IM_BEGIN);
2190}
2191
3b88ed2a 2192SCM_SYNTAX (s_gset_x, "set!", scm_i_makbimacro, scm_m_generalized_set_x);
9fbee57e
DH
2193SCM_SYMBOL (scm_sym_setter, "setter");
2194
4d0949ea 2195static SCM
7893dbbf 2196scm_m_generalized_set_x (SCM expr, SCM env)
9fbee57e 2197{
7893dbbf 2198 SCM target, exp_target;
da48db62
DH
2199
2200 const SCM cdr_expr = SCM_CDR (expr);
2201 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
2202 ASSERT_SYNTAX (scm_ilength (cdr_expr) == 2, s_expression, expr);
2203
2204 target = SCM_CAR (cdr_expr);
a61f4e0c 2205 if (!scm_is_pair (target))
da48db62
DH
2206 {
2207 /* R5RS usage */
2208 return scm_m_set_x (expr, env);
2209 }
9fbee57e 2210 else
da48db62
DH
2211 {
2212 /* (set! (foo bar ...) baz) becomes ((setter foo) bar ... baz) */
7893dbbf
MV
2213 /* Macroexpanding the target might return things of the form
2214 (begin <atom>). In that case, <atom> must be a symbol or a
2215 variable and we memoize to (set! <atom> ...).
2216 */
2b189e65 2217 exp_target = macroexp (target, env);
bc36d050 2218 if (scm_is_eq (SCM_CAR (exp_target), SCM_IM_BEGIN)
a61f4e0c
MV
2219 && !scm_is_null (SCM_CDR (exp_target))
2220 && scm_is_null (SCM_CDDR (exp_target)))
7893dbbf
MV
2221 {
2222 exp_target= SCM_CADR (exp_target);
cc95e00a 2223 ASSERT_SYNTAX_2 (scm_is_symbol (exp_target)
6d1a2e9f
MV
2224 || SCM_VARIABLEP (exp_target),
2225 s_bad_variable, exp_target, expr);
7893dbbf
MV
2226 return scm_cons (SCM_IM_SET_X, scm_cons (exp_target,
2227 SCM_CDR (cdr_expr)));
2228 }
2229 else
2230 {
2231 const SCM setter_proc_tail = scm_list_1 (SCM_CAR (target));
2232 const SCM setter_proc = scm_cons_source (expr, scm_sym_setter,
2233 setter_proc_tail);
da48db62 2234
7893dbbf
MV
2235 const SCM cddr_expr = SCM_CDR (cdr_expr);
2236 const SCM setter_args = scm_append_x (scm_list_2 (SCM_CDR (target),
2237 cddr_expr));
da48db62 2238
7893dbbf
MV
2239 SCM_SETCAR (expr, setter_proc);
2240 SCM_SETCDR (expr, setter_args);
2241 return expr;
2242 }
da48db62 2243 }
9fbee57e
DH
2244}
2245
2246
a4aa2134
DH
2247/* @slot-ref is bound privately in the (oop goops) module from goops.c. As
2248 * soon as the module system allows us to more freely create bindings in
2249 * arbitrary modules during the startup phase, the code from goops.c should be
2250 * moved here. */
212e58ed 2251
4d0949ea
LC
2252SCM_SYNTAX (s_atslot_ref, "@slot-ref", scm_i_makbimacro, scm_m_atslot_ref);
2253SCM_SYNTAX (s_atslot_set_x, "@slot-set!", scm_i_makbimacro, scm_m_atslot_set_x);
212e58ed
DH
2254SCM_SYMBOL (sym_atslot_ref, "@slot-ref");
2255
4d0949ea 2256static SCM
9a848baf 2257scm_m_atslot_ref (SCM expr, SCM env SCM_UNUSED)
9fbee57e 2258{
9a848baf
DH
2259 SCM slot_nr;
2260
2261 const SCM cdr_expr = SCM_CDR (expr);
2262 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
2263 ASSERT_SYNTAX (scm_ilength (cdr_expr) == 2, s_expression, expr);
2264 slot_nr = SCM_CADR (cdr_expr);
e11e83f3 2265 ASSERT_SYNTAX_2 (SCM_I_INUMP (slot_nr), s_bad_slot_number, slot_nr, expr);
9fbee57e 2266
9a848baf 2267 SCM_SETCAR (expr, SCM_IM_SLOT_REF);
e7313a9d 2268 SCM_SETCDR (cdr_expr, slot_nr);
9a848baf
DH
2269 return expr;
2270}
9fbee57e 2271
212e58ed
DH
2272static SCM
2273unmemoize_atslot_ref (const SCM expr, const SCM env)
2274{
2275 const SCM instance = SCM_CADR (expr);
2276 const SCM um_instance = unmemoize_expression (instance, env);
2277 const SCM slot_nr = SCM_CDDR (expr);
2278 return scm_list_3 (sym_atslot_ref, um_instance, slot_nr);
2279}
2280
9fbee57e 2281
a4aa2134
DH
2282/* @slot-set! is bound privately in the (oop goops) module from goops.c. As
2283 * soon as the module system allows us to more freely create bindings in
2284 * arbitrary modules during the startup phase, the code from goops.c should be
2285 * moved here. */
212e58ed
DH
2286
2287SCM_SYMBOL (sym_atslot_set_x, "@slot-set!");
2288
4d0949ea 2289static SCM
9a848baf 2290scm_m_atslot_set_x (SCM expr, SCM env SCM_UNUSED)
9fbee57e 2291{
9a848baf
DH
2292 SCM slot_nr;
2293
2294 const SCM cdr_expr = SCM_CDR (expr);
2295 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
2296 ASSERT_SYNTAX (scm_ilength (cdr_expr) == 3, s_expression, expr);
2297 slot_nr = SCM_CADR (cdr_expr);
e11e83f3 2298 ASSERT_SYNTAX_2 (SCM_I_INUMP (slot_nr), s_bad_slot_number, slot_nr, expr);
9a848baf
DH
2299
2300 SCM_SETCAR (expr, SCM_IM_SLOT_SET_X);
2301 return expr;
9fbee57e 2302}
9fbee57e 2303
212e58ed
DH
2304static SCM
2305unmemoize_atslot_set_x (const SCM expr, const SCM env)
2306{
2307 const SCM cdr_expr = SCM_CDR (expr);
2308 const SCM instance = SCM_CAR (cdr_expr);
2309 const SCM um_instance = unmemoize_expression (instance, env);
2310 const SCM cddr_expr = SCM_CDR (cdr_expr);
2311 const SCM slot_nr = SCM_CAR (cddr_expr);
2312 const SCM cdddr_expr = SCM_CDR (cddr_expr);
2313 const SCM value = SCM_CAR (cdddr_expr);
2314 const SCM um_value = unmemoize_expression (value, env);
2315 return scm_list_4 (sym_atslot_set_x, um_instance, slot_nr, um_value);
2316}
2317
9fbee57e
DH
2318
2319#if SCM_ENABLE_ELISP
2320
70c1c108
DH
2321static const char s_defun[] = "Symbol's function definition is void";
2322
3b88ed2a 2323SCM_SYNTAX (s_nil_cond, "nil-cond", scm_i_makbimacro, scm_m_nil_cond);
9fbee57e 2324
70c1c108
DH
2325/* nil-cond expressions have the form
2326 * (nil-cond COND VAL COND VAL ... ELSEVAL) */
4d0949ea 2327static SCM
70c1c108 2328scm_m_nil_cond (SCM expr, SCM env SCM_UNUSED)
9fbee57e 2329{
70c1c108
DH
2330 const long length = scm_ilength (SCM_CDR (expr));
2331 ASSERT_SYNTAX (length >= 0, s_bad_expression, expr);
2332 ASSERT_SYNTAX (length >= 1 && (length % 2) == 1, s_expression, expr);
2333
2334 SCM_SETCAR (expr, SCM_IM_NIL_COND);
2335 return expr;
9fbee57e
DH
2336}
2337
2338
3b88ed2a 2339SCM_SYNTAX (s_atfop, "@fop", scm_i_makbimacro, scm_m_atfop);
9fbee57e 2340
70c1c108
DH
2341/* The @fop-macro handles procedure and macro applications for elisp. The
2342 * input expression must have the form
2343 * (@fop <var> (transformer-macro <expr> ...))
2344 * where <var> must be a symbol. The expression is transformed into the
2345 * memoized form of either
2346 * (apply <un-aliased var> (transformer-macro <expr> ...))
2347 * if the value of var (across all aliasing) is not a macro, or
2348 * (<un-aliased var> <expr> ...)
2349 * if var is a macro. */
4d0949ea 2350static SCM
70c1c108 2351scm_m_atfop (SCM expr, SCM env SCM_UNUSED)
9fbee57e 2352{
70c1c108
DH
2353 SCM location;
2354 SCM symbol;
2355
2356 const SCM cdr_expr = SCM_CDR (expr);
2357 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
2358 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 1, s_missing_expression, expr);
2359
2360 symbol = SCM_CAR (cdr_expr);
cc95e00a 2361 ASSERT_SYNTAX_2 (scm_is_symbol (symbol), s_bad_variable, symbol, expr);
70c1c108
DH
2362
2363 location = scm_symbol_fref (symbol);
2364 ASSERT_SYNTAX_2 (SCM_VARIABLEP (location), s_defun, symbol, expr);
2365
2366 /* The elisp function `defalias' allows to define aliases for symbols. To
2367 * look up such definitions, the chain of symbol definitions has to be
2368 * followed up to the terminal symbol. */
cc95e00a 2369 while (scm_is_symbol (SCM_VARIABLE_REF (location)))
9fbee57e 2370 {
70c1c108
DH
2371 const SCM alias = SCM_VARIABLE_REF (location);
2372 location = scm_symbol_fref (alias);
2373 ASSERT_SYNTAX_2 (SCM_VARIABLEP (location), s_defun, symbol, expr);
9fbee57e 2374 }
70c1c108
DH
2375
2376 /* Memoize the value location belonging to the terminal symbol. */
2377 SCM_SETCAR (cdr_expr, location);
2378
2379 if (!SCM_MACROP (SCM_VARIABLE_REF (location)))
9fbee57e 2380 {
70c1c108
DH
2381 /* Since the location does not contain a macro, the form is a procedure
2382 * application. Replace `@fop' by `@apply' and transform the expression
2383 * including the `transformer-macro'. */
2384 SCM_SETCAR (expr, SCM_IM_APPLY);
2385 return expr;
2386 }
2387 else
2388 {
2389 /* Since the location contains a macro, the arguments should not be
2390 * transformed, so the `transformer-macro' is cut out. The resulting
2391 * expression starts with the memoized variable, that is at the cdr of
2392 * the input expression. */
2393 SCM_SETCDR (cdr_expr, SCM_CDADR (cdr_expr));
2394 return cdr_expr;
9fbee57e 2395 }
9fbee57e
DH
2396}
2397
2398#endif /* SCM_ENABLE_ELISP */
2399
2400
212e58ed
DH
2401static SCM
2402unmemoize_builtin_macro (const SCM expr, const SCM env)
2403{
2404 switch (ISYMNUM (SCM_CAR (expr)))
2405 {
2406 case (ISYMNUM (SCM_IM_AND)):
2407 return unmemoize_and (expr, env);
2408
2409 case (ISYMNUM (SCM_IM_BEGIN)):
2410 return unmemoize_begin (expr, env);
2411
2412 case (ISYMNUM (SCM_IM_CASE)):
2413 return unmemoize_case (expr, env);
2414
2415 case (ISYMNUM (SCM_IM_COND)):
2416 return unmemoize_cond (expr, env);
2417
2418 case (ISYMNUM (SCM_IM_DELAY)):
2419 return unmemoize_delay (expr, env);
2420
2421 case (ISYMNUM (SCM_IM_DO)):
2422 return unmemoize_do (expr, env);
2423
2424 case (ISYMNUM (SCM_IM_IF)):
2425 return unmemoize_if (expr, env);
2426
2427 case (ISYMNUM (SCM_IM_LAMBDA)):
2428 return unmemoize_lambda (expr, env);
2429
2430 case (ISYMNUM (SCM_IM_LET)):
2431 return unmemoize_let (expr, env);
2432
2433 case (ISYMNUM (SCM_IM_LETREC)):
2434 return unmemoize_letrec (expr, env);
2435
2436 case (ISYMNUM (SCM_IM_LETSTAR)):
2437 return unmemoize_letstar (expr, env);
2438
2439 case (ISYMNUM (SCM_IM_OR)):
2440 return unmemoize_or (expr, env);
2441
2442 case (ISYMNUM (SCM_IM_QUOTE)):
2443 return unmemoize_quote (expr, env);
2444
2445 case (ISYMNUM (SCM_IM_SET_X)):
2446 return unmemoize_set_x (expr, env);
2447
2448 case (ISYMNUM (SCM_IM_APPLY)):
2449 return unmemoize_apply (expr, env);
2450
2451 case (ISYMNUM (SCM_IM_BIND)):
2452 return unmemoize_exprs (expr, env); /* FIXME */
2453
2454 case (ISYMNUM (SCM_IM_CONT)):
2455 return unmemoize_atcall_cc (expr, env);
2456
2457 case (ISYMNUM (SCM_IM_CALL_WITH_VALUES)):
2458 return unmemoize_at_call_with_values (expr, env);
2459
212e58ed
DH
2460 case (ISYMNUM (SCM_IM_SLOT_REF)):
2461 return unmemoize_atslot_ref (expr, env);
2462
2463 case (ISYMNUM (SCM_IM_SLOT_SET_X)):
2464 return unmemoize_atslot_set_x (expr, env);
2465
2466 case (ISYMNUM (SCM_IM_NIL_COND)):
2467 return unmemoize_exprs (expr, env); /* FIXME */
2468
2469 default:
2470 return unmemoize_exprs (expr, env); /* FIXME */
2471 }
2472}
2473
2474
9fcf3cbb
DH
2475/* scm_i_unmemocopy_expr and scm_i_unmemocopy_body take a memoized expression
2476 * respectively a memoized body together with its environment and rewrite it
2477 * to its original form. Thus, these functions are the inversion of the
2478 * rewrite rules above. The procedure is not optimized for speed. It's used
2479 * in scm_i_unmemoize_expr, scm_procedure_source, macro_print and scm_iprin1.
212e58ed
DH
2480 *
2481 * Unmemoizing is not a reliable process. You cannot in general expect to get
2482 * the original source back.
2483 *
2484 * However, GOOPS currently relies on this for method compilation. This ought
2485 * to change. */
2486
2487SCM
9fcf3cbb
DH
2488scm_i_unmemocopy_expr (SCM expr, SCM env)
2489{
2490 const SCM source_properties = scm_whash_lookup (scm_source_whash, expr);
2491 const SCM um_expr = unmemoize_expression (expr, env);
2492
7888309b 2493 if (scm_is_true (source_properties))
9fcf3cbb
DH
2494 scm_whash_insert (scm_source_whash, um_expr, source_properties);
2495
2496 return um_expr;
2497}
2498
2499SCM
2500scm_i_unmemocopy_body (SCM forms, SCM env)
212e58ed
DH
2501{
2502 const SCM source_properties = scm_whash_lookup (scm_source_whash, forms);
2503 const SCM um_forms = unmemoize_exprs (forms, env);
2504
7888309b 2505 if (scm_is_true (source_properties))
212e58ed
DH
2506 scm_whash_insert (scm_source_whash, um_forms, source_properties);
2507
2508 return um_forms;
2509}
2510
2511
434f2f7a 2512#if (SCM_ENABLE_DEPRECATED == 1)
f58c472a 2513
b3ce13b6 2514static SCM scm_m_undefine (SCM expr, SCM env);
f58c472a
DH
2515
2516SCM_SYNTAX (s_undefine, "undefine", scm_makacro, scm_m_undefine);
2517
b3ce13b6 2518static SCM
70c1c108 2519scm_m_undefine (SCM expr, SCM env)
f58c472a 2520{
70c1c108
DH
2521 SCM variable;
2522 SCM location;
2523
2524 const SCM cdr_expr = SCM_CDR (expr);
2525 ASSERT_SYNTAX (SCM_TOP_LEVEL (env), "Bad undefine placement in", expr);
2526 ASSERT_SYNTAX (scm_ilength (cdr_expr) >= 0, s_bad_expression, expr);
2527 ASSERT_SYNTAX (scm_ilength (cdr_expr) == 1, s_expression, expr);
2528
2b189e65
MV
2529 scm_c_issue_deprecation_warning
2530 ("`undefine' is deprecated.\n");
2531
70c1c108 2532 variable = SCM_CAR (cdr_expr);
cc95e00a 2533 ASSERT_SYNTAX_2 (scm_is_symbol (variable), s_bad_variable, variable, expr);
70c1c108 2534 location = scm_sym2var (variable, scm_env_top_level (env), SCM_BOOL_F);
7888309b 2535 ASSERT_SYNTAX_2 (scm_is_true (location)
70c1c108
DH
2536 && !SCM_UNBNDP (SCM_VARIABLE_REF (location)),
2537 "variable already unbound ", variable, expr);
2538 SCM_VARIABLE_SET (location, SCM_UNDEFINED);
f58c472a 2539 return SCM_UNSPECIFIED;
f58c472a
DH
2540}
2541
b3ce13b6 2542#endif /* SCM_ENABLE_DEPRECATED */
60a49842 2543
434f2f7a 2544
b3ce13b6 2545\f
6f81708a
DH
2546/*****************************************************************************/
2547/*****************************************************************************/
2548/* The definitions for execution start here. */
2549/*****************************************************************************/
2550/*****************************************************************************/
2551
2552SCM_GLOBAL_SYMBOL (scm_sym_enter_frame, "enter-frame");
2553SCM_GLOBAL_SYMBOL (scm_sym_apply_frame, "apply-frame");
2554SCM_GLOBAL_SYMBOL (scm_sym_exit_frame, "exit-frame");
72f19c26 2555SCM_GLOBAL_SYMBOL (scm_sym_memoize_symbol, "memoize-symbol");
6f81708a 2556SCM_GLOBAL_SYMBOL (scm_sym_trace, "trace");
7c9c0169 2557SCM_SYMBOL (sym_instead, "instead");
6f81708a
DH
2558
2559/* A function object to implement "apply" for non-closure functions. */
2560static SCM f_apply;
2561/* An endless list consisting of #<undefined> objects: */
2562static SCM undefineds;
2563
2564
2565int
6e8d25a6 2566scm_badargsp (SCM formals, SCM args)
0f2d19dd 2567{
a61f4e0c 2568 while (!scm_is_null (formals))
0f2d19dd 2569 {
a61f4e0c 2570 if (!scm_is_pair (formals))
ff467021 2571 return 0;
a61f4e0c 2572 if (scm_is_null (args))
ff467021 2573 return 1;
0f2d19dd
JB
2574 formals = SCM_CDR (formals);
2575 args = SCM_CDR (args);
2576 }
a61f4e0c 2577 return !scm_is_null (args) ? 1 : 0;
0f2d19dd 2578}
a392ee15 2579
0f2d19dd 2580\f
62360b89 2581
0ee05b85 2582/* The evaluator contains a plethora of EVAL symbols.
62360b89 2583 *
62360b89 2584 *
385609b9 2585 * SCM_I_EVALIM is used when it is known that the expression is an
62360b89 2586 * immediate. (This macro never calls an evaluator.)
434f2f7a 2587 *
0ee05b85 2588 * SCM_I_XEVAL evaluates an expression that is expected to have its symbols already
434f2f7a
DH
2589 * memoized. Expressions that are not of the form '(<form> <form> ...)' are
2590 * evaluated inline without calling an evaluator.
2591 *
0ee05b85
HWN
2592 * This macro uses ceval or deval depending on its 3rd argument.
2593 *
2594 * SCM_I_XEVALCAR evaluates the car of an expression 'X:(Y:<form> <form> ...)',
434f2f7a
DH
2595 * potentially replacing a symbol at the position Y:<form> by its memoized
2596 * variable. If Y:<form> is not of the form '(<form> <form> ...)', the
2597 * evaluation is performed inline without calling an evaluator.
62360b89 2598 *
0ee05b85 2599 * This macro uses ceval or deval depending on its 3rd argument.
62360b89 2600 *
62360b89
DH
2601 */
2602
385609b9 2603#define SCM_I_EVALIM2(x) \
bc36d050 2604 ((scm_is_eq ((x), SCM_EOL) \
62360b89
DH
2605 ? syntax_error (s_empty_combination, (x), SCM_UNDEFINED), 0 \
2606 : 0), \
2607 (x))
2608
385609b9 2609#define SCM_I_EVALIM(x, env) (SCM_ILOCP (x) \
434f2f7a 2610 ? *scm_ilookup ((x), (env)) \
385609b9 2611 : SCM_I_EVALIM2(x))
62360b89 2612
0ee05b85 2613#define SCM_I_XEVAL(x, env, debug_p) \
434f2f7a 2614 (SCM_IMP (x) \
385609b9 2615 ? SCM_I_EVALIM2 (x) \
434f2f7a
DH
2616 : (SCM_VARIABLEP (x) \
2617 ? SCM_VARIABLE_REF (x) \
a61f4e0c 2618 : (scm_is_pair (x) \
0ee05b85 2619 ? (debug_p \
434f2f7a
DH
2620 ? deval ((x), (env)) \
2621 : ceval ((x), (env))) \
2622 : (x))))
2623
0ee05b85 2624#define SCM_I_XEVALCAR(x, env, debug_p) \
434f2f7a 2625 (SCM_IMP (SCM_CAR (x)) \
385609b9 2626 ? SCM_I_EVALIM (SCM_CAR (x), (env)) \
434f2f7a
DH
2627 : (SCM_VARIABLEP (SCM_CAR (x)) \
2628 ? SCM_VARIABLE_REF (SCM_CAR (x)) \
a61f4e0c 2629 : (scm_is_pair (SCM_CAR (x)) \
0ee05b85 2630 ? (debug_p \
434f2f7a
DH
2631 ? deval (SCM_CAR (x), (env)) \
2632 : ceval (SCM_CAR (x), (env))) \
cc95e00a 2633 : (!scm_is_symbol (SCM_CAR (x)) \
434f2f7a
DH
2634 ? SCM_CAR (x) \
2635 : *scm_lookupcar ((x), (env), 1)))))
2636
d1138028 2637scm_i_pthread_mutex_t source_mutex;
62360b89
DH
2638
2639
e5156567
DH
2640/* Lookup a given local variable in an environment. The local variable is
2641 * given as an iloc, that is a triple <frame, binding, last?>, where frame
2642 * indicates the relative number of the environment frame (counting upwards
2643 * from the innermost environment frame), binding indicates the number of the
2644 * binding within the frame, and last? (which is extracted from the iloc using
2645 * the macro SCM_ICDRP) indicates whether the binding forms the binding at the
2646 * very end of the improper list of bindings. */
2647SCM *
2648scm_ilookup (SCM iloc, SCM env)
2649{
2650 unsigned int frame_nr = SCM_IFRAME (iloc);
2651 unsigned int binding_nr = SCM_IDIST (iloc);
2652 SCM frames = env;
2653 SCM bindings;
2654
2655 for (; 0 != frame_nr; --frame_nr)
2656 frames = SCM_CDR (frames);
2657
2658 bindings = SCM_CAR (frames);
2659 for (; 0 != binding_nr; --binding_nr)
2660 bindings = SCM_CDR (bindings);
2661
2662 if (SCM_ICDRP (iloc))
2663 return SCM_CDRLOC (bindings);
2664 return SCM_CARLOC (SCM_CDR (bindings));
2665}
2666
2667
2668SCM_SYMBOL (scm_unbound_variable_key, "unbound-variable");
2669
2d0c133f
MV
2670/* Call this for variables that are unfound.
2671 */
e5156567
DH
2672static void
2673error_unbound_variable (SCM symbol)
2674{
2675 scm_error (scm_unbound_variable_key, NULL,
2676 "Unbound variable: ~S",
2677 scm_list_1 (symbol), SCM_BOOL_F);
2678}
2679
2d0c133f
MV
2680/* Call this for variables that are found but contain SCM_UNDEFINED.
2681 */
2682static void
2683error_defined_variable (SCM symbol)
2684{
2685 /* We use the 'unbound-variable' key here as well, since it
2686 basically is the same kind of error, with a slight variation in
2687 the displayed message.
2688 */
2689 scm_error (scm_unbound_variable_key, NULL,
a03bad87 2690 "Variable used before given a value: ~S",
2d0c133f
MV
2691 scm_list_1 (symbol), SCM_BOOL_F);
2692}
2693
e5156567
DH
2694
2695/* The Lookup Car Race
2696 - by Eva Luator
2697
2698 Memoization of variables and special forms is done while executing
2699 the code for the first time. As long as there is only one thread
2700 everything is fine, but as soon as two threads execute the same
2701 code concurrently `for the first time' they can come into conflict.
2702
2703 This memoization includes rewriting variable references into more
2704 efficient forms and expanding macros. Furthermore, macro expansion
2705 includes `compiling' special forms like `let', `cond', etc. into
2706 tree-code instructions.
2707
2708 There shouldn't normally be a problem with memoizing local and
2709 global variable references (into ilocs and variables), because all
2710 threads will mutate the code in *exactly* the same way and (if I
2711 read the C code correctly) it is not possible to observe a half-way
2712 mutated cons cell. The lookup procedure can handle this
2713 transparently without any critical sections.
2714
2715 It is different with macro expansion, because macro expansion
2716 happens outside of the lookup procedure and can't be
2717 undone. Therefore the lookup procedure can't cope with it. It has
2718 to indicate failure when it detects a lost race and hope that the
2719 caller can handle it. Luckily, it turns out that this is the case.
2720
2721 An example to illustrate this: Suppose that the following form will
2722 be memoized concurrently by two threads
2723
2724 (let ((x 12)) x)
2725
2726 Let's first examine the lookup of X in the body. The first thread
2727 decides that it has to find the symbol "x" in the environment and
2728 starts to scan it. Then the other thread takes over and actually
2729 overtakes the first. It looks up "x" and substitutes an
2730 appropriate iloc for it. Now the first thread continues and
2731 completes its lookup. It comes to exactly the same conclusions as
2732 the second one and could - without much ado - just overwrite the
2733 iloc with the same iloc.
2734
2735 But let's see what will happen when the race occurs while looking
2736 up the symbol "let" at the start of the form. It could happen that
2737 the second thread interrupts the lookup of the first thread and not
2738 only substitutes a variable for it but goes right ahead and
2739 replaces it with the compiled form (#@let* (x 12) x). Now, when
2740 the first thread completes its lookup, it would replace the #@let*
2741 with a variable containing the "let" binding, effectively reverting
2742 the form to (let (x 12) x). This is wrong. It has to detect that
2743 it has lost the race and the evaluator has to reconsider the
2744 changed form completely.
2745
2746 This race condition could be resolved with some kind of traffic
2747 light (like mutexes) around scm_lookupcar, but I think that it is
2748 best to avoid them in this case. They would serialize memoization
2749 completely and because lookup involves calling arbitrary Scheme
2750 code (via the lookup-thunk), threads could be blocked for an
2751 arbitrary amount of time or even deadlock. But with the current
2752 solution a lot of unnecessary work is potentially done. */
2753
2754/* SCM_LOOKUPCAR1 is what SCM_LOOKUPCAR used to be but is allowed to
2755 return NULL to indicate a failed lookup due to some race conditions
2756 between threads. This only happens when VLOC is the first cell of
2757 a special form that will eventually be memoized (like `let', etc.)
2758 In that case the whole lookup is bogus and the caller has to
2759 reconsider the complete special form.
2760
2761 SCM_LOOKUPCAR is still there, of course. It just calls
2762 SCM_LOOKUPCAR1 and aborts on receiving NULL. So SCM_LOOKUPCAR
2763 should only be called when it is known that VLOC is not the first
2764 pair of a special form. Otherwise, use SCM_LOOKUPCAR1 and check
2765 for NULL. I think I've found the only places where this
2766 applies. */
2767
2768static SCM *
2769scm_lookupcar1 (SCM vloc, SCM genv, int check)
2770{
2771 SCM env = genv;
2772 register SCM *al, fl, var = SCM_CAR (vloc);
2773 register SCM iloc = SCM_ILOC00;
2774 for (; SCM_NIMP (env); env = SCM_CDR (env))
2775 {
a61f4e0c 2776 if (!scm_is_pair (SCM_CAR (env)))
e5156567
DH
2777 break;
2778 al = SCM_CARLOC (env);
2779 for (fl = SCM_CAR (*al); SCM_NIMP (fl); fl = SCM_CDR (fl))
2780 {
a61f4e0c 2781 if (!scm_is_pair (fl))
e5156567 2782 {
bc36d050 2783 if (scm_is_eq (fl, var))
e5156567 2784 {
bc36d050 2785 if (!scm_is_eq (SCM_CAR (vloc), var))
e5156567
DH
2786 goto race;
2787 SCM_SET_CELL_WORD_0 (vloc, SCM_UNPACK (iloc) + SCM_ICDR);
2788 return SCM_CDRLOC (*al);
2789 }
2790 else
2791 break;
2792 }
2793 al = SCM_CDRLOC (*al);
bc36d050 2794 if (scm_is_eq (SCM_CAR (fl), var))
e5156567
DH
2795 {
2796 if (SCM_UNBNDP (SCM_CAR (*al)))
2d0c133f 2797 error_defined_variable (var);
bc36d050 2798 if (!scm_is_eq (SCM_CAR (vloc), var))
e5156567
DH
2799 goto race;
2800 SCM_SETCAR (vloc, iloc);
2801 return SCM_CARLOC (*al);
2802 }
2803 iloc = SCM_PACK (SCM_UNPACK (iloc) + SCM_IDINC);
2804 }
2805 iloc = SCM_PACK ((~SCM_IDSTMSK) & (SCM_UNPACK(iloc) + SCM_IFRINC));
2806 }
2807 {
2808 SCM top_thunk, real_var;
2809 if (SCM_NIMP (env))
2810 {
2811 top_thunk = SCM_CAR (env); /* env now refers to a
2812 top level env thunk */
2813 env = SCM_CDR (env);
2814 }
2815 else
2816 top_thunk = SCM_BOOL_F;
2817 real_var = scm_sym2var (var, top_thunk, SCM_BOOL_F);
7888309b 2818 if (scm_is_false (real_var))
e5156567
DH
2819 goto errout;
2820
a61f4e0c 2821 if (!scm_is_null (env) || SCM_UNBNDP (SCM_VARIABLE_REF (real_var)))
e5156567
DH
2822 {
2823 errout:
2824 if (check)
2825 {
a61f4e0c 2826 if (scm_is_null (env))
e5156567
DH
2827 error_unbound_variable (var);
2828 else
2829 scm_misc_error (NULL, "Damaged environment: ~S",
2830 scm_list_1 (var));
2831 }
2832 else
2833 {
2834 /* A variable could not be found, but we shall
2835 not throw an error. */
2836 static SCM undef_object = SCM_UNDEFINED;
2837 return &undef_object;
2838 }
2839 }
2840
bc36d050 2841 if (!scm_is_eq (SCM_CAR (vloc), var))
e5156567
DH
2842 {
2843 /* Some other thread has changed the very cell we are working
2844 on. In effect, it must have done our job or messed it up
2845 completely. */
2846 race:
2847 var = SCM_CAR (vloc);
2848 if (SCM_VARIABLEP (var))
2849 return SCM_VARIABLE_LOC (var);
2850 if (SCM_ILOCP (var))
2851 return scm_ilookup (var, genv);
2852 /* We can't cope with anything else than variables and ilocs. When
2853 a special form has been memoized (i.e. `let' into `#@let') we
2854 return NULL and expect the calling function to do the right
2855 thing. For the evaluator, this means going back and redoing
2856 the dispatch on the car of the form. */
2857 return NULL;
2858 }
2859
2860 SCM_SETCAR (vloc, real_var);
2861 return SCM_VARIABLE_LOC (real_var);
2862 }
2863}
2864
2865SCM *
2866scm_lookupcar (SCM vloc, SCM genv, int check)
2867{
2868 SCM *loc = scm_lookupcar1 (vloc, genv, check);
2869 if (loc == NULL)
2870 abort ();
2871 return loc;
2872}
2873
2874
36245b66
DH
2875/* During execution, look up a symbol in the top level of the given local
2876 * environment and return the corresponding variable object. If no binding
2877 * for the symbol can be found, an 'Unbound variable' error is signalled. */
2878static SCM
2879lazy_memoize_variable (const SCM symbol, const SCM environment)
2880{
2881 const SCM top_level = scm_env_top_level (environment);
2882 const SCM variable = scm_sym2var (symbol, top_level, SCM_BOOL_F);
2883
7888309b 2884 if (scm_is_false (variable))
36245b66
DH
2885 error_unbound_variable (symbol);
2886 else
2887 return variable;
2888}
2889
2890
62360b89
DH
2891SCM
2892scm_eval_car (SCM pair, SCM env)
2893{
0ee05b85 2894 return SCM_I_XEVALCAR (pair, env, scm_debug_mode_p);
6dbd0af5 2895}
c4ac4d88 2896
d0b07b5d 2897
9de33deb
MD
2898SCM
2899scm_eval_body (SCM code, SCM env)
2900{
2901 SCM next;
434f2f7a 2902
9de33deb 2903 again:
01f11e02 2904 next = SCM_CDR (code);
a61f4e0c 2905 while (!scm_is_null (next))
9de33deb
MD
2906 {
2907 if (SCM_IMP (SCM_CAR (code)))
2908 {
2909 if (SCM_ISYMP (SCM_CAR (code)))
2910 {
cce0e9c8 2911 scm_dynwind_begin (0);
2b829bbb 2912 scm_i_dynwind_pthread_mutex_lock (&source_mutex);
9bc4701c
MD
2913 /* check for race condition */
2914 if (SCM_ISYMP (SCM_CAR (code)))
9d4bf6d3 2915 m_expand_body (code, env);
cce0e9c8 2916 scm_dynwind_end ();
9de33deb
MD
2917 goto again;
2918 }
2919 }
2920 else
0ee05b85 2921 SCM_I_XEVAL (SCM_CAR (code), env, scm_debug_mode_p);
9de33deb 2922 code = next;
01f11e02 2923 next = SCM_CDR (code);
9de33deb 2924 }
0ee05b85 2925 return SCM_I_XEVALCAR (code, env, scm_debug_mode_p);
9de33deb
MD
2926}
2927
0f2d19dd 2928
434f2f7a
DH
2929/* scm_last_debug_frame contains a pointer to the last debugging information
2930 * stack frame. It is accessed very often from the debugging evaluator, so it
2931 * should probably not be indirectly addressed. Better to save and restore it
2932 * from the current root at any stack swaps.
6dbd0af5
MD
2933 */
2934
6dbd0af5
MD
2935/* scm_debug_eframe_size is the number of slots available for pseudo
2936 * stack frames at each real stack frame.
2937 */
2938
c014a02e 2939long scm_debug_eframe_size;
6dbd0af5 2940
434f2f7a
DH
2941int scm_debug_mode_p;
2942int scm_check_entry_p;
2943int scm_check_apply_p;
2944int scm_check_exit_p;
72f19c26 2945int scm_check_memoize_p;
6dbd0af5 2946
c014a02e 2947long scm_eval_stack;
a74145b8 2948
92c2555f 2949scm_t_option scm_eval_opts[] = {
62560650
HWN
2950 { SCM_OPTION_INTEGER, "stack", 22000, "Size of thread stacks (in machine words)." },
2951 { 0 }
33b97402
MD
2952};
2953
92c2555f 2954scm_t_option scm_debug_opts[] = {
b7ff98dd 2955 { SCM_OPTION_BOOLEAN, "cheap", 1,
7c9c0169 2956 "*This option is now obsolete. Setting it has no effect." },
b7ff98dd
MD
2957 { SCM_OPTION_BOOLEAN, "breakpoints", 0, "*Check for breakpoints." },
2958 { SCM_OPTION_BOOLEAN, "trace", 0, "*Trace mode." },
2959 { SCM_OPTION_BOOLEAN, "procnames", 1,
2960 "Record procedure names at definition." },
2961 { SCM_OPTION_BOOLEAN, "backwards", 0,
2962 "Display backtrace in anti-chronological order." },
274dc5fd 2963 { SCM_OPTION_INTEGER, "width", 79, "Maximal width of backtrace." },
4e646a03
MD
2964 { SCM_OPTION_INTEGER, "indent", 10, "Maximal indentation in backtrace." },
2965 { SCM_OPTION_INTEGER, "frames", 3,
b7ff98dd 2966 "Maximum number of tail-recursive frames in backtrace." },
4e646a03
MD
2967 { SCM_OPTION_INTEGER, "maxdepth", 1000,
2968 "Maximal number of stored backtrace frames." },
2969 { SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." },
11f77bfc
MD
2970 { SCM_OPTION_BOOLEAN, "backtrace", 0, "Show backtrace on error." },
2971 { SCM_OPTION_BOOLEAN, "debug", 0, "Use the debugging evaluator." },
de3d1fc9
AW
2972 /* This default stack limit will be overridden by debug.c:init_stack_limit(),
2973 if we have getrlimit() and the stack limit is not INFINITY. But it is still
2974 important, as some systems have both the soft and the hard limits set to
2975 INFINITY; in that case we fall back to this value.
0ee05b85 2976
de3d1fc9
AW
2977 The situation is aggravated by certain compilers, which can consume
2978 "beaucoup de stack", as they say in France.
2979
2980 See http://thread.gmane.org/gmane.lisp.guile.devel/8599/focus=8662 for
2981 more discussion. This setting is 640 KB on 32-bit arches (should be enough
2982 for anyone!) or a whoppin' 1280 KB on 64-bit arches.
2983 */
2984 { SCM_OPTION_INTEGER, "stack", 160000, "Stack size limit (measured in words; 0 = no check)." },
243ebb61
HWN
2985 { SCM_OPTION_SCM, "show-file-name", (unsigned long)SCM_BOOL_T,
2986 "Show file names and line numbers "
2987 "in backtraces when not `#f'. A value of `base' "
2988 "displays only base names, while `#t' displays full names."},
2989 { SCM_OPTION_BOOLEAN, "warn-deprecated", 0,
2990 "Warn when deprecated features are used." },
62560650 2991 { 0 },
6dbd0af5
MD
2992};
2993
62560650 2994
72f19c26 2995/*
0ee05b85
HWN
2996 * this ordering is awkward and illogical, but we maintain it for
2997 * compatibility. --hwn
2998 */
92c2555f 2999scm_t_option scm_evaluator_trap_table[] = {
b6d75948 3000 { SCM_OPTION_BOOLEAN, "traps", 0, "Enable evaluator traps." },
b7ff98dd
MD
3001 { SCM_OPTION_BOOLEAN, "enter-frame", 0, "Trap when eval enters new frame." },
3002 { SCM_OPTION_BOOLEAN, "apply-frame", 0, "Trap when entering apply." },
d95c0b76
NJ
3003 { SCM_OPTION_BOOLEAN, "exit-frame", 0, "Trap when exiting eval or apply." },
3004 { SCM_OPTION_SCM, "enter-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for enter-frame traps." },
3005 { SCM_OPTION_SCM, "apply-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for apply-frame traps." },
62560650 3006 { SCM_OPTION_SCM, "exit-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for exit-frame traps." },
72f19c26
HWN
3007 { SCM_OPTION_BOOLEAN, "memoize-symbol", 0, "Trap when memoizing a symbol." },
3008 { SCM_OPTION_SCM, "memoize-symbol-handler", (unsigned long)SCM_BOOL_F, "The handler for memoization." },
62560650 3009 { 0 }
6dbd0af5
MD
3010};
3011
72f19c26 3012
a1ec6916 3013SCM_DEFINE (scm_eval_options_interface, "eval-options-interface", 0, 1, 0,
1bbd0b84 3014 (SCM setting),
b3f26b14
MG
3015 "Option interface for the evaluation options. Instead of using\n"
3016 "this procedure directly, use the procedures @code{eval-enable},\n"
3939e9df 3017 "@code{eval-disable}, @code{eval-set!} and @code{eval-options}.")
1bbd0b84 3018#define FUNC_NAME s_scm_eval_options_interface
33b97402
MD
3019{
3020 SCM ans;
876099d4 3021
661ae7ab
MV
3022 scm_dynwind_begin (0);
3023 scm_dynwind_critical_section (SCM_BOOL_F);
33b97402
MD
3024 ans = scm_options (setting,
3025 scm_eval_opts,
1bbd0b84 3026 FUNC_NAME);
a74145b8 3027 scm_eval_stack = SCM_EVAL_STACK * sizeof (void *);
661ae7ab 3028 scm_dynwind_end ();
876099d4 3029
33b97402
MD
3030 return ans;
3031}
1bbd0b84 3032#undef FUNC_NAME
33b97402 3033
d0b07b5d 3034
a1ec6916 3035SCM_DEFINE (scm_evaluator_traps, "evaluator-traps-interface", 0, 1, 0,
1bbd0b84 3036 (SCM setting),
b3f26b14 3037 "Option interface for the evaluator trap options.")
1bbd0b84 3038#define FUNC_NAME s_scm_evaluator_traps
33b97402
MD
3039{
3040 SCM ans;
72f19c26
HWN
3041
3042
3043 scm_options_try (setting,
3044 scm_evaluator_trap_table,
3045 FUNC_NAME, 1);
9de87eea 3046 SCM_CRITICAL_SECTION_START;
33b97402
MD
3047 ans = scm_options (setting,
3048 scm_evaluator_trap_table,
1bbd0b84 3049 FUNC_NAME);
72f19c26 3050
2b0fb0a5 3051 /* njrev: same again. */
33b97402 3052 SCM_RESET_DEBUG_MODE;
9de87eea 3053 SCM_CRITICAL_SECTION_END;
33b97402
MD
3054 return ans;
3055}
1bbd0b84 3056#undef FUNC_NAME
33b97402 3057
d0b07b5d 3058
0f2d19dd 3059
fdc28395 3060\f
d0b07b5d 3061
fdc28395
KN
3062/* Simple procedure calls
3063 */
3064
3065SCM
3066scm_call_0 (SCM proc)
3067{
4abef68f
AW
3068 if (SCM_PROGRAM_P (proc))
3069 return scm_c_vm_run (scm_the_vm (), proc, NULL, 0);
3070 else
3071 return scm_apply (proc, SCM_EOL, SCM_EOL);
fdc28395
KN
3072}
3073
3074SCM
3075scm_call_1 (SCM proc, SCM arg1)
3076{
4abef68f
AW
3077 if (SCM_PROGRAM_P (proc))
3078 return scm_c_vm_run (scm_the_vm (), proc, &arg1, 1);
3079 else
3080 return scm_apply (proc, arg1, scm_listofnull);
fdc28395
KN
3081}
3082
3083SCM
3084scm_call_2 (SCM proc, SCM arg1, SCM arg2)
3085{
4abef68f
AW
3086 if (SCM_PROGRAM_P (proc))
3087 {
3088 SCM args[] = { arg1, arg2 };
3089 return scm_c_vm_run (scm_the_vm (), proc, args, 2);
3090 }
3091 else
3092 return scm_apply (proc, arg1, scm_cons (arg2, scm_listofnull));
fdc28395
KN
3093}
3094
3095SCM
3096scm_call_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)
3097{
4abef68f
AW
3098 if (SCM_PROGRAM_P (proc))
3099 {
3100 SCM args[] = { arg1, arg2, arg3 };
3101 return scm_c_vm_run (scm_the_vm (), proc, args, 3);
3102 }
3103 else
3104 return scm_apply (proc, arg1, scm_cons2 (arg2, arg3, scm_listofnull));
fdc28395
KN
3105}
3106
d95c0b76
NJ
3107SCM
3108scm_call_4 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4)
3109{
4abef68f
AW
3110 if (SCM_PROGRAM_P (proc))
3111 {
3112 SCM args[] = { arg1, arg2, arg3, arg4 };
3113 return scm_c_vm_run (scm_the_vm (), proc, args, 4);
3114 }
3115 else
3116 return scm_apply (proc, arg1, scm_cons2 (arg2, arg3,
3117 scm_cons (arg4, scm_listofnull)));
d95c0b76
NJ
3118}
3119
fdc28395
KN
3120/* Simple procedure applies
3121 */
3122
3123SCM
3124scm_apply_0 (SCM proc, SCM args)
3125{
3126 return scm_apply (proc, args, SCM_EOL);
3127}
3128
3129SCM
3130scm_apply_1 (SCM proc, SCM arg1, SCM args)
3131{
3132 return scm_apply (proc, scm_cons (arg1, args), SCM_EOL);
3133}
3134
3135SCM
3136scm_apply_2 (SCM proc, SCM arg1, SCM arg2, SCM args)
3137{
3138 return scm_apply (proc, scm_cons2 (arg1, arg2, args), SCM_EOL);
3139}
3140
3141SCM
3142scm_apply_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM args)
3143{
3144 return scm_apply (proc, scm_cons (arg1, scm_cons2 (arg2, arg3, args)),
3145 SCM_EOL);
3146}
3147
82a2622a 3148/* This code processes the arguments to apply:
b145c172
JB
3149
3150 (apply PROC ARG1 ... ARGS)
3151
82a2622a
JB
3152 Given a list (ARG1 ... ARGS), this function conses the ARG1
3153 ... arguments onto the front of ARGS, and returns the resulting
3154 list. Note that ARGS is a list; thus, the argument to this
3155 function is a list whose last element is a list.
3156
3157 Apply calls this function, and applies PROC to the elements of the
b145c172
JB
3158 result. apply:nconc2last takes care of building the list of
3159 arguments, given (ARG1 ... ARGS).
3160
82a2622a
JB
3161 Rather than do new consing, apply:nconc2last destroys its argument.
3162 On that topic, this code came into my care with the following
3163 beautifully cryptic comment on that topic: "This will only screw
3164 you if you do (scm_apply scm_apply '( ... ))" If you know what
3165 they're referring to, send me a patch to this comment. */
b145c172 3166
3b3b36dd 3167SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
b3f26b14
MG
3168 (SCM lst),
3169 "Given a list (@var{arg1} @dots{} @var{args}), this function\n"
3170 "conses the @var{arg1} @dots{} arguments onto the front of\n"
3171 "@var{args}, and returns the resulting list. Note that\n"
3172 "@var{args} is a list; thus, the argument to this function is\n"
3173 "a list whose last element is a list.\n"
3174 "Note: Rather than do new consing, @code{apply:nconc2last}\n"
3175 "destroys its argument, so use with care.")
1bbd0b84 3176#define FUNC_NAME s_scm_nconc2last
0f2d19dd
JB
3177{
3178 SCM *lloc;
34d19ef6 3179 SCM_VALIDATE_NONEMPTYLIST (1, lst);
0f2d19dd 3180 lloc = &lst;
a61f4e0c 3181 while (!scm_is_null (SCM_CDR (*lloc))) /* Perhaps should be
c96d76b8
NJ
3182 SCM_NULL_OR_NIL_P, but not
3183 needed in 99.99% of cases,
3184 and it could seriously hurt
3185 performance. - Neil */
a23afe53 3186 lloc = SCM_CDRLOC (*lloc);
1bbd0b84 3187 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
0f2d19dd
JB
3188 *lloc = SCM_CAR (*lloc);
3189 return lst;
3190}
1bbd0b84 3191#undef FUNC_NAME
0f2d19dd 3192
0f2d19dd 3193
6dbd0af5
MD
3194
3195/* SECTION: The rest of this file is only read once.
3196 */
3197
504d99c5
MD
3198/* Trampolines
3199 *
3200 * Trampolines make it possible to move procedure application dispatch
3201 * outside inner loops. The motivation was clean implementation of
3202 * efficient replacements of R5RS primitives in SRFI-1.
3203 *
3204 * The semantics is clear: scm_trampoline_N returns an optimized
3205 * version of scm_call_N (or NULL if the procedure isn't applicable
3206 * on N args).
3207 *
3208 * Applying the optimization to map and for-each increased efficiency
3209 * noticeably. For example, (map abs ls) is now 8 times faster than
3210 * before.
3211 */
3212
756414cf
MD
3213static SCM
3214call_subr0_0 (SCM proc)
3215{
3216 return SCM_SUBRF (proc) ();
3217}
3218
3219static SCM
3220call_subr1o_0 (SCM proc)
3221{
3222 return SCM_SUBRF (proc) (SCM_UNDEFINED);
3223}
3224
3225static SCM
3226call_lsubr_0 (SCM proc)
3227{
3228 return SCM_SUBRF (proc) (SCM_EOL);
3229}
3230
3231SCM
3232scm_i_call_closure_0 (SCM proc)
3233{
6a3f13f0
DH
3234 const SCM env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3235 SCM_EOL,
3236 SCM_ENV (proc));
3237 const SCM result = scm_eval_body (SCM_CLOSURE_BODY (proc), env);
d0b07b5d 3238 return result;
756414cf
MD
3239}
3240
3241scm_t_trampoline_0
3242scm_trampoline_0 (SCM proc)
3243{
2510c810
DH
3244 scm_t_trampoline_0 trampoline;
3245
756414cf 3246 if (SCM_IMP (proc))
d0b07b5d 3247 return NULL;
2510c810 3248
756414cf
MD
3249 switch (SCM_TYP7 (proc))
3250 {
3251 case scm_tc7_subr_0:
2510c810
DH
3252 trampoline = call_subr0_0;
3253 break;
756414cf 3254 case scm_tc7_subr_1o:
2510c810
DH
3255 trampoline = call_subr1o_0;
3256 break;
756414cf 3257 case scm_tc7_lsubr:
2510c810
DH
3258 trampoline = call_lsubr_0;
3259 break;
756414cf
MD
3260 case scm_tcs_closures:
3261 {
3262 SCM formals = SCM_CLOSURE_FORMALS (proc);
a61f4e0c 3263 if (scm_is_null (formals) || !scm_is_pair (formals))
2510c810 3264 trampoline = scm_i_call_closure_0;
756414cf 3265 else
d0b07b5d 3266 return NULL;
2510c810 3267 break;
756414cf
MD
3268 }
3269 case scm_tcs_struct:
3270 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2510c810 3271 trampoline = scm_call_generic_0;
2510c810
DH
3272 else
3273 return NULL;
3274 break;
756414cf
MD
3275 case scm_tc7_smob:
3276 if (SCM_SMOB_APPLICABLE_P (proc))
2510c810 3277 trampoline = SCM_SMOB_DESCRIPTOR (proc).apply_0;
756414cf 3278 else
d0b07b5d 3279 return NULL;
2510c810 3280 break;
756414cf
MD
3281 case scm_tc7_asubr:
3282 case scm_tc7_rpsubr:
e20d7001 3283 case scm_tc7_gsubr:
756414cf 3284 case scm_tc7_pws:
2fb924f6 3285 case scm_tc7_program:
2510c810
DH
3286 trampoline = scm_call_0;
3287 break;
756414cf 3288 default:
2510c810 3289 return NULL; /* not applicable on zero arguments */
756414cf 3290 }
2510c810
DH
3291 /* We only reach this point if a valid trampoline was determined. */
3292
3293 /* If debugging is enabled, we want to see all calls to proc on the stack.
3294 * Thus, we replace the trampoline shortcut with scm_call_0. */
434f2f7a 3295 if (scm_debug_mode_p)
2510c810
DH
3296 return scm_call_0;
3297 else
3298 return trampoline;
756414cf
MD
3299}
3300
504d99c5
MD
3301static SCM
3302call_subr1_1 (SCM proc, SCM arg1)
3303{
3304 return SCM_SUBRF (proc) (arg1);
3305}
3306
9ed24633
MD
3307static SCM
3308call_subr2o_1 (SCM proc, SCM arg1)
3309{
3310 return SCM_SUBRF (proc) (arg1, SCM_UNDEFINED);
3311}
3312
504d99c5
MD
3313static SCM
3314call_lsubr_1 (SCM proc, SCM arg1)
3315{
3316 return SCM_SUBRF (proc) (scm_list_1 (arg1));
3317}
3318
3319static SCM
3320call_dsubr_1 (SCM proc, SCM arg1)
3321{
e11e83f3 3322 if (SCM_I_INUMP (arg1))
504d99c5 3323 {
0ee05b85 3324 return (scm_from_double (SCM_DSUBRF (proc) ((double) SCM_I_INUM (arg1))));
504d99c5
MD
3325 }
3326 else if (SCM_REALP (arg1))
3327 {
0ee05b85 3328 return (scm_from_double (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
504d99c5 3329 }
504d99c5 3330 else if (SCM_BIGP (arg1))
f92e85f7 3331 {
0ee05b85 3332 return (scm_from_double (SCM_DSUBRF (proc) (scm_i_big2dbl (arg1))));
f92e85f7
MV
3333 }
3334 else if (SCM_FRACTIONP (arg1))
3335 {
0ee05b85 3336 return (scm_from_double (SCM_DSUBRF (proc) (scm_i_fraction2double (arg1))));
f92e85f7 3337 }
0193377d 3338 SCM_WTA_DISPATCH_1_SUBR (proc, arg1, SCM_ARG1);
504d99c5
MD
3339}
3340
3341static SCM
3342call_cxr_1 (SCM proc, SCM arg1)
3343{
a61f4e0c 3344 return scm_i_chase_pairs (arg1, (scm_t_bits) SCM_SUBRF (proc));
504d99c5
MD
3345}
3346
3347static SCM
3348call_closure_1 (SCM proc, SCM arg1)
3349{
6a3f13f0
DH
3350 const SCM env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3351 scm_list_1 (arg1),
3352 SCM_ENV (proc));
3353 const SCM result = scm_eval_body (SCM_CLOSURE_BODY (proc), env);
d0b07b5d 3354 return result;
504d99c5
MD
3355}
3356
3357scm_t_trampoline_1
3358scm_trampoline_1 (SCM proc)
3359{
2510c810
DH
3360 scm_t_trampoline_1 trampoline;
3361
504d99c5 3362 if (SCM_IMP (proc))
d0b07b5d 3363 return NULL;
2510c810 3364
504d99c5
MD
3365 switch (SCM_TYP7 (proc))
3366 {
3367 case scm_tc7_subr_1:
3368 case scm_tc7_subr_1o:
2510c810
DH
3369 trampoline = call_subr1_1;
3370 break;
9ed24633 3371 case scm_tc7_subr_2o:
2510c810
DH
3372 trampoline = call_subr2o_1;
3373 break;
504d99c5 3374 case scm_tc7_lsubr:
2510c810
DH
3375 trampoline = call_lsubr_1;
3376 break;
14b18ed6 3377 case scm_tc7_dsubr:
2510c810
DH
3378 trampoline = call_dsubr_1;
3379 break;
504d99c5 3380 case scm_tc7_cxr:
2510c810
DH
3381 trampoline = call_cxr_1;
3382 break;
504d99c5
MD
3383 case scm_tcs_closures:
3384 {
3385 SCM formals = SCM_CLOSURE_FORMALS (proc);
a61f4e0c
MV
3386 if (!scm_is_null (formals)
3387 && (!scm_is_pair (formals) || !scm_is_pair (SCM_CDR (formals))))
2510c810 3388 trampoline = call_closure_1;
504d99c5 3389 else
d0b07b5d 3390 return NULL;
2510c810 3391 break;
504d99c5
MD
3392 }
3393 case scm_tcs_struct:
3394 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2510c810 3395 trampoline = scm_call_generic_1;
2510c810
DH
3396 else
3397 return NULL;
3398 break;
504d99c5
MD
3399 case scm_tc7_smob:
3400 if (SCM_SMOB_APPLICABLE_P (proc))
2510c810 3401 trampoline = SCM_SMOB_DESCRIPTOR (proc).apply_1;
504d99c5 3402 else
d0b07b5d 3403 return NULL;
2510c810 3404 break;
504d99c5
MD
3405 case scm_tc7_asubr:
3406 case scm_tc7_rpsubr:
e20d7001 3407 case scm_tc7_gsubr:
504d99c5 3408 case scm_tc7_pws:
2fb924f6 3409 case scm_tc7_program:
2510c810
DH
3410 trampoline = scm_call_1;
3411 break;
504d99c5 3412 default:
d0b07b5d 3413 return NULL; /* not applicable on one arg */
504d99c5 3414 }
2510c810
DH
3415 /* We only reach this point if a valid trampoline was determined. */
3416
3417 /* If debugging is enabled, we want to see all calls to proc on the stack.
3418 * Thus, we replace the trampoline shortcut with scm_call_1. */
434f2f7a 3419 if (scm_debug_mode_p)
2510c810
DH
3420 return scm_call_1;
3421 else
3422 return trampoline;
504d99c5
MD
3423}
3424
3425static SCM
3426call_subr2_2 (SCM proc, SCM arg1, SCM arg2)
3427{
3428 return SCM_SUBRF (proc) (arg1, arg2);
3429}
3430
9ed24633
MD
3431static SCM
3432call_lsubr2_2 (SCM proc, SCM arg1, SCM arg2)
3433{
3434 return SCM_SUBRF (proc) (arg1, arg2, SCM_EOL);
3435}
3436
504d99c5
MD
3437static SCM
3438call_lsubr_2 (SCM proc, SCM arg1, SCM arg2)
3439{
3440 return SCM_SUBRF (proc) (scm_list_2 (arg1, arg2));
3441}
3442
3443static SCM
3444call_closure_2 (SCM proc, SCM arg1, SCM arg2)
3445{
6a3f13f0
DH
3446 const SCM env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3447 scm_list_2 (arg1, arg2),
3448 SCM_ENV (proc));
3449 const SCM result = scm_eval_body (SCM_CLOSURE_BODY (proc), env);
d0b07b5d 3450 return result;
504d99c5
MD
3451}
3452
3453scm_t_trampoline_2
3454scm_trampoline_2 (SCM proc)
3455{
2510c810
DH
3456 scm_t_trampoline_2 trampoline;
3457
504d99c5 3458 if (SCM_IMP (proc))
d0b07b5d 3459 return NULL;
2510c810 3460
504d99c5
MD
3461 switch (SCM_TYP7 (proc))
3462 {
3463 case scm_tc7_subr_2:
3464 case scm_tc7_subr_2o:
3465 case scm_tc7_rpsubr:
3466 case scm_tc7_asubr:
2510c810
DH
3467 trampoline = call_subr2_2;
3468 break;
9ed24633 3469 case scm_tc7_lsubr_2:
2510c810
DH
3470 trampoline = call_lsubr2_2;
3471 break;
504d99c5 3472 case scm_tc7_lsubr:
2510c810
DH
3473 trampoline = call_lsubr_2;
3474 break;
504d99c5
MD
3475 case scm_tcs_closures:
3476 {
3477 SCM formals = SCM_CLOSURE_FORMALS (proc);
a61f4e0c
MV
3478 if (!scm_is_null (formals)
3479 && (!scm_is_pair (formals)
3480 || (!scm_is_null (SCM_CDR (formals))
3481 && (!scm_is_pair (SCM_CDR (formals))
3482 || !scm_is_pair (SCM_CDDR (formals))))))
2510c810 3483 trampoline = call_closure_2;
504d99c5 3484 else
d0b07b5d 3485 return NULL;
2510c810 3486 break;
504d99c5
MD
3487 }
3488 case scm_tcs_struct:
3489 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2510c810 3490 trampoline = scm_call_generic_2;
2510c810
DH
3491 else
3492 return NULL;
3493 break;
504d99c5
MD
3494 case scm_tc7_smob:
3495 if (SCM_SMOB_APPLICABLE_P (proc))
2510c810 3496 trampoline = SCM_SMOB_DESCRIPTOR (proc).apply_2;
504d99c5 3497 else
d0b07b5d 3498 return NULL;
2510c810 3499 break;
e20d7001 3500 case scm_tc7_gsubr:
504d99c5 3501 case scm_tc7_pws:
2fb924f6 3502 case scm_tc7_program:
2510c810
DH
3503 trampoline = scm_call_2;
3504 break;
504d99c5 3505 default:
d0b07b5d 3506 return NULL; /* not applicable on two args */
504d99c5 3507 }
2510c810
DH
3508 /* We only reach this point if a valid trampoline was determined. */
3509
3510 /* If debugging is enabled, we want to see all calls to proc on the stack.
3511 * Thus, we replace the trampoline shortcut with scm_call_2. */
434f2f7a 3512 if (scm_debug_mode_p)
2510c810
DH
3513 return scm_call_2;
3514 else
3515 return trampoline;
504d99c5
MD
3516}
3517
d9c393f5
JB
3518/* Typechecking for multi-argument MAP and FOR-EACH.
3519
47c3f06d 3520 Verify that each element of the vector ARGV, except for the first,
d9c393f5 3521 is a proper list whose length is LEN. Attribute errors to WHO,
47c3f06d 3522 and claim that the i'th element of ARGV is WHO's i+2'th argument. */
d9c393f5 3523static inline void
47c3f06d 3524check_map_args (SCM argv,
c014a02e 3525 long len,
47c3f06d
MD
3526 SCM gf,
3527 SCM proc,
3528 SCM args,
3529 const char *who)
d9c393f5 3530{
c014a02e 3531 long i;
d9c393f5 3532
4057a3e0 3533 for (i = SCM_SIMPLE_VECTOR_LENGTH (argv) - 1; i >= 1; i--)
d9c393f5 3534 {
4057a3e0
MV
3535 SCM elt = SCM_SIMPLE_VECTOR_REF (argv, i);
3536 long elt_len = scm_ilength (elt);
d9c393f5
JB
3537
3538 if (elt_len < 0)
47c3f06d
MD
3539 {
3540 if (gf)
3541 scm_apply_generic (gf, scm_cons (proc, args));
3542 else
4057a3e0 3543 scm_wrong_type_arg (who, i + 2, elt);
47c3f06d 3544 }
d9c393f5
JB
3545
3546 if (elt_len != len)
4057a3e0 3547 scm_out_of_range_pos (who, elt, scm_from_long (i + 2));
d9c393f5 3548 }
d9c393f5
JB
3549}
3550
3551
47c3f06d 3552SCM_GPROC (s_map, "map", 2, 0, 1, scm_map, g_map);
1cc91f1b 3553
368bf056
MD
3554/* Note: Currently, scm_map applies PROC to the argument list(s)
3555 sequentially, starting with the first element(s). This is used in
8878f040 3556 evalext.c where the Scheme procedure `map-in-order', which guarantees
368bf056 3557 sequential behaviour, is implemented using scm_map. If the
8878f040 3558 behaviour changes, we need to update `map-in-order'.
368bf056
MD
3559*/
3560
0f2d19dd 3561SCM
1bbd0b84 3562scm_map (SCM proc, SCM arg1, SCM args)
af45e3b0 3563#define FUNC_NAME s_map
0f2d19dd 3564{
c014a02e 3565 long i, len;
0f2d19dd
JB
3566 SCM res = SCM_EOL;
3567 SCM *pres = &res;
0f2d19dd 3568
d9c393f5 3569 len = scm_ilength (arg1);
47c3f06d
MD
3570 SCM_GASSERTn (len >= 0,
3571 g_map, scm_cons2 (proc, arg1, args), SCM_ARG2, s_map);
af45e3b0 3572 SCM_VALIDATE_REST_ARGUMENT (args);
a61f4e0c 3573 if (scm_is_null (args))
0f2d19dd 3574 {
504d99c5
MD
3575 scm_t_trampoline_1 call = scm_trampoline_1 (proc);
3576 SCM_GASSERT2 (call, g_map, proc, arg1, SCM_ARG1, s_map);
3577 while (SCM_NIMP (arg1))
3578 {
3579 *pres = scm_list_1 (call (proc, SCM_CAR (arg1)));
3580 pres = SCM_CDRLOC (*pres);
3581 arg1 = SCM_CDR (arg1);
3582 }
3583 return res;
3584 }
a61f4e0c 3585 if (scm_is_null (SCM_CDR (args)))
504d99c5
MD
3586 {
3587 SCM arg2 = SCM_CAR (args);
3588 int len2 = scm_ilength (arg2);
3589 scm_t_trampoline_2 call = scm_trampoline_2 (proc);
3590 SCM_GASSERTn (call,
3591 g_map, scm_cons2 (proc, arg1, args), SCM_ARG1, s_map);
3592 SCM_GASSERTn (len2 >= 0,
3593 g_map, scm_cons2 (proc, arg1, args), SCM_ARG3, s_map);
3594 if (len2 != len)
3595 SCM_OUT_OF_RANGE (3, arg2);
0f2d19dd
JB
3596 while (SCM_NIMP (arg1))
3597 {
504d99c5 3598 *pres = scm_list_1 (call (proc, SCM_CAR (arg1), SCM_CAR (arg2)));
a23afe53 3599 pres = SCM_CDRLOC (*pres);
0f2d19dd 3600 arg1 = SCM_CDR (arg1);
504d99c5 3601 arg2 = SCM_CDR (arg2);
0f2d19dd
JB
3602 }
3603 return res;
3604 }
05b15362
DH
3605 arg1 = scm_cons (arg1, args);
3606 args = scm_vector (arg1);
47c3f06d 3607 check_map_args (args, len, g_map, proc, arg1, s_map);
0f2d19dd
JB
3608 while (1)
3609 {
3610 arg1 = SCM_EOL;
4057a3e0 3611 for (i = SCM_SIMPLE_VECTOR_LENGTH (args) - 1; i >= 0; i--)
0f2d19dd 3612 {
4057a3e0
MV
3613 SCM elt = SCM_SIMPLE_VECTOR_REF (args, i);
3614 if (SCM_IMP (elt))
d9c393f5 3615 return res;
4057a3e0
MV
3616 arg1 = scm_cons (SCM_CAR (elt), arg1);
3617 SCM_SIMPLE_VECTOR_SET (args, i, SCM_CDR (elt));
0f2d19dd 3618 }
8ea46249 3619 *pres = scm_list_1 (scm_apply (proc, arg1, SCM_EOL));
a23afe53 3620 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
3621 }
3622}
af45e3b0 3623#undef FUNC_NAME
0f2d19dd
JB
3624
3625
47c3f06d 3626SCM_GPROC (s_for_each, "for-each", 2, 0, 1, scm_for_each, g_for_each);
1cc91f1b 3627
0f2d19dd 3628SCM
1bbd0b84 3629scm_for_each (SCM proc, SCM arg1, SCM args)
af45e3b0 3630#define FUNC_NAME s_for_each
0f2d19dd 3631{
c014a02e 3632 long i, len;
d9c393f5 3633 len = scm_ilength (arg1);
47c3f06d
MD
3634 SCM_GASSERTn (len >= 0, g_for_each, scm_cons2 (proc, arg1, args),
3635 SCM_ARG2, s_for_each);
af45e3b0 3636 SCM_VALIDATE_REST_ARGUMENT (args);
a61f4e0c 3637 if (scm_is_null (args))
0f2d19dd 3638 {
504d99c5
MD
3639 scm_t_trampoline_1 call = scm_trampoline_1 (proc);
3640 SCM_GASSERT2 (call, g_for_each, proc, arg1, SCM_ARG1, s_for_each);
3641 while (SCM_NIMP (arg1))
3642 {
3643 call (proc, SCM_CAR (arg1));
3644 arg1 = SCM_CDR (arg1);
3645 }
3646 return SCM_UNSPECIFIED;
3647 }
a61f4e0c 3648 if (scm_is_null (SCM_CDR (args)))
504d99c5
MD
3649 {
3650 SCM arg2 = SCM_CAR (args);
3651 int len2 = scm_ilength (arg2);
3652 scm_t_trampoline_2 call = scm_trampoline_2 (proc);
3653 SCM_GASSERTn (call, g_for_each,
3654 scm_cons2 (proc, arg1, args), SCM_ARG1, s_for_each);
3655 SCM_GASSERTn (len2 >= 0, g_for_each,
3656 scm_cons2 (proc, arg1, args), SCM_ARG3, s_for_each);
3657 if (len2 != len)
3658 SCM_OUT_OF_RANGE (3, arg2);
c96d76b8 3659 while (SCM_NIMP (arg1))
0f2d19dd 3660 {
504d99c5 3661 call (proc, SCM_CAR (arg1), SCM_CAR (arg2));
0f2d19dd 3662 arg1 = SCM_CDR (arg1);
504d99c5 3663 arg2 = SCM_CDR (arg2);
0f2d19dd
JB
3664 }
3665 return SCM_UNSPECIFIED;
3666 }
05b15362
DH
3667 arg1 = scm_cons (arg1, args);
3668 args = scm_vector (arg1);
47c3f06d 3669 check_map_args (args, len, g_for_each, proc, arg1, s_for_each);
0f2d19dd
JB
3670 while (1)
3671 {
3672 arg1 = SCM_EOL;
4057a3e0 3673 for (i = SCM_SIMPLE_VECTOR_LENGTH (args) - 1; i >= 0; i--)
0f2d19dd 3674 {
4057a3e0
MV
3675 SCM elt = SCM_SIMPLE_VECTOR_REF (args, i);
3676 if (SCM_IMP (elt))
c96d76b8 3677 return SCM_UNSPECIFIED;
4057a3e0
MV
3678 arg1 = scm_cons (SCM_CAR (elt), arg1);
3679 SCM_SIMPLE_VECTOR_SET (args, i, SCM_CDR (elt));
0f2d19dd
JB
3680 }
3681 scm_apply (proc, arg1, SCM_EOL);
3682 }
3683}
af45e3b0 3684#undef FUNC_NAME
0f2d19dd 3685
1cc91f1b 3686
0f2d19dd 3687SCM
6e8d25a6 3688scm_closure (SCM code, SCM env)
0f2d19dd 3689{
16d4699b
MV
3690 SCM z;
3691 SCM closcar = scm_cons (code, SCM_EOL);
3db825b0
LC
3692 z = scm_immutable_cell (SCM_UNPACK (closcar) + scm_tc3_closure,
3693 (scm_t_bits) env);
16d4699b 3694 scm_remember_upto_here (closcar);
0f2d19dd
JB
3695 return z;
3696}
3697
3698
92c2555f 3699scm_t_bits scm_tc16_promise;
1cc91f1b 3700
7c455996
AW
3701SCM_DEFINE (scm_make_promise, "make-promise", 1, 0, 0,
3702 (SCM thunk),
3703 "Create a new promise object.\n\n"
3704 "@code{make-promise} is a procedural form of @code{delay}.\n"
3705 "These two expressions are equivalent:\n"
3706 "@lisp\n"
3707 "(delay @var{exp})\n"
3708 "(make-promise (lambda () @var{exp}))\n"
3709 "@end lisp\n")
3710#define FUNC_NAME s_scm_make_promise
3711{
3712 SCM_VALIDATE_THUNK (1, thunk);
28d52ebb 3713 SCM_RETURN_NEWSMOB2 (scm_tc16_promise,
7c455996 3714 SCM_UNPACK (thunk),
9de87eea
MV
3715 scm_make_recursive_mutex ());
3716}
7c455996 3717#undef FUNC_NAME
9de87eea 3718
1cc91f1b 3719
0f2d19dd 3720static int
e841c3e0 3721promise_print (SCM exp, SCM port, scm_print_state *pstate)
0f2d19dd 3722{
19402679 3723 int writingp = SCM_WRITINGP (pstate);
b7f3516f 3724 scm_puts ("#<promise ", port);
19402679 3725 SCM_SET_WRITINGP (pstate, 1);
28d52ebb 3726 scm_iprin1 (SCM_PROMISE_DATA (exp), port, pstate);
19402679 3727 SCM_SET_WRITINGP (pstate, writingp);
b7f3516f 3728 scm_putc ('>', port);
0f2d19dd
JB
3729 return !0;
3730}
3731
3b3b36dd 3732SCM_DEFINE (scm_force, "force", 1, 0, 0,
28d52ebb 3733 (SCM promise),
67e8151b
MG
3734 "If the promise @var{x} has not been computed yet, compute and\n"
3735 "return @var{x}, otherwise just return the previously computed\n"
3736 "value.")
1bbd0b84 3737#define FUNC_NAME s_scm_force
0f2d19dd 3738{
28d52ebb 3739 SCM_VALIDATE_SMOB (1, promise, promise);
9de87eea 3740 scm_lock_mutex (SCM_PROMISE_MUTEX (promise));
28d52ebb 3741 if (!SCM_PROMISE_COMPUTED_P (promise))
0f2d19dd 3742 {
28d52ebb
MD
3743 SCM ans = scm_call_0 (SCM_PROMISE_DATA (promise));
3744 if (!SCM_PROMISE_COMPUTED_P (promise))
0f2d19dd 3745 {
28d52ebb
MD
3746 SCM_SET_PROMISE_DATA (promise, ans);
3747 SCM_SET_PROMISE_COMPUTED (promise);
0f2d19dd
JB
3748 }
3749 }
9de87eea 3750 scm_unlock_mutex (SCM_PROMISE_MUTEX (promise));
28d52ebb 3751 return SCM_PROMISE_DATA (promise);
0f2d19dd 3752}
1bbd0b84 3753#undef FUNC_NAME
0f2d19dd 3754
445f675c 3755
a1ec6916 3756SCM_DEFINE (scm_promise_p, "promise?", 1, 0, 0,
67e8151b 3757 (SCM obj),
b380b885 3758 "Return true if @var{obj} is a promise, i.e. a delayed computation\n"
7a095584 3759 "(@pxref{Delayed evaluation,,,r5rs.info,The Revised^5 Report on Scheme}).")
1bbd0b84 3760#define FUNC_NAME s_scm_promise_p
0f2d19dd 3761{
7888309b 3762 return scm_from_bool (SCM_TYP16_PREDICATE (scm_tc16_promise, obj));
0f2d19dd 3763}
1bbd0b84 3764#undef FUNC_NAME
0f2d19dd 3765
445f675c 3766
a1ec6916 3767SCM_DEFINE (scm_cons_source, "cons-source", 3, 0, 0,
1bbd0b84 3768 (SCM xorig, SCM x, SCM y),
11768c04
NJ
3769 "Create and return a new pair whose car and cdr are @var{x} and @var{y}.\n"
3770 "Any source properties associated with @var{xorig} are also associated\n"
3771 "with the new pair.")
1bbd0b84 3772#define FUNC_NAME s_scm_cons_source
26d5b9b4
MD
3773{
3774 SCM p, z;
16d4699b 3775 z = scm_cons (x, y);
26d5b9b4
MD
3776 /* Copy source properties possibly associated with xorig. */
3777 p = scm_whash_lookup (scm_source_whash, xorig);
7888309b 3778 if (scm_is_true (p))
26d5b9b4
MD
3779 scm_whash_insert (scm_source_whash, z, p);
3780 return z;
3781}
1bbd0b84 3782#undef FUNC_NAME
26d5b9b4 3783
445f675c 3784
62360b89
DH
3785/* The function scm_copy_tree is used to copy an expression tree to allow the
3786 * memoizer to modify the expression during memoization. scm_copy_tree
3787 * creates deep copies of pairs and vectors, but not of any other data types,
3788 * since only pairs and vectors will be parsed by the memoizer.
3789 *
3790 * To avoid infinite recursion due to cyclic structures, the hare-and-tortoise
3791 * pattern is used to detect cycles. In fact, the pattern is used in two
3792 * dimensions, vertical (indicated in the code by the variable names 'hare'
3793 * and 'tortoise') and horizontal ('rabbit' and 'turtle'). In both
3794 * dimensions, the hare/rabbit will take two steps when the tortoise/turtle
3795 * takes one.
3796 *
3797 * The vertical dimension corresponds to recursive calls to function
3798 * copy_tree: This happens when descending into vector elements, into cars of
3799 * lists and into the cdr of an improper list. In this dimension, the
3800 * tortoise follows the hare by using the processor stack: Every stack frame
3801 * will hold an instance of struct t_trace. These instances are connected in
3802 * a way that represents the trace of the hare, which thus can be followed by
3803 * the tortoise. The tortoise will always point to struct t_trace instances
3804 * relating to SCM objects that have already been copied. Thus, a cycle is
3805 * detected if the tortoise and the hare point to the same object,
3806 *
3807 * The horizontal dimension is within one execution of copy_tree, when the
3808 * function cdr's along the pairs of a list. This is the standard
3809 * hare-and-tortoise implementation, found several times in guile. */
3810
3811struct t_trace {
2b829bbb
KR
3812 struct t_trace *trace; /* These pointers form a trace along the stack. */
3813 SCM obj; /* The object handled at the respective stack frame.*/
62360b89
DH
3814};
3815
3816static SCM
3817copy_tree (
3818 struct t_trace *const hare,
3819 struct t_trace *tortoise,
3820 unsigned int tortoise_delay )
3821{
4057a3e0 3822 if (!scm_is_pair (hare->obj) && !scm_is_simple_vector (hare->obj))
62360b89
DH
3823 {
3824 return hare->obj;
3825 }
3826 else
3827 {
3828 /* Prepare the trace along the stack. */
3829 struct t_trace new_hare;
3830 hare->trace = &new_hare;
3831
3832 /* The tortoise will make its step after the delay has elapsed. Note
3833 * that in contrast to the typical hare-and-tortoise pattern, the step
3834 * of the tortoise happens before the hare takes its steps. This is, in
3835 * principle, no problem, except for the start of the algorithm: Then,
5fb64383 3836 * it has to be made sure that the hare actually gets its advantage of
62360b89
DH
3837 * two steps. */
3838 if (tortoise_delay == 0)
3839 {
3840 tortoise_delay = 1;
3841 tortoise = tortoise->trace;
bc36d050 3842 ASSERT_SYNTAX (!scm_is_eq (hare->obj, tortoise->obj),
62360b89
DH
3843 s_bad_expression, hare->obj);
3844 }
3845 else
3846 {
3847 --tortoise_delay;
3848 }
3849
4057a3e0 3850 if (scm_is_simple_vector (hare->obj))
62360b89 3851 {
4057a3e0
MV
3852 size_t length = SCM_SIMPLE_VECTOR_LENGTH (hare->obj);
3853 SCM new_vector = scm_c_make_vector (length, SCM_UNSPECIFIED);
62360b89
DH
3854
3855 /* Each vector element is copied by recursing into copy_tree, having
3856 * the tortoise follow the hare into the depths of the stack. */
3857 unsigned long int i;
3858 for (i = 0; i < length; ++i)
3859 {
3860 SCM new_element;
4057a3e0 3861 new_hare.obj = SCM_SIMPLE_VECTOR_REF (hare->obj, i);
62360b89 3862 new_element = copy_tree (&new_hare, tortoise, tortoise_delay);
4057a3e0 3863 SCM_SIMPLE_VECTOR_SET (new_vector, i, new_element);
62360b89
DH
3864 }
3865
3866 return new_vector;
3867 }
2b829bbb 3868 else /* scm_is_pair (hare->obj) */
62360b89
DH
3869 {
3870 SCM result;
3871 SCM tail;
3872
3873 SCM rabbit = hare->obj;
3874 SCM turtle = hare->obj;
3875
3876 SCM copy;
3877
3878 /* The first pair of the list is treated specially, in order to
3879 * preserve a potential source code position. */
3880 result = tail = scm_cons_source (rabbit, SCM_EOL, SCM_EOL);
3881 new_hare.obj = SCM_CAR (rabbit);
3882 copy = copy_tree (&new_hare, tortoise, tortoise_delay);
3883 SCM_SETCAR (tail, copy);
3884
3885 /* The remaining pairs of the list are copied by, horizontally,
3886 * having the turtle follow the rabbit, and, vertically, having the
3887 * tortoise follow the hare into the depths of the stack. */
3888 rabbit = SCM_CDR (rabbit);
a61f4e0c 3889 while (scm_is_pair (rabbit))
62360b89
DH
3890 {
3891 new_hare.obj = SCM_CAR (rabbit);
3892 copy = copy_tree (&new_hare, tortoise, tortoise_delay);
3893 SCM_SETCDR (tail, scm_cons (copy, SCM_UNDEFINED));
3894 tail = SCM_CDR (tail);
3895
3896 rabbit = SCM_CDR (rabbit);
a61f4e0c 3897 if (scm_is_pair (rabbit))
62360b89
DH
3898 {
3899 new_hare.obj = SCM_CAR (rabbit);
3900 copy = copy_tree (&new_hare, tortoise, tortoise_delay);
3901 SCM_SETCDR (tail, scm_cons (copy, SCM_UNDEFINED));
3902 tail = SCM_CDR (tail);
3903 rabbit = SCM_CDR (rabbit);
3904
3905 turtle = SCM_CDR (turtle);
bc36d050 3906 ASSERT_SYNTAX (!scm_is_eq (rabbit, turtle),
62360b89
DH
3907 s_bad_expression, rabbit);
3908 }
3909 }
3910
3911 /* We have to recurse into copy_tree again for the last cdr, in
3912 * order to handle the situation that it holds a vector. */
3913 new_hare.obj = rabbit;
3914 copy = copy_tree (&new_hare, tortoise, tortoise_delay);
3915 SCM_SETCDR (tail, copy);
3916
3917 return result;
3918 }
3919 }
3920}
3921
a1ec6916 3922SCM_DEFINE (scm_copy_tree, "copy-tree", 1, 0, 0,
1bbd0b84 3923 (SCM obj),
b380b885 3924 "Recursively copy the data tree that is bound to @var{obj}, and return a\n"
bfefbf18 3925 "the new data structure. @code{copy-tree} recurses down the\n"
b380b885
MD
3926 "contents of both pairs and vectors (since both cons cells and vector\n"
3927 "cells may point to arbitrary objects), and stops recursing when it hits\n"
3928 "any other object.")
1bbd0b84 3929#define FUNC_NAME s_scm_copy_tree
0f2d19dd 3930{
62360b89
DH
3931 /* Prepare the trace along the stack. */
3932 struct t_trace trace;
3933 trace.obj = obj;
3934
3935 /* In function copy_tree, if the tortoise makes its step, it will do this
3936 * before the hare has the chance to move. Thus, we have to make sure that
3937 * the very first step of the tortoise will not happen after the hare has
3938 * really made two steps. This is achieved by passing '2' as the initial
3939 * delay for the tortoise. NOTE: Since cycles are unlikely, giving the hare
3940 * a bigger advantage may improve performance slightly. */
3941 return copy_tree (&trace, &trace, 2);
0f2d19dd 3942}
1bbd0b84 3943#undef FUNC_NAME
0f2d19dd 3944
1cc91f1b 3945
4163eb72
MV
3946/* We have three levels of EVAL here:
3947
3948 - scm_i_eval (exp, env)
3949
3950 evaluates EXP in environment ENV. ENV is a lexical environment
3951 structure as used by the actual tree code evaluator. When ENV is
3952 a top-level environment, then changes to the current module are
a513ead3 3953 tracked by updating ENV so that it continues to be in sync with
4163eb72
MV
3954 the current module.
3955
3956 - scm_primitive_eval (exp)
3957
3958 evaluates EXP in the top-level environment as determined by the
3959 current module. This is done by constructing a suitable
3960 environment and calling scm_i_eval. Thus, changes to the
3961 top-level module are tracked normally.
3962
9de87eea 3963 - scm_eval (exp, mod_or_state)
4163eb72 3964
9de87eea
MV
3965 evaluates EXP while MOD_OR_STATE is the current module or current
3966 dynamic state (as appropriate). This is done by setting the
3967 current module (or dynamic state) to MOD_OR_STATE, invoking
3968 scm_primitive_eval on EXP, and then restoring the current module
3969 (or dynamic state) to the value it had previously. That is,
3970 while EXP is evaluated, changes to the current module (or dynamic
3971 state) are tracked, but these changes do not persist when
4163eb72
MV
3972 scm_eval returns.
3973
3974 For each level of evals, there are two variants, distinguished by a
3975 _x suffix: the ordinary variant does not modify EXP while the _x
3976 variant can destructively modify EXP into something completely
3977 unintelligible. A Scheme data structure passed as EXP to one of the
3978 _x variants should not ever be used again for anything. So when in
3979 doubt, use the ordinary variant.
3980
3981*/
3982
0f2d19dd 3983SCM
68d8be66 3984scm_i_eval_x (SCM exp, SCM env)
0f2d19dd 3985{
cc95e00a 3986 if (scm_is_symbol (exp))
434f2f7a
DH
3987 return *scm_lookupcar (scm_cons (exp, SCM_UNDEFINED), env, 1);
3988 else
0ee05b85 3989 return SCM_I_XEVAL (exp, env, scm_debug_mode_p);
0f2d19dd
JB
3990}
3991
68d8be66
MD
3992SCM
3993scm_i_eval (SCM exp, SCM env)
3994{
26fb6390 3995 exp = scm_copy_tree (exp);
cc95e00a 3996 if (scm_is_symbol (exp))
434f2f7a
DH
3997 return *scm_lookupcar (scm_cons (exp, SCM_UNDEFINED), env, 1);
3998 else
0ee05b85 3999 return SCM_I_XEVAL (exp, env, scm_debug_mode_p);
68d8be66
MD
4000}
4001
4002SCM
4163eb72 4003scm_primitive_eval_x (SCM exp)
0f2d19dd 4004{
a513ead3 4005 SCM env;
bcdab802 4006 SCM transformer = scm_current_module_transformer ();
a513ead3 4007 if (SCM_NIMP (transformer))
fdc28395 4008 exp = scm_call_1 (transformer, exp);
a513ead3 4009 env = scm_top_level_env (scm_current_module_lookup_closure ());
4163eb72 4010 return scm_i_eval_x (exp, env);
0f2d19dd
JB
4011}
4012
4163eb72
MV
4013SCM_DEFINE (scm_primitive_eval, "primitive-eval", 1, 0, 0,
4014 (SCM exp),
2069af38 4015 "Evaluate @var{exp} in the top-level environment specified by\n"
4163eb72
MV
4016 "the current module.")
4017#define FUNC_NAME s_scm_primitive_eval
4018{
a513ead3 4019 SCM env;
bcdab802 4020 SCM transformer = scm_current_module_transformer ();
7888309b 4021 if (scm_is_true (transformer))
fdc28395 4022 exp = scm_call_1 (transformer, exp);
a513ead3 4023 env = scm_top_level_env (scm_current_module_lookup_closure ());
4163eb72
MV
4024 return scm_i_eval (exp, env);
4025}
4026#undef FUNC_NAME
4027
6bff1368 4028
68d8be66
MD
4029/* Eval does not take the second arg optionally. This is intentional
4030 * in order to be R5RS compatible, and to prepare for the new module
4031 * system, where we would like to make the choice of evaluation
4163eb72 4032 * environment explicit. */
549e6ec6 4033
4163eb72 4034SCM
9de87eea 4035scm_eval_x (SCM exp, SCM module_or_state)
4163eb72 4036{
9de87eea 4037 SCM res;
4163eb72 4038
661ae7ab 4039 scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
9de87eea 4040 if (scm_is_dynamic_state (module_or_state))
661ae7ab 4041 scm_dynwind_current_dynamic_state (module_or_state);
9de87eea 4042 else
661ae7ab 4043 scm_dynwind_current_module (module_or_state);
4163eb72 4044
9de87eea
MV
4045 res = scm_primitive_eval_x (exp);
4046
661ae7ab 4047 scm_dynwind_end ();
9de87eea 4048 return res;
4163eb72 4049}
09074dbf 4050
68d8be66 4051SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
9de87eea 4052 (SCM exp, SCM module_or_state),
4163eb72 4053 "Evaluate @var{exp}, a list representing a Scheme expression,\n"
9de87eea
MV
4054 "in the top-level environment specified by\n"
4055 "@var{module_or_state}.\n"
8f85c0c6 4056 "While @var{exp} is evaluated (using @code{primitive-eval}),\n"
9de87eea
MV
4057 "@var{module_or_state} is made the current module when\n"
4058 "it is a module, or the current dynamic state when it is\n"
4059 "a dynamic state."
6be1fab9 4060 "Example: (eval '(+ 1 2) (interaction-environment))")
1bbd0b84 4061#define FUNC_NAME s_scm_eval
0f2d19dd 4062{
9de87eea
MV
4063 SCM res;
4064
661ae7ab 4065 scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
9de87eea 4066 if (scm_is_dynamic_state (module_or_state))
661ae7ab 4067 scm_dynwind_current_dynamic_state (module_or_state);
181f1cd7 4068 else if (scm_module_system_booted_p)
61b6542a
LC
4069 {
4070 SCM_VALIDATE_MODULE (2, module_or_state);
4071 scm_dynwind_current_module (module_or_state);
4072 }
181f1cd7 4073 /* otherwise if the module system isn't booted, ignore the module arg */
9de87eea
MV
4074
4075 res = scm_primitive_eval (exp);
09074dbf 4076
661ae7ab 4077 scm_dynwind_end ();
9de87eea 4078 return res;
0f2d19dd 4079}
1bbd0b84 4080#undef FUNC_NAME
0f2d19dd 4081
6dbd0af5 4082
434f2f7a 4083/* At this point, deval and scm_dapply are generated.
6dbd0af5
MD
4084 */
4085
a44a9715 4086#define DEVAL
0ee05b85
HWN
4087#include "eval.i.c"
4088#undef DEVAL
4089#include "eval.i.c"
434f2f7a
DH
4090
4091
0f2d19dd
JB
4092void
4093scm_init_eval ()
0f2d19dd 4094{
d1138028
MV
4095 scm_i_pthread_mutex_init (&source_mutex,
4096 scm_i_pthread_mutexattr_recursive);
4097
33b97402 4098 scm_init_opts (scm_evaluator_traps,
62560650 4099 scm_evaluator_trap_table);
33b97402 4100 scm_init_opts (scm_eval_options_interface,
62560650 4101 scm_eval_opts);
33b97402 4102
f99c9c28 4103 scm_tc16_promise = scm_make_smob_type ("promise", 0);
e841c3e0 4104 scm_set_smob_print (scm_tc16_promise, promise_print);
b8229a3b 4105
a44a9715
DH
4106 undefineds = scm_list_1 (SCM_UNDEFINED);
4107 SCM_SETCDR (undefineds, undefineds);
4108 scm_permanent_object (undefineds);
7c33806a 4109
a44a9715 4110 scm_listofnull = scm_list_1 (SCM_EOL);
0f2d19dd 4111
a44a9715
DH
4112 f_apply = scm_c_define_subr ("apply", scm_tc7_lsubr_2, scm_apply);
4113 scm_permanent_object (f_apply);
86d31dfe 4114
a0599745 4115#include "libguile/eval.x"
60a49842 4116
25eaf21a 4117 scm_add_feature ("delay");
0f2d19dd 4118}
0f2d19dd 4119
89e00824
ML
4120/*
4121 Local Variables:
4122 c-file-style: "gnu"
4123 End:
4124*/
62560650 4125