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