* libguile/eval.c: Sorted include files alphabetically.
[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
1490scm_m_set_x (SCM xorig, SCM env SCM_UNUSED)
1491{
1492 SCM x = SCM_CDR (xorig);
e90c3a89
DH
1493 SCM_ASSYNT (scm_ilength (x) == 2, s_expression, s_set_x);
1494 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (x)), s_variable, s_set_x);
9fbee57e
DH
1495 return scm_cons (SCM_IM_SET_X, x);
1496}
1497
1498
1499/* Start of the memoizers for non-R5RS builtin macros. */
1500
1501
3b88ed2a 1502SCM_SYNTAX (s_atapply, "@apply", scm_i_makbimacro, scm_m_apply);
9fbee57e
DH
1503SCM_GLOBAL_SYMBOL (scm_sym_atapply, s_atapply);
1504SCM_GLOBAL_SYMBOL (scm_sym_apply, s_atapply + 1);
1505
1506SCM
1507scm_m_apply (SCM xorig, SCM env SCM_UNUSED)
1508{
e90c3a89 1509 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 2, s_expression, s_atapply);
9fbee57e 1510 return scm_cons (SCM_IM_APPLY, SCM_CDR (xorig));
73b64342
MD
1511}
1512
c96d76b8 1513
2e171178
MV
1514/* (@bind ((var exp) ...) body ...)
1515
1516 This will assign the values of the `exp's to the global variables
1517 named by `var's (symbols, not evaluated), creating them if they
1518 don't exist, executes body, and then restores the previous values of
1519 the `var's. Additionally, whenever control leaves body, the values
1520 of the `var's are saved and restored when control returns. It is an
1521 error when a symbol appears more than once among the `var's.
1522 All `exp's are evaluated before any `var' is set.
1523
c96d76b8 1524 Think of this as `let' for dynamic scope.
2e171178
MV
1525
1526 It is memoized into (#@bind ((var ...) . (reversed-val ...)) body ...).
1527
1528 XXX - also implement `@bind*'.
1529*/
1530
3b88ed2a 1531SCM_SYNTAX (s_atbind, "@bind", scm_i_makbimacro, scm_m_atbind);
73b64342
MD
1532
1533SCM
1534scm_m_atbind (SCM xorig, SCM env)
1535{
1536 SCM x = SCM_CDR (xorig);
2e171178 1537 SCM top_level = scm_env_top_level (env);
311f6782 1538 SCM vars = SCM_EOL, var;
2e171178
MV
1539 SCM exps = SCM_EOL;
1540
e90c3a89 1541 SCM_ASSYNT (scm_ilength (x) > 1, s_expression, s_atbind);
73b64342 1542
73b64342
MD
1543 x = SCM_CAR (x);
1544 while (SCM_NIMP (x))
1545 {
2e171178
MV
1546 SCM rest;
1547 SCM sym_exp = SCM_CAR (x);
e90c3a89
DH
1548 SCM_ASSYNT (scm_ilength (sym_exp) == 2, s_bindings, s_atbind);
1549 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (sym_exp)), s_bindings, s_atbind);
73b64342 1550 x = SCM_CDR (x);
2e171178 1551 for (rest = x; SCM_NIMP (rest); rest = SCM_CDR (rest))
8ea46249 1552 if (SCM_EQ_P (SCM_CAR (sym_exp), SCM_CAAR (rest)))
e90c3a89 1553 scm_misc_error (s_atbind, s_duplicate_bindings, SCM_EOL);
311f6782
MV
1554 /* The first call to scm_sym2var will look beyond the current
1555 module, while the second call wont. */
1556 var = scm_sym2var (SCM_CAR (sym_exp), top_level, SCM_BOOL_F);
1557 if (SCM_FALSEP (var))
1558 var = scm_sym2var (SCM_CAR (sym_exp), top_level, SCM_BOOL_T);
1559 vars = scm_cons (var, vars);
2e171178 1560 exps = scm_cons (SCM_CADR (sym_exp), exps);
73b64342 1561 }
2e171178
MV
1562 return scm_cons (SCM_IM_BIND,
1563 scm_cons (scm_cons (scm_reverse_x (vars, SCM_EOL), exps),
1564 SCM_CDDR (xorig)));
73b64342 1565}
73b64342 1566
b0c5d67b 1567
3b88ed2a 1568SCM_SYNTAX(s_atcall_cc, "@call-with-current-continuation", scm_i_makbimacro, scm_m_cont);
9fbee57e
DH
1569SCM_GLOBAL_SYMBOL(scm_sym_atcall_cc, s_atcall_cc);
1570
1571
1572SCM
1573scm_m_cont (SCM xorig, SCM env SCM_UNUSED)
b0c5d67b 1574{
9fbee57e 1575 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1,
e90c3a89 1576 s_expression, s_atcall_cc);
9fbee57e 1577 return scm_cons (SCM_IM_CONT, SCM_CDR (xorig));
b0c5d67b 1578}
b0c5d67b
DH
1579
1580
3b88ed2a 1581SCM_SYNTAX (s_at_call_with_values, "@call-with-values", scm_i_makbimacro, scm_m_at_call_with_values);
9fbee57e 1582SCM_GLOBAL_SYMBOL(scm_sym_at_call_with_values, s_at_call_with_values);
b0c5d67b
DH
1583
1584SCM
9fbee57e 1585scm_m_at_call_with_values (SCM xorig, SCM env SCM_UNUSED)
b0c5d67b 1586{
9fbee57e 1587 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 2,
e90c3a89 1588 s_expression, s_at_call_with_values);
9fbee57e 1589 return scm_cons (SCM_IM_CALL_WITH_VALUES, SCM_CDR (xorig));
b0c5d67b 1590}
b0c5d67b
DH
1591
1592
3b88ed2a 1593SCM_SYNTAX (s_future, "future", scm_i_makbimacro, scm_m_future);
9fbee57e 1594SCM_GLOBAL_SYMBOL (scm_sym_future, s_future);
a513ead3 1595
9fbee57e
DH
1596/* Like promises, futures are implemented as closures with an empty
1597 * parameter list. Thus, (future <expression>) is transformed into
1598 * (#@future '() <expression>), where the empty list represents the
1599 * empty parameter list. This representation allows for easy creation
1600 * of the closure during evaluation. */
a513ead3 1601SCM
8ae95199 1602scm_m_future (SCM expr, SCM env)
a513ead3 1603{
8ae95199
DH
1604 const SCM new_expr = memoize_as_thunk_prototype (expr, env);
1605 SCM_SETCAR (new_expr, SCM_IM_FUTURE);
1606 return new_expr;
a513ead3
MV
1607}
1608
9fbee57e 1609
3b88ed2a 1610SCM_SYNTAX (s_gset_x, "set!", scm_i_makbimacro, scm_m_generalized_set_x);
9fbee57e
DH
1611SCM_SYMBOL (scm_sym_setter, "setter");
1612
1613SCM
1614scm_m_generalized_set_x (SCM xorig, SCM env SCM_UNUSED)
1615{
1616 SCM x = SCM_CDR (xorig);
e90c3a89 1617 SCM_ASSYNT (2 == scm_ilength (x), s_expression, s_set_x);
9fbee57e
DH
1618 if (SCM_SYMBOLP (SCM_CAR (x)))
1619 return scm_cons (SCM_IM_SET_X, x);
1620 else if (SCM_CONSP (SCM_CAR (x)))
1621 return scm_cons (scm_list_2 (scm_sym_setter, SCM_CAAR (x)),
1622 scm_append (scm_list_2 (SCM_CDAR (x), SCM_CDR (x))));
1623 else
e90c3a89 1624 scm_misc_error (s_set_x, s_variable, SCM_EOL);
9fbee57e
DH
1625}
1626
1627
a4aa2134 1628static const char* s_atslot_ref = "@slot-ref";
9fbee57e 1629
a4aa2134
DH
1630/* @slot-ref is bound privately in the (oop goops) module from goops.c. As
1631 * soon as the module system allows us to more freely create bindings in
1632 * arbitrary modules during the startup phase, the code from goops.c should be
1633 * moved here. */
9fbee57e
DH
1634SCM
1635scm_m_atslot_ref (SCM xorig, SCM env SCM_UNUSED)
1636#define FUNC_NAME s_atslot_ref
1637{
1638 SCM x = SCM_CDR (xorig);
e90c3a89 1639 SCM_ASSYNT (scm_ilength (x) == 2, s_expression, FUNC_NAME);
9fbee57e
DH
1640 SCM_VALIDATE_INUM (SCM_ARG2, SCM_CADR (x));
1641 return scm_cons (SCM_IM_SLOT_REF, x);
1642}
1643#undef FUNC_NAME
1644
1645
a4aa2134 1646static const char* s_atslot_set_x = "@slot-set!";
9fbee57e 1647
a4aa2134
DH
1648/* @slot-set! is bound privately in the (oop goops) module from goops.c. As
1649 * soon as the module system allows us to more freely create bindings in
1650 * arbitrary modules during the startup phase, the code from goops.c should be
1651 * moved here. */
9fbee57e
DH
1652SCM
1653scm_m_atslot_set_x (SCM xorig, SCM env SCM_UNUSED)
1654#define FUNC_NAME s_atslot_set_x
1655{
1656 SCM x = SCM_CDR (xorig);
e90c3a89 1657 SCM_ASSYNT (scm_ilength (x) == 3, s_expression, FUNC_NAME);
9fbee57e
DH
1658 SCM_VALIDATE_INUM (SCM_ARG2, SCM_CADR (x));
1659 return scm_cons (SCM_IM_SLOT_SET_X, x);
1660}
1661#undef FUNC_NAME
1662
1663
1664#if SCM_ENABLE_ELISP
1665
3b88ed2a 1666SCM_SYNTAX (s_nil_cond, "nil-cond", scm_i_makbimacro, scm_m_nil_cond);
9fbee57e
DH
1667
1668SCM
1669scm_m_nil_cond (SCM xorig, SCM env SCM_UNUSED)
1670{
1671 long len = scm_ilength (SCM_CDR (xorig));
e90c3a89 1672 SCM_ASSYNT (len >= 1 && (len & 1) == 1, s_expression, "nil-cond");
9fbee57e
DH
1673 return scm_cons (SCM_IM_NIL_COND, SCM_CDR (xorig));
1674}
1675
1676
3b88ed2a 1677SCM_SYNTAX (s_atfop, "@fop", scm_i_makbimacro, scm_m_atfop);
9fbee57e
DH
1678
1679SCM
1680scm_m_atfop (SCM xorig, SCM env SCM_UNUSED)
1681{
1682 SCM x = SCM_CDR (xorig), var;
e90c3a89 1683 SCM_ASSYNT (scm_ilength (x) >= 1, s_expression, "@fop");
9fbee57e
DH
1684 var = scm_symbol_fref (SCM_CAR (x));
1685 /* Passing the symbol name as the `subr' arg here isn't really
1686 right, but without it it can be very difficult to work out from
1687 the error message which function definition was missing. In any
1688 case, we shouldn't really use SCM_ASSYNT here at all, but instead
1689 something equivalent to (signal void-function (list SYM)) in
1690 Elisp. */
1691 SCM_ASSYNT (SCM_VARIABLEP (var),
1692 "Symbol's function definition is void",
1693 SCM_SYMBOL_CHARS (SCM_CAR (x)));
1694 /* Support `defalias'. */
1695 while (SCM_SYMBOLP (SCM_VARIABLE_REF (var)))
1696 {
1697 var = scm_symbol_fref (SCM_VARIABLE_REF (var));
1698 SCM_ASSYNT (SCM_VARIABLEP (var),
1699 "Symbol's function definition is void",
1700 SCM_SYMBOL_CHARS (SCM_CAR (x)));
1701 }
1702 /* Use `var' here rather than `SCM_VARIABLE_REF (var)' because the
1703 former allows for automatically picking up redefinitions of the
1704 corresponding symbol. */
1705 SCM_SETCAR (x, var);
1706 /* If the variable contains a procedure, leave the
1707 `transformer-macro' in place so that the procedure's arguments
1708 get properly transformed, and change the initial @fop to
1709 SCM_IM_APPLY. */
1710 if (!SCM_MACROP (SCM_VARIABLE_REF (var)))
1711 {
1712 SCM_SETCAR (xorig, SCM_IM_APPLY);
1713 return xorig;
1714 }
1715 /* Otherwise (the variable contains a macro), the arguments should
1716 not be transformed, so cut the `transformer-macro' out and return
1717 the resulting expression starting with the variable. */
1718 SCM_SETCDR (x, SCM_CDADR (x));
1719 return x;
1720}
1721
1722#endif /* SCM_ENABLE_ELISP */
1723
1724
f58c472a
DH
1725/* Start of the memoizers for deprecated macros. */
1726
1727
1728#if (SCM_ENABLE_DEPRECATED == 1)
1729
1730SCM_SYNTAX (s_undefine, "undefine", scm_makacro, scm_m_undefine);
1731
1732SCM
1733scm_m_undefine (SCM x, SCM env)
1734{
1735 SCM arg1 = x;
1736 x = SCM_CDR (x);
1737 SCM_ASSYNT (SCM_TOP_LEVEL (env), "bad placement ", s_undefine);
1738 SCM_ASSYNT (SCM_CONSP (x) && SCM_NULLP (SCM_CDR (x)),
e90c3a89 1739 s_expression, s_undefine);
f58c472a 1740 x = SCM_CAR (x);
e90c3a89 1741 SCM_ASSYNT (SCM_SYMBOLP (x), s_variable, s_undefine);
f58c472a
DH
1742 arg1 = scm_sym2var (x, scm_env_top_level (env), SCM_BOOL_F);
1743 SCM_ASSYNT (!SCM_FALSEP (arg1) && !SCM_UNBNDP (SCM_VARIABLE_REF (arg1)),
1744 "variable already unbound ", s_undefine);
1745 SCM_VARIABLE_SET (arg1, SCM_UNDEFINED);
1746#ifdef SICP
1747 return x;
1748#else
1749 return SCM_UNSPECIFIED;
1750#endif
1751}
1752
1753#endif
1754
1755
26d5b9b4
MD
1756SCM
1757scm_m_expand_body (SCM xorig, SCM env)
1758{
22a52da1 1759 SCM x = SCM_CDR (xorig), defs = SCM_EOL;
26d5b9b4
MD
1760 char *what = SCM_ISYMCHARS (SCM_CAR (xorig)) + 2;
1761
1762 while (SCM_NIMP (x))
1763 {
22a52da1
DH
1764 SCM form = SCM_CAR (x);
1765 if (!SCM_CONSP (form))
26d5b9b4
MD
1766 break;
1767 if (!SCM_SYMBOLP (SCM_CAR (form)))
1768 break;
22a52da1 1769
3a3111a8
MD
1770 form = scm_macroexp (scm_cons_source (form,
1771 SCM_CAR (form),
1772 SCM_CDR (form)),
1773 env);
26d5b9b4 1774
cf498326 1775 if (SCM_EQ_P (SCM_IM_DEFINE, SCM_CAR (form)))
26d5b9b4
MD
1776 {
1777 defs = scm_cons (SCM_CDR (form), defs);
22a52da1 1778 x = SCM_CDR (x);
26d5b9b4 1779 }
22a52da1 1780 else if (!SCM_IMP (defs))
26d5b9b4
MD
1781 {
1782 break;
1783 }
cf498326 1784 else if (SCM_EQ_P (SCM_IM_BEGIN, SCM_CAR (form)))
26d5b9b4 1785 {
8ea46249 1786 x = scm_append (scm_list_2 (SCM_CDR (form), SCM_CDR (x)));
26d5b9b4
MD
1787 }
1788 else
1789 {
22a52da1 1790 x = scm_cons (form, SCM_CDR (x));
26d5b9b4
MD
1791 break;
1792 }
1793 }
1794
302c12b4 1795 if (!SCM_NULLP (defs))
26d5b9b4 1796 {
302c12b4 1797 SCM rvars, inits, body, letrec;
d6754c23
DH
1798 check_bindings (defs, xorig);
1799 transform_bindings (defs, xorig, &rvars, &inits);
302c12b4
DH
1800 body = scm_m_body (SCM_IM_DEFINE, x, what);
1801 letrec = scm_cons2 (SCM_IM_LETREC, rvars, scm_cons (inits, body));
1802 SCM_SETCAR (xorig, letrec);
1803 SCM_SETCDR (xorig, SCM_EOL);
1804 }
1805 else
1806 {
e90c3a89 1807 SCM_ASSYNT (SCM_CONSP (x), s_body, what);
302c12b4
DH
1808 SCM_SETCAR (xorig, SCM_CAR (x));
1809 SCM_SETCDR (xorig, SCM_CDR (x));
26d5b9b4 1810 }
26d5b9b4
MD
1811
1812 return xorig;
1813}
1814
1815SCM
1816scm_macroexp (SCM x, SCM env)
1817{
86d31dfe 1818 SCM res, proc, orig_sym;
26d5b9b4
MD
1819
1820 /* Don't bother to produce error messages here. We get them when we
1821 eventually execute the code for real. */
1822
1823 macro_tail:
86d31dfe
MV
1824 orig_sym = SCM_CAR (x);
1825 if (!SCM_SYMBOLP (orig_sym))
26d5b9b4
MD
1826 return x;
1827
26d5b9b4
MD
1828 {
1829 SCM *proc_ptr = scm_lookupcar1 (x, env, 0);
1830 if (proc_ptr == NULL)
1831 {
1832 /* We have lost the race. */
1833 goto macro_tail;
1834 }
1835 proc = *proc_ptr;
1836 }
26d5b9b4
MD
1837
1838 /* Only handle memoizing macros. `Acros' and `macros' are really
1839 special forms and should not be evaluated here. */
1840
3b88ed2a
DH
1841 if (!SCM_MACROP (proc)
1842 || (SCM_MACRO_TYPE (proc) != 2 && !SCM_BUILTIN_MACRO_P (proc)))
26d5b9b4
MD
1843 return x;
1844
86d31dfe 1845 SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of lookupcar */
fdc28395 1846 res = scm_call_2 (SCM_MACRO_CODE (proc), x, env);
26d5b9b4
MD
1847
1848 if (scm_ilength (res) <= 0)
8ea46249 1849 res = scm_list_2 (SCM_IM_BEGIN, res);
26d5b9b4 1850
26d5b9b4
MD
1851 SCM_DEFER_INTS;
1852 SCM_SETCAR (x, SCM_CAR (res));
1853 SCM_SETCDR (x, SCM_CDR (res));
1854 SCM_ALLOW_INTS;
1855
1856 goto macro_tail;
1857}
73b64342 1858
a44a9715
DH
1859#define SCM_BIT7(x) (127 & SCM_UNPACK (x))
1860
1861/* A function object to implement "apply" for non-closure functions. */
1862static SCM f_apply;
1863/* An endless list consisting of #<undefined> objects: */
1864static SCM undefineds;
1865
6dbd0af5
MD
1866/* scm_unmemocopy takes a memoized expression together with its
1867 * environment and rewrites it to its original form. Thus, it is the
1868 * inversion of the rewrite rules above. The procedure is not
1869 * optimized for speed. It's used in scm_iprin1 when printing the
220ff1eb
MD
1870 * code of a closure, in scm_procedure_source, in display_frame when
1871 * generating the source for a stackframe in a backtrace, and in
1872 * display_expression.
86d31dfe 1873 *
c96d76b8 1874 * Unmemoizing is not a reliable process. You cannot in general
86d31dfe
MV
1875 * expect to get the original source back.
1876 *
1877 * However, GOOPS currently relies on this for method compilation.
1878 * This ought to change.
26d5b9b4
MD
1879 */
1880
8ea46249
DH
1881static SCM
1882build_binding_list (SCM names, SCM inits)
1883{
1884 SCM bindings = SCM_EOL;
1885 while (!SCM_NULLP (names))
1886 {
1887 SCM binding = scm_list_2 (SCM_CAR (names), SCM_CAR (inits));
1888 bindings = scm_cons (binding, bindings);
1889 names = SCM_CDR (names);
1890 inits = SCM_CDR (inits);
1891 }
1892 return bindings;
1893}
1894
6dbd0af5 1895static SCM
1bbd0b84 1896unmemocopy (SCM x, SCM env)
6dbd0af5
MD
1897{
1898 SCM ls, z;
6dbd0af5 1899 SCM p;
21628685
DH
1900
1901 if (SCM_VECTORP (x))
1902 {
1903 return scm_list_2 (scm_sym_quote, x);
1904 }
1905 else if (!SCM_CONSP (x))
6dbd0af5 1906 return x;
21628685 1907
6dbd0af5 1908 p = scm_whash_lookup (scm_source_whash, x);
8ea46249 1909 switch (SCM_ITAG7 (SCM_CAR (x)))
6dbd0af5 1910 {
1b43d24c 1911 case SCM_BIT7 (SCM_IM_AND):
2f0d1375 1912 ls = z = scm_cons (scm_sym_and, SCM_UNSPECIFIED);
6dbd0af5 1913 break;
1b43d24c 1914 case SCM_BIT7 (SCM_IM_BEGIN):
2f0d1375 1915 ls = z = scm_cons (scm_sym_begin, SCM_UNSPECIFIED);
6dbd0af5 1916 break;
1b43d24c 1917 case SCM_BIT7 (SCM_IM_CASE):
2f0d1375 1918 ls = z = scm_cons (scm_sym_case, SCM_UNSPECIFIED);
6dbd0af5 1919 break;
1b43d24c 1920 case SCM_BIT7 (SCM_IM_COND):
2f0d1375 1921 ls = z = scm_cons (scm_sym_cond, SCM_UNSPECIFIED);
6dbd0af5 1922 break;
1b43d24c 1923 case SCM_BIT7 (SCM_IM_DO):
6dbd0af5 1924 {
e681d187
DH
1925 /* format: (#@do (i1 ... ik) (nk nk-1 ...) (test) (body) s1 ... sk),
1926 * where ix is an initializer for a local variable, nx is the name of
8ea46249
DH
1927 * the local variable, test is the test clause of the do loop, body is
1928 * the body of the do loop and sx are the step clauses for the local
1929 * variables. */
1930 SCM names, inits, test, memoized_body, steps, bindings;
1931
6dbd0af5 1932 x = SCM_CDR (x);
8ea46249 1933 inits = scm_reverse (unmemocopy (SCM_CAR (x), env));
e681d187
DH
1934 x = SCM_CDR (x);
1935 names = SCM_CAR (x);
821f18a4 1936 env = SCM_EXTEND_ENV (names, SCM_EOL, env);
6dbd0af5 1937 x = SCM_CDR (x);
8ea46249
DH
1938 test = unmemocopy (SCM_CAR (x), env);
1939 x = SCM_CDR (x);
1940 memoized_body = SCM_CAR (x);
1941 x = SCM_CDR (x);
1942 steps = scm_reverse (unmemocopy (x, env));
1943
26d5b9b4 1944 /* build transformed binding list */
8ea46249
DH
1945 bindings = SCM_EOL;
1946 while (!SCM_NULLP (names))
6dbd0af5 1947 {
8ea46249
DH
1948 SCM name = SCM_CAR (names);
1949 SCM init = SCM_CAR (inits);
1950 SCM step = SCM_CAR (steps);
1951 step = SCM_EQ_P (step, name) ? SCM_EOL : scm_list_1 (step);
1952
1953 bindings = scm_cons (scm_cons2 (name, init, step), bindings);
1954
1955 names = SCM_CDR (names);
1956 inits = SCM_CDR (inits);
1957 steps = SCM_CDR (steps);
6dbd0af5 1958 }
8ea46249
DH
1959 z = scm_cons (test, SCM_UNSPECIFIED);
1960 ls = scm_cons2 (scm_sym_do, bindings, z);
1961
1962 x = scm_cons (SCM_BOOL_F, memoized_body);
1963 break;
1964 }
1b43d24c 1965 case SCM_BIT7 (SCM_IM_IF):
8ea46249
DH
1966 ls = z = scm_cons (scm_sym_if, SCM_UNSPECIFIED);
1967 break;
1b43d24c 1968 case SCM_BIT7 (SCM_IM_LET):
8ea46249
DH
1969 {
1970 /* format: (#@let (nk nk-1 ...) (i1 ... ik) b1 ...),
1971 * where nx is the name of a local variable, ix is an initializer for
1972 * the local variable and by are the body clauses. */
1973 SCM names, inits, bindings;
1974
1975 x = SCM_CDR (x);
1976 names = SCM_CAR (x);
1977 x = SCM_CDR (x);
1978 inits = scm_reverse (unmemocopy (SCM_CAR (x), env));
821f18a4 1979 env = SCM_EXTEND_ENV (names, SCM_EOL, env);
8ea46249
DH
1980
1981 bindings = build_binding_list (names, inits);
1982 z = scm_cons (bindings, SCM_UNSPECIFIED);
1983 ls = scm_cons (scm_sym_let, z);
1984 break;
1985 }
1b43d24c 1986 case SCM_BIT7 (SCM_IM_LETREC):
8ea46249
DH
1987 {
1988 /* format: (#@letrec (nk nk-1 ...) (i1 ... ik) b1 ...),
1989 * where nx is the name of a local variable, ix is an initializer for
1990 * the local variable and by are the body clauses. */
1991 SCM names, inits, bindings;
1992
1993 x = SCM_CDR (x);
1994 names = SCM_CAR (x);
821f18a4 1995 env = SCM_EXTEND_ENV (names, SCM_EOL, env);
8ea46249
DH
1996 x = SCM_CDR (x);
1997 inits = scm_reverse (unmemocopy (SCM_CAR (x), env));
1998
1999 bindings = build_binding_list (names, inits);
2000 z = scm_cons (bindings, SCM_UNSPECIFIED);
2001 ls = scm_cons (scm_sym_letrec, z);
6dbd0af5
MD
2002 break;
2003 }
1b43d24c 2004 case SCM_BIT7 (SCM_IM_LETSTAR):
6dbd0af5
MD
2005 {
2006 SCM b, y;
2007 x = SCM_CDR (x);
2008 b = SCM_CAR (x);
2009 y = SCM_EOL;
2010 if SCM_IMP (b)
2011 {
821f18a4 2012 env = SCM_EXTEND_ENV (SCM_EOL, SCM_EOL, env);
6dbd0af5
MD
2013 goto letstar;
2014 }
2015 y = z = scm_acons (SCM_CAR (b),
2016 unmemocar (
8ea46249 2017 scm_cons (unmemocopy (SCM_CADR (b), env), SCM_EOL), env),
6dbd0af5 2018 SCM_UNSPECIFIED);
821f18a4 2019 env = SCM_EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
8ea46249 2020 b = SCM_CDDR (b);
6dbd0af5
MD
2021 if (SCM_IMP (b))
2022 {
2023 SCM_SETCDR (y, SCM_EOL);
05b15362
DH
2024 z = scm_cons (y, SCM_UNSPECIFIED);
2025 ls = scm_cons (scm_sym_let, z);
6dbd0af5
MD
2026 break;
2027 }
2028 do
2029 {
a23afe53
MD
2030 SCM_SETCDR (z, scm_acons (SCM_CAR (b),
2031 unmemocar (
8ea46249 2032 scm_list_1 (unmemocopy (SCM_CADR (b), env)), env),
a23afe53
MD
2033 SCM_UNSPECIFIED));
2034 z = SCM_CDR (z);
821f18a4 2035 env = SCM_EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
8ea46249 2036 b = SCM_CDDR (b);
6dbd0af5 2037 }
ff467021 2038 while (SCM_NIMP (b));
a23afe53 2039 SCM_SETCDR (z, SCM_EOL);
6dbd0af5 2040 letstar:
05b15362
DH
2041 z = scm_cons (y, SCM_UNSPECIFIED);
2042 ls = scm_cons (scm_sym_letstar, z);
6dbd0af5
MD
2043 break;
2044 }
1b43d24c 2045 case SCM_BIT7 (SCM_IM_OR):
2f0d1375 2046 ls = z = scm_cons (scm_sym_or, SCM_UNSPECIFIED);
6dbd0af5 2047 break;
1b43d24c 2048 case SCM_BIT7 (SCM_IM_LAMBDA):
6dbd0af5 2049 x = SCM_CDR (x);
8ea46249
DH
2050 z = scm_cons (SCM_CAR (x), SCM_UNSPECIFIED);
2051 ls = scm_cons (scm_sym_lambda, z);
821f18a4 2052 env = SCM_EXTEND_ENV (SCM_CAR (x), SCM_EOL, env);
6dbd0af5 2053 break;
1b43d24c 2054 case SCM_BIT7 (SCM_IM_QUOTE):
2f0d1375 2055 ls = z = scm_cons (scm_sym_quote, SCM_UNSPECIFIED);
6dbd0af5 2056 break;
1b43d24c 2057 case SCM_BIT7 (SCM_IM_SET_X):
89efbff4 2058 ls = z = scm_cons (scm_sym_set_x, SCM_UNSPECIFIED);
6dbd0af5 2059 break;
1b43d24c 2060 case SCM_BIT7 (SCM_MAKISYM (0)):
6dbd0af5 2061 z = SCM_CAR (x);
ff467021 2062 switch (SCM_ISYMNUM (z))
6dbd0af5 2063 {
22f2cf2d
DH
2064 case (SCM_ISYMNUM (SCM_IM_DEFINE)):
2065 {
2066 SCM n;
2067 x = SCM_CDR (x);
2068 n = SCM_CAR (x);
2069 z = scm_cons (n, SCM_UNSPECIFIED);
2070 ls = scm_cons (scm_sym_define, z);
2071 if (!SCM_NULLP (env))
2072 env = scm_cons (scm_cons (scm_cons (n, SCM_CAAR (env)),
2073 SCM_CDAR (env)),
2074 SCM_CDR (env));
2075 break;
2076 }
6dbd0af5 2077 case (SCM_ISYMNUM (SCM_IM_APPLY)):
2f0d1375 2078 ls = z = scm_cons (scm_sym_atapply, SCM_UNSPECIFIED);
6dbd0af5
MD
2079 goto loop;
2080 case (SCM_ISYMNUM (SCM_IM_CONT)):
2f0d1375 2081 ls = z = scm_cons (scm_sym_atcall_cc, SCM_UNSPECIFIED);
6dbd0af5 2082 goto loop;
a570e93a
MD
2083 case (SCM_ISYMNUM (SCM_IM_DELAY)):
2084 ls = z = scm_cons (scm_sym_delay, SCM_UNSPECIFIED);
2085 x = SCM_CDR (x);
2086 goto loop;
28d52ebb 2087 case (SCM_ISYMNUM (SCM_IM_FUTURE)):
ebf9b47c 2088 ls = z = scm_cons (scm_sym_future, SCM_UNSPECIFIED);
28d52ebb
MD
2089 x = SCM_CDR (x);
2090 goto loop;
a513ead3
MV
2091 case (SCM_ISYMNUM (SCM_IM_CALL_WITH_VALUES)):
2092 ls = z = scm_cons (scm_sym_at_call_with_values, SCM_UNSPECIFIED);
2093 goto loop;
2a6f7afe
DH
2094 case (SCM_ISYMNUM (SCM_IM_ELSE)):
2095 ls = z = scm_cons (scm_sym_else, SCM_UNSPECIFIED);
2096 goto loop;
6dbd0af5 2097 default:
fa888178 2098 /* appease the Sun compiler god: */ ;
6dbd0af5 2099 }
6dbd0af5
MD
2100 default:
2101 ls = z = unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env),
2102 SCM_UNSPECIFIED),
2103 env);
2104 }
2105loop:
8c494e99
DH
2106 x = SCM_CDR (x);
2107 while (SCM_CONSP (x))
a23afe53 2108 {
8c494e99
DH
2109 SCM form = SCM_CAR (x);
2110 if (!SCM_ISYMP (form))
2111 {
2112 SCM copy = scm_cons (unmemocopy (form, env), SCM_UNSPECIFIED);
2113 SCM_SETCDR (z, unmemocar (copy, env));
2114 z = SCM_CDR (z);
2115 }
609a8b86
DH
2116 else if (SCM_EQ_P (form, SCM_IM_ARROW))
2117 {
2118 SCM_SETCDR (z, scm_cons (scm_sym_arrow, SCM_UNSPECIFIED));
2119 z = SCM_CDR (z);
2120 }
8c494e99 2121 x = SCM_CDR (x);
a23afe53
MD
2122 }
2123 SCM_SETCDR (z, x);
01f11e02 2124 if (!SCM_FALSEP (p))
6dbd0af5 2125 scm_whash_insert (scm_source_whash, ls, p);
6dbd0af5
MD
2126 return ls;
2127}
2128
1cc91f1b 2129
6dbd0af5 2130SCM
6e8d25a6 2131scm_unmemocopy (SCM x, SCM env)
6dbd0af5 2132{
01f11e02 2133 if (!SCM_NULLP (env))
6dbd0af5
MD
2134 /* Make a copy of the lowest frame to protect it from
2135 modifications by SCM_IM_DEFINE */
2136 return unmemocopy (x, scm_cons (SCM_CAR (env), SCM_CDR (env)));
2137 else
2138 return unmemocopy (x, env);
2139}
2140
1cc91f1b 2141
0f2d19dd 2142int
6e8d25a6 2143scm_badargsp (SCM formals, SCM args)
0f2d19dd 2144{
6a0f6ff3 2145 while (!SCM_NULLP (formals))
0f2d19dd 2146 {
01f11e02 2147 if (!SCM_CONSP (formals))
ff467021 2148 return 0;
6a0f6ff3 2149 if (SCM_NULLP (args))
ff467021 2150 return 1;
0f2d19dd
JB
2151 formals = SCM_CDR (formals);
2152 args = SCM_CDR (args);
2153 }
01f11e02 2154 return !SCM_NULLP (args) ? 1 : 0;
0f2d19dd 2155}
a392ee15 2156
0f2d19dd 2157\f
6dbd0af5 2158SCM
6e8d25a6 2159scm_eval_args (SCM l, SCM env, SCM proc)
6dbd0af5 2160{
680ed4a8 2161 SCM results = SCM_EOL, *lloc = &results, res;
904a077d 2162 while (SCM_CONSP (l))
6dbd0af5 2163 {
680ed4a8 2164 res = EVALCAR (l, env);
904a077d 2165
8ea46249 2166 *lloc = scm_list_1 (res);
a23afe53 2167 lloc = SCM_CDRLOC (*lloc);
6dbd0af5
MD
2168 l = SCM_CDR (l);
2169 }
22a52da1 2170 if (!SCM_NULLP (l))
904a077d 2171 scm_wrong_num_args (proc);
680ed4a8 2172 return results;
6dbd0af5 2173}
c4ac4d88 2174
d0b07b5d 2175
9de33deb
MD
2176SCM
2177scm_eval_body (SCM code, SCM env)
2178{
2179 SCM next;
2180 again:
01f11e02
DH
2181 next = SCM_CDR (code);
2182 while (!SCM_NULLP (next))
9de33deb
MD
2183 {
2184 if (SCM_IMP (SCM_CAR (code)))
2185 {
2186 if (SCM_ISYMP (SCM_CAR (code)))
2187 {
28d52ebb 2188 scm_rec_mutex_lock (&source_mutex);
9bc4701c
MD
2189 /* check for race condition */
2190 if (SCM_ISYMP (SCM_CAR (code)))
2191 code = scm_m_expand_body (code, env);
28d52ebb 2192 scm_rec_mutex_unlock (&source_mutex);
9de33deb
MD
2193 goto again;
2194 }
2195 }
2196 else
2197 SCM_XEVAL (SCM_CAR (code), env);
2198 code = next;
01f11e02 2199 next = SCM_CDR (code);
9de33deb
MD
2200 }
2201 return SCM_XEVALCAR (code, env);
2202}
2203
0f2d19dd
JB
2204#endif /* !DEVAL */
2205
6dbd0af5
MD
2206
2207/* SECTION: This code is specific for the debugging support. One
2208 * branch is read when DEVAL isn't defined, the other when DEVAL is
2209 * defined.
2210 */
2211
2212#ifndef DEVAL
2213
2214#define SCM_APPLY scm_apply
2215#define PREP_APPLY(proc, args)
2216#define ENTER_APPLY
ddea3325 2217#define RETURN(x) do { return x; } while (0)
b7ff98dd
MD
2218#ifdef STACK_CHECKING
2219#ifndef NO_CEVAL_STACK_CHECKING
2220#define EVAL_STACK_CHECKING
2221#endif
6dbd0af5
MD
2222#endif
2223
2224#else /* !DEVAL */
2225
0f2d19dd
JB
2226#undef SCM_CEVAL
2227#define SCM_CEVAL scm_deval /* Substitute all uses of scm_ceval */
2228#undef SCM_APPLY
2229#define SCM_APPLY scm_dapply
6dbd0af5
MD
2230#undef PREP_APPLY
2231#define PREP_APPLY(p, l) \
2232{ ++debug.info; debug.info->a.proc = p; debug.info->a.args = l; }
2233#undef ENTER_APPLY
2234#define ENTER_APPLY \
d3a6bc94 2235do { \
b7ff98dd 2236 SCM_SET_ARGSREADY (debug);\
5132eef0 2237 if (scm_check_apply_p && SCM_TRAPS_P)\
b7ff98dd 2238 if (SCM_APPLY_FRAME_P || (SCM_TRACE_P && PROCTRACEP (proc)))\
6dbd0af5 2239 {\
156dcb09 2240 SCM tmp, tail = SCM_BOOL(SCM_TRACED_FRAME_P (debug)); \
c6a4fbce 2241 SCM_SET_TRACED_FRAME (debug); \
d95c0b76 2242 SCM_TRAPS_P = 0;\
b7ff98dd 2243 if (SCM_CHEAPTRAPS_P)\
6dbd0af5 2244 {\
c0ab1b8d 2245 tmp = scm_make_debugobj (&debug);\
d95c0b76 2246 scm_call_3 (SCM_APPLY_FRAME_HDLR, scm_sym_apply_frame, tmp, tail);\
b6d75948 2247 }\
6dbd0af5
MD
2248 else\
2249 {\
5f144b10
GH
2250 int first;\
2251 tmp = scm_make_continuation (&first);\
2252 if (first)\
d95c0b76 2253 scm_call_3 (SCM_APPLY_FRAME_HDLR, scm_sym_apply_frame, tmp, tail);\
6dbd0af5 2254 }\
d95c0b76 2255 SCM_TRAPS_P = 1;\
6dbd0af5 2256 }\
d3a6bc94 2257} while (0)
0f2d19dd 2258#undef RETURN
ddea3325 2259#define RETURN(e) do { proc = (e); goto exit; } while (0)
b7ff98dd
MD
2260#ifdef STACK_CHECKING
2261#ifndef EVAL_STACK_CHECKING
2262#define EVAL_STACK_CHECKING
2263#endif
6dbd0af5
MD
2264#endif
2265
2266/* scm_ceval_ptr points to the currently selected evaluator.
2267 * *fixme*: Although efficiency is important here, this state variable
2268 * should probably not be a global. It should be related to the
2269 * current repl.
2270 */
2271
1cc91f1b 2272
1bbd0b84 2273SCM (*scm_ceval_ptr) (SCM x, SCM env);
0f2d19dd 2274
1646d37b 2275/* scm_last_debug_frame contains a pointer to the last debugging
6dbd0af5
MD
2276 * information stack frame. It is accessed very often from the
2277 * debugging evaluator, so it should probably not be indirectly
2278 * addressed. Better to save and restore it from the current root at
2279 * any stack swaps.
2280 */
2281
6dbd0af5
MD
2282/* scm_debug_eframe_size is the number of slots available for pseudo
2283 * stack frames at each real stack frame.
2284 */
2285
c014a02e 2286long scm_debug_eframe_size;
6dbd0af5 2287
b7ff98dd 2288int scm_debug_mode, scm_check_entry_p, scm_check_apply_p, scm_check_exit_p;
6dbd0af5 2289
c014a02e 2290long scm_eval_stack;
a74145b8 2291
92c2555f 2292scm_t_option scm_eval_opts[] = {
a74145b8 2293 { SCM_OPTION_INTEGER, "stack", 22000, "Size of thread stacks (in machine words)." }
33b97402
MD
2294};
2295
92c2555f 2296scm_t_option scm_debug_opts[] = {
b7ff98dd
MD
2297 { SCM_OPTION_BOOLEAN, "cheap", 1,
2298 "*Flyweight representation of the stack at traps." },
2299 { SCM_OPTION_BOOLEAN, "breakpoints", 0, "*Check for breakpoints." },
2300 { SCM_OPTION_BOOLEAN, "trace", 0, "*Trace mode." },
2301 { SCM_OPTION_BOOLEAN, "procnames", 1,
2302 "Record procedure names at definition." },
2303 { SCM_OPTION_BOOLEAN, "backwards", 0,
2304 "Display backtrace in anti-chronological order." },
274dc5fd 2305 { SCM_OPTION_INTEGER, "width", 79, "Maximal width of backtrace." },
4e646a03
MD
2306 { SCM_OPTION_INTEGER, "indent", 10, "Maximal indentation in backtrace." },
2307 { SCM_OPTION_INTEGER, "frames", 3,
b7ff98dd 2308 "Maximum number of tail-recursive frames in backtrace." },
4e646a03
MD
2309 { SCM_OPTION_INTEGER, "maxdepth", 1000,
2310 "Maximal number of stored backtrace frames." },
2311 { SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." },
11f77bfc
MD
2312 { SCM_OPTION_BOOLEAN, "backtrace", 0, "Show backtrace on error." },
2313 { SCM_OPTION_BOOLEAN, "debug", 0, "Use the debugging evaluator." },
863e833b 2314 { SCM_OPTION_INTEGER, "stack", 20000, "Stack size limit (measured in words; 0 = no check)." },
d95c0b76 2315 { 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
2316};
2317
92c2555f 2318scm_t_option scm_evaluator_trap_table[] = {
b6d75948 2319 { SCM_OPTION_BOOLEAN, "traps", 0, "Enable evaluator traps." },
b7ff98dd
MD
2320 { SCM_OPTION_BOOLEAN, "enter-frame", 0, "Trap when eval enters new frame." },
2321 { SCM_OPTION_BOOLEAN, "apply-frame", 0, "Trap when entering apply." },
d95c0b76
NJ
2322 { SCM_OPTION_BOOLEAN, "exit-frame", 0, "Trap when exiting eval or apply." },
2323 { SCM_OPTION_SCM, "enter-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for enter-frame traps." },
2324 { SCM_OPTION_SCM, "apply-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for apply-frame traps." },
2325 { SCM_OPTION_SCM, "exit-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for exit-frame traps." }
6dbd0af5
MD
2326};
2327
a1ec6916 2328SCM_DEFINE (scm_eval_options_interface, "eval-options-interface", 0, 1, 0,
1bbd0b84 2329 (SCM setting),
b3f26b14
MG
2330 "Option interface for the evaluation options. Instead of using\n"
2331 "this procedure directly, use the procedures @code{eval-enable},\n"
3939e9df 2332 "@code{eval-disable}, @code{eval-set!} and @code{eval-options}.")
1bbd0b84 2333#define FUNC_NAME s_scm_eval_options_interface
33b97402
MD
2334{
2335 SCM ans;
2336 SCM_DEFER_INTS;
2337 ans = scm_options (setting,
2338 scm_eval_opts,
2339 SCM_N_EVAL_OPTIONS,
1bbd0b84 2340 FUNC_NAME);
a74145b8 2341 scm_eval_stack = SCM_EVAL_STACK * sizeof (void *);
33b97402
MD
2342 SCM_ALLOW_INTS;
2343 return ans;
2344}
1bbd0b84 2345#undef FUNC_NAME
33b97402 2346
d0b07b5d 2347
a1ec6916 2348SCM_DEFINE (scm_evaluator_traps, "evaluator-traps-interface", 0, 1, 0,
1bbd0b84 2349 (SCM setting),
b3f26b14 2350 "Option interface for the evaluator trap options.")
1bbd0b84 2351#define FUNC_NAME s_scm_evaluator_traps
33b97402
MD
2352{
2353 SCM ans;
2354 SCM_DEFER_INTS;
2355 ans = scm_options (setting,
2356 scm_evaluator_trap_table,
2357 SCM_N_EVALUATOR_TRAPS,
1bbd0b84 2358 FUNC_NAME);
33b97402 2359 SCM_RESET_DEBUG_MODE;
bfc69694 2360 SCM_ALLOW_INTS;
33b97402
MD
2361 return ans;
2362}
1bbd0b84 2363#undef FUNC_NAME
33b97402 2364
d0b07b5d 2365
24933780 2366static SCM
a392ee15 2367deval_args (SCM l, SCM env, SCM proc, SCM *lloc)
0f2d19dd 2368{
680ed4a8 2369 SCM *results = lloc, res;
904a077d 2370 while (SCM_CONSP (l))
0f2d19dd 2371 {
680ed4a8 2372 res = EVALCAR (l, env);
904a077d 2373
8ea46249 2374 *lloc = scm_list_1 (res);
a23afe53 2375 lloc = SCM_CDRLOC (*lloc);
0f2d19dd
JB
2376 l = SCM_CDR (l);
2377 }
22a52da1 2378 if (!SCM_NULLP (l))
904a077d 2379 scm_wrong_num_args (proc);
680ed4a8 2380 return *results;
0f2d19dd
JB
2381}
2382
6dbd0af5
MD
2383#endif /* !DEVAL */
2384
2385
a392ee15 2386/* SECTION: This code is compiled twice.
6dbd0af5
MD
2387 */
2388
a392ee15 2389
d9d39d76 2390/* Update the toplevel environment frame ENV so that it refers to the
a392ee15 2391 * current module. */
d9d39d76
MV
2392#define UPDATE_TOPLEVEL_ENV(env) \
2393 do { \
2394 SCM p = scm_current_module_lookup_closure (); \
d0b07b5d 2395 if (p != SCM_CAR (env)) \
d9d39d76
MV
2396 env = scm_top_level_env (p); \
2397 } while (0)
2398
6dbd0af5 2399
a392ee15
DH
2400/* This is the evaluator. Like any real monster, it has three heads:
2401 *
2402 * scm_ceval is the non-debugging evaluator, scm_deval is the debugging
2403 * version. Both are implemented using a common code base, using the
2404 * following mechanism: SCM_CEVAL is a macro, which is either defined to
2405 * scm_ceval or scm_deval. Thus, there is no function SCM_CEVAL, but the code
2406 * for SCM_CEVAL actually compiles to either scm_ceval or scm_deval. When
2407 * SCM_CEVAL is defined to scm_ceval, it is known that the macro DEVAL is not
2408 * defined. When SCM_CEVAL is defined to scm_deval, then the macro DEVAL is
2409 * known to be defined. Thus, in SCM_CEVAL parts for the debugging evaluator
2410 * are enclosed within #ifdef DEVAL ... #endif.
2411 *
2412 * All three (scm_ceval, scm_deval and their common implementation SCM_CEVAL)
2413 * take two input parameters, x and env: x is a single expression to be
2414 * evalutated. env is the environment in which bindings are searched.
2415 *
2416 * x is known to be a cell (i. e. a pair or any other non-immediate). Since x
2417 * is a single expression, it is necessarily in a tail position. If x is just
2418 * a call to another function like in the expression (foo exp1 exp2 ...), the
2419 * realization of that call therefore _must_not_ increase stack usage (the
2420 * evaluation of exp1, exp2 etc., however, may do so). This is realized by
2421 * making extensive use of 'goto' statements within the evaluator: The gotos
2422 * replace recursive calls to SCM_CEVAL, thus re-using the same stack frame
2423 * that SCM_CEVAL was already using. If, however, x represents some form that
2424 * requires to evaluate a sequence of expressions like (begin exp1 exp2 ...),
2425 * then recursive calls to SCM_CEVAL are performed for all but the last
2426 * expression of that sequence. */
6dbd0af5 2427
0f2d19dd 2428#if 0
0f2d19dd 2429SCM
1bbd0b84 2430scm_ceval (SCM x, SCM env)
0f2d19dd
JB
2431{}
2432#endif
1cc91f1b 2433
a392ee15 2434#if 0
0f2d19dd 2435SCM
1bbd0b84 2436scm_deval (SCM x, SCM env)
0f2d19dd
JB
2437{}
2438#endif
2439
6dbd0af5 2440SCM
1bbd0b84 2441SCM_CEVAL (SCM x, SCM env)
0f2d19dd 2442{
42030fb2 2443 SCM proc, arg1;
6dbd0af5 2444#ifdef DEVAL
92c2555f
MV
2445 scm_t_debug_frame debug;
2446 scm_t_debug_info *debug_info_end;
1646d37b 2447 debug.prev = scm_last_debug_frame;
020c890c 2448 debug.status = 0;
04b6c081 2449 /*
92c2555f 2450 * The debug.vect contains twice as much scm_t_debug_info frames as the
04b6c081
MD
2451 * user has specified with (debug-set! frames <n>).
2452 *
2453 * Even frames are eval frames, odd frames are apply frames.
2454 */
92c2555f 2455 debug.vect = (scm_t_debug_info *) alloca (scm_debug_eframe_size
a392ee15 2456 * sizeof (scm_t_debug_info));
c0ab1b8d
JB
2457 debug.info = debug.vect;
2458 debug_info_end = debug.vect + scm_debug_eframe_size;
2459 scm_last_debug_frame = &debug;
6dbd0af5 2460#endif
b7ff98dd 2461#ifdef EVAL_STACK_CHECKING
79f55b7c 2462 if (scm_stack_checking_enabled_p && SCM_STACK_OVERFLOW_P (&proc))
6dbd0af5 2463 {
b7ff98dd 2464#ifdef DEVAL
6dbd0af5
MD
2465 debug.info->e.exp = x;
2466 debug.info->e.env = env;
b7ff98dd 2467#endif
6dbd0af5
MD
2468 scm_report_stack_overflow ();
2469 }
2470#endif
6a0f6ff3 2471
6dbd0af5
MD
2472#ifdef DEVAL
2473 goto start;
2474#endif
6a0f6ff3 2475
6dbd0af5
MD
2476loop:
2477#ifdef DEVAL
b7ff98dd
MD
2478 SCM_CLEAR_ARGSREADY (debug);
2479 if (SCM_OVERFLOWP (debug))
6dbd0af5 2480 --debug.info;
04b6c081
MD
2481 /*
2482 * In theory, this should be the only place where it is necessary to
2483 * check for space in debug.vect since both eval frames and
2484 * available space are even.
2485 *
2486 * For this to be the case, however, it is necessary that primitive
2487 * special forms which jump back to `loop', `begin' or some similar
680516ba 2488 * label call PREP_APPLY.
04b6c081 2489 */
c0ab1b8d 2490 else if (++debug.info >= debug_info_end)
6dbd0af5 2491 {
b7ff98dd 2492 SCM_SET_OVERFLOW (debug);
6dbd0af5
MD
2493 debug.info -= 2;
2494 }
6a0f6ff3 2495
6dbd0af5
MD
2496start:
2497 debug.info->e.exp = x;
2498 debug.info->e.env = env;
5132eef0
DH
2499 if (scm_check_entry_p && SCM_TRAPS_P)
2500 {
bc76d628
DH
2501 if (SCM_ENTER_FRAME_P
2502 || (SCM_BREAKPOINTS_P && scm_c_source_property_breakpoint_p (x)))
5132eef0 2503 {
bc76d628
DH
2504 SCM stackrep;
2505 SCM tail = SCM_BOOL (SCM_TAILRECP (debug));
5132eef0
DH
2506 SCM_SET_TAILREC (debug);
2507 if (SCM_CHEAPTRAPS_P)
bc76d628 2508 stackrep = scm_make_debugobj (&debug);
5132eef0
DH
2509 else
2510 {
2511 int first;
2512 SCM val = scm_make_continuation (&first);
2513
2514 if (first)
bc76d628 2515 stackrep = val;
5132eef0
DH
2516 else
2517 {
2518 x = val;
2519 if (SCM_IMP (x))
2520 RETURN (x);
2521 else
2522 /* This gives the possibility for the debugger to
2523 modify the source expression before evaluation. */
2524 goto dispatch;
2525 }
2526 }
2527 SCM_TRAPS_P = 0;
2528 scm_call_4 (SCM_ENTER_FRAME_HDLR,
2529 scm_sym_enter_frame,
bc76d628 2530 stackrep,
5132eef0
DH
2531 tail,
2532 scm_unmemocopy (x, env));
2533 SCM_TRAPS_P = 1;
2534 }
2535 }
6dbd0af5 2536#endif
f8769b1d 2537dispatch:
9cb5124f 2538 SCM_TICK;
0f2d19dd
JB
2539 switch (SCM_TYP7 (x))
2540 {
28b06554 2541 case scm_tc7_symbol:
a392ee15 2542 /* Only happens when called at top level. */
0f2d19dd 2543 x = scm_cons (x, SCM_UNDEFINED);
ddea3325 2544 RETURN (*scm_lookupcar (x, env, 1));
0f2d19dd 2545
1b43d24c 2546 case SCM_BIT7 (SCM_IM_AND):
0f2d19dd 2547 x = SCM_CDR (x);
302c12b4
DH
2548 while (!SCM_NULLP (SCM_CDR (x)))
2549 {
38ace99e
DH
2550 SCM test_result = EVALCAR (x, env);
2551 if (SCM_FALSEP (test_result) || SCM_NILP (test_result))
0f2d19dd 2552 RETURN (SCM_BOOL_F);
302c12b4
DH
2553 else
2554 x = SCM_CDR (x);
2555 }
6dbd0af5 2556 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2557 goto carloop;
2558
1b43d24c 2559 case SCM_BIT7 (SCM_IM_BEGIN):
e050d4f8
DH
2560 x = SCM_CDR (x);
2561 if (SCM_NULLP (x))
b8113bc8
MV
2562 RETURN (SCM_UNSPECIFIED);
2563
6dbd0af5 2564 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2565
2566 begin:
4163eb72
MV
2567 /* If we are on toplevel with a lookup closure, we need to sync
2568 with the current module. */
22a52da1 2569 if (SCM_CONSP (env) && !SCM_CONSP (SCM_CAR (env)))
4163eb72 2570 {
d9d39d76 2571 UPDATE_TOPLEVEL_ENV (env);
302c12b4 2572 while (!SCM_NULLP (SCM_CDR (x)))
4163eb72 2573 {
5280aaca 2574 EVALCAR (x, env);
d9d39d76 2575 UPDATE_TOPLEVEL_ENV (env);
302c12b4 2576 x = SCM_CDR (x);
4163eb72 2577 }
5280aaca 2578 goto carloop;
4163eb72
MV
2579 }
2580 else
5280aaca
MV
2581 goto nontoplevel_begin;
2582
5280aaca 2583 nontoplevel_begin:
302c12b4 2584 while (!SCM_NULLP (SCM_CDR (x)))
0f2d19dd 2585 {
6a0f6ff3
DH
2586 SCM form = SCM_CAR (x);
2587 if (SCM_IMP (form))
26d5b9b4 2588 {
6a0f6ff3 2589 if (SCM_ISYMP (form))
26d5b9b4 2590 {
28d52ebb 2591 scm_rec_mutex_lock (&source_mutex);
9bc4701c
MD
2592 /* check for race condition */
2593 if (SCM_ISYMP (SCM_CAR (x)))
2594 x = scm_m_expand_body (x, env);
28d52ebb 2595 scm_rec_mutex_unlock (&source_mutex);
5280aaca 2596 goto nontoplevel_begin;
26d5b9b4 2597 }
4163eb72 2598 else
6a0f6ff3 2599 SCM_VALIDATE_NON_EMPTY_COMBINATION (form);
26d5b9b4 2600 }
5280aaca 2601 else
6a0f6ff3 2602 SCM_CEVAL (form, env);
302c12b4 2603 x = SCM_CDR (x);
0f2d19dd 2604 }
5280aaca 2605
6a0f6ff3
DH
2606 carloop:
2607 {
2608 /* scm_eval last form in list */
2609 SCM last_form = SCM_CAR (x);
0f2d19dd 2610
6a0f6ff3
DH
2611 if (SCM_CONSP (last_form))
2612 {
2613 /* This is by far the most frequent case. */
2614 x = last_form;
2615 goto loop; /* tail recurse */
2616 }
2617 else if (SCM_IMP (last_form))
2618 RETURN (SCM_EVALIM (last_form, env));
2619 else if (SCM_VARIABLEP (last_form))
2620 RETURN (SCM_VARIABLE_REF (last_form));
2621 else if (SCM_SYMBOLP (last_form))
2622 RETURN (*scm_lookupcar (x, env, 1));
2623 else
2624 RETURN (last_form);
2625 }
0f2d19dd
JB
2626
2627
1b43d24c 2628 case SCM_BIT7 (SCM_IM_CASE):
0f2d19dd 2629 x = SCM_CDR (x);
6a0f6ff3
DH
2630 {
2631 SCM key = EVALCAR (x, env);
2632 x = SCM_CDR (x);
2633 while (!SCM_NULLP (x))
2634 {
2635 SCM clause = SCM_CAR (x);
2636 SCM labels = SCM_CAR (clause);
2a6f7afe 2637 if (SCM_EQ_P (labels, SCM_IM_ELSE))
6a0f6ff3
DH
2638 {
2639 x = SCM_CDR (clause);
2640 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2641 goto begin;
2642 }
2643 while (!SCM_NULLP (labels))
2644 {
2645 SCM label = SCM_CAR (labels);
2646 if (SCM_EQ_P (label, key) || !SCM_FALSEP (scm_eqv_p (label, key)))
2647 {
2648 x = SCM_CDR (clause);
2649 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2650 goto begin;
2651 }
2652 labels = SCM_CDR (labels);
2653 }
2654 x = SCM_CDR (x);
2655 }
2656 }
ddea3325 2657 RETURN (SCM_UNSPECIFIED);
0f2d19dd
JB
2658
2659
1b43d24c 2660 case SCM_BIT7 (SCM_IM_COND):
8ea46249
DH
2661 x = SCM_CDR (x);
2662 while (!SCM_NULLP (x))
0f2d19dd 2663 {
e5cb71a0 2664 SCM clause = SCM_CAR (x);
609a8b86 2665 if (SCM_EQ_P (SCM_CAR (clause), SCM_IM_ELSE))
8ea46249 2666 {
e5cb71a0 2667 x = SCM_CDR (clause);
8ea46249
DH
2668 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2669 goto begin;
2670 }
e5cb71a0 2671 else
0f2d19dd 2672 {
dff98306
DH
2673 arg1 = EVALCAR (clause, env);
2674 if (!SCM_FALSEP (arg1) && !SCM_NILP (arg1))
6dbd0af5 2675 {
e5cb71a0
DH
2676 x = SCM_CDR (clause);
2677 if (SCM_NULLP (x))
dff98306 2678 RETURN (arg1);
609a8b86 2679 else if (!SCM_EQ_P (SCM_CAR (x), SCM_IM_ARROW))
e5cb71a0
DH
2680 {
2681 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2682 goto begin;
2683 }
2684 else
2685 {
2686 proc = SCM_CDR (x);
2687 proc = EVALCAR (proc, env);
dff98306 2688 PREP_APPLY (proc, scm_list_1 (arg1));
e5cb71a0 2689 ENTER_APPLY;
ddd8f927 2690 goto evap1;
e5cb71a0 2691 }
6dbd0af5 2692 }
e5cb71a0 2693 x = SCM_CDR (x);
0f2d19dd
JB
2694 }
2695 }
ddea3325 2696 RETURN (SCM_UNSPECIFIED);
0f2d19dd
JB
2697
2698
1b43d24c 2699 case SCM_BIT7 (SCM_IM_DO):
0f2d19dd 2700 x = SCM_CDR (x);
e5cb71a0
DH
2701 {
2702 /* Compute the initialization values and the initial environment. */
e681d187 2703 SCM init_forms = SCM_CAR (x);
e5cb71a0
DH
2704 SCM init_values = SCM_EOL;
2705 while (!SCM_NULLP (init_forms))
2706 {
2707 init_values = scm_cons (EVALCAR (init_forms, env), init_values);
2708 init_forms = SCM_CDR (init_forms);
2709 }
e681d187 2710 x = SCM_CDR (x);
821f18a4 2711 env = SCM_EXTEND_ENV (SCM_CAR (x), init_values, env);
e5cb71a0 2712 }
e681d187 2713 x = SCM_CDR (x);
e5cb71a0
DH
2714 {
2715 SCM test_form = SCM_CAR (x);
2716 SCM body_forms = SCM_CADR (x);
2717 SCM step_forms = SCM_CDDR (x);
2718
2719 SCM test_result = EVALCAR (test_form, env);
2720
2721 while (SCM_FALSEP (test_result) || SCM_NILP (test_result))
2722 {
0f2d19dd 2723 {
e5cb71a0
DH
2724 /* Evaluate body forms. */
2725 SCM temp_forms;
2726 for (temp_forms = body_forms;
2727 !SCM_NULLP (temp_forms);
2728 temp_forms = SCM_CDR (temp_forms))
2729 {
2730 SCM form = SCM_CAR (temp_forms);
2731 /* Dirk:FIXME: We only need to eval forms, that may have a
2732 * side effect here. This is only true for forms that start
2733 * with a pair. All others are just constants. However,
2734 * since in the common case there is no constant expression
2735 * in a body of a do form, we just check for immediates here
2736 * and have SCM_CEVAL take care of other cases. In the long
2737 * run it would make sense to get rid of this test and have
2738 * the macro transformer of 'do' eliminate all forms that
2739 * have no sideeffect. */
2740 if (!SCM_IMP (form))
2741 SCM_CEVAL (form, env);
2742 }
0f2d19dd 2743 }
e5cb71a0
DH
2744
2745 {
2746 /* Evaluate the step expressions. */
2747 SCM temp_forms;
2748 SCM step_values = SCM_EOL;
2749 for (temp_forms = step_forms;
2750 !SCM_NULLP (temp_forms);
2751 temp_forms = SCM_CDR (temp_forms))
2752 {
2753 SCM value = EVALCAR (temp_forms, env);
2754 step_values = scm_cons (value, step_values);
2755 }
821f18a4
DH
2756 env = SCM_EXTEND_ENV (SCM_CAAR (env),
2757 step_values,
2758 SCM_CDR (env));
e5cb71a0
DH
2759 }
2760
2761 test_result = EVALCAR (test_form, env);
2762 }
2763 }
2764 x = SCM_CDAR (x);
0f2d19dd 2765 if (SCM_NULLP (x))
6dbd0af5
MD
2766 RETURN (SCM_UNSPECIFIED);
2767 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
5280aaca 2768 goto nontoplevel_begin;
0f2d19dd
JB
2769
2770
1b43d24c 2771 case SCM_BIT7 (SCM_IM_IF):
0f2d19dd 2772 x = SCM_CDR (x);
38ace99e
DH
2773 {
2774 SCM test_result = EVALCAR (x, env);
4610b011
DH
2775 x = SCM_CDR (x); /* then expression */
2776 if (SCM_FALSEP (test_result) || SCM_NILP (test_result))
38ace99e 2777 {
4610b011 2778 x = SCM_CDR (x); /* else expression */
38ace99e
DH
2779 if (SCM_NULLP (x))
2780 RETURN (SCM_UNSPECIFIED);
2781 }
2782 }
6dbd0af5 2783 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2784 goto carloop;
2785
2786
1b43d24c 2787 case SCM_BIT7 (SCM_IM_LET):
0f2d19dd 2788 x = SCM_CDR (x);
38ace99e
DH
2789 {
2790 SCM init_forms = SCM_CADR (x);
2791 SCM init_values = SCM_EOL;
2792 do
2793 {
2794 init_values = scm_cons (EVALCAR (init_forms, env), init_values);
2795 init_forms = SCM_CDR (init_forms);
2796 }
2797 while (!SCM_NULLP (init_forms));
821f18a4 2798 env = SCM_EXTEND_ENV (SCM_CAR (x), init_values, env);
38ace99e 2799 }
e050d4f8
DH
2800 x = SCM_CDDR (x);
2801 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2802 goto nontoplevel_begin;
0f2d19dd
JB
2803
2804
1b43d24c 2805 case SCM_BIT7 (SCM_IM_LETREC):
0f2d19dd 2806 x = SCM_CDR (x);
821f18a4 2807 env = SCM_EXTEND_ENV (SCM_CAR (x), undefineds, env);
0f2d19dd 2808 x = SCM_CDR (x);
38ace99e
DH
2809 {
2810 SCM init_forms = SCM_CAR (x);
2811 SCM init_values = SCM_EOL;
2812 do
2813 {
2814 init_values = scm_cons (EVALCAR (init_forms, env), init_values);
2815 init_forms = SCM_CDR (init_forms);
2816 }
2817 while (!SCM_NULLP (init_forms));
2818 SCM_SETCDR (SCM_CAR (env), init_values);
2819 }
e050d4f8
DH
2820 x = SCM_CDR (x);
2821 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2822 goto nontoplevel_begin;
0f2d19dd
JB
2823
2824
1b43d24c 2825 case SCM_BIT7 (SCM_IM_LETSTAR):
0f2d19dd 2826 x = SCM_CDR (x);
302c12b4
DH
2827 {
2828 SCM bindings = SCM_CAR (x);
2829 if (SCM_NULLP (bindings))
821f18a4 2830 env = SCM_EXTEND_ENV (SCM_EOL, SCM_EOL, env);
302c12b4
DH
2831 else
2832 {
2833 do
2834 {
2835 SCM name = SCM_CAR (bindings);
2836 SCM init = SCM_CDR (bindings);
821f18a4 2837 env = SCM_EXTEND_ENV (name, EVALCAR (init, env), env);
302c12b4
DH
2838 bindings = SCM_CDR (init);
2839 }
2840 while (!SCM_NULLP (bindings));
2841 }
2842 }
e050d4f8
DH
2843 x = SCM_CDR (x);
2844 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2845 goto nontoplevel_begin;
0f2d19dd 2846
302c12b4 2847
1b43d24c 2848 case SCM_BIT7 (SCM_IM_OR):
0f2d19dd 2849 x = SCM_CDR (x);
302c12b4 2850 while (!SCM_NULLP (SCM_CDR (x)))
0f2d19dd 2851 {
302c12b4 2852 SCM val = EVALCAR (x, env);
c96d76b8 2853 if (!SCM_FALSEP (val) && !SCM_NILP (val))
302c12b4
DH
2854 RETURN (val);
2855 else
2856 x = SCM_CDR (x);
0f2d19dd 2857 }
6dbd0af5 2858 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2859 goto carloop;
2860
2861
1b43d24c 2862 case SCM_BIT7 (SCM_IM_LAMBDA):
0f2d19dd
JB
2863 RETURN (scm_closure (SCM_CDR (x), env));
2864
2865
1b43d24c 2866 case SCM_BIT7 (SCM_IM_QUOTE):
8ea46249 2867 RETURN (SCM_CADR (x));
0f2d19dd
JB
2868
2869
1b43d24c 2870 case SCM_BIT7 (SCM_IM_SET_X):
0f2d19dd 2871 x = SCM_CDR (x);
38ace99e
DH
2872 {
2873 SCM *location;
2874 SCM variable = SCM_CAR (x);
e050d4f8 2875 if (SCM_ILOCP (variable))
38ace99e 2876 location = scm_ilookup (variable, env);
3063e30a 2877 else if (SCM_VARIABLEP (variable))
e050d4f8 2878 location = SCM_VARIABLE_LOC (variable);
38ace99e
DH
2879 else /* (SCM_SYMBOLP (variable)) is known to be true */
2880 location = scm_lookupcar (x, env, 1);
2881 x = SCM_CDR (x);
2882 *location = EVALCAR (x, env);
2883 }
0f2d19dd 2884 RETURN (SCM_UNSPECIFIED);
0f2d19dd
JB
2885
2886
0f2d19dd 2887 /* new syntactic forms go here. */
1b43d24c 2888 case SCM_BIT7 (SCM_MAKISYM (0)):
0f2d19dd 2889 proc = SCM_CAR (x);
a392ee15 2890 switch (SCM_ISYMNUM (proc))
0f2d19dd 2891 {
3f04400d
DH
2892
2893
22f2cf2d
DH
2894 case (SCM_ISYMNUM (SCM_IM_DEFINE)):
2895 /* Top level defines are handled directly by the memoizer and thus
2896 * will never generate memoized code with SCM_IM_DEFINE. Internal
2897 * defines which occur at valid positions will be transformed into
2898 * letrec expressions. Thus, whenever the executor detects
2899 * SCM_IM_DEFINE, this must come from an internal definition at an
2900 * illegal position. */
2901 scm_misc_error (NULL, "Bad define placement", SCM_EOL);
2902
2903
0f2d19dd 2904 case (SCM_ISYMNUM (SCM_IM_APPLY)):
e910e9d2
DH
2905 x = SCM_CDR (x);
2906 proc = EVALCAR (x, env);
2907 PREP_APPLY (proc, SCM_EOL);
2908 x = SCM_CDR (x);
2909 arg1 = EVALCAR (x, env);
9a069bdd
DH
2910
2911 apply_proc:
2912 /* Go here to tail-apply a procedure. PROC is the procedure and
2913 * ARG1 is the list of arguments. PREP_APPLY must have been called
2914 * before jumping to apply_proc. */
0f2d19dd
JB
2915 if (SCM_CLOSUREP (proc))
2916 {
9a069bdd 2917 SCM formals = SCM_CLOSURE_FORMALS (proc);
6dbd0af5 2918#ifdef DEVAL
9a069bdd 2919 debug.info->a.args = arg1;
6dbd0af5 2920#endif
9a069bdd
DH
2921 if (scm_badargsp (formals, arg1))
2922 scm_wrong_num_args (proc);
2923 ENTER_APPLY;
2924 /* Copy argument list */
2925 if (SCM_NULL_OR_NIL_P (arg1))
2926 env = SCM_EXTEND_ENV (formals, SCM_EOL, SCM_ENV (proc));
2927 else
2928 {
2929 SCM args = scm_list_1 (SCM_CAR (arg1));
2930 SCM tail = args;
2931 arg1 = SCM_CDR (arg1);
2932 while (!SCM_NULL_OR_NIL_P (arg1))
2933 {
2934 SCM new_tail = scm_list_1 (SCM_CAR (arg1));
2935 SCM_SETCDR (tail, new_tail);
2936 tail = new_tail;
2937 arg1 = SCM_CDR (arg1);
2938 }
2939 env = SCM_EXTEND_ENV (formals, args, SCM_ENV (proc));
2940 }
2941
2942 x = SCM_CLOSURE_BODY (proc);
2943 goto nontoplevel_begin;
0f2d19dd 2944 }
3f04400d
DH
2945 else
2946 {
e910e9d2
DH
2947 ENTER_APPLY;
2948 RETURN (SCM_APPLY (proc, arg1, SCM_EOL));
3f04400d
DH
2949 }
2950
0f2d19dd
JB
2951
2952 case (SCM_ISYMNUM (SCM_IM_CONT)):
5f144b10
GH
2953 {
2954 int first;
2955 SCM val = scm_make_continuation (&first);
2956
e050d4f8 2957 if (!first)
5f144b10 2958 RETURN (val);
e050d4f8
DH
2959 else
2960 {
2961 arg1 = val;
2962 proc = SCM_CDR (x);
2963 proc = scm_eval_car (proc, env);
e050d4f8
DH
2964 PREP_APPLY (proc, scm_list_1 (arg1));
2965 ENTER_APPLY;
e050d4f8
DH
2966 goto evap1;
2967 }
5f144b10 2968 }
e050d4f8 2969
0f2d19dd 2970
a570e93a 2971 case (SCM_ISYMNUM (SCM_IM_DELAY)):
ddea3325 2972 RETURN (scm_makprom (scm_closure (SCM_CDR (x), env)));
a570e93a 2973
e050d4f8 2974
28d52ebb
MD
2975 case (SCM_ISYMNUM (SCM_IM_FUTURE)):
2976 RETURN (scm_i_make_future (scm_closure (SCM_CDR (x), env)));
2977
2978
c8e1d354
MD
2979 /* PLACEHOLDER for case (SCM_ISYMNUM (SCM_IM_DISPATCH)): The
2980 following code (type_dispatch) is intended to be the tail
2981 of the case clause for the internal macro
2982 SCM_IM_DISPATCH. Please don't remove it from this
2983 location without discussing it with Mikael
2984 <djurfeldt@nada.kth.se> */
2985
f12745b6
DH
2986 /* The type dispatch code is duplicated below
2987 * (c.f. objects.c:scm_mcache_compute_cmethod) since that
2988 * cuts down execution time for type dispatch to 50%. */
dff98306 2989 type_dispatch: /* inputs: x, arg1 */
f12745b6
DH
2990 /* Type dispatch means to determine from the types of the function
2991 * arguments (i. e. the 'signature' of the call), which method from
2992 * a generic function is to be called. This process of selecting
2993 * the right method takes some time. To speed it up, guile uses
2994 * caching: Together with the macro call to dispatch the signatures
2995 * of some previous calls to that generic function from the same
2996 * place are stored (in the code!) in a cache that we call the
2997 * 'method cache'. This is done since it is likely, that
2998 * consecutive calls to dispatch from that position in the code will
2999 * have the same signature. Thus, the type dispatch works as
3000 * follows: First, determine a hash value from the signature of the
3001 * actual arguments. Second, use this hash value as an index to
3002 * find that same signature in the method cache stored at this
3003 * position in the code. If found, you have also found the
3004 * corresponding method that belongs to that signature. If the
3005 * signature is not found in the method cache, you have to perform a
3006 * full search over all signatures stored with the generic
3007 * function. */
3008 {
3009 unsigned long int specializers;
3010 unsigned long int hash_value;
3011 unsigned long int cache_end_pos;
3012 unsigned long int mask;
3013 SCM method_cache;
3014
3015 {
3016 SCM z = SCM_CDDR (x);
3017 SCM tmp = SCM_CADR (z);
3018 specializers = SCM_INUM (SCM_CAR (z));
3019
3020 /* Compute a hash value for searching the method cache. There
3021 * are two variants for computing the hash value, a (rather)
3022 * complicated one, and a simple one. For the complicated one
3023 * explained below, tmp holds a number that is used in the
3024 * computation. */
3025 if (SCM_INUMP (tmp))
3026 {
3027 /* Use the signature of the actual arguments to determine
3028 * the hash value. This is done as follows: Each class has
3029 * an array of random numbers, that are determined when the
3030 * class is created. The integer 'hashset' is an index into
3031 * that array of random numbers. Now, from all classes that
3032 * are part of the signature of the actual arguments, the
3033 * random numbers at index 'hashset' are taken and summed
3034 * up, giving the hash value. The value of 'hashset' is
3035 * stored at the call to dispatch. This allows to have
3036 * different 'formulas' for calculating the hash value at
3037 * different places where dispatch is called. This allows
3038 * to optimize the hash formula at every individual place
3039 * where dispatch is called, such that hopefully the hash
3040 * value that is computed will directly point to the right
3041 * method in the method cache. */
3042 unsigned long int hashset = SCM_INUM (tmp);
3043 unsigned long int counter = specializers + 1;
dff98306 3044 SCM tmp_arg = arg1;
f12745b6
DH
3045 hash_value = 0;
3046 while (!SCM_NULLP (tmp_arg) && counter != 0)
61364ba6 3047 {
f12745b6
DH
3048 SCM class = scm_class_of (SCM_CAR (tmp_arg));
3049 hash_value += SCM_INSTANCE_HASH (class, hashset);
3050 tmp_arg = SCM_CDR (tmp_arg);
3051 counter--;
61364ba6 3052 }
f12745b6
DH
3053 z = SCM_CDDR (z);
3054 method_cache = SCM_CADR (z);
3055 mask = SCM_INUM (SCM_CAR (z));
3056 hash_value &= mask;
3057 cache_end_pos = hash_value;
3058 }
3059 else
3060 {
3061 /* This method of determining the hash value is much
3062 * simpler: Set the hash value to zero and just perform a
3063 * linear search through the method cache. */
3064 method_cache = tmp;
3065 mask = (unsigned long int) ((long) -1);
3066 hash_value = 0;
3067 cache_end_pos = SCM_VECTOR_LENGTH (method_cache);
3068 }
3069 }
61364ba6 3070
f12745b6
DH
3071 {
3072 /* Search the method cache for a method with a matching
3073 * signature. Start the search at position 'hash_value'. The
3074 * hashing implementation uses linear probing for conflict
3075 * resolution, that is, if the signature in question is not
3076 * found at the starting index in the hash table, the next table
3077 * entry is tried, and so on, until in the worst case the whole
3078 * cache has been searched, but still the signature has not been
3079 * found. */
3080 SCM z;
3081 do
3082 {
dff98306 3083 SCM args = arg1; /* list of arguments */
f12745b6
DH
3084 z = SCM_VELTS (method_cache)[hash_value];
3085 while (!SCM_NULLP (args))
61364ba6
MD
3086 {
3087 /* More arguments than specifiers => CLASS != ENV */
f12745b6
DH
3088 SCM class_of_arg = scm_class_of (SCM_CAR (args));
3089 if (!SCM_EQ_P (class_of_arg, SCM_CAR (z)))
61364ba6 3090 goto next_method;
f12745b6 3091 args = SCM_CDR (args);
61364ba6
MD
3092 z = SCM_CDR (z);
3093 }
f12745b6
DH
3094 /* Fewer arguments than specifiers => CAR != ENV */
3095 if (SCM_NULLP (SCM_CAR (z)) || SCM_CONSP (SCM_CAR (z)))
3096 goto apply_cmethod;
3097 next_method:
3098 hash_value = (hash_value + 1) & mask;
3099 } while (hash_value != cache_end_pos);
3100
3101 /* No appropriate method was found in the cache. */
dff98306 3102 z = scm_memoize_method (x, arg1);
f12745b6 3103
dff98306 3104 apply_cmethod: /* inputs: z, arg1 */
f12745b6
DH
3105 {
3106 SCM formals = SCM_CMETHOD_FORMALS (z);
821f18a4 3107 env = SCM_EXTEND_ENV (formals, arg1, SCM_CMETHOD_ENV (z));
f12745b6
DH
3108 x = SCM_CMETHOD_BODY (z);
3109 goto nontoplevel_begin;
3110 }
3111 }
61364ba6 3112 }
73b64342 3113
1d15ecd3 3114
ca4be6ea
MD
3115 case (SCM_ISYMNUM (SCM_IM_SLOT_REF)):
3116 x = SCM_CDR (x);
1d15ecd3
DH
3117 {
3118 SCM instance = EVALCAR (x, env);
3119 unsigned long int slot = SCM_INUM (SCM_CADR (x));
3120 RETURN (SCM_PACK (SCM_STRUCT_DATA (instance) [slot]));
3121 }
3122
3123
ca4be6ea
MD
3124 case (SCM_ISYMNUM (SCM_IM_SLOT_SET_X)):
3125 x = SCM_CDR (x);
1d15ecd3
DH
3126 {
3127 SCM instance = EVALCAR (x, env);
3128 unsigned long int slot = SCM_INUM (SCM_CADR (x));
3129 SCM value = EVALCAR (SCM_CDDR (x), env);
3130 SCM_STRUCT_DATA (instance) [slot] = SCM_UNPACK (value);
3131 RETURN (SCM_UNSPECIFIED);
3132 }
3133
c96d76b8 3134
22721140 3135#if SCM_ENABLE_ELISP
ca4be6ea 3136
73b64342 3137 case (SCM_ISYMNUM (SCM_IM_NIL_COND)):
1d15ecd3
DH
3138 {
3139 SCM test_form = SCM_CDR (x);
3140 x = SCM_CDR (test_form);
3141 while (!SCM_NULL_OR_NIL_P (x))
3142 {
3143 SCM test_result = EVALCAR (test_form, env);
3144 if (!(SCM_FALSEP (test_result)
3145 || SCM_NULL_OR_NIL_P (test_result)))
3146 {
3147 if (SCM_EQ_P (SCM_CAR (x), SCM_UNSPECIFIED))
3148 RETURN (test_result);
3149 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
3150 goto carloop;
3151 }
3152 else
3153 {
3154 test_form = SCM_CDR (x);
3155 x = SCM_CDR (test_form);
3156 }
3157 }
3158 x = test_form;
3159 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
3160 goto carloop;
3161 }
73b64342 3162
c96d76b8 3163#endif /* SCM_ENABLE_ELISP */
73b64342
MD
3164
3165 case (SCM_ISYMNUM (SCM_IM_BIND)):
2e171178
MV
3166 {
3167 SCM vars, exps, vals;
73b64342 3168
2e171178
MV
3169 x = SCM_CDR (x);
3170 vars = SCM_CAAR (x);
3171 exps = SCM_CDAR (x);
3172
3173 vals = SCM_EOL;
3174
3175 while (SCM_NIMP (exps))
3176 {
3177 vals = scm_cons (EVALCAR (exps, env), vals);
3178 exps = SCM_CDR (exps);
3179 }
3180
3181 scm_swap_bindings (vars, vals);
3182 scm_dynwinds = scm_acons (vars, vals, scm_dynwinds);
1d15ecd3
DH
3183
3184 /* Ignore all but the last evaluation result. */
3185 for (x = SCM_CDR (x); !SCM_NULLP (SCM_CDR (x)); x = SCM_CDR (x))
2e171178 3186 {
1d15ecd3
DH
3187 if (SCM_CONSP (SCM_CAR (x)))
3188 SCM_CEVAL (SCM_CAR (x), env);
2e171178
MV
3189 }
3190 proc = EVALCAR (x, env);
73b64342 3191
2e171178
MV
3192 scm_dynwinds = SCM_CDR (scm_dynwinds);
3193 scm_swap_bindings (vars, vals);
73b64342 3194
ddea3325 3195 RETURN (proc);
2e171178 3196 }
c96d76b8 3197
1d15ecd3 3198
a513ead3
MV
3199 case (SCM_ISYMNUM (SCM_IM_CALL_WITH_VALUES)):
3200 {
9a069bdd
DH
3201 SCM producer;
3202
3203 x = SCM_CDR (x);
3204 producer = EVALCAR (x, env);
3205 x = SCM_CDR (x);
3206 proc = EVALCAR (x, env); /* proc is the consumer. */
3207 arg1 = SCM_APPLY (producer, SCM_EOL, SCM_EOL);
dff98306
DH
3208 if (SCM_VALUESP (arg1))
3209 arg1 = scm_struct_ref (arg1, SCM_INUM0);
a513ead3 3210 else
dff98306 3211 arg1 = scm_list_1 (arg1);
9a069bdd
DH
3212 PREP_APPLY (proc, arg1);
3213 goto apply_proc;
a513ead3
MV
3214 }
3215
b7798e10 3216
0f2d19dd 3217 default:
ddd8f927 3218 goto evapply;
0f2d19dd
JB
3219 }
3220
3221 default:
3222 proc = x;
ddd8f927 3223 goto evapply;
0f2d19dd
JB
3224 case scm_tc7_vector:
3225 case scm_tc7_wvect:
22721140 3226#if SCM_HAVE_ARRAYS
0f2d19dd
JB
3227 case scm_tc7_bvect:
3228 case scm_tc7_byvect:
3229 case scm_tc7_svect:
3230 case scm_tc7_ivect:
3231 case scm_tc7_uvect:
3232 case scm_tc7_fvect:
3233 case scm_tc7_dvect:
3234 case scm_tc7_cvect:
3d05f2e0 3235#if SCM_SIZEOF_LONG_LONG != 0
0f2d19dd 3236 case scm_tc7_llvect:
afe5177e 3237#endif
0f2d19dd 3238#endif
534c55a9 3239 case scm_tc7_number:
0f2d19dd 3240 case scm_tc7_string:
0f2d19dd
JB
3241 case scm_tc7_smob:
3242 case scm_tcs_closures:
224822be 3243 case scm_tc7_cclo:
89efbff4 3244 case scm_tc7_pws:
0f2d19dd 3245 case scm_tcs_subrs:
904a077d 3246 case scm_tcs_struct:
0f2d19dd
JB
3247 RETURN (x);
3248
d22a0ea1 3249 case scm_tc7_variable:
a130e982 3250 RETURN (SCM_VARIABLE_REF(x));
d22a0ea1 3251
1b43d24c 3252 case SCM_BIT7 (SCM_ILOC00):
0f2d19dd 3253 proc = *scm_ilookup (SCM_CAR (x), env);
ddd8f927 3254 goto checkmacro;
b7798e10 3255
0f2d19dd 3256 case scm_tcs_cons_nimcar:
e050d4f8 3257 if (SCM_SYMBOLP (SCM_CAR (x)))
0f2d19dd 3258 {
e050d4f8 3259 SCM orig_sym = SCM_CAR (x);
b7798e10
DH
3260 {
3261 SCM *location = scm_lookupcar1 (x, env, 1);
3262 if (location == NULL)
3263 {
3264 /* we have lost the race, start again. */
3265 goto dispatch;
3266 }
3267 proc = *location;
3268 }
f8769b1d 3269
22a52da1 3270 if (SCM_MACROP (proc))
0f2d19dd 3271 {
86d31dfe
MV
3272 SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of
3273 lookupcar */
e050d4f8 3274 handle_a_macro: /* inputs: x, env, proc */
368bf056 3275#ifdef DEVAL
7c354052
MD
3276 /* Set a flag during macro expansion so that macro
3277 application frames can be deleted from the backtrace. */
3278 SCM_SET_MACROEXP (debug);
368bf056 3279#endif
dff98306 3280 arg1 = SCM_APPLY (SCM_MACRO_CODE (proc), x,
f8769b1d
MV
3281 scm_cons (env, scm_listofnull));
3282
7c354052
MD
3283#ifdef DEVAL
3284 SCM_CLEAR_MACROEXP (debug);
3285#endif
22a52da1 3286 switch (SCM_MACRO_TYPE (proc))
0f2d19dd 3287 {
3b88ed2a 3288 case 3:
0f2d19dd 3289 case 2:
dff98306
DH
3290 if (scm_ilength (arg1) <= 0)
3291 arg1 = scm_list_2 (SCM_IM_BEGIN, arg1);
6dbd0af5 3292#ifdef DEVAL
22a52da1 3293 if (!SCM_CLOSUREP (SCM_MACRO_CODE (proc)))
6dbd0af5 3294 {
6dbd0af5 3295 SCM_DEFER_INTS;
dff98306
DH
3296 SCM_SETCAR (x, SCM_CAR (arg1));
3297 SCM_SETCDR (x, SCM_CDR (arg1));
6dbd0af5
MD
3298 SCM_ALLOW_INTS;
3299 goto dispatch;
3300 }
3301 /* Prevent memoizing of debug info expression. */
6203706f
MD
3302 debug.info->e.exp = scm_cons_source (debug.info->e.exp,
3303 SCM_CAR (x),
3304 SCM_CDR (x));
6dbd0af5 3305#endif
0f2d19dd 3306 SCM_DEFER_INTS;
dff98306
DH
3307 SCM_SETCAR (x, SCM_CAR (arg1));
3308 SCM_SETCDR (x, SCM_CDR (arg1));
0f2d19dd 3309 SCM_ALLOW_INTS;
680516ba
DH
3310 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
3311 goto loop;
3063e30a 3312#if SCM_ENABLE_DEPRECATED == 1
0f2d19dd 3313 case 1:
680516ba
DH
3314 x = arg1;
3315 if (SCM_NIMP (x))
3316 {
3317 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
3318 goto loop;
3319 }
3320 else
3321 RETURN (arg1);
3063e30a 3322#endif
0f2d19dd 3323 case 0:
dff98306 3324 RETURN (arg1);
0f2d19dd
JB
3325 }
3326 }
3327 }
3328 else
3329 proc = SCM_CEVAL (SCM_CAR (x), env);
bd987b8e 3330
ddd8f927
DH
3331 checkmacro:
3332 if (SCM_MACROP (proc))
0f2d19dd 3333 goto handle_a_macro;
0f2d19dd
JB
3334 }
3335
3336
e050d4f8 3337evapply: /* inputs: x, proc */
6dbd0af5
MD
3338 PREP_APPLY (proc, SCM_EOL);
3339 if (SCM_NULLP (SCM_CDR (x))) {
3340 ENTER_APPLY;
89efbff4 3341 evap0:
ddd8f927 3342 SCM_ASRTGO (!SCM_IMP (proc), badfun);
0f2d19dd
JB
3343 switch (SCM_TYP7 (proc))
3344 { /* no arguments given */
3345 case scm_tc7_subr_0:
3346 RETURN (SCM_SUBRF (proc) ());
3347 case scm_tc7_subr_1o:
3348 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED));
3349 case scm_tc7_lsubr:
3350 RETURN (SCM_SUBRF (proc) (SCM_EOL));
3351 case scm_tc7_rpsubr:
3352 RETURN (SCM_BOOL_T);
3353 case scm_tc7_asubr:
3354 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED));
0717dfd8 3355 case scm_tc7_smob:
68b06924 3356 if (!SCM_SMOB_APPLICABLE_P (proc))
0717dfd8 3357 goto badfun;
68b06924 3358 RETURN (SCM_SMOB_APPLY_0 (proc));
0f2d19dd 3359 case scm_tc7_cclo:
dff98306 3360 arg1 = proc;
0f2d19dd 3361 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
3362#ifdef DEVAL
3363 debug.info->a.proc = proc;
dff98306 3364 debug.info->a.args = scm_list_1 (arg1);
6dbd0af5 3365#endif
0f2d19dd 3366 goto evap1;
89efbff4
MD
3367 case scm_tc7_pws:
3368 proc = SCM_PROCEDURE (proc);
3369#ifdef DEVAL
3370 debug.info->a.proc = proc;
3371#endif
002f1a5d
MD
3372 if (!SCM_CLOSUREP (proc))
3373 goto evap0;
ddd8f927 3374 /* fallthrough */
0f2d19dd 3375 case scm_tcs_closures:
ddd8f927
DH
3376 {
3377 const SCM formals = SCM_CLOSURE_FORMALS (proc);
3378 if (SCM_CONSP (formals))
3379 goto umwrongnumargs;
3380 x = SCM_CLOSURE_BODY (proc);
3381 env = SCM_EXTEND_ENV (formals, SCM_EOL, SCM_ENV (proc));
3382 goto nontoplevel_begin;
3383 }
904a077d 3384 case scm_tcs_struct:
195847fa
MD
3385 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3386 {
3387 x = SCM_ENTITY_PROCEDURE (proc);
dff98306 3388 arg1 = SCM_EOL;
195847fa
MD
3389 goto type_dispatch;
3390 }
2ca0d207 3391 else if (SCM_I_OPERATORP (proc))
da7f71d7 3392 {
dff98306 3393 arg1 = proc;
195847fa
MD
3394 proc = (SCM_I_ENTITYP (proc)
3395 ? SCM_ENTITY_PROCEDURE (proc)
3396 : SCM_OPERATOR_PROCEDURE (proc));
da7f71d7 3397#ifdef DEVAL
195847fa 3398 debug.info->a.proc = proc;
dff98306 3399 debug.info->a.args = scm_list_1 (arg1);
da7f71d7 3400#endif
ddd8f927 3401 goto evap1;
da7f71d7 3402 }
2ca0d207
DH
3403 else
3404 goto badfun;
0f2d19dd
JB
3405 case scm_tc7_subr_1:
3406 case scm_tc7_subr_2:
3407 case scm_tc7_subr_2o:
14b18ed6 3408 case scm_tc7_dsubr:
0f2d19dd
JB
3409 case scm_tc7_cxr:
3410 case scm_tc7_subr_3:
3411 case scm_tc7_lsubr_2:
3412 umwrongnumargs:
3413 unmemocar (x, env);
f5bf2977 3414 scm_wrong_num_args (proc);
0f2d19dd 3415 default:
ddd8f927
DH
3416 badfun:
3417 scm_misc_error (NULL, "Wrong type to apply: ~S", scm_list_1 (proc));
0f2d19dd 3418 }
6dbd0af5 3419 }
0f2d19dd
JB
3420
3421 /* must handle macros by here */
3422 x = SCM_CDR (x);
dff98306
DH
3423 if (SCM_CONSP (x))
3424 arg1 = EVALCAR (x, env);
680ed4a8 3425 else
ab1f1094 3426 scm_wrong_num_args (proc);
6dbd0af5 3427#ifdef DEVAL
dff98306 3428 debug.info->a.args = scm_list_1 (arg1);
6dbd0af5 3429#endif
0f2d19dd 3430 x = SCM_CDR (x);
42030fb2
DH
3431 {
3432 SCM arg2;
3433 if (SCM_NULLP (x))
3434 {
3435 ENTER_APPLY;
3436 evap1: /* inputs: proc, arg1 */
ddd8f927 3437 SCM_ASRTGO (!SCM_IMP (proc), badfun);
42030fb2
DH
3438 switch (SCM_TYP7 (proc))
3439 { /* have one argument in arg1 */
3440 case scm_tc7_subr_2o:
3441 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED));
3442 case scm_tc7_subr_1:
3443 case scm_tc7_subr_1o:
3444 RETURN (SCM_SUBRF (proc) (arg1));
14b18ed6
DH
3445 case scm_tc7_dsubr:
3446 if (SCM_INUMP (arg1))
3447 {
3448 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
3449 }
3450 else if (SCM_REALP (arg1))
3451 {
3452 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
3453 }
3454 else if (SCM_BIGP (arg1))
3455 {
3456 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_i_big2dbl (arg1))));
3457 }
3458 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
3459 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
42030fb2 3460 case scm_tc7_cxr:
42030fb2 3461 {
14b18ed6
DH
3462 unsigned char pattern = (scm_t_bits) SCM_SUBRF (proc);
3463 do
3464 {
3465 SCM_ASSERT (SCM_CONSP (arg1), arg1, SCM_ARG1,
3466 SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
3467 arg1 = (pattern & 1) ? SCM_CAR (arg1) : SCM_CDR (arg1);
3468 pattern >>= 2;
3469 } while (pattern);
42030fb2 3470 RETURN (arg1);
0f2d19dd 3471 }
42030fb2
DH
3472 case scm_tc7_rpsubr:
3473 RETURN (SCM_BOOL_T);
3474 case scm_tc7_asubr:
3475 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED));
3476 case scm_tc7_lsubr:
0f2d19dd 3477#ifdef DEVAL
42030fb2 3478 RETURN (SCM_SUBRF (proc) (debug.info->a.args));
0f2d19dd 3479#else
42030fb2 3480 RETURN (SCM_SUBRF (proc) (scm_list_1 (arg1)));
0f2d19dd 3481#endif
42030fb2
DH
3482 case scm_tc7_smob:
3483 if (!SCM_SMOB_APPLICABLE_P (proc))
3484 goto badfun;
3485 RETURN (SCM_SMOB_APPLY_1 (proc, arg1));
3486 case scm_tc7_cclo:
3487 arg2 = arg1;
3488 arg1 = proc;
3489 proc = SCM_CCLO_SUBR (proc);
6dbd0af5 3490#ifdef DEVAL
42030fb2
DH
3491 debug.info->a.args = scm_cons (arg1, debug.info->a.args);
3492 debug.info->a.proc = proc;
6dbd0af5 3493#endif
42030fb2
DH
3494 goto evap2;
3495 case scm_tc7_pws:
3496 proc = SCM_PROCEDURE (proc);
89efbff4 3497#ifdef DEVAL
42030fb2 3498 debug.info->a.proc = proc;
89efbff4 3499#endif
42030fb2
DH
3500 if (!SCM_CLOSUREP (proc))
3501 goto evap1;
ddd8f927 3502 /* fallthrough */
42030fb2 3503 case scm_tcs_closures:
ddd8f927
DH
3504 {
3505 /* clos1: */
3506 const SCM formals = SCM_CLOSURE_FORMALS (proc);
3507 if (SCM_NULLP (formals)
3508 || (SCM_CONSP (formals) && SCM_CONSP (SCM_CDR (formals))))
3509 goto umwrongnumargs;
3510 x = SCM_CLOSURE_BODY (proc);
0f2d19dd 3511#ifdef DEVAL
ddd8f927
DH
3512 env = SCM_EXTEND_ENV (formals,
3513 debug.info->a.args,
3514 SCM_ENV (proc));
0f2d19dd 3515#else
ddd8f927
DH
3516 env = SCM_EXTEND_ENV (formals,
3517 scm_list_1 (arg1),
3518 SCM_ENV (proc));
0f2d19dd 3519#endif
ddd8f927
DH
3520 goto nontoplevel_begin;
3521 }
42030fb2
DH
3522 case scm_tcs_struct:
3523 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3524 {
3525 x = SCM_ENTITY_PROCEDURE (proc);
f3d2630a 3526#ifdef DEVAL
42030fb2 3527 arg1 = debug.info->a.args;
f3d2630a 3528#else
42030fb2 3529 arg1 = scm_list_1 (arg1);
f3d2630a 3530#endif
42030fb2
DH
3531 goto type_dispatch;
3532 }
2ca0d207 3533 else if (SCM_I_OPERATORP (proc))
42030fb2
DH
3534 {
3535 arg2 = arg1;
3536 arg1 = proc;
3537 proc = (SCM_I_ENTITYP (proc)
3538 ? SCM_ENTITY_PROCEDURE (proc)
3539 : SCM_OPERATOR_PROCEDURE (proc));
0c32d76c 3540#ifdef DEVAL
42030fb2
DH
3541 debug.info->a.args = scm_cons (arg1, debug.info->a.args);
3542 debug.info->a.proc = proc;
0c32d76c 3543#endif
ddd8f927 3544 goto evap2;
42030fb2 3545 }
2ca0d207
DH
3546 else
3547 goto badfun;
42030fb2
DH
3548 case scm_tc7_subr_2:
3549 case scm_tc7_subr_0:
3550 case scm_tc7_subr_3:
3551 case scm_tc7_lsubr_2:
ab1f1094 3552 scm_wrong_num_args (proc);
42030fb2
DH
3553 default:
3554 goto badfun;
3555 }
3556 }
42030fb2
DH
3557 if (SCM_CONSP (x))
3558 arg2 = EVALCAR (x, env);
3559 else
ab1f1094 3560 scm_wrong_num_args (proc);
bd987b8e 3561
42030fb2 3562 { /* have two or more arguments */
6dbd0af5 3563#ifdef DEVAL
42030fb2 3564 debug.info->a.args = scm_list_2 (arg1, arg2);
6dbd0af5 3565#endif
42030fb2
DH
3566 x = SCM_CDR (x);
3567 if (SCM_NULLP (x)) {
3568 ENTER_APPLY;
3569 evap2:
ddd8f927 3570 SCM_ASRTGO (!SCM_IMP (proc), badfun);
42030fb2
DH
3571 switch (SCM_TYP7 (proc))
3572 { /* have two arguments */
3573 case scm_tc7_subr_2:
3574 case scm_tc7_subr_2o:
3575 RETURN (SCM_SUBRF (proc) (arg1, arg2));
3576 case scm_tc7_lsubr:
0f2d19dd 3577#ifdef DEVAL
42030fb2 3578 RETURN (SCM_SUBRF (proc) (debug.info->a.args));
6dbd0af5 3579#else
42030fb2
DH
3580 RETURN (SCM_SUBRF (proc) (scm_list_2 (arg1, arg2)));
3581#endif
3582 case scm_tc7_lsubr_2:
3583 RETURN (SCM_SUBRF (proc) (arg1, arg2, SCM_EOL));
3584 case scm_tc7_rpsubr:
3585 case scm_tc7_asubr:
3586 RETURN (SCM_SUBRF (proc) (arg1, arg2));
3587 case scm_tc7_smob:
3588 if (!SCM_SMOB_APPLICABLE_P (proc))
3589 goto badfun;
3590 RETURN (SCM_SMOB_APPLY_2 (proc, arg1, arg2));
3591 cclon:
3592 case scm_tc7_cclo:
0f2d19dd 3593#ifdef DEVAL
42030fb2
DH
3594 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
3595 scm_cons (proc, debug.info->a.args),
3596 SCM_EOL));
0f2d19dd 3597#else
42030fb2
DH
3598 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
3599 scm_cons2 (proc, arg1,
3600 scm_cons (arg2,
3601 scm_eval_args (x,
3602 env,
3603 proc))),
3604 SCM_EOL));
3605#endif
3606 case scm_tcs_struct:
3607 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3608 {
3609 x = SCM_ENTITY_PROCEDURE (proc);
3610#ifdef DEVAL
3611 arg1 = debug.info->a.args;
3612#else
3613 arg1 = scm_list_2 (arg1, arg2);
6dbd0af5 3614#endif
42030fb2
DH
3615 goto type_dispatch;
3616 }
2ca0d207 3617 else if (SCM_I_OPERATORP (proc))
42030fb2
DH
3618 {
3619 operatorn:
f3d2630a 3620#ifdef DEVAL
42030fb2
DH
3621 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
3622 ? SCM_ENTITY_PROCEDURE (proc)
3623 : SCM_OPERATOR_PROCEDURE (proc),
3624 scm_cons (proc, debug.info->a.args),
3625 SCM_EOL));
f3d2630a 3626#else
42030fb2
DH
3627 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
3628 ? SCM_ENTITY_PROCEDURE (proc)
3629 : SCM_OPERATOR_PROCEDURE (proc),
3630 scm_cons2 (proc, arg1,
3631 scm_cons (arg2,
3632 scm_eval_args (x,
3633 env,
3634 proc))),
3635 SCM_EOL));
f3d2630a 3636#endif
42030fb2 3637 }
2ca0d207
DH
3638 else
3639 goto badfun;
42030fb2 3640 case scm_tc7_subr_0:
14b18ed6 3641 case scm_tc7_dsubr:
42030fb2
DH
3642 case scm_tc7_cxr:
3643 case scm_tc7_subr_1o:
3644 case scm_tc7_subr_1:
3645 case scm_tc7_subr_3:
ab1f1094 3646 scm_wrong_num_args (proc);
42030fb2 3647 default:
9b07e212 3648 goto badfun;
42030fb2
DH
3649 case scm_tc7_pws:
3650 proc = SCM_PROCEDURE (proc);
3651#ifdef DEVAL
3652 debug.info->a.proc = proc;
3653#endif
3654 if (!SCM_CLOSUREP (proc))
3655 goto evap2;
ddd8f927 3656 /* fallthrough */
42030fb2 3657 case scm_tcs_closures:
ddd8f927
DH
3658 {
3659 /* clos2: */
3660 const SCM formals = SCM_CLOSURE_FORMALS (proc);
3661 if (SCM_NULLP (formals)
3662 || (SCM_CONSP (formals)
3663 && (SCM_NULLP (SCM_CDR (formals))
3664 || (SCM_CONSP (SCM_CDR (formals))
3665 && SCM_CONSP (SCM_CDDR (formals))))))
3666 goto umwrongnumargs;
0c32d76c 3667#ifdef DEVAL
ddd8f927
DH
3668 env = SCM_EXTEND_ENV (formals,
3669 debug.info->a.args,
3670 SCM_ENV (proc));
195847fa 3671#else
ddd8f927
DH
3672 env = SCM_EXTEND_ENV (formals,
3673 scm_list_2 (arg1, arg2),
3674 SCM_ENV (proc));
195847fa 3675#endif
ddd8f927
DH
3676 x = SCM_CLOSURE_BODY (proc);
3677 goto nontoplevel_begin;
3678 }
42030fb2
DH
3679 }
3680 }
42030fb2 3681 if (!SCM_CONSP (x))
ab1f1094 3682 scm_wrong_num_args (proc);
42030fb2
DH
3683#ifdef DEVAL
3684 debug.info->a.args = scm_cons2 (arg1, arg2,
3685 deval_args (x, env, proc,
3686 SCM_CDRLOC (SCM_CDR (debug.info->a.args))));
3687#endif
3688 ENTER_APPLY;
3689 evap3:
ddd8f927 3690 SCM_ASRTGO (!SCM_IMP (proc), badfun);
42030fb2
DH
3691 switch (SCM_TYP7 (proc))
3692 { /* have 3 or more arguments */
3693#ifdef DEVAL
6dbd0af5 3694 case scm_tc7_subr_3:
ab1f1094
DH
3695 if (!SCM_NULLP (SCM_CDR (x)))
3696 scm_wrong_num_args (proc);
3697 else
3698 RETURN (SCM_SUBRF (proc) (arg1, arg2,
3699 SCM_CADDR (debug.info->a.args)));
42030fb2
DH
3700 case scm_tc7_asubr:
3701 arg1 = SCM_SUBRF(proc)(arg1, arg2);
3702 arg2 = SCM_CDDR (debug.info->a.args);
3703 do
3704 {
3705 arg1 = SCM_SUBRF(proc)(arg1, SCM_CAR (arg2));
3706 arg2 = SCM_CDR (arg2);
3707 }
3708 while (SCM_NIMP (arg2));
3709 RETURN (arg1);
3710 case scm_tc7_rpsubr:
3711 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, arg2)))
3712 RETURN (SCM_BOOL_F);
3713 arg1 = SCM_CDDR (debug.info->a.args);
3714 do
3715 {
3716 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, SCM_CAR (arg1))))
3717 RETURN (SCM_BOOL_F);
3718 arg2 = SCM_CAR (arg1);
3719 arg1 = SCM_CDR (arg1);
3720 }
3721 while (SCM_NIMP (arg1));
3722 RETURN (SCM_BOOL_T);
3723 case scm_tc7_lsubr_2:
3724 RETURN (SCM_SUBRF (proc) (arg1, arg2,
3725 SCM_CDDR (debug.info->a.args)));
3726 case scm_tc7_lsubr:
3727 RETURN (SCM_SUBRF (proc) (debug.info->a.args));
3728 case scm_tc7_smob:
3729 if (!SCM_SMOB_APPLICABLE_P (proc))
3730 goto badfun;
3731 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, arg2,
3732 SCM_CDDR (debug.info->a.args)));
3733 case scm_tc7_cclo:
3734 goto cclon;
002f1a5d
MD
3735 case scm_tc7_pws:
3736 proc = SCM_PROCEDURE (proc);
002f1a5d 3737 debug.info->a.proc = proc;
002f1a5d 3738 if (!SCM_CLOSUREP (proc))
42030fb2 3739 goto evap3;
ddd8f927 3740 /* fallthrough */
6dbd0af5 3741 case scm_tcs_closures:
ddd8f927
DH
3742 {
3743 const SCM formals = SCM_CLOSURE_FORMALS (proc);
3744 if (SCM_NULLP (formals)
3745 || (SCM_CONSP (formals)
3746 && (SCM_NULLP (SCM_CDR (formals))
3747 || (SCM_CONSP (SCM_CDR (formals))
3748 && scm_badargsp (SCM_CDDR (formals), x)))))
3749 goto umwrongnumargs;
3750 SCM_SET_ARGSREADY (debug);
3751 env = SCM_EXTEND_ENV (formals,
3752 debug.info->a.args,
3753 SCM_ENV (proc));
3754 x = SCM_CLOSURE_BODY (proc);
3755 goto nontoplevel_begin;
3756 }
6dbd0af5 3757#else /* DEVAL */
42030fb2 3758 case scm_tc7_subr_3:
ab1f1094
DH
3759 if (!SCM_NULLP (SCM_CDR (x)))
3760 scm_wrong_num_args (proc);
3761 else
3762 RETURN (SCM_SUBRF (proc) (arg1, arg2, EVALCAR (x, env)));
42030fb2
DH
3763 case scm_tc7_asubr:
3764 arg1 = SCM_SUBRF (proc) (arg1, arg2);
3765 do
3766 {
3767 arg1 = SCM_SUBRF(proc)(arg1, EVALCAR(x, env));
3768 x = SCM_CDR(x);
3769 }
3770 while (SCM_NIMP (x));
3771 RETURN (arg1);
3772 case scm_tc7_rpsubr:
3773 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, arg2)))
3774 RETURN (SCM_BOOL_F);
3775 do
3776 {
3777 arg1 = EVALCAR (x, env);
3778 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, arg1)))
3779 RETURN (SCM_BOOL_F);
3780 arg2 = arg1;
3781 x = SCM_CDR (x);
3782 }
3783 while (SCM_NIMP (x));
3784 RETURN (SCM_BOOL_T);
3785 case scm_tc7_lsubr_2:
3786 RETURN (SCM_SUBRF (proc) (arg1, arg2, scm_eval_args (x, env, proc)));
3787 case scm_tc7_lsubr:
3788 RETURN (SCM_SUBRF (proc) (scm_cons2 (arg1,
3789 arg2,
3790 scm_eval_args (x, env, proc))));
3791 case scm_tc7_smob:
3792 if (!SCM_SMOB_APPLICABLE_P (proc))
3793 goto badfun;
3794 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, arg2,
3795 scm_eval_args (x, env, proc)));
3796 case scm_tc7_cclo:
3797 goto cclon;
3798 case scm_tc7_pws:
3799 proc = SCM_PROCEDURE (proc);
3800 if (!SCM_CLOSUREP (proc))
3801 goto evap3;
ddd8f927
DH
3802 /* fallthrough */
3803 case scm_tcs_closures:
da7f71d7 3804 {
ddd8f927 3805 const SCM formals = SCM_CLOSURE_FORMALS (proc);
42030fb2
DH
3806 if (SCM_NULLP (formals)
3807 || (SCM_CONSP (formals)
3808 && (SCM_NULLP (SCM_CDR (formals))
3809 || (SCM_CONSP (SCM_CDR (formals))
3810 && scm_badargsp (SCM_CDDR (formals), x)))))
3811 goto umwrongnumargs;
ddd8f927
DH
3812 env = SCM_EXTEND_ENV (formals,
3813 scm_cons2 (arg1,
3814 arg2,
3815 scm_eval_args (x, env, proc)),
3816 SCM_ENV (proc));
3817 x = SCM_CLOSURE_BODY (proc);
3818 goto nontoplevel_begin;
da7f71d7 3819 }
0f2d19dd 3820#endif /* DEVAL */
42030fb2
DH
3821 case scm_tcs_struct:
3822 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3823 {
f3d2630a 3824#ifdef DEVAL
42030fb2 3825 arg1 = debug.info->a.args;
f3d2630a 3826#else
42030fb2 3827 arg1 = scm_cons2 (arg1, arg2, scm_eval_args (x, env, proc));
f3d2630a 3828#endif
42030fb2
DH
3829 x = SCM_ENTITY_PROCEDURE (proc);
3830 goto type_dispatch;
3831 }
2ca0d207 3832 else if (SCM_I_OPERATORP (proc))
42030fb2 3833 goto operatorn;
2ca0d207
DH
3834 else
3835 goto badfun;
42030fb2
DH
3836 case scm_tc7_subr_2:
3837 case scm_tc7_subr_1o:
3838 case scm_tc7_subr_2o:
3839 case scm_tc7_subr_0:
14b18ed6 3840 case scm_tc7_dsubr:
42030fb2
DH
3841 case scm_tc7_cxr:
3842 case scm_tc7_subr_1:
ab1f1094 3843 scm_wrong_num_args (proc);
42030fb2 3844 default:
9b07e212 3845 goto badfun;
42030fb2
DH
3846 }
3847 }
0f2d19dd
JB
3848 }
3849#ifdef DEVAL
6dbd0af5 3850exit:
5132eef0 3851 if (scm_check_exit_p && SCM_TRAPS_P)
b7ff98dd 3852 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 3853 {
b7ff98dd
MD
3854 SCM_CLEAR_TRACED_FRAME (debug);
3855 if (SCM_CHEAPTRAPS_P)
dff98306 3856 arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
3857 else
3858 {
5f144b10
GH
3859 int first;
3860 SCM val = scm_make_continuation (&first);
e050d4f8 3861
5f144b10 3862 if (first)
dff98306 3863 arg1 = val;
5f144b10 3864 else
6dbd0af5 3865 {
5f144b10 3866 proc = val;
6dbd0af5
MD
3867 goto ret;
3868 }
3869 }
d95c0b76 3870 SCM_TRAPS_P = 0;
dff98306 3871 scm_call_3 (SCM_EXIT_FRAME_HDLR, scm_sym_exit_frame, arg1, proc);
d95c0b76 3872 SCM_TRAPS_P = 1;
6dbd0af5
MD
3873 }
3874ret:
1646d37b 3875 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
3876 return proc;
3877#endif
3878}
3879
6dbd0af5
MD
3880
3881/* SECTION: This code is compiled once.
3882 */
3883
0f2d19dd
JB
3884#ifndef DEVAL
3885
fdc28395 3886\f
d0b07b5d 3887
fdc28395
KN
3888/* Simple procedure calls
3889 */
3890
3891SCM
3892scm_call_0 (SCM proc)
3893{
3894 return scm_apply (proc, SCM_EOL, SCM_EOL);
3895}
3896
3897SCM
3898scm_call_1 (SCM proc, SCM arg1)
3899{
3900 return scm_apply (proc, arg1, scm_listofnull);
3901}
3902
3903SCM
3904scm_call_2 (SCM proc, SCM arg1, SCM arg2)
3905{
3906 return scm_apply (proc, arg1, scm_cons (arg2, scm_listofnull));
3907}
3908
3909SCM
3910scm_call_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)
3911{
3912 return scm_apply (proc, arg1, scm_cons2 (arg2, arg3, scm_listofnull));
3913}
3914
d95c0b76
NJ
3915SCM
3916scm_call_4 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4)
3917{
3918 return scm_apply (proc, arg1, scm_cons2 (arg2, arg3,
3919 scm_cons (arg4, scm_listofnull)));
3920}
3921
fdc28395
KN
3922/* Simple procedure applies
3923 */
3924
3925SCM
3926scm_apply_0 (SCM proc, SCM args)
3927{
3928 return scm_apply (proc, args, SCM_EOL);
3929}
3930
3931SCM
3932scm_apply_1 (SCM proc, SCM arg1, SCM args)
3933{
3934 return scm_apply (proc, scm_cons (arg1, args), SCM_EOL);
3935}
3936
3937SCM
3938scm_apply_2 (SCM proc, SCM arg1, SCM arg2, SCM args)
3939{
3940 return scm_apply (proc, scm_cons2 (arg1, arg2, args), SCM_EOL);
3941}
3942
3943SCM
3944scm_apply_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM args)
3945{
3946 return scm_apply (proc, scm_cons (arg1, scm_cons2 (arg2, arg3, args)),
3947 SCM_EOL);
3948}
3949
82a2622a 3950/* This code processes the arguments to apply:
b145c172
JB
3951
3952 (apply PROC ARG1 ... ARGS)
3953
82a2622a
JB
3954 Given a list (ARG1 ... ARGS), this function conses the ARG1
3955 ... arguments onto the front of ARGS, and returns the resulting
3956 list. Note that ARGS is a list; thus, the argument to this
3957 function is a list whose last element is a list.
3958
3959 Apply calls this function, and applies PROC to the elements of the
b145c172
JB
3960 result. apply:nconc2last takes care of building the list of
3961 arguments, given (ARG1 ... ARGS).
3962
82a2622a
JB
3963 Rather than do new consing, apply:nconc2last destroys its argument.
3964 On that topic, this code came into my care with the following
3965 beautifully cryptic comment on that topic: "This will only screw
3966 you if you do (scm_apply scm_apply '( ... ))" If you know what
3967 they're referring to, send me a patch to this comment. */
b145c172 3968
3b3b36dd 3969SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
b3f26b14
MG
3970 (SCM lst),
3971 "Given a list (@var{arg1} @dots{} @var{args}), this function\n"
3972 "conses the @var{arg1} @dots{} arguments onto the front of\n"
3973 "@var{args}, and returns the resulting list. Note that\n"
3974 "@var{args} is a list; thus, the argument to this function is\n"
3975 "a list whose last element is a list.\n"
3976 "Note: Rather than do new consing, @code{apply:nconc2last}\n"
3977 "destroys its argument, so use with care.")
1bbd0b84 3978#define FUNC_NAME s_scm_nconc2last
0f2d19dd
JB
3979{
3980 SCM *lloc;
34d19ef6 3981 SCM_VALIDATE_NONEMPTYLIST (1, lst);
0f2d19dd 3982 lloc = &lst;
c96d76b8
NJ
3983 while (!SCM_NULLP (SCM_CDR (*lloc))) /* Perhaps should be
3984 SCM_NULL_OR_NIL_P, but not
3985 needed in 99.99% of cases,
3986 and it could seriously hurt
3987 performance. - Neil */
a23afe53 3988 lloc = SCM_CDRLOC (*lloc);
1bbd0b84 3989 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
0f2d19dd
JB
3990 *lloc = SCM_CAR (*lloc);
3991 return lst;
3992}
1bbd0b84 3993#undef FUNC_NAME
0f2d19dd
JB
3994
3995#endif /* !DEVAL */
3996
6dbd0af5
MD
3997
3998/* SECTION: When DEVAL is defined this code yields scm_dapply.
3999 * It is compiled twice.
4000 */
4001
0f2d19dd 4002#if 0
0f2d19dd 4003SCM
6e8d25a6 4004scm_apply (SCM proc, SCM arg1, SCM args)
0f2d19dd
JB
4005{}
4006#endif
4007
4008#if 0
0f2d19dd 4009SCM
6e8d25a6 4010scm_dapply (SCM proc, SCM arg1, SCM args)
d0b07b5d 4011{}
0f2d19dd
JB
4012#endif
4013
1cc91f1b 4014
82a2622a
JB
4015/* Apply a function to a list of arguments.
4016
4017 This function is exported to the Scheme level as taking two
4018 required arguments and a tail argument, as if it were:
4019 (lambda (proc arg1 . args) ...)
4020 Thus, if you just have a list of arguments to pass to a procedure,
4021 pass the list as ARG1, and '() for ARGS. If you have some fixed
4022 args, pass the first as ARG1, then cons any remaining fixed args
4023 onto the front of your argument list, and pass that as ARGS. */
4024
0f2d19dd 4025SCM
1bbd0b84 4026SCM_APPLY (SCM proc, SCM arg1, SCM args)
0f2d19dd 4027{
0f2d19dd 4028#ifdef DEVAL
92c2555f
MV
4029 scm_t_debug_frame debug;
4030 scm_t_debug_info debug_vect_body;
1646d37b 4031 debug.prev = scm_last_debug_frame;
b7ff98dd 4032 debug.status = SCM_APPLYFRAME;
c0ab1b8d 4033 debug.vect = &debug_vect_body;
6dbd0af5
MD
4034 debug.vect[0].a.proc = proc;
4035 debug.vect[0].a.args = SCM_EOL;
1646d37b 4036 scm_last_debug_frame = &debug;
0f2d19dd 4037#else
b7ff98dd 4038 if (SCM_DEBUGGINGP)
0f2d19dd 4039 return scm_dapply (proc, arg1, args);
0f2d19dd
JB
4040#endif
4041
4042 SCM_ASRTGO (SCM_NIMP (proc), badproc);
82a2622a
JB
4043
4044 /* If ARGS is the empty list, then we're calling apply with only two
4045 arguments --- ARG1 is the list of arguments for PROC. Whatever
4046 the case, futz with things so that ARG1 is the first argument to
4047 give to PROC (or SCM_UNDEFINED if no args), and ARGS contains the
30000774
JB
4048 rest.
4049
4050 Setting the debug apply frame args this way is pretty messy.
4051 Perhaps we should store arg1 and args directly in the frame as
4052 received, and let scm_frame_arguments unpack them, because that's
4053 a relatively rare operation. This works for now; if the Guile
4054 developer archives are still around, see Mikael's post of
4055 11-Apr-97. */
0f2d19dd
JB
4056 if (SCM_NULLP (args))
4057 {
4058 if (SCM_NULLP (arg1))
30000774
JB
4059 {
4060 arg1 = SCM_UNDEFINED;
4061#ifdef DEVAL
4062 debug.vect[0].a.args = SCM_EOL;
4063#endif
4064 }
0f2d19dd
JB
4065 else
4066 {
30000774
JB
4067#ifdef DEVAL
4068 debug.vect[0].a.args = arg1;
4069#endif
0f2d19dd
JB
4070 args = SCM_CDR (arg1);
4071 arg1 = SCM_CAR (arg1);
4072 }
4073 }
4074 else
4075 {
0f2d19dd 4076 args = scm_nconc2last (args);
30000774
JB
4077#ifdef DEVAL
4078 debug.vect[0].a.args = scm_cons (arg1, args);
4079#endif
0f2d19dd 4080 }
0f2d19dd 4081#ifdef DEVAL
b6d75948 4082 if (SCM_ENTER_FRAME_P && SCM_TRAPS_P)
6dbd0af5
MD
4083 {
4084 SCM tmp;
b7ff98dd 4085 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 4086 tmp = scm_make_debugobj (&debug);
6dbd0af5
MD
4087 else
4088 {
5f144b10
GH
4089 int first;
4090
4091 tmp = scm_make_continuation (&first);
4092 if (!first)
6dbd0af5
MD
4093 goto entap;
4094 }
d95c0b76
NJ
4095 SCM_TRAPS_P = 0;
4096 scm_call_2 (SCM_ENTER_FRAME_HDLR, scm_sym_enter_frame, tmp);
4097 SCM_TRAPS_P = 1;
6dbd0af5
MD
4098 }
4099entap:
4100 ENTER_APPLY;
4101#endif
6dbd0af5 4102tail:
0f2d19dd
JB
4103 switch (SCM_TYP7 (proc))
4104 {
4105 case scm_tc7_subr_2o:
4106 args = SCM_NULLP (args) ? SCM_UNDEFINED : SCM_CAR (args);
ddea3325 4107 RETURN (SCM_SUBRF (proc) (arg1, args));
0f2d19dd 4108 case scm_tc7_subr_2:
ab1f1094
DH
4109 if (SCM_NULLP (args) || !SCM_NULLP (SCM_CDR (args)))
4110 scm_wrong_num_args (proc);
0f2d19dd 4111 args = SCM_CAR (args);
ddea3325 4112 RETURN (SCM_SUBRF (proc) (arg1, args));
0f2d19dd 4113 case scm_tc7_subr_0:
ab1f1094
DH
4114 if (!SCM_UNBNDP (arg1))
4115 scm_wrong_num_args (proc);
4116 else
4117 RETURN (SCM_SUBRF (proc) ());
0f2d19dd 4118 case scm_tc7_subr_1:
ab1f1094
DH
4119 if (SCM_UNBNDP (arg1))
4120 scm_wrong_num_args (proc);
0f2d19dd 4121 case scm_tc7_subr_1o:
ab1f1094
DH
4122 if (!SCM_NULLP (args))
4123 scm_wrong_num_args (proc);
4124 else
4125 RETURN (SCM_SUBRF (proc) (arg1));
14b18ed6
DH
4126 case scm_tc7_dsubr:
4127 if (SCM_UNBNDP (arg1) || !SCM_NULLP (args))
4128 scm_wrong_num_args (proc);
4129 if (SCM_INUMP (arg1))
4130 {
4131 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
4132 }
4133 else if (SCM_REALP (arg1))
4134 {
4135 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
4136 }
4137 else if (SCM_BIGP (arg1))
4138 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_i_big2dbl (arg1))));
4139 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
4140 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
0f2d19dd 4141 case scm_tc7_cxr:
ab1f1094
DH
4142 if (SCM_UNBNDP (arg1) || !SCM_NULLP (args))
4143 scm_wrong_num_args (proc);
0f2d19dd 4144 {
14b18ed6
DH
4145 unsigned char pattern = (scm_t_bits) SCM_SUBRF (proc);
4146 do
4147 {
4148 SCM_ASSERT (SCM_CONSP (arg1), arg1, SCM_ARG1,
4149 SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
4150 arg1 = (pattern & 1) ? SCM_CAR (arg1) : SCM_CDR (arg1);
4151 pattern >>= 2;
4152 } while (pattern);
4153 RETURN (arg1);
0f2d19dd
JB
4154 }
4155 case scm_tc7_subr_3:
ab1f1094
DH
4156 if (SCM_NULLP (args)
4157 || SCM_NULLP (SCM_CDR (args))
4158 || !SCM_NULLP (SCM_CDDR (args)))
4159 scm_wrong_num_args (proc);
4160 else
4161 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CADR (args)));
0f2d19dd
JB
4162 case scm_tc7_lsubr:
4163#ifdef DEVAL
ddea3325 4164 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args));
0f2d19dd 4165#else
ddea3325 4166 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args)));
0f2d19dd
JB
4167#endif
4168 case scm_tc7_lsubr_2:
ab1f1094
DH
4169 if (!SCM_CONSP (args))
4170 scm_wrong_num_args (proc);
4171 else
4172 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CDR (args)));
0f2d19dd
JB
4173 case scm_tc7_asubr:
4174 if (SCM_NULLP (args))
ddea3325 4175 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED));
0f2d19dd
JB
4176 while (SCM_NIMP (args))
4177 {
4178 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
4179 arg1 = SCM_SUBRF (proc) (arg1, SCM_CAR (args));
4180 args = SCM_CDR (args);
4181 }
4182 RETURN (arg1);
4183 case scm_tc7_rpsubr:
4184 if (SCM_NULLP (args))
4185 RETURN (SCM_BOOL_T);
4186 while (SCM_NIMP (args))
4187 {
4188 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
4189 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, SCM_CAR (args))))
4190 RETURN (SCM_BOOL_F);
4191 arg1 = SCM_CAR (args);
4192 args = SCM_CDR (args);
4193 }
4194 RETURN (SCM_BOOL_T);
4195 case scm_tcs_closures:
4196#ifdef DEVAL
6dbd0af5 4197 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args);
0f2d19dd
JB
4198#else
4199 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args));
4200#endif
726d810a 4201 if (scm_badargsp (SCM_CLOSURE_FORMALS (proc), arg1))
ab1f1094 4202 scm_wrong_num_args (proc);
1609038c
MD
4203
4204 /* Copy argument list */
4205 if (SCM_IMP (arg1))
4206 args = arg1;
4207 else
4208 {
4209 SCM tl = args = scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED);
05b15362 4210 for (arg1 = SCM_CDR (arg1); SCM_CONSP (arg1); arg1 = SCM_CDR (arg1))
1609038c 4211 {
05b15362 4212 SCM_SETCDR (tl, scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED));
1609038c
MD
4213 tl = SCM_CDR (tl);
4214 }
4215 SCM_SETCDR (tl, arg1);
4216 }
4217
821f18a4
DH
4218 args = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
4219 args,
4220 SCM_ENV (proc));
f9450cdb 4221 proc = SCM_CLOSURE_BODY (proc);
e791c18f 4222 again:
05b15362
DH
4223 arg1 = SCM_CDR (proc);
4224 while (!SCM_NULLP (arg1))
2ddb0920
MD
4225 {
4226 if (SCM_IMP (SCM_CAR (proc)))
4227 {
4228 if (SCM_ISYMP (SCM_CAR (proc)))
4229 {
28d52ebb 4230 scm_rec_mutex_lock (&source_mutex);
9bc4701c
MD
4231 /* check for race condition */
4232 if (SCM_ISYMP (SCM_CAR (proc)))
4233 proc = scm_m_expand_body (proc, args);
28d52ebb 4234 scm_rec_mutex_unlock (&source_mutex);
e791c18f 4235 goto again;
2ddb0920 4236 }
5280aaca 4237 else
17fa3fcf 4238 SCM_VALIDATE_NON_EMPTY_COMBINATION (SCM_CAR (proc));
2ddb0920
MD
4239 }
4240 else
e791c18f
MD
4241 SCM_CEVAL (SCM_CAR (proc), args);
4242 proc = arg1;
05b15362 4243 arg1 = SCM_CDR (proc);
2ddb0920 4244 }
e791c18f 4245 RETURN (EVALCAR (proc, args));
0717dfd8 4246 case scm_tc7_smob:
68b06924 4247 if (!SCM_SMOB_APPLICABLE_P (proc))
0717dfd8 4248 goto badproc;
afa38f6e 4249 if (SCM_UNBNDP (arg1))
ddea3325 4250 RETURN (SCM_SMOB_APPLY_0 (proc));
afa38f6e 4251 else if (SCM_NULLP (args))
ddea3325 4252 RETURN (SCM_SMOB_APPLY_1 (proc, arg1));
0717dfd8 4253 else if (SCM_NULLP (SCM_CDR (args)))
ddea3325 4254 RETURN (SCM_SMOB_APPLY_2 (proc, arg1, SCM_CAR (args)));
0717dfd8 4255 else
68b06924 4256 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, SCM_CAR (args), SCM_CDR (args)));
0f2d19dd
JB
4257 case scm_tc7_cclo:
4258#ifdef DEVAL
6dbd0af5
MD
4259 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
4260 arg1 = proc;
4261 proc = SCM_CCLO_SUBR (proc);
4262 debug.vect[0].a.proc = proc;
4263 debug.vect[0].a.args = scm_cons (arg1, args);
0f2d19dd
JB
4264#else
4265 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
0f2d19dd
JB
4266 arg1 = proc;
4267 proc = SCM_CCLO_SUBR (proc);
6dbd0af5 4268#endif
0f2d19dd 4269 goto tail;
89efbff4
MD
4270 case scm_tc7_pws:
4271 proc = SCM_PROCEDURE (proc);
4272#ifdef DEVAL
4273 debug.vect[0].a.proc = proc;
4274#endif
4275 goto tail;
904a077d 4276 case scm_tcs_struct:
f3d2630a
MD
4277 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
4278 {
4279#ifdef DEVAL
4280 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
4281#else
4282 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
4283#endif
195847fa 4284 RETURN (scm_apply_generic (proc, args));
f3d2630a 4285 }
2ca0d207 4286 else if (SCM_I_OPERATORP (proc))
da7f71d7 4287 {
504d99c5 4288 /* operator */
da7f71d7
MD
4289#ifdef DEVAL
4290 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
4291#else
4292 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
4293#endif
4294 arg1 = proc;
195847fa
MD
4295 proc = (SCM_I_ENTITYP (proc)
4296 ? SCM_ENTITY_PROCEDURE (proc)
4297 : SCM_OPERATOR_PROCEDURE (proc));
da7f71d7
MD
4298#ifdef DEVAL
4299 debug.vect[0].a.proc = proc;
4300 debug.vect[0].a.args = scm_cons (arg1, args);
4301#endif
195847fa
MD
4302 if (SCM_NIMP (proc))
4303 goto tail;
4304 else
4305 goto badproc;
da7f71d7 4306 }
2ca0d207
DH
4307 else
4308 goto badproc;
0f2d19dd
JB
4309 default:
4310 badproc:
db4b4ca6 4311 scm_wrong_type_arg ("apply", SCM_ARG1, proc);
0f2d19dd
JB
4312 }
4313#ifdef DEVAL
6dbd0af5 4314exit:
5132eef0 4315 if (scm_check_exit_p && SCM_TRAPS_P)
b7ff98dd 4316 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 4317 {
b7ff98dd
MD
4318 SCM_CLEAR_TRACED_FRAME (debug);
4319 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 4320 arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
4321 else
4322 {
5f144b10
GH
4323 int first;
4324 SCM val = scm_make_continuation (&first);
4325
4326 if (first)
4327 arg1 = val;
4328 else
6dbd0af5 4329 {
5f144b10 4330 proc = val;
6dbd0af5
MD
4331 goto ret;
4332 }
4333 }
d95c0b76
NJ
4334 SCM_TRAPS_P = 0;
4335 scm_call_3 (SCM_EXIT_FRAME_HDLR, scm_sym_exit_frame, arg1, proc);
4336 SCM_TRAPS_P = 1;
6dbd0af5
MD
4337 }
4338ret:
1646d37b 4339 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
4340 return proc;
4341#endif
4342}
4343
6dbd0af5
MD
4344
4345/* SECTION: The rest of this file is only read once.
4346 */
4347
0f2d19dd
JB
4348#ifndef DEVAL
4349
504d99c5
MD
4350/* Trampolines
4351 *
4352 * Trampolines make it possible to move procedure application dispatch
4353 * outside inner loops. The motivation was clean implementation of
4354 * efficient replacements of R5RS primitives in SRFI-1.
4355 *
4356 * The semantics is clear: scm_trampoline_N returns an optimized
4357 * version of scm_call_N (or NULL if the procedure isn't applicable
4358 * on N args).
4359 *
4360 * Applying the optimization to map and for-each increased efficiency
4361 * noticeably. For example, (map abs ls) is now 8 times faster than
4362 * before.
4363 */
4364
756414cf
MD
4365static SCM
4366call_subr0_0 (SCM proc)
4367{
4368 return SCM_SUBRF (proc) ();
4369}
4370
4371static SCM
4372call_subr1o_0 (SCM proc)
4373{
4374 return SCM_SUBRF (proc) (SCM_UNDEFINED);
4375}
4376
4377static SCM
4378call_lsubr_0 (SCM proc)
4379{
4380 return SCM_SUBRF (proc) (SCM_EOL);
4381}
4382
4383SCM
4384scm_i_call_closure_0 (SCM proc)
4385{
6a3f13f0
DH
4386 const SCM env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
4387 SCM_EOL,
4388 SCM_ENV (proc));
4389 const SCM result = scm_eval_body (SCM_CLOSURE_BODY (proc), env);
d0b07b5d 4390 return result;
756414cf
MD
4391}
4392
4393scm_t_trampoline_0
4394scm_trampoline_0 (SCM proc)
4395{
4396 if (SCM_IMP (proc))
d0b07b5d 4397 return NULL;
756414cf
MD
4398 if (SCM_DEBUGGINGP)
4399 return scm_call_0;
4400 switch (SCM_TYP7 (proc))
4401 {
4402 case scm_tc7_subr_0:
4403 return call_subr0_0;
4404 case scm_tc7_subr_1o:
4405 return call_subr1o_0;
4406 case scm_tc7_lsubr:
4407 return call_lsubr_0;
4408 case scm_tcs_closures:
4409 {
4410 SCM formals = SCM_CLOSURE_FORMALS (proc);
4b612c5b 4411 if (SCM_NULLP (formals) || !SCM_CONSP (formals))
756414cf
MD
4412 return scm_i_call_closure_0;
4413 else
d0b07b5d 4414 return NULL;
756414cf
MD
4415 }
4416 case scm_tcs_struct:
4417 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
4418 return scm_call_generic_0;
2ca0d207
DH
4419 else if (SCM_I_OPERATORP (proc))
4420 return scm_call_0;
4421 return NULL;
756414cf
MD
4422 case scm_tc7_smob:
4423 if (SCM_SMOB_APPLICABLE_P (proc))
4424 return SCM_SMOB_DESCRIPTOR (proc).apply_0;
4425 else
d0b07b5d 4426 return NULL;
756414cf
MD
4427 case scm_tc7_asubr:
4428 case scm_tc7_rpsubr:
4429 case scm_tc7_cclo:
4430 case scm_tc7_pws:
4431 return scm_call_0;
4432 default:
d0b07b5d 4433 return NULL; /* not applicable on one arg */
756414cf
MD
4434 }
4435}
4436
504d99c5
MD
4437static SCM
4438call_subr1_1 (SCM proc, SCM arg1)
4439{
4440 return SCM_SUBRF (proc) (arg1);
4441}
4442
9ed24633
MD
4443static SCM
4444call_subr2o_1 (SCM proc, SCM arg1)
4445{
4446 return SCM_SUBRF (proc) (arg1, SCM_UNDEFINED);
4447}
4448
504d99c5
MD
4449static SCM
4450call_lsubr_1 (SCM proc, SCM arg1)
4451{
4452 return SCM_SUBRF (proc) (scm_list_1 (arg1));
4453}
4454
4455static SCM
4456call_dsubr_1 (SCM proc, SCM arg1)
4457{
4458 if (SCM_INUMP (arg1))
4459 {
4460 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
4461 }
4462 else if (SCM_REALP (arg1))
4463 {
4464 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
4465 }
504d99c5
MD
4466 else if (SCM_BIGP (arg1))
4467 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_i_big2dbl (arg1))));
504d99c5
MD
4468 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
4469 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
4470}
4471
4472static SCM
4473call_cxr_1 (SCM proc, SCM arg1)
4474{
14b18ed6
DH
4475 unsigned char pattern = (scm_t_bits) SCM_SUBRF (proc);
4476 do
4477 {
4478 SCM_ASSERT (SCM_CONSP (arg1), arg1, SCM_ARG1,
4479 SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
4480 arg1 = (pattern & 1) ? SCM_CAR (arg1) : SCM_CDR (arg1);
4481 pattern >>= 2;
4482 } while (pattern);
4483 return arg1;
504d99c5
MD
4484}
4485
4486static SCM
4487call_closure_1 (SCM proc, SCM arg1)
4488{
6a3f13f0
DH
4489 const SCM env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
4490 scm_list_1 (arg1),
4491 SCM_ENV (proc));
4492 const SCM result = scm_eval_body (SCM_CLOSURE_BODY (proc), env);
d0b07b5d 4493 return result;
504d99c5
MD
4494}
4495
4496scm_t_trampoline_1
4497scm_trampoline_1 (SCM proc)
4498{
4499 if (SCM_IMP (proc))
d0b07b5d 4500 return NULL;
504d99c5
MD
4501 if (SCM_DEBUGGINGP)
4502 return scm_call_1;
4503 switch (SCM_TYP7 (proc))
4504 {
4505 case scm_tc7_subr_1:
4506 case scm_tc7_subr_1o:
4507 return call_subr1_1;
9ed24633
MD
4508 case scm_tc7_subr_2o:
4509 return call_subr2o_1;
504d99c5
MD
4510 case scm_tc7_lsubr:
4511 return call_lsubr_1;
14b18ed6
DH
4512 case scm_tc7_dsubr:
4513 return call_dsubr_1;
504d99c5 4514 case scm_tc7_cxr:
14b18ed6 4515 return call_cxr_1;
504d99c5
MD
4516 case scm_tcs_closures:
4517 {
4518 SCM formals = SCM_CLOSURE_FORMALS (proc);
4b612c5b
MD
4519 if (!SCM_NULLP (formals)
4520 && (!SCM_CONSP (formals) || !SCM_CONSP (SCM_CDR (formals))))
504d99c5
MD
4521 return call_closure_1;
4522 else
d0b07b5d 4523 return NULL;
504d99c5
MD
4524 }
4525 case scm_tcs_struct:
4526 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
4527 return scm_call_generic_1;
2ca0d207
DH
4528 else if (SCM_I_OPERATORP (proc))
4529 return scm_call_1;
4530 return NULL;
504d99c5
MD
4531 case scm_tc7_smob:
4532 if (SCM_SMOB_APPLICABLE_P (proc))
4533 return SCM_SMOB_DESCRIPTOR (proc).apply_1;
4534 else
d0b07b5d 4535 return NULL;
504d99c5
MD
4536 case scm_tc7_asubr:
4537 case scm_tc7_rpsubr:
4538 case scm_tc7_cclo:
4539 case scm_tc7_pws:
4540 return scm_call_1;
4541 default:
d0b07b5d 4542 return NULL; /* not applicable on one arg */
504d99c5
MD
4543 }
4544}
4545
4546static SCM
4547call_subr2_2 (SCM proc, SCM arg1, SCM arg2)
4548{
4549 return SCM_SUBRF (proc) (arg1, arg2);
4550}
4551
9ed24633
MD
4552static SCM
4553call_lsubr2_2 (SCM proc, SCM arg1, SCM arg2)
4554{
4555 return SCM_SUBRF (proc) (arg1, arg2, SCM_EOL);
4556}
4557
504d99c5
MD
4558static SCM
4559call_lsubr_2 (SCM proc, SCM arg1, SCM arg2)
4560{
4561 return SCM_SUBRF (proc) (scm_list_2 (arg1, arg2));
4562}
4563
4564static SCM
4565call_closure_2 (SCM proc, SCM arg1, SCM arg2)
4566{
6a3f13f0
DH
4567 const SCM env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
4568 scm_list_2 (arg1, arg2),
4569 SCM_ENV (proc));
4570 const SCM result = scm_eval_body (SCM_CLOSURE_BODY (proc), env);
d0b07b5d 4571 return result;
504d99c5
MD
4572}
4573
4574scm_t_trampoline_2
4575scm_trampoline_2 (SCM proc)
4576{
4577 if (SCM_IMP (proc))
d0b07b5d 4578 return NULL;
504d99c5
MD
4579 if (SCM_DEBUGGINGP)
4580 return scm_call_2;
4581 switch (SCM_TYP7 (proc))
4582 {
4583 case scm_tc7_subr_2:
4584 case scm_tc7_subr_2o:
4585 case scm_tc7_rpsubr:
4586 case scm_tc7_asubr:
4587 return call_subr2_2;
9ed24633
MD
4588 case scm_tc7_lsubr_2:
4589 return call_lsubr2_2;
504d99c5
MD
4590 case scm_tc7_lsubr:
4591 return call_lsubr_2;
4592 case scm_tcs_closures:
4593 {
4594 SCM formals = SCM_CLOSURE_FORMALS (proc);
4b612c5b
MD
4595 if (!SCM_NULLP (formals)
4596 && (!SCM_CONSP (formals)
4597 || (!SCM_NULLP (SCM_CDR (formals))
4598 && (!SCM_CONSP (SCM_CDR (formals))
4599 || !SCM_CONSP (SCM_CDDR (formals))))))
504d99c5
MD
4600 return call_closure_2;
4601 else
d0b07b5d 4602 return NULL;
504d99c5
MD
4603 }
4604 case scm_tcs_struct:
4605 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
4606 return scm_call_generic_2;
2ca0d207
DH
4607 else if (SCM_I_OPERATORP (proc))
4608 return scm_call_2;
4609 return NULL;
504d99c5
MD
4610 case scm_tc7_smob:
4611 if (SCM_SMOB_APPLICABLE_P (proc))
4612 return SCM_SMOB_DESCRIPTOR (proc).apply_2;
4613 else
d0b07b5d 4614 return NULL;
504d99c5
MD
4615 case scm_tc7_cclo:
4616 case scm_tc7_pws:
4617 return scm_call_2;
4618 default:
d0b07b5d 4619 return NULL; /* not applicable on two args */
504d99c5
MD
4620 }
4621}
4622
d9c393f5
JB
4623/* Typechecking for multi-argument MAP and FOR-EACH.
4624
47c3f06d 4625 Verify that each element of the vector ARGV, except for the first,
d9c393f5 4626 is a proper list whose length is LEN. Attribute errors to WHO,
47c3f06d 4627 and claim that the i'th element of ARGV is WHO's i+2'th argument. */
d9c393f5 4628static inline void
47c3f06d 4629check_map_args (SCM argv,
c014a02e 4630 long len,
47c3f06d
MD
4631 SCM gf,
4632 SCM proc,
4633 SCM args,
4634 const char *who)
d9c393f5 4635{
34d19ef6 4636 SCM const *ve = SCM_VELTS (argv);
c014a02e 4637 long i;
d9c393f5 4638
b5c2579a 4639 for (i = SCM_VECTOR_LENGTH (argv) - 1; i >= 1; i--)
d9c393f5 4640 {
c014a02e 4641 long elt_len = scm_ilength (ve[i]);
d9c393f5
JB
4642
4643 if (elt_len < 0)
47c3f06d
MD
4644 {
4645 if (gf)
4646 scm_apply_generic (gf, scm_cons (proc, args));
4647 else
4648 scm_wrong_type_arg (who, i + 2, ve[i]);
4649 }
d9c393f5
JB
4650
4651 if (elt_len != len)
504d99c5 4652 scm_out_of_range_pos (who, ve[i], SCM_MAKINUM (i + 2));
d9c393f5
JB
4653 }
4654
5d2b97cd 4655 scm_remember_upto_here_1 (argv);
d9c393f5
JB
4656}
4657
4658
47c3f06d 4659SCM_GPROC (s_map, "map", 2, 0, 1, scm_map, g_map);
1cc91f1b 4660
368bf056
MD
4661/* Note: Currently, scm_map applies PROC to the argument list(s)
4662 sequentially, starting with the first element(s). This is used in
8878f040 4663 evalext.c where the Scheme procedure `map-in-order', which guarantees
368bf056 4664 sequential behaviour, is implemented using scm_map. If the
8878f040 4665 behaviour changes, we need to update `map-in-order'.
368bf056
MD
4666*/
4667
0f2d19dd 4668SCM
1bbd0b84 4669scm_map (SCM proc, SCM arg1, SCM args)
af45e3b0 4670#define FUNC_NAME s_map
0f2d19dd 4671{
c014a02e 4672 long i, len;
0f2d19dd
JB
4673 SCM res = SCM_EOL;
4674 SCM *pres = &res;
34d19ef6 4675 SCM const *ve = &args; /* Keep args from being optimized away. */
0f2d19dd 4676
d9c393f5 4677 len = scm_ilength (arg1);
47c3f06d
MD
4678 SCM_GASSERTn (len >= 0,
4679 g_map, scm_cons2 (proc, arg1, args), SCM_ARG2, s_map);
af45e3b0 4680 SCM_VALIDATE_REST_ARGUMENT (args);
0f2d19dd
JB
4681 if (SCM_NULLP (args))
4682 {
504d99c5
MD
4683 scm_t_trampoline_1 call = scm_trampoline_1 (proc);
4684 SCM_GASSERT2 (call, g_map, proc, arg1, SCM_ARG1, s_map);
4685 while (SCM_NIMP (arg1))
4686 {
4687 *pres = scm_list_1 (call (proc, SCM_CAR (arg1)));
4688 pres = SCM_CDRLOC (*pres);
4689 arg1 = SCM_CDR (arg1);
4690 }
4691 return res;
4692 }
4693 if (SCM_NULLP (SCM_CDR (args)))
4694 {
4695 SCM arg2 = SCM_CAR (args);
4696 int len2 = scm_ilength (arg2);
4697 scm_t_trampoline_2 call = scm_trampoline_2 (proc);
4698 SCM_GASSERTn (call,
4699 g_map, scm_cons2 (proc, arg1, args), SCM_ARG1, s_map);
4700 SCM_GASSERTn (len2 >= 0,
4701 g_map, scm_cons2 (proc, arg1, args), SCM_ARG3, s_map);
4702 if (len2 != len)
4703 SCM_OUT_OF_RANGE (3, arg2);
0f2d19dd
JB
4704 while (SCM_NIMP (arg1))
4705 {
504d99c5 4706 *pres = scm_list_1 (call (proc, SCM_CAR (arg1), SCM_CAR (arg2)));
a23afe53 4707 pres = SCM_CDRLOC (*pres);
0f2d19dd 4708 arg1 = SCM_CDR (arg1);
504d99c5 4709 arg2 = SCM_CDR (arg2);
0f2d19dd
JB
4710 }
4711 return res;
4712 }
05b15362
DH
4713 arg1 = scm_cons (arg1, args);
4714 args = scm_vector (arg1);
0f2d19dd 4715 ve = SCM_VELTS (args);
47c3f06d 4716 check_map_args (args, len, g_map, proc, arg1, s_map);
0f2d19dd
JB
4717 while (1)
4718 {
4719 arg1 = SCM_EOL;
b5c2579a 4720 for (i = SCM_VECTOR_LENGTH (args) - 1; i >= 0; i--)
0f2d19dd 4721 {
d9c393f5
JB
4722 if (SCM_IMP (ve[i]))
4723 return res;
0f2d19dd 4724 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
34d19ef6 4725 SCM_VECTOR_SET (args, i, SCM_CDR (ve[i]));
0f2d19dd 4726 }
8ea46249 4727 *pres = scm_list_1 (scm_apply (proc, arg1, SCM_EOL));
a23afe53 4728 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
4729 }
4730}
af45e3b0 4731#undef FUNC_NAME
0f2d19dd
JB
4732
4733
47c3f06d 4734SCM_GPROC (s_for_each, "for-each", 2, 0, 1, scm_for_each, g_for_each);
1cc91f1b 4735
0f2d19dd 4736SCM
1bbd0b84 4737scm_for_each (SCM proc, SCM arg1, SCM args)
af45e3b0 4738#define FUNC_NAME s_for_each
0f2d19dd 4739{
34d19ef6 4740 SCM const *ve = &args; /* Keep args from being optimized away. */
c014a02e 4741 long i, len;
d9c393f5 4742 len = scm_ilength (arg1);
47c3f06d
MD
4743 SCM_GASSERTn (len >= 0, g_for_each, scm_cons2 (proc, arg1, args),
4744 SCM_ARG2, s_for_each);
af45e3b0 4745 SCM_VALIDATE_REST_ARGUMENT (args);
c96d76b8 4746 if (SCM_NULLP (args))
0f2d19dd 4747 {
504d99c5
MD
4748 scm_t_trampoline_1 call = scm_trampoline_1 (proc);
4749 SCM_GASSERT2 (call, g_for_each, proc, arg1, SCM_ARG1, s_for_each);
4750 while (SCM_NIMP (arg1))
4751 {
4752 call (proc, SCM_CAR (arg1));
4753 arg1 = SCM_CDR (arg1);
4754 }
4755 return SCM_UNSPECIFIED;
4756 }
4757 if (SCM_NULLP (SCM_CDR (args)))
4758 {
4759 SCM arg2 = SCM_CAR (args);
4760 int len2 = scm_ilength (arg2);
4761 scm_t_trampoline_2 call = scm_trampoline_2 (proc);
4762 SCM_GASSERTn (call, g_for_each,
4763 scm_cons2 (proc, arg1, args), SCM_ARG1, s_for_each);
4764 SCM_GASSERTn (len2 >= 0, g_for_each,
4765 scm_cons2 (proc, arg1, args), SCM_ARG3, s_for_each);
4766 if (len2 != len)
4767 SCM_OUT_OF_RANGE (3, arg2);
c96d76b8 4768 while (SCM_NIMP (arg1))
0f2d19dd 4769 {
504d99c5 4770 call (proc, SCM_CAR (arg1), SCM_CAR (arg2));
0f2d19dd 4771 arg1 = SCM_CDR (arg1);
504d99c5 4772 arg2 = SCM_CDR (arg2);
0f2d19dd
JB
4773 }
4774 return SCM_UNSPECIFIED;
4775 }
05b15362
DH
4776 arg1 = scm_cons (arg1, args);
4777 args = scm_vector (arg1);
0f2d19dd 4778 ve = SCM_VELTS (args);
47c3f06d 4779 check_map_args (args, len, g_for_each, proc, arg1, s_for_each);
0f2d19dd
JB
4780 while (1)
4781 {
4782 arg1 = SCM_EOL;
b5c2579a 4783 for (i = SCM_VECTOR_LENGTH (args) - 1; i >= 0; i--)
0f2d19dd 4784 {
c96d76b8
NJ
4785 if (SCM_IMP (ve[i]))
4786 return SCM_UNSPECIFIED;
0f2d19dd 4787 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
34d19ef6 4788 SCM_VECTOR_SET (args, i, SCM_CDR (ve[i]));
0f2d19dd
JB
4789 }
4790 scm_apply (proc, arg1, SCM_EOL);
4791 }
4792}
af45e3b0 4793#undef FUNC_NAME
0f2d19dd 4794
1cc91f1b 4795
0f2d19dd 4796SCM
6e8d25a6 4797scm_closure (SCM code, SCM env)
0f2d19dd 4798{
16d4699b
MV
4799 SCM z;
4800 SCM closcar = scm_cons (code, SCM_EOL);
228a24ef 4801 z = scm_cell (SCM_UNPACK (closcar) + scm_tc3_closure, (scm_t_bits) env);
16d4699b 4802 scm_remember_upto_here (closcar);
0f2d19dd
JB
4803 return z;
4804}
4805
4806
92c2555f 4807scm_t_bits scm_tc16_promise;
1cc91f1b 4808
0f2d19dd 4809SCM
6e8d25a6 4810scm_makprom (SCM code)
0f2d19dd 4811{
28d52ebb
MD
4812 SCM_RETURN_NEWSMOB2 (scm_tc16_promise,
4813 SCM_UNPACK (code),
4814 scm_make_rec_mutex ());
0f2d19dd
JB
4815}
4816
28d52ebb
MD
4817static size_t
4818promise_free (SCM promise)
4819{
4820 scm_rec_mutex_free (SCM_PROMISE_MUTEX (promise));
4821 return 0;
4822}
1cc91f1b 4823
0f2d19dd 4824static int
e841c3e0 4825promise_print (SCM exp, SCM port, scm_print_state *pstate)
0f2d19dd 4826{
19402679 4827 int writingp = SCM_WRITINGP (pstate);
b7f3516f 4828 scm_puts ("#<promise ", port);
19402679 4829 SCM_SET_WRITINGP (pstate, 1);
28d52ebb 4830 scm_iprin1 (SCM_PROMISE_DATA (exp), port, pstate);
19402679 4831 SCM_SET_WRITINGP (pstate, writingp);
b7f3516f 4832 scm_putc ('>', port);
0f2d19dd
JB
4833 return !0;
4834}
4835
3b3b36dd 4836SCM_DEFINE (scm_force, "force", 1, 0, 0,
28d52ebb 4837 (SCM promise),
67e8151b
MG
4838 "If the promise @var{x} has not been computed yet, compute and\n"
4839 "return @var{x}, otherwise just return the previously computed\n"
4840 "value.")
1bbd0b84 4841#define FUNC_NAME s_scm_force
0f2d19dd 4842{
28d52ebb
MD
4843 SCM_VALIDATE_SMOB (1, promise, promise);
4844 scm_rec_mutex_lock (SCM_PROMISE_MUTEX (promise));
4845 if (!SCM_PROMISE_COMPUTED_P (promise))
0f2d19dd 4846 {
28d52ebb
MD
4847 SCM ans = scm_call_0 (SCM_PROMISE_DATA (promise));
4848 if (!SCM_PROMISE_COMPUTED_P (promise))
0f2d19dd 4849 {
28d52ebb
MD
4850 SCM_SET_PROMISE_DATA (promise, ans);
4851 SCM_SET_PROMISE_COMPUTED (promise);
0f2d19dd
JB
4852 }
4853 }
28d52ebb
MD
4854 scm_rec_mutex_unlock (SCM_PROMISE_MUTEX (promise));
4855 return SCM_PROMISE_DATA (promise);
0f2d19dd 4856}
1bbd0b84 4857#undef FUNC_NAME
0f2d19dd 4858
445f675c 4859
a1ec6916 4860SCM_DEFINE (scm_promise_p, "promise?", 1, 0, 0,
67e8151b 4861 (SCM obj),
b380b885 4862 "Return true if @var{obj} is a promise, i.e. a delayed computation\n"
7a095584 4863 "(@pxref{Delayed evaluation,,,r5rs.info,The Revised^5 Report on Scheme}).")
1bbd0b84 4864#define FUNC_NAME s_scm_promise_p
0f2d19dd 4865{
67e8151b 4866 return SCM_BOOL (SCM_TYP16_PREDICATE (scm_tc16_promise, obj));
0f2d19dd 4867}
1bbd0b84 4868#undef FUNC_NAME
0f2d19dd 4869
445f675c 4870
a1ec6916 4871SCM_DEFINE (scm_cons_source, "cons-source", 3, 0, 0,
1bbd0b84 4872 (SCM xorig, SCM x, SCM y),
11768c04
NJ
4873 "Create and return a new pair whose car and cdr are @var{x} and @var{y}.\n"
4874 "Any source properties associated with @var{xorig} are also associated\n"
4875 "with the new pair.")
1bbd0b84 4876#define FUNC_NAME s_scm_cons_source
26d5b9b4
MD
4877{
4878 SCM p, z;
16d4699b 4879 z = scm_cons (x, y);
26d5b9b4
MD
4880 /* Copy source properties possibly associated with xorig. */
4881 p = scm_whash_lookup (scm_source_whash, xorig);
445f675c 4882 if (!SCM_IMP (p))
26d5b9b4
MD
4883 scm_whash_insert (scm_source_whash, z, p);
4884 return z;
4885}
1bbd0b84 4886#undef FUNC_NAME
26d5b9b4 4887
445f675c 4888
a1ec6916 4889SCM_DEFINE (scm_copy_tree, "copy-tree", 1, 0, 0,
1bbd0b84 4890 (SCM obj),
b380b885
MD
4891 "Recursively copy the data tree that is bound to @var{obj}, and return a\n"
4892 "pointer to the new data structure. @code{copy-tree} recurses down the\n"
4893 "contents of both pairs and vectors (since both cons cells and vector\n"
4894 "cells may point to arbitrary objects), and stops recursing when it hits\n"
4895 "any other object.")
1bbd0b84 4896#define FUNC_NAME s_scm_copy_tree
0f2d19dd
JB
4897{
4898 SCM ans, tl;
26d5b9b4 4899 if (SCM_IMP (obj))
ff467021 4900 return obj;
3910272e
MD
4901 if (SCM_VECTORP (obj))
4902 {
c014a02e 4903 unsigned long i = SCM_VECTOR_LENGTH (obj);
00ffa0e7 4904 ans = scm_c_make_vector (i, SCM_UNSPECIFIED);
3910272e 4905 while (i--)
34d19ef6 4906 SCM_VECTOR_SET (ans, i, scm_copy_tree (SCM_VELTS (obj)[i]));
3910272e
MD
4907 return ans;
4908 }
01f11e02 4909 if (!SCM_CONSP (obj))
0f2d19dd 4910 return obj;
26d5b9b4
MD
4911 ans = tl = scm_cons_source (obj,
4912 scm_copy_tree (SCM_CAR (obj)),
4913 SCM_UNSPECIFIED);
05b15362 4914 for (obj = SCM_CDR (obj); SCM_CONSP (obj); obj = SCM_CDR (obj))
a23afe53
MD
4915 {
4916 SCM_SETCDR (tl, scm_cons (scm_copy_tree (SCM_CAR (obj)),
4917 SCM_UNSPECIFIED));
4918 tl = SCM_CDR (tl);
4919 }
4920 SCM_SETCDR (tl, obj);
0f2d19dd
JB
4921 return ans;
4922}
1bbd0b84 4923#undef FUNC_NAME
0f2d19dd 4924
1cc91f1b 4925
4163eb72
MV
4926/* We have three levels of EVAL here:
4927
4928 - scm_i_eval (exp, env)
4929
4930 evaluates EXP in environment ENV. ENV is a lexical environment
4931 structure as used by the actual tree code evaluator. When ENV is
4932 a top-level environment, then changes to the current module are
a513ead3 4933 tracked by updating ENV so that it continues to be in sync with
4163eb72
MV
4934 the current module.
4935
4936 - scm_primitive_eval (exp)
4937
4938 evaluates EXP in the top-level environment as determined by the
4939 current module. This is done by constructing a suitable
4940 environment and calling scm_i_eval. Thus, changes to the
4941 top-level module are tracked normally.
4942
4943 - scm_eval (exp, mod)
4944
a513ead3 4945 evaluates EXP while MOD is the current module. This is done by
4163eb72
MV
4946 setting the current module to MOD, invoking scm_primitive_eval on
4947 EXP, and then restoring the current module to the value it had
4948 previously. That is, while EXP is evaluated, changes to the
4949 current module are tracked, but these changes do not persist when
4950 scm_eval returns.
4951
4952 For each level of evals, there are two variants, distinguished by a
4953 _x suffix: the ordinary variant does not modify EXP while the _x
4954 variant can destructively modify EXP into something completely
4955 unintelligible. A Scheme data structure passed as EXP to one of the
4956 _x variants should not ever be used again for anything. So when in
4957 doubt, use the ordinary variant.
4958
4959*/
4960
0f2d19dd 4961SCM
68d8be66 4962scm_i_eval_x (SCM exp, SCM env)
0f2d19dd 4963{
68d8be66 4964 return SCM_XEVAL (exp, env);
0f2d19dd
JB
4965}
4966
68d8be66
MD
4967SCM
4968scm_i_eval (SCM exp, SCM env)
4969{
26fb6390 4970 exp = scm_copy_tree (exp);
e37a4fba 4971 return SCM_XEVAL (exp, env);
68d8be66
MD
4972}
4973
4974SCM
4163eb72 4975scm_primitive_eval_x (SCM exp)
0f2d19dd 4976{
a513ead3 4977 SCM env;
bcdab802 4978 SCM transformer = scm_current_module_transformer ();
a513ead3 4979 if (SCM_NIMP (transformer))
fdc28395 4980 exp = scm_call_1 (transformer, exp);
a513ead3 4981 env = scm_top_level_env (scm_current_module_lookup_closure ());
4163eb72 4982 return scm_i_eval_x (exp, env);
0f2d19dd
JB
4983}
4984
4163eb72
MV
4985SCM_DEFINE (scm_primitive_eval, "primitive-eval", 1, 0, 0,
4986 (SCM exp),
2069af38 4987 "Evaluate @var{exp} in the top-level environment specified by\n"
4163eb72
MV
4988 "the current module.")
4989#define FUNC_NAME s_scm_primitive_eval
4990{
a513ead3 4991 SCM env;
bcdab802 4992 SCM transformer = scm_current_module_transformer ();
a513ead3 4993 if (SCM_NIMP (transformer))
fdc28395 4994 exp = scm_call_1 (transformer, exp);
a513ead3 4995 env = scm_top_level_env (scm_current_module_lookup_closure ());
4163eb72
MV
4996 return scm_i_eval (exp, env);
4997}
4998#undef FUNC_NAME
4999
68d8be66
MD
5000/* Eval does not take the second arg optionally. This is intentional
5001 * in order to be R5RS compatible, and to prepare for the new module
5002 * system, where we would like to make the choice of evaluation
4163eb72 5003 * environment explicit. */
549e6ec6 5004
09074dbf
DH
5005static void
5006change_environment (void *data)
5007{
5008 SCM pair = SCM_PACK (data);
5009 SCM new_module = SCM_CAR (pair);
aa767bc5 5010 SCM old_module = scm_current_module ();
09074dbf 5011 SCM_SETCDR (pair, old_module);
aa767bc5 5012 scm_set_current_module (new_module);
09074dbf
DH
5013}
5014
5015
09074dbf
DH
5016static void
5017restore_environment (void *data)
5018{
5019 SCM pair = SCM_PACK (data);
5020 SCM old_module = SCM_CDR (pair);
aa767bc5 5021 SCM new_module = scm_current_module ();
2e9c835d 5022 SCM_SETCAR (pair, new_module);
aa767bc5 5023 scm_set_current_module (old_module);
09074dbf
DH
5024}
5025
4163eb72
MV
5026static SCM
5027inner_eval_x (void *data)
5028{
5029 return scm_primitive_eval_x (SCM_PACK(data));
5030}
5031
5032SCM
5033scm_eval_x (SCM exp, SCM module)
5034#define FUNC_NAME "eval!"
5035{
5036 SCM_VALIDATE_MODULE (2, module);
5037
5038 return scm_internal_dynamic_wind
5039 (change_environment, inner_eval_x, restore_environment,
5040 (void *) SCM_UNPACK (exp),
5041 (void *) SCM_UNPACK (scm_cons (module, SCM_BOOL_F)));
5042}
5043#undef FUNC_NAME
5044
5045static SCM
5046inner_eval (void *data)
5047{
5048 return scm_primitive_eval (SCM_PACK(data));
5049}
09074dbf 5050
68d8be66 5051SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
4163eb72
MV
5052 (SCM exp, SCM module),
5053 "Evaluate @var{exp}, a list representing a Scheme expression,\n"
5054 "in the top-level environment specified by @var{module}.\n"
8f85c0c6 5055 "While @var{exp} is evaluated (using @code{primitive-eval}),\n"
4163eb72
MV
5056 "@var{module} is made the current module. The current module\n"
5057 "is reset to its previous value when @var{eval} returns.")
1bbd0b84 5058#define FUNC_NAME s_scm_eval
0f2d19dd 5059{
4163eb72 5060 SCM_VALIDATE_MODULE (2, module);
09074dbf
DH
5061
5062 return scm_internal_dynamic_wind
5063 (change_environment, inner_eval, restore_environment,
4163eb72
MV
5064 (void *) SCM_UNPACK (exp),
5065 (void *) SCM_UNPACK (scm_cons (module, SCM_BOOL_F)));
0f2d19dd 5066}
1bbd0b84 5067#undef FUNC_NAME
0f2d19dd 5068
6dbd0af5
MD
5069
5070/* At this point, scm_deval and scm_dapply are generated.
5071 */
5072
a44a9715
DH
5073#define DEVAL
5074#include "eval.c"
0f2d19dd 5075
1cc91f1b 5076
0f2d19dd
JB
5077void
5078scm_init_eval ()
0f2d19dd 5079{
33b97402
MD
5080 scm_init_opts (scm_evaluator_traps,
5081 scm_evaluator_trap_table,
5082 SCM_N_EVALUATOR_TRAPS);
5083 scm_init_opts (scm_eval_options_interface,
5084 scm_eval_opts,
5085 SCM_N_EVAL_OPTIONS);
5086
f99c9c28
MD
5087 scm_tc16_promise = scm_make_smob_type ("promise", 0);
5088 scm_set_smob_mark (scm_tc16_promise, scm_markcdr);
28d52ebb 5089 scm_set_smob_free (scm_tc16_promise, promise_free);
e841c3e0 5090 scm_set_smob_print (scm_tc16_promise, promise_print);
b8229a3b 5091
a44a9715
DH
5092 undefineds = scm_list_1 (SCM_UNDEFINED);
5093 SCM_SETCDR (undefineds, undefineds);
5094 scm_permanent_object (undefineds);
7c33806a 5095
a44a9715 5096 scm_listofnull = scm_list_1 (SCM_EOL);
0f2d19dd 5097
a44a9715
DH
5098 f_apply = scm_c_define_subr ("apply", scm_tc7_lsubr_2, scm_apply);
5099 scm_permanent_object (f_apply);
86d31dfe 5100
a0599745 5101#include "libguile/eval.x"
86d31dfe 5102
25eaf21a 5103 scm_add_feature ("delay");
0f2d19dd 5104}
0f2d19dd 5105
6dbd0af5 5106#endif /* !DEVAL */
89e00824
ML
5107
5108/*
5109 Local Variables:
5110 c-file-style: "gnu"
5111 End:
5112*/