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