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