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