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