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