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