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