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