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