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