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