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