* Makefile.in: Regenerated.
[bpt/guile.git] / libguile / eval.c
CommitLineData
7dc6e754 1/* Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.
0f2d19dd
JB
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program 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
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
0f2d19dd
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
82892bed 40 * If you do not wish that, delete this exception notice. */
0f2d19dd
JB
41\f
42
6dbd0af5
MD
43/* This file is read twice in order to produce debugging versions of
44 * scm_ceval and scm_apply. These functions, scm_deval and
45 * scm_dapply, are produced when we define the preprocessor macro
46 * DEVAL. The file is divided into sections which are treated
47 * differently with respect to DEVAL. The heads of these sections are
48 * marked with the string "SECTION:".
49 */
50
51
52/* SECTION: This code is compiled once.
0f2d19dd
JB
53 */
54
55#ifndef DEVAL
56
d16332b3
JB
57/* We need this to get the definitions for HAVE_ALLOCA_H, etc. */
58#include "scmconfig.h"
59
48b96f4b
JB
60/* AIX requires this to be the first thing in the file. The #pragma
61 directive is indented so pre-ANSI compilers will ignore it, rather
62 than choke on it. */
5862b540 63#ifndef __GNUC__
48b96f4b
JB
64# if HAVE_ALLOCA_H
65# include <alloca.h>
66# else
67# ifdef _AIX
68 #pragma alloca
69# else
70# ifndef alloca /* predefined by HP cc +Olibcalls */
71char *alloca ();
72# endif
73# endif
74# endif
75#endif
76
0f2d19dd
JB
77#include <stdio.h>
78#include "_scm.h"
20e6290e 79#include "debug.h"
20e6290e 80#include "alist.h"
20e6290e
JB
81#include "eq.h"
82#include "continuations.h"
83#include "throw.h"
84#include "smob.h"
85#include "markers.h"
6cb702da 86#include "macros.h"
20e6290e
JB
87#include "procprop.h"
88#include "hashtab.h"
ac46ab16 89#include "hash.h"
20e6290e
JB
90#include "srcprop.h"
91#include "stackchk.h"
0c32d76c
MD
92#include "objects.h"
93#include "feature.h"
20e6290e
JB
94
95#include "eval.h"
0f2d19dd
JB
96\f
97
6dbd0af5
MD
98/* The evaluator contains a plethora of EVAL symbols.
99 * This is an attempt at explanation.
100 *
101 * The following macros should be used in code which is read twice
102 * (where the choice of evaluator is hard soldered):
103 *
104 * SCM_CEVAL is the symbol used within one evaluator to call itself.
105 * Originally, it is defined to scm_ceval, but is redefined to
106 * scm_deval during the second pass.
107 *
108 * SIDEVAL corresponds to SCM_CEVAL, but is used in situations where
109 * only side effects of expressions matter. All immediates are
110 * ignored.
111 *
6cb702da 112 * SCM_EVALIM is used when it is known that the expression is an
6dbd0af5
MD
113 * immediate. (This macro never calls an evaluator.)
114 *
115 * EVALCAR evaluates the car of an expression.
116 *
117 * EVALCELLCAR is like EVALCAR, but is used when it is known that the
118 * car is a lisp cell.
119 *
120 * The following macros should be used in code which is read once
121 * (where the choice of evaluator is dynamic):
122 *
6cb702da 123 * SCM_XEVAL takes care of immediates without calling an evaluator. It
6dbd0af5
MD
124 * then calls scm_ceval *or* scm_deval, depending on the debugging
125 * mode.
126 *
6cb702da 127 * SCM_XEVALCAR corresponds to EVALCAR, but uses scm_ceval *or* scm_deval
6dbd0af5
MD
128 * depending on the debugging mode.
129 *
130 * The main motivation for keeping this plethora is efficiency
131 * together with maintainability (=> locality of code).
132 */
133
6cb702da
MD
134#define SCM_CEVAL scm_ceval
135#define SIDEVAL(x, env) if SCM_NIMP(x) SCM_CEVAL((x), (env))
136
0f2d19dd
JB
137#define EVALCELLCAR(x, env) (SCM_SYMBOLP (SCM_CAR(x)) \
138 ? *scm_lookupcar(x, env) \
139 : SCM_CEVAL(SCM_CAR(x), env))
140
0f2d19dd
JB
141#define EVALCAR(x, env) (SCM_NCELLP(SCM_CAR(x))\
142 ? (SCM_IMP(SCM_CAR(x)) \
6cb702da 143 ? SCM_EVALIM(SCM_CAR(x), env) \
0f2d19dd
JB
144 : SCM_GLOC_VAL(SCM_CAR(x))) \
145 : EVALCELLCAR(x, env))
0f2d19dd 146
e2806c10 147#define EXTEND_ENV SCM_EXTEND_ENV
0f2d19dd
JB
148
149#ifdef MEMOIZE_LOCALS
1cc91f1b 150
0f2d19dd
JB
151SCM *
152scm_ilookup (iloc, env)
153 SCM iloc;
154 SCM env;
0f2d19dd
JB
155{
156 register int ir = SCM_IFRAME (iloc);
157 register SCM er = env;
158 for (; 0 != ir; --ir)
159 er = SCM_CDR (er);
160 er = SCM_CAR (er);
161 for (ir = SCM_IDIST (iloc); 0 != ir; --ir)
162 er = SCM_CDR (er);
163 if (SCM_ICDRP (iloc))
a23afe53
MD
164 return SCM_CDRLOC (er);
165 return SCM_CARLOC (SCM_CDR (er));
0f2d19dd
JB
166}
167#endif
168
f8769b1d
MV
169#ifdef USE_THREADS
170
171/* The Lookup Car Race
172 - by Eva Luator
173
174 Memoization of variables and special forms is done while executing
175 the code for the first time. As long as there is only one thread
176 everything is fine, but as soon as two threads execute the same
177 code concurrently `for the first time' they can come into conflict.
178
179 This memoization includes rewriting variable references into more
180 efficient forms and expanding macros. Furthermore, macro expansion
181 includes `compiling' special forms like `let', `cond', etc. into
182 tree-code instructions.
183
184 There shouldn't normally be a problem with memoizing local and
185 global variable references (into ilocs and glocs), because all
186 threads will mutate the code in *exactly* the same way and (if I
187 read the C code correctly) it is not possible to observe a half-way
188 mutated cons cell. The lookup procedure can handle this
189 transparently without any critical sections.
190
191 It is different with macro expansion, because macro expansion
192 happens outside of the lookup procedure and can't be
193 undone. Therefore it can't cope with it. It has to indicate
194 failure when it detects a lost race and hope that the caller can
195 handle it. Luckily, it turns out that this is the case.
196
197 An example to illustrate this: Suppose that the follwing form will
198 be memoized concurrently by two threads
199
200 (let ((x 12)) x)
201
202 Let's first examine the lookup of X in the body. The first thread
203 decides that it has to find the symbol "x" in the environment and
204 starts to scan it. Then the other thread takes over and actually
205 overtakes the first. It looks up "x" and substitutes an
206 appropriate iloc for it. Now the first thread continues and
207 completes its lookup. It comes to exactly the same conclusions as
208 the second one and could - without much ado - just overwrite the
209 iloc with the same iloc.
210
211 But let's see what will happen when the race occurs while looking
212 up the symbol "let" at the start of the form. It could happen that
213 the second thread interrupts the lookup of the first thread and not
214 only substitutes a gloc for it but goes right ahead and replaces it
215 with the compiled form (#@let* (x 12) x). Now, when the first
216 thread completes its lookup, it would replace the #@let* with a
217 gloc pointing to the "let" binding, effectively reverting the form
218 to (let (x 12) x). This is wrong. It has to detect that it has
219 lost the race and the evaluator has to reconsider the changed form
220 completely.
221
222 This race condition could be resolved with some kind of traffic
223 light (like mutexes) around scm_lookupcar, but I think that it is
224 best to avoid them in this case. They would serialize memoization
225 completely and because lookup involves calling arbitrary Scheme
226 code (via the lookup-thunk), threads could be blocked for an
227 arbitrary amount of time or even deadlock. But with the current
228 solution a lot of unnecessary work is potentially done. */
229
230/* SCM_LOOKUPCAR1 is was SCM_LOOKUPCAR used to be but is allowed to
231 return NULL to indicate a failed lookup due to some race conditions
232 between threads. This only happens when VLOC is the first cell of
233 a special form that will eventually be memoized (like `let', etc.)
234 In that case the whole lookup is bogus and the caller has to
235 reconsider the complete special form.
236
237 SCM_LOOKUPCAR is still there, of course. It just calls
238 SCM_LOOKUPCAR1 and aborts on recieving NULL. So SCM_LOOKUPCAR
239 should only be called when it is known that VLOC is not the first
240 pair of a special form. Otherwise, use SCM_LOOKUPCAR1 and check
241 for NULL. I think I've found the only place where this applies. */
242
243#endif /* USE_THREADS */
1cc91f1b 244
d0b7bad7 245#ifdef USE_THREADS
8ecf1f13
JB
246static SCM *
247scm_lookupcar1 (SCM vloc, SCM genv)
d0b7bad7
MD
248#else
249SCM *
250scm_lookupcar (SCM vloc, SCM genv)
251#endif
0f2d19dd
JB
252{
253 SCM env = genv;
e3173f93
JB
254 register SCM *al, fl, var = SCM_CAR (vloc);
255#ifdef USE_THREADS
256 register SCM var2 = var;
257#endif
0f2d19dd
JB
258#ifdef MEMOIZE_LOCALS
259 register SCM iloc = SCM_ILOC00;
260#endif
261 for (; SCM_NIMP (env); env = SCM_CDR (env))
262 {
263 if (SCM_BOOL_T == scm_procedure_p (SCM_CAR (env)))
264 break;
a23afe53 265 al = SCM_CARLOC (env);
0f2d19dd
JB
266 for (fl = SCM_CAR (*al); SCM_NIMP (fl); fl = SCM_CDR (fl))
267 {
268 if (SCM_NCONSP (fl))
33b97402 269 {
0f2d19dd
JB
270 if (fl == var)
271 {
272#ifdef MEMOIZE_LOCALS
f8769b1d
MV
273#ifdef USE_THREADS
274 if (SCM_CAR (vloc) != var)
275 goto race;
276#endif
a23afe53 277 SCM_SETCAR (vloc, iloc + SCM_ICDR);
0f2d19dd 278#endif
a23afe53 279 return SCM_CDRLOC (*al);
0f2d19dd 280 }
33b97402
MD
281 else
282 break;
283 }
a23afe53 284 al = SCM_CDRLOC (*al);
0f2d19dd
JB
285 if (SCM_CAR (fl) == var)
286 {
287#ifdef MEMOIZE_LOCALS
cf7c17e9 288#ifndef SCM_RECKLESS /* letrec inits to SCM_UNDEFINED */
0f2d19dd
JB
289 if (SCM_UNBNDP (SCM_CAR (*al)))
290 {
291 env = SCM_EOL;
292 goto errout;
293 }
f8769b1d
MV
294#endif
295#ifdef USE_THREADS
296 if (SCM_CAR (vloc) != var)
297 goto race;
0f2d19dd 298#endif
a23afe53 299 SCM_SETCAR (vloc, iloc);
0f2d19dd 300#endif
a23afe53 301 return SCM_CARLOC (*al);
0f2d19dd
JB
302 }
303#ifdef MEMOIZE_LOCALS
304 iloc += SCM_IDINC;
305#endif
306 }
307#ifdef MEMOIZE_LOCALS
308 iloc = (~SCM_IDSTMSK) & (iloc + SCM_IFRINC);
309#endif
310 }
311 {
312 SCM top_thunk, vcell;
313 if (SCM_NIMP(env))
314 {
315 top_thunk = SCM_CAR(env); /* env now refers to a top level env thunk */
316 env = SCM_CDR (env);
317 }
318 else
319 top_thunk = SCM_BOOL_F;
320 vcell = scm_sym2vcell (var, top_thunk, SCM_BOOL_F);
321 if (vcell == SCM_BOOL_F)
322 goto errout;
323 else
324 var = vcell;
325 }
cf7c17e9 326#ifndef SCM_RECKLESS
0f2d19dd
JB
327 if (SCM_NNULLP (env) || SCM_UNBNDP (SCM_CDR (var)))
328 {
329 var = SCM_CAR (var);
330 errout:
f5bf2977 331 /* scm_everr (vloc, genv,...) */
523f5266
GH
332 scm_misc_error (NULL,
333 SCM_NULLP (env)
334 ? "Unbound variable: %S"
335 : "Damaged environment: %S",
336 scm_listify (var, SCM_UNDEFINED));
0f2d19dd
JB
337 }
338#endif
f8769b1d
MV
339#ifdef USE_THREADS
340 if (SCM_CAR (vloc) != var2)
341 {
342 /* Some other thread has changed the very cell we are working
343 on. In effect, it must have done our job or messed it up
344 completely. */
345 race:
346 var = SCM_CAR (vloc);
347 if ((var & 7) == 1)
348 return SCM_GLOC_VAL_LOC (var);
349#ifdef MEMOIZE_LOCALS
350 if ((var & 127) == (127 & SCM_ILOC00))
351 return scm_ilookup (var, genv);
352#endif
353 /* We can't cope with anything else than glocs and ilocs. When
354 a special form has been memoized (i.e. `let' into `#@let') we
355 return NULL and expect the calling function to do the right
356 thing. For the evaluator, this means going back and redoing
357 the dispatch on the car of the form. */
358 return NULL;
359 }
360#endif /* USE_THREADS */
361
a23afe53 362 SCM_SETCAR (vloc, var + 1);
0f2d19dd 363 /* Except wait...what if the var is not a vcell,
f8769b1d 364 * but syntax or something.... */
a23afe53 365 return SCM_CDRLOC (var);
0f2d19dd
JB
366}
367
f8769b1d
MV
368#ifdef USE_THREADS
369SCM *
370scm_lookupcar (vloc, genv)
371 SCM vloc;
372 SCM genv;
373{
374 SCM *loc = scm_lookupcar1 (vloc, genv);
375 if (loc == NULL)
376 abort ();
377 return loc;
378}
f8769b1d
MV
379#endif
380
0f2d19dd 381#define unmemocar scm_unmemocar
1cc91f1b 382
0f2d19dd
JB
383SCM
384scm_unmemocar (form, env)
385 SCM form;
386 SCM env;
0f2d19dd 387{
6dbd0af5 388#ifdef DEBUG_EXTENSIONS
0f2d19dd 389 register int ir;
6dbd0af5 390#endif
0f2d19dd
JB
391 SCM c;
392
393 if (SCM_IMP (form))
394 return form;
395 c = SCM_CAR (form);
396 if (1 == (c & 7))
a23afe53 397 SCM_SETCAR (form, SCM_CAR (c - 1));
0f2d19dd 398#ifdef MEMOIZE_LOCALS
6dbd0af5 399#ifdef DEBUG_EXTENSIONS
0f2d19dd
JB
400 else if (SCM_ILOCP (c))
401 {
402 for (ir = SCM_IFRAME (c); ir != 0; --ir)
403 env = SCM_CDR (env);
404 env = SCM_CAR (SCM_CAR (env));
405 for (ir = SCM_IDIST (c); ir != 0; --ir)
406 env = SCM_CDR (env);
a23afe53 407 SCM_SETCAR (form, SCM_ICDRP (c) ? env : SCM_CAR (env));
0f2d19dd 408 }
6dbd0af5 409#endif
0f2d19dd
JB
410#endif
411 return form;
412}
413
1cc91f1b 414
0f2d19dd
JB
415SCM
416scm_eval_car (pair, env)
417 SCM pair;
418 SCM env;
0f2d19dd 419{
6cb702da 420 return SCM_XEVALCAR (pair, env);
0f2d19dd
JB
421}
422
423\f
424/*
425 * The following rewrite expressions and
426 * some memoized forms have different syntax
427 */
428
6cb702da
MD
429char scm_s_expression[] = "missing or extra expression";
430char scm_s_test[] = "bad test";
431char scm_s_body[] = "bad body";
432char scm_s_bindings[] = "bad bindings";
433char scm_s_variable[] = "bad variable";
434char scm_s_clauses[] = "bad or missing clauses";
435char scm_s_formals[] = "bad formals";
0f2d19dd
JB
436
437SCM scm_i_dot, scm_i_quote, scm_i_quasiquote, scm_i_lambda, scm_i_let,
438 scm_i_arrow, scm_i_else, scm_i_unquote, scm_i_uq_splicing, scm_i_apply;
6dbd0af5
MD
439SCM scm_i_define, scm_i_and, scm_i_begin, scm_i_case, scm_i_cond,
440 scm_i_do, scm_i_if, scm_i_let, scm_i_letrec, scm_i_letstar,
441 scm_i_or, scm_i_set, scm_i_atapply, scm_i_atcall_cc;
0f2d19dd
JB
442static char s_quasiquote[] = "quasiquote";
443static char s_delay[] = "delay";
6dbd0af5
MD
444#ifdef DEBUG_EXTENSIONS
445SCM scm_i_enter_frame, scm_i_apply_frame, scm_i_exit_frame;
446SCM scm_i_trace;
447#endif
0f2d19dd
JB
448
449#define ASRTSYNTAX(cond_, msg_) if(!(cond_))scm_wta(xorig, (msg_), what);
450
451
1cc91f1b
JB
452
453static void bodycheck SCM_P ((SCM xorig, SCM *bodyloc, char *what));
454
0f2d19dd
JB
455static void
456bodycheck (xorig, bodyloc, what)
457 SCM xorig;
458 SCM *bodyloc;
459 char *what;
0f2d19dd 460{
6cb702da 461 ASRTSYNTAX (scm_ilength (*bodyloc) >= 1, scm_s_expression);
0f2d19dd
JB
462}
463
464
1cc91f1b 465
0f2d19dd
JB
466SCM
467scm_m_quote (xorig, env)
468 SCM xorig;
469 SCM env;
0f2d19dd 470{
6cb702da
MD
471 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1,
472 xorig, scm_s_expression, "quote");
0f2d19dd
JB
473 return scm_cons (SCM_IM_QUOTE, SCM_CDR (xorig));
474}
475
476
1cc91f1b 477
0f2d19dd
JB
478SCM
479scm_m_begin (xorig, env)
480 SCM xorig;
481 SCM env;
0f2d19dd 482{
6cb702da
MD
483 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) >= 1,
484 xorig, scm_s_expression, "begin");
0f2d19dd
JB
485 return scm_cons (SCM_IM_BEGIN, SCM_CDR (xorig));
486}
487
488
1cc91f1b 489
0f2d19dd
JB
490SCM
491scm_m_if (xorig, env)
492 SCM xorig;
493 SCM env;
0f2d19dd
JB
494{
495 int len = scm_ilength (SCM_CDR (xorig));
6cb702da 496 SCM_ASSYNT (len >= 2 && len <= 3, xorig, scm_s_expression, "if");
0f2d19dd
JB
497 return scm_cons (SCM_IM_IF, SCM_CDR (xorig));
498}
499
500
1cc91f1b 501
0f2d19dd
JB
502SCM
503scm_m_set (xorig, env)
504 SCM xorig;
505 SCM env;
0f2d19dd 506{
6dbd0af5 507 SCM x = SCM_CDR (xorig);
6cb702da
MD
508 SCM_ASSYNT (2 == scm_ilength (x), xorig, scm_s_expression, "set!");
509 SCM_ASSYNT (SCM_NIMP (SCM_CAR (x)) && SCM_SYMBOLP (SCM_CAR (x)),
510 xorig, scm_s_variable, "set!");
0f2d19dd
JB
511 return scm_cons (SCM_IM_SET, x);
512}
513
514
515#if 0
1cc91f1b 516
0f2d19dd
JB
517SCM
518scm_m_vref (xorig, env)
519 SCM xorig;
520 SCM env;
0f2d19dd
JB
521{
522 SCM x = SCM_CDR (xorig);
6cb702da 523 SCM_ASSYNT (1 == scm_ilength (x), xorig, scm_s_expression, s_vref);
0f2d19dd
JB
524 if (SCM_NIMP(x) && UDSCM_VARIABLEP (SCM_CAR (x)))
525 {
f5bf2977 526 /* scm_everr (SCM_UNDEFINED, env,..., "global variable reference") */
523f5266
GH
527 scm_misc_error (NULL,
528 "Bad variable: %S",
529 scm_listify (SCM_CAR (SCM_CDR (x)), SCM_UNDEFINED));
0f2d19dd 530 }
6cb702da
MD
531 SCM_ASSYNT (SCM_NIMP(x) && DEFSCM_VARIABLEP (SCM_CAR (x)),
532 xorig, scm_s_variable, s_vref);
0f2d19dd
JB
533 return
534 return scm_cons (IM_VREF, x);
535}
536
537
1cc91f1b 538
0f2d19dd
JB
539SCM
540scm_m_vset (xorig, env)
541 SCM xorig;
542 SCM env;
0f2d19dd
JB
543{
544 SCM x = SCM_CDR (xorig);
6cb702da
MD
545 SCM_ASSYNT (3 == scm_ilength (x), xorig, scm_s_expression, s_vset);
546 SCM_ASSYNT ((DEFSCM_VARIABLEP (SCM_CAR (x))
547 || UDSCM_VARIABLEP (SCM_CAR (x))),
548 xorig, scm_s_variable, s_vset);
0f2d19dd
JB
549 return scm_cons (IM_VSET, x);
550}
551#endif
552
553
1cc91f1b 554
0f2d19dd
JB
555SCM
556scm_m_and (xorig, env)
557 SCM xorig;
558 SCM env;
0f2d19dd
JB
559{
560 int len = scm_ilength (SCM_CDR (xorig));
6cb702da 561 SCM_ASSYNT (len >= 0, xorig, scm_s_test, "and");
0f2d19dd
JB
562 if (len >= 1)
563 return scm_cons (SCM_IM_AND, SCM_CDR (xorig));
564 else
565 return SCM_BOOL_T;
566}
567
568
1cc91f1b 569
0f2d19dd
JB
570SCM
571scm_m_or (xorig, env)
572 SCM xorig;
573 SCM env;
0f2d19dd
JB
574{
575 int len = scm_ilength (SCM_CDR (xorig));
6cb702da 576 SCM_ASSYNT (len >= 0, xorig, scm_s_test, "or");
0f2d19dd
JB
577 if (len >= 1)
578 return scm_cons (SCM_IM_OR, SCM_CDR (xorig));
579 else
580 return SCM_BOOL_F;
581}
582
583
1cc91f1b 584
0f2d19dd
JB
585SCM
586scm_m_case (xorig, env)
587 SCM xorig;
588 SCM env;
0f2d19dd
JB
589{
590 SCM proc, x = SCM_CDR (xorig);
6cb702da 591 SCM_ASSYNT (scm_ilength (x) >= 2, xorig, scm_s_clauses, "case");
0f2d19dd
JB
592 while (SCM_NIMP (x = SCM_CDR (x)))
593 {
594 proc = SCM_CAR (x);
6cb702da
MD
595 SCM_ASSYNT (scm_ilength (proc) >= 2, xorig, scm_s_clauses, "case");
596 SCM_ASSYNT (scm_ilength (SCM_CAR (proc)) >= 0
597 || scm_i_else == SCM_CAR (proc),
598 xorig, scm_s_clauses, "case");
0f2d19dd
JB
599 }
600 return scm_cons (SCM_IM_CASE, SCM_CDR (xorig));
601}
602
603
1cc91f1b 604
0f2d19dd
JB
605SCM
606scm_m_cond (xorig, env)
607 SCM xorig;
608 SCM env;
0f2d19dd
JB
609{
610 SCM arg1, x = SCM_CDR (xorig);
611 int len = scm_ilength (x);
6cb702da 612 SCM_ASSYNT (len >= 1, xorig, scm_s_clauses, "cond");
0f2d19dd
JB
613 while (SCM_NIMP (x))
614 {
615 arg1 = SCM_CAR (x);
616 len = scm_ilength (arg1);
6cb702da 617 SCM_ASSYNT (len >= 1, xorig, scm_s_clauses, "cond");
0f2d19dd
JB
618 if (scm_i_else == SCM_CAR (arg1))
619 {
6cb702da
MD
620 SCM_ASSYNT (SCM_NULLP (SCM_CDR (x)) && len >= 2,
621 xorig, "bad ELSE clause", "cond");
a23afe53 622 SCM_SETCAR (arg1, SCM_BOOL_T);
0f2d19dd
JB
623 }
624 if (len >= 2 && scm_i_arrow == SCM_CAR (SCM_CDR (arg1)))
6cb702da
MD
625 SCM_ASSYNT (3 == len && SCM_NIMP (SCM_CAR (SCM_CDR (SCM_CDR (arg1)))),
626 xorig, "bad recipient", "cond");
0f2d19dd
JB
627 x = SCM_CDR (x);
628 }
629 return scm_cons (SCM_IM_COND, SCM_CDR (xorig));
630}
631
632
1cc91f1b 633
0f2d19dd
JB
634SCM
635scm_m_lambda (xorig, env)
636 SCM xorig;
637 SCM env;
0f2d19dd
JB
638{
639 SCM proc, x = SCM_CDR (xorig);
640 if (scm_ilength (x) < 2)
641 goto badforms;
642 proc = SCM_CAR (x);
33b97402
MD
643 if (SCM_NULLP (proc))
644 goto memlambda;
645 if (SCM_IMP (proc))
646 goto badforms;
647 if (SCM_SYMBOLP (proc))
648 goto memlambda;
649 if (SCM_NCONSP (proc))
650 goto badforms;
651 while (SCM_NIMP (proc))
0f2d19dd 652 {
33b97402
MD
653 if (SCM_NCONSP (proc))
654 {
0f2d19dd 655 if (!SCM_SYMBOLP (proc))
33b97402
MD
656 goto badforms;
657 else
658 goto memlambda;
659 }
0f2d19dd
JB
660 if (!(SCM_NIMP (SCM_CAR (proc)) && SCM_SYMBOLP (SCM_CAR (proc))))
661 goto badforms;
662 proc = SCM_CDR (proc);
663 }
664 if SCM_NNULLP
665 (proc)
6cb702da 666 badforms:scm_wta (xorig, scm_s_formals, "lambda");
0f2d19dd 667memlambda:
a23afe53 668 bodycheck (xorig, SCM_CDRLOC (x), "lambda");
0f2d19dd
JB
669 return scm_cons (SCM_IM_LAMBDA, SCM_CDR (xorig));
670}
671
672
1cc91f1b 673
0f2d19dd
JB
674SCM
675scm_m_letstar (xorig, env)
676 SCM xorig;
677 SCM env;
0f2d19dd
JB
678{
679 SCM x = SCM_CDR (xorig), arg1, proc, vars = SCM_EOL, *varloc = &vars;
680 int len = scm_ilength (x);
6cb702da 681 SCM_ASSYNT (len >= 2, xorig, scm_s_body, "let*");
0f2d19dd 682 proc = SCM_CAR (x);
6cb702da 683 SCM_ASSYNT (scm_ilength (proc) >= 0, xorig, scm_s_bindings, "let*");
6dbd0af5 684 while SCM_NIMP (proc)
0f2d19dd
JB
685 {
686 arg1 = SCM_CAR (proc);
6cb702da
MD
687 SCM_ASSYNT (2 == scm_ilength (arg1), xorig, scm_s_bindings, "let*");
688 SCM_ASSYNT (SCM_NIMP (SCM_CAR (arg1)) && SCM_SYMBOLP (SCM_CAR (arg1)),
689 xorig, scm_s_variable, "let*");
0f2d19dd 690 *varloc = scm_cons2 (SCM_CAR (arg1), SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
a23afe53 691 varloc = SCM_CDRLOC (SCM_CDR (*varloc));
0f2d19dd
JB
692 proc = SCM_CDR (proc);
693 }
694 x = scm_cons (vars, SCM_CDR (x));
a23afe53 695 bodycheck (xorig, SCM_CDRLOC (x), "let*");
0f2d19dd
JB
696 return scm_cons (SCM_IM_LETSTAR, x);
697}
698
699/* DO gets the most radically altered syntax
700 (do ((<var1> <init1> <step1>)
701 (<var2> <init2>)
702 ... )
703 (<test> <return>)
704 <body>)
705 ;; becomes
706 (do_mem (varn ... var2 var1)
707 (<init1> <init2> ... <initn>)
708 (<test> <return>)
709 (<body>)
710 <step1> <step2> ... <stepn>) ;; missing steps replaced by var
711 */
712
713
1cc91f1b 714
0f2d19dd
JB
715SCM
716scm_m_do (xorig, env)
717 SCM xorig;
718 SCM env;
0f2d19dd
JB
719{
720 SCM x = SCM_CDR (xorig), arg1, proc;
721 SCM vars = SCM_EOL, inits = SCM_EOL, steps = SCM_EOL;
722 SCM *initloc = &inits, *steploc = &steps;
723 int len = scm_ilength (x);
6cb702da 724 SCM_ASSYNT (len >= 2, xorig, scm_s_test, "do");
0f2d19dd 725 proc = SCM_CAR (x);
6cb702da 726 SCM_ASSYNT (scm_ilength (proc) >= 0, xorig, scm_s_bindings, "do");
0f2d19dd
JB
727 while SCM_NIMP
728 (proc)
729 {
730 arg1 = SCM_CAR (proc);
731 len = scm_ilength (arg1);
6cb702da
MD
732 SCM_ASSYNT (2 == len || 3 == len, xorig, scm_s_bindings, "do");
733 SCM_ASSYNT (SCM_NIMP (SCM_CAR (arg1)) && SCM_SYMBOLP (SCM_CAR (arg1)),
734 xorig, scm_s_variable, "do");
0f2d19dd
JB
735 /* vars reversed here, inits and steps reversed at evaluation */
736 vars = scm_cons (SCM_CAR (arg1), vars); /* variable */
737 arg1 = SCM_CDR (arg1);
738 *initloc = scm_cons (SCM_CAR (arg1), SCM_EOL); /* init */
a23afe53 739 initloc = SCM_CDRLOC (*initloc);
0f2d19dd
JB
740 arg1 = SCM_CDR (arg1);
741 *steploc = scm_cons (SCM_IMP (arg1) ? SCM_CAR (vars) : SCM_CAR (arg1), SCM_EOL); /* step */
a23afe53 742 steploc = SCM_CDRLOC (*steploc);
0f2d19dd
JB
743 proc = SCM_CDR (proc);
744 }
745 x = SCM_CDR (x);
6cb702da 746 SCM_ASSYNT (scm_ilength (SCM_CAR (x)) >= 1, xorig, scm_s_test, "do");
0f2d19dd
JB
747 x = scm_cons2 (SCM_CAR (x), SCM_CDR (x), steps);
748 x = scm_cons2 (vars, inits, x);
a23afe53 749 bodycheck (xorig, SCM_CARLOC (SCM_CDR (SCM_CDR (x))), "do");
0f2d19dd
JB
750 return scm_cons (SCM_IM_DO, x);
751}
752
6dbd0af5
MD
753/* evalcar is small version of inline EVALCAR when we don't care about
754 * speed
755 */
756#define evalcar scm_eval_car
0f2d19dd 757
1cc91f1b
JB
758
759static SCM iqq SCM_P ((SCM form, SCM env, int depth));
760
0f2d19dd
JB
761static SCM
762iqq (form, env, depth)
763 SCM form;
764 SCM env;
765 int depth;
0f2d19dd
JB
766{
767 SCM tmp;
768 int edepth = depth;
769 if SCM_IMP
770 (form) return form;
771 if (SCM_VECTORP (form))
772 {
773 long i = SCM_LENGTH (form);
774 SCM *data = SCM_VELTS (form);
775 tmp = SCM_EOL;
776 for (; --i >= 0;)
777 tmp = scm_cons (data[i], tmp);
778 return scm_vector (iqq (tmp, env, depth));
779 }
780 if SCM_NCONSP
781 (form) return form;
782 tmp = SCM_CAR (form);
783 if (scm_i_quasiquote == tmp)
784 {
785 depth++;
786 goto label;
787 }
788 if (scm_i_unquote == tmp)
789 {
790 --depth;
791 label:
792 form = SCM_CDR (form);
0f2d19dd
JB
793 SCM_ASSERT (SCM_NIMP (form) && SCM_ECONSP (form) && SCM_NULLP (SCM_CDR (form)),
794 form, SCM_ARG1, s_quasiquote);
795 if (0 == depth)
796 return evalcar (form, env);
797 return scm_cons2 (tmp, iqq (SCM_CAR (form), env, depth), SCM_EOL);
798 }
799 if (SCM_NIMP (tmp) && (scm_i_uq_splicing == SCM_CAR (tmp)))
800 {
801 tmp = SCM_CDR (tmp);
802 if (0 == --edepth)
803 return scm_append (scm_cons2 (evalcar (tmp, env), iqq (SCM_CDR (form), env, depth), SCM_EOL));
804 }
805 return scm_cons (iqq (SCM_CAR (form), env, edepth), iqq (SCM_CDR (form), env, depth));
806}
807
808/* Here are acros which return values rather than code. */
809
1cc91f1b 810
0f2d19dd
JB
811SCM
812scm_m_quasiquote (xorig, env)
813 SCM xorig;
814 SCM env;
0f2d19dd
JB
815{
816 SCM x = SCM_CDR (xorig);
6cb702da 817 SCM_ASSYNT (scm_ilength (x) == 1, xorig, scm_s_expression, s_quasiquote);
0f2d19dd
JB
818 return iqq (SCM_CAR (x), env, 1);
819}
820
1cc91f1b 821
0f2d19dd
JB
822SCM
823scm_m_delay (xorig, env)
824 SCM xorig;
825 SCM env;
0f2d19dd 826{
6cb702da 827 SCM_ASSYNT (scm_ilength (xorig) == 2, xorig, scm_s_expression, s_delay);
0f2d19dd
JB
828 xorig = SCM_CDR (xorig);
829 return scm_makprom (scm_closure (scm_cons2 (SCM_EOL, SCM_CAR (xorig), SCM_CDR (xorig)),
830 env));
831}
832
1cc91f1b 833
6cb702da
MD
834SCM
835scm_env_top_level (env)
0f2d19dd 836 SCM env;
0f2d19dd
JB
837{
838 while (SCM_NIMP(env))
839 {
840 if (SCM_BOOL_T == scm_procedure_p (SCM_CAR(env)))
841 return SCM_CAR(env);
842 env = SCM_CDR (env);
843 }
844 return SCM_BOOL_F;
845}
846
1cc91f1b 847
0f2d19dd
JB
848SCM
849scm_m_define (x, env)
850 SCM x;
851 SCM env;
0f2d19dd
JB
852{
853 SCM proc, arg1 = x;
854 x = SCM_CDR (x);
6cb702da
MD
855 /* SCM_ASSYNT(SCM_NULLP(env), x, "bad placement", s_define);*/
856 SCM_ASSYNT (scm_ilength (x) >= 2, arg1, scm_s_expression, "define");
0f2d19dd
JB
857 proc = SCM_CAR (x);
858 x = SCM_CDR (x);
859 while (SCM_NIMP (proc) && SCM_CONSP (proc))
860 { /* nested define syntax */
861 x = scm_cons (scm_cons2 (scm_i_lambda, SCM_CDR (proc), x), SCM_EOL);
862 proc = SCM_CAR (proc);
863 }
6cb702da
MD
864 SCM_ASSYNT (SCM_NIMP (proc) && SCM_SYMBOLP (proc),
865 arg1, scm_s_variable, "define");
866 SCM_ASSYNT (1 == scm_ilength (x), arg1, scm_s_expression, "define");
0f2d19dd
JB
867 if (SCM_TOP_LEVEL (env))
868 {
869 x = evalcar (x, env);
6dbd0af5 870#ifdef DEBUG_EXTENSIONS
80ea260c
MD
871 if (SCM_REC_PROCNAMES_P && SCM_NIMP (x))
872 {
873 arg1 = x;
874 proc:
875 if (SCM_CLOSUREP (arg1)
876 /* Only the first definition determines the name. */
877 && scm_procedure_property (arg1, scm_i_name) == SCM_BOOL_F)
878 scm_set_procedure_property_x (arg1, scm_i_name, proc);
879 else if (SCM_TYP16 (arg1) == scm_tc16_macro
880 && SCM_CDR (arg1) != arg1)
881 {
882 arg1 = SCM_CDR (arg1);
883 goto proc;
884 }
885 }
6dbd0af5 886#endif
6cb702da 887 arg1 = scm_sym2vcell (proc, scm_env_top_level (env), SCM_BOOL_T);
0f2d19dd 888#if 0
cf7c17e9 889#ifndef SCM_RECKLESS
0f2d19dd
JB
890 if (SCM_NIMP (SCM_CDR (arg1)) && ((SCM) SCM_SNAME (SCM_CDR (arg1)) == proc)
891 && (SCM_CDR (arg1) != x))
892 scm_warn ("redefining built-in ", SCM_CHARS (proc));
893 else
894#endif
895 if (5 <= scm_verbose && SCM_UNDEFINED != SCM_CDR (arg1))
896 scm_warn ("redefining ", SCM_CHARS (proc));
0f2d19dd 897#endif
a23afe53 898 SCM_SETCDR (arg1, x);
0f2d19dd
JB
899#ifdef SICP
900 return scm_cons2 (scm_i_quote, SCM_CAR (arg1), SCM_EOL);
901#else
902 return SCM_UNSPECIFIED;
903#endif
904 }
905 return scm_cons2 (SCM_IM_DEFINE, proc, x);
906}
6dbd0af5 907
0f2d19dd
JB
908/* end of acros */
909
1cc91f1b 910
0f2d19dd
JB
911SCM
912scm_m_letrec (xorig, env)
913 SCM xorig;
914 SCM env;
0f2d19dd
JB
915{
916 SCM cdrx = SCM_CDR (xorig); /* locally mutable version of form */
917 char *what = SCM_CHARS (SCM_CAR (xorig));
918 SCM x = cdrx, proc, arg1; /* structure traversers */
919 SCM vars = SCM_EOL, inits = SCM_EOL, *initloc = &inits;
920
6cb702da 921 ASRTSYNTAX (scm_ilength (x) >= 2, scm_s_body);
0f2d19dd
JB
922 proc = SCM_CAR (x);
923 if SCM_NULLP
924 (proc) return scm_m_letstar (xorig, env); /* null binding, let* faster */
6cb702da 925 ASRTSYNTAX (scm_ilength (proc) >= 1, scm_s_bindings);
0f2d19dd
JB
926 do
927 {
928 /* vars scm_list reversed here, inits reversed at evaluation */
929 arg1 = SCM_CAR (proc);
6cb702da
MD
930 ASRTSYNTAX (2 == scm_ilength (arg1), scm_s_bindings);
931 ASRTSYNTAX (SCM_NIMP (SCM_CAR (arg1)) && SCM_SYMBOLP (SCM_CAR (arg1)), scm_s_variable);
0f2d19dd
JB
932 vars = scm_cons (SCM_CAR (arg1), vars);
933 *initloc = scm_cons (SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
a23afe53 934 initloc = SCM_CDRLOC (*initloc);
0f2d19dd
JB
935 }
936 while SCM_NIMP
937 (proc = SCM_CDR (proc));
938 cdrx = scm_cons2 (vars, inits, SCM_CDR (x));
a23afe53 939 bodycheck (xorig, SCM_CDRLOC (SCM_CDR (cdrx)), what);
0f2d19dd
JB
940 return scm_cons (SCM_IM_LETREC, cdrx);
941}
942
1cc91f1b 943
0f2d19dd
JB
944SCM
945scm_m_let (xorig, env)
946 SCM xorig;
947 SCM env;
0f2d19dd
JB
948{
949 SCM cdrx = SCM_CDR (xorig); /* locally mutable version of form */
950 SCM x = cdrx, proc, arg1, name; /* structure traversers */
951 SCM vars = SCM_EOL, inits = SCM_EOL, *varloc = &vars, *initloc = &inits;
952
6cb702da 953 SCM_ASSYNT (scm_ilength (x) >= 2, xorig, scm_s_body, "let");
0f2d19dd
JB
954 proc = SCM_CAR (x);
955 if (SCM_NULLP (proc)
956 || (SCM_NIMP (proc) && SCM_CONSP (proc)
957 && SCM_NIMP (SCM_CAR (proc)) && SCM_CONSP (SCM_CAR (proc)) && SCM_NULLP (SCM_CDR (proc))))
958 return scm_m_letstar (xorig, env); /* null or single binding, let* is faster */
6cb702da 959 SCM_ASSYNT (SCM_NIMP (proc), xorig, scm_s_bindings, "let");
0f2d19dd
JB
960 if (SCM_CONSP (proc)) /* plain let, proc is <bindings> */
961 return scm_cons (SCM_IM_LET, SCM_CDR (scm_m_letrec (xorig, env)));
962 if (!SCM_SYMBOLP (proc))
6cb702da 963 scm_wta (xorig, scm_s_bindings, "let"); /* bad let */
0f2d19dd
JB
964 name = proc; /* named let, build equiv letrec */
965 x = SCM_CDR (x);
6cb702da 966 SCM_ASSYNT (scm_ilength (x) >= 2, xorig, scm_s_body, "let");
0f2d19dd 967 proc = SCM_CAR (x); /* bindings scm_list */
6cb702da 968 SCM_ASSYNT (scm_ilength (proc) >= 0, xorig, scm_s_bindings, "let");
0f2d19dd
JB
969 while SCM_NIMP
970 (proc)
971 { /* vars and inits both in order */
972 arg1 = SCM_CAR (proc);
6cb702da
MD
973 SCM_ASSYNT (2 == scm_ilength (arg1), xorig, scm_s_bindings, "let");
974 SCM_ASSYNT (SCM_NIMP (SCM_CAR (arg1)) && SCM_SYMBOLP (SCM_CAR (arg1)),
975 xorig, scm_s_variable, "let");
0f2d19dd 976 *varloc = scm_cons (SCM_CAR (arg1), SCM_EOL);
a23afe53 977 varloc = SCM_CDRLOC (*varloc);
0f2d19dd 978 *initloc = scm_cons (SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
a23afe53 979 initloc = SCM_CDRLOC (*initloc);
0f2d19dd
JB
980 proc = SCM_CDR (proc);
981 }
982 return
983 scm_m_letrec (scm_cons2 (scm_i_let,
984 scm_cons (scm_cons2 (name, scm_cons2 (scm_i_lambda, vars, SCM_CDR (x)), SCM_EOL), SCM_EOL),
985 scm_acons (name, inits, SCM_EOL)), /* body */
986 env);
987}
988
989
1cc91f1b 990
0f2d19dd
JB
991SCM
992scm_m_apply (xorig, env)
993 SCM xorig;
994 SCM env;
0f2d19dd 995{
6cb702da
MD
996 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 2,
997 xorig, scm_s_expression, "@apply");
0f2d19dd
JB
998 return scm_cons (SCM_IM_APPLY, SCM_CDR (xorig));
999}
1000
e2806c10 1001#define s_atcall_cc (SCM_ISYMCHARS(SCM_IM_CONT)+1)
0f2d19dd 1002
1cc91f1b 1003
0f2d19dd
JB
1004SCM
1005scm_m_cont (xorig, env)
1006 SCM xorig;
1007 SCM env;
0f2d19dd 1008{
6cb702da
MD
1009 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1,
1010 xorig, scm_s_expression, "@call-with-current-continuation");
0f2d19dd
JB
1011 return scm_cons (SCM_IM_CONT, SCM_CDR (xorig));
1012}
1013
6dbd0af5
MD
1014/* scm_unmemocopy takes a memoized expression together with its
1015 * environment and rewrites it to its original form. Thus, it is the
1016 * inversion of the rewrite rules above. The procedure is not
1017 * optimized for speed. It's used in scm_iprin1 when printing the
220ff1eb
MD
1018 * code of a closure, in scm_procedure_source, in display_frame when
1019 * generating the source for a stackframe in a backtrace, and in
1020 * display_expression.
6dbd0af5
MD
1021 */
1022
1cc91f1b
JB
1023static SCM unmemocopy SCM_P ((SCM x, SCM env));
1024
6dbd0af5
MD
1025static SCM
1026unmemocopy (x, env)
1027 SCM x;
1028 SCM env;
6dbd0af5
MD
1029{
1030 SCM ls, z;
1031#ifdef DEBUG_EXTENSIONS
1032 SCM p;
1033#endif
1034 if (SCM_NCELLP (x) || SCM_NECONSP (x))
1035 return x;
1036#ifdef DEBUG_EXTENSIONS
1037 p = scm_whash_lookup (scm_source_whash, x);
1038#endif
1039 switch (SCM_TYP7 (x))
1040 {
1041 case (127 & SCM_IM_AND):
1042 ls = z = scm_cons (scm_i_and, SCM_UNSPECIFIED);
1043 break;
1044 case (127 & SCM_IM_BEGIN):
1045 ls = z = scm_cons (scm_i_begin, SCM_UNSPECIFIED);
1046 break;
1047 case (127 & SCM_IM_CASE):
1048 ls = z = scm_cons (scm_i_case, SCM_UNSPECIFIED);
1049 break;
1050 case (127 & SCM_IM_COND):
1051 ls = z = scm_cons (scm_i_cond, SCM_UNSPECIFIED);
1052 break;
1053 case (127 & SCM_IM_DO):
1054 ls = scm_cons (scm_i_do, SCM_UNSPECIFIED);
1055 goto transform;
1056 case (127 & SCM_IM_IF):
1057 ls = z = scm_cons (scm_i_if, SCM_UNSPECIFIED);
1058 break;
1059 case (127 & SCM_IM_LET):
1060 ls = scm_cons (scm_i_let, SCM_UNSPECIFIED);
1061 goto transform;
1062 case (127 & SCM_IM_LETREC):
1063 {
1064 SCM f, v, e, s;
1065 ls = scm_cons (scm_i_letrec, SCM_UNSPECIFIED);
1066 transform:
1067 x = SCM_CDR (x);
1068 f = v = SCM_CAR (x);
1069 x = SCM_CDR (x);
e2806c10 1070 z = EXTEND_ENV (f, SCM_EOL, env);
6dbd0af5
MD
1071 e = scm_reverse (unmemocopy (SCM_CAR (x),
1072 SCM_CAR (ls) == scm_i_letrec ? z : env));
1073 env = z;
1074 s = SCM_CAR (ls) == scm_i_do
1075 ? scm_reverse (unmemocopy (SCM_CDR (SCM_CDR (SCM_CDR (x))), env))
1076 : f;
1077 z = SCM_EOL;
1078 do
1079 {
1080 z = scm_acons (SCM_CAR (v),
1081 scm_cons (SCM_CAR (e),
1082 SCM_CAR (s) == SCM_CAR (v)
1083 ? SCM_EOL
1084 : scm_cons (SCM_CAR (s), SCM_EOL)),
1085 z);
1086 v = SCM_CDR (v);
1087 e = SCM_CDR (e);
1088 s = SCM_CDR (s);
1089 }
1090 while SCM_NIMP (v);
a23afe53
MD
1091 z = scm_cons (z, SCM_UNSPECIFIED);
1092 SCM_SETCDR (ls, z);
6dbd0af5
MD
1093 if (SCM_CAR (ls) == scm_i_do)
1094 {
1095 x = SCM_CDR (x);
a23afe53 1096 SCM_SETCDR (z, scm_cons (unmemocopy (SCM_CAR (x), env),
6dbd0af5 1097 SCM_UNSPECIFIED));
a23afe53
MD
1098 z = SCM_CDR (z);
1099 x = (SCM) (SCM_CARLOC (SCM_CDR (x)) - 1);
6dbd0af5
MD
1100 }
1101 break;
1102 }
1103 case (127 & SCM_IM_LETSTAR):
1104 {
1105 SCM b, y;
1106 x = SCM_CDR (x);
1107 b = SCM_CAR (x);
1108 y = SCM_EOL;
1109 if SCM_IMP (b)
1110 {
e2806c10 1111 env = EXTEND_ENV (SCM_EOL, SCM_EOL, env);
6dbd0af5
MD
1112 goto letstar;
1113 }
1114 y = z = scm_acons (SCM_CAR (b),
1115 unmemocar (
1116 scm_cons (unmemocopy (SCM_CAR (SCM_CDR (b)), env), SCM_EOL), env),
1117 SCM_UNSPECIFIED);
e2806c10 1118 env = EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
6dbd0af5
MD
1119 b = SCM_CDR (SCM_CDR (b));
1120 if (SCM_IMP (b))
1121 {
1122 SCM_SETCDR (y, SCM_EOL);
1123 ls = scm_cons (scm_i_let, z = scm_cons (y, SCM_UNSPECIFIED));
1124 break;
1125 }
1126 do
1127 {
a23afe53
MD
1128 SCM_SETCDR (z, scm_acons (SCM_CAR (b),
1129 unmemocar (
6dbd0af5 1130 scm_cons (unmemocopy (SCM_CAR (SCM_CDR (b)), env), SCM_EOL), env),
a23afe53
MD
1131 SCM_UNSPECIFIED));
1132 z = SCM_CDR (z);
e2806c10 1133 env = EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
6dbd0af5
MD
1134 b = SCM_CDR (SCM_CDR (b));
1135 }
1136 while SCM_NIMP (b);
a23afe53 1137 SCM_SETCDR (z, SCM_EOL);
6dbd0af5
MD
1138 letstar:
1139 ls = scm_cons (scm_i_letstar, z = scm_cons (y, SCM_UNSPECIFIED));
1140 break;
1141 }
1142 case (127 & SCM_IM_OR):
1143 ls = z = scm_cons (scm_i_or, SCM_UNSPECIFIED);
1144 break;
1145 case (127 & SCM_IM_LAMBDA):
1146 x = SCM_CDR (x);
1147 ls = scm_cons (scm_i_lambda,
1148 z = scm_cons (SCM_CAR (x), SCM_UNSPECIFIED));
e2806c10 1149 env = EXTEND_ENV (SCM_CAR (x), SCM_EOL, env);
6dbd0af5
MD
1150 break;
1151 case (127 & SCM_IM_QUOTE):
1152 ls = z = scm_cons (scm_i_quote, SCM_UNSPECIFIED);
1153 break;
1154 case (127 & SCM_IM_SET):
1155 ls = z = scm_cons (scm_i_set, SCM_UNSPECIFIED);
1156 break;
1157 case (127 & SCM_IM_DEFINE):
1158 {
1159 SCM n;
1160 x = SCM_CDR (x);
1161 ls = scm_cons (scm_i_define,
1162 z = scm_cons (n = SCM_CAR (x), SCM_UNSPECIFIED));
1163 if (SCM_NNULLP (env))
a23afe53 1164 SCM_SETCAR (SCM_CAR (env), scm_cons (n, SCM_CAR (SCM_CAR (env))));
6dbd0af5
MD
1165 break;
1166 }
1167 case (127 & SCM_MAKISYM (0)):
1168 z = SCM_CAR (x);
1169 if (!SCM_ISYMP (z))
1170 goto unmemo;
1171 switch SCM_ISYMNUM (z)
1172 {
1173 case (SCM_ISYMNUM (SCM_IM_APPLY)):
1174 ls = z = scm_cons (scm_i_atapply, SCM_UNSPECIFIED);
1175 goto loop;
1176 case (SCM_ISYMNUM (SCM_IM_CONT)):
1177 ls = z = scm_cons (scm_i_atcall_cc, SCM_UNSPECIFIED);
1178 goto loop;
1179 default:
fa888178 1180 /* appease the Sun compiler god: */ ;
6dbd0af5
MD
1181 }
1182 unmemo:
1183 default:
1184 ls = z = unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env),
1185 SCM_UNSPECIFIED),
1186 env);
1187 }
1188loop:
1189 while (SCM_CELLP (x = SCM_CDR (x)) && SCM_ECONSP (x))
a23afe53
MD
1190 {
1191 SCM_SETCDR (z, unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env),
1192 SCM_UNSPECIFIED),
1193 env));
1194 z = SCM_CDR (z);
1195 }
1196 SCM_SETCDR (z, x);
6dbd0af5
MD
1197#ifdef DEBUG_EXTENSIONS
1198 if (SCM_NFALSEP (p))
1199 scm_whash_insert (scm_source_whash, ls, p);
1200#endif
1201 return ls;
1202}
1203
1cc91f1b 1204
6dbd0af5
MD
1205SCM
1206scm_unmemocopy (x, env)
1207 SCM x;
1208 SCM env;
6dbd0af5
MD
1209{
1210 if (SCM_NNULLP (env))
1211 /* Make a copy of the lowest frame to protect it from
1212 modifications by SCM_IM_DEFINE */
1213 return unmemocopy (x, scm_cons (SCM_CAR (env), SCM_CDR (env)));
1214 else
1215 return unmemocopy (x, env);
1216}
1217
cf7c17e9 1218#ifndef SCM_RECKLESS
1cc91f1b 1219
0f2d19dd
JB
1220int
1221scm_badargsp (formals, args)
1222 SCM formals;
1223 SCM args;
0f2d19dd
JB
1224{
1225 while SCM_NIMP
1226 (formals)
1227 {
1228 if SCM_NCONSP
1229 (formals) return 0;
1230 if SCM_IMP
1231 (args) return 1;
1232 formals = SCM_CDR (formals);
1233 args = SCM_CDR (args);
1234 }
1235 return SCM_NNULLP (args) ? 1 : 0;
1236}
1237#endif
1238
1239
1240\f
6dbd0af5 1241SCM
680ed4a8 1242scm_eval_args (l, env, proc)
6dbd0af5
MD
1243 SCM l;
1244 SCM env;
680ed4a8 1245 SCM proc;
6dbd0af5 1246{
680ed4a8 1247 SCM results = SCM_EOL, *lloc = &results, res;
6dbd0af5
MD
1248 while (SCM_NIMP (l))
1249 {
cf7c17e9 1250#ifdef SCM_CAUTIOUS
680ed4a8
MD
1251 if (SCM_IMP (l))
1252 goto wrongnumargs;
1253 else if (SCM_CONSP (l))
1254 {
1255 if (SCM_IMP (SCM_CAR (l)))
6cb702da 1256 res = SCM_EVALIM (SCM_CAR (l), env);
680ed4a8
MD
1257 else
1258 res = EVALCELLCAR (l, env);
1259 }
1260 else if (SCM_TYP3 (l) == 1)
1261 {
1262 if ((res = SCM_GLOC_VAL (SCM_CAR (l))) == 0)
1263 res = SCM_CAR (l); /* struct planted in code */
1264 }
1265 else
1266 goto wrongnumargs;
1267#else
1268 res = EVALCAR (l, env);
1269#endif
1270 *lloc = scm_cons (res, SCM_EOL);
a23afe53 1271 lloc = SCM_CDRLOC (*lloc);
6dbd0af5
MD
1272 l = SCM_CDR (l);
1273 }
cf7c17e9 1274#ifdef SCM_CAUTIOUS
680ed4a8
MD
1275 if (SCM_NNULLP (l))
1276 {
1277 wrongnumargs:
1278 scm_wrong_num_args (proc);
1279 }
1280#endif
1281 return results;
6dbd0af5 1282}
c4ac4d88
JB
1283
1284
0f2d19dd
JB
1285#endif /* !DEVAL */
1286
6dbd0af5
MD
1287
1288/* SECTION: This code is specific for the debugging support. One
1289 * branch is read when DEVAL isn't defined, the other when DEVAL is
1290 * defined.
1291 */
1292
1293#ifndef DEVAL
1294
1295#define SCM_APPLY scm_apply
1296#define PREP_APPLY(proc, args)
1297#define ENTER_APPLY
1298#define RETURN(x) return x;
b7ff98dd
MD
1299#ifdef STACK_CHECKING
1300#ifndef NO_CEVAL_STACK_CHECKING
1301#define EVAL_STACK_CHECKING
1302#endif
6dbd0af5
MD
1303#endif
1304
1305#else /* !DEVAL */
1306
0f2d19dd
JB
1307#undef SCM_CEVAL
1308#define SCM_CEVAL scm_deval /* Substitute all uses of scm_ceval */
1309#undef SCM_APPLY
1310#define SCM_APPLY scm_dapply
6dbd0af5
MD
1311#undef PREP_APPLY
1312#define PREP_APPLY(p, l) \
1313{ ++debug.info; debug.info->a.proc = p; debug.info->a.args = l; }
1314#undef ENTER_APPLY
1315#define ENTER_APPLY \
1316{\
b7ff98dd 1317 SCM_SET_ARGSREADY (debug);\
b6d75948 1318 if (CHECK_APPLY && SCM_TRAPS_P)\
b7ff98dd 1319 if (SCM_APPLY_FRAME_P || (SCM_TRACE_P && PROCTRACEP (proc)))\
6dbd0af5 1320 {\
b7ff98dd 1321 SCM tmp, tail = SCM_TRACED_FRAME_P (debug) ? SCM_BOOL_T : SCM_BOOL_F;\
c6a4fbce 1322 SCM_SET_TRACED_FRAME (debug); \
b7ff98dd 1323 if (SCM_CHEAPTRAPS_P)\
6dbd0af5 1324 {\
c0ab1b8d 1325 tmp = scm_make_debugobj (&debug);\
6dbd0af5 1326 scm_ithrow (scm_i_apply_frame, scm_cons2 (tmp, tail, SCM_EOL), 0);\
b6d75948 1327 }\
6dbd0af5
MD
1328 else\
1329 {\
1330 scm_make_cont (&tmp);\
ca6ef71a 1331 if (!setjmp (SCM_JMPBUF (tmp)))\
6dbd0af5
MD
1332 scm_ithrow (scm_i_apply_frame, scm_cons2 (tmp, tail, SCM_EOL), 0);\
1333 }\
1334 }\
1335}
0f2d19dd
JB
1336#undef RETURN
1337#define RETURN(e) {proc = (e); goto exit;}
b7ff98dd
MD
1338#ifdef STACK_CHECKING
1339#ifndef EVAL_STACK_CHECKING
1340#define EVAL_STACK_CHECKING
1341#endif
6dbd0af5
MD
1342#endif
1343
1344/* scm_ceval_ptr points to the currently selected evaluator.
1345 * *fixme*: Although efficiency is important here, this state variable
1346 * should probably not be a global. It should be related to the
1347 * current repl.
1348 */
1349
1cc91f1b
JB
1350
1351SCM (*scm_ceval_ptr) SCM_P ((SCM x, SCM env));
0f2d19dd 1352
1646d37b 1353/* scm_last_debug_frame contains a pointer to the last debugging
6dbd0af5
MD
1354 * information stack frame. It is accessed very often from the
1355 * debugging evaluator, so it should probably not be indirectly
1356 * addressed. Better to save and restore it from the current root at
1357 * any stack swaps.
1358 */
1359
1646d37b
MD
1360#ifndef USE_THREADS
1361scm_debug_frame *scm_last_debug_frame;
1362#endif
6dbd0af5
MD
1363
1364/* scm_debug_eframe_size is the number of slots available for pseudo
1365 * stack frames at each real stack frame.
1366 */
1367
1368int scm_debug_eframe_size;
1369
b7ff98dd 1370int scm_debug_mode, scm_check_entry_p, scm_check_apply_p, scm_check_exit_p;
6dbd0af5 1371
a74145b8
MD
1372int scm_eval_stack;
1373
33b97402 1374scm_option scm_eval_opts[] = {
a74145b8 1375 { SCM_OPTION_INTEGER, "stack", 22000, "Size of thread stacks (in machine words)." }
33b97402
MD
1376};
1377
6dbd0af5 1378scm_option scm_debug_opts[] = {
b7ff98dd
MD
1379 { SCM_OPTION_BOOLEAN, "cheap", 1,
1380 "*Flyweight representation of the stack at traps." },
1381 { SCM_OPTION_BOOLEAN, "breakpoints", 0, "*Check for breakpoints." },
1382 { SCM_OPTION_BOOLEAN, "trace", 0, "*Trace mode." },
1383 { SCM_OPTION_BOOLEAN, "procnames", 1,
1384 "Record procedure names at definition." },
1385 { SCM_OPTION_BOOLEAN, "backwards", 0,
1386 "Display backtrace in anti-chronological order." },
4e646a03
MD
1387 { SCM_OPTION_INTEGER, "indent", 10, "Maximal indentation in backtrace." },
1388 { SCM_OPTION_INTEGER, "frames", 3,
b7ff98dd 1389 "Maximum number of tail-recursive frames in backtrace." },
4e646a03
MD
1390 { SCM_OPTION_INTEGER, "maxdepth", 1000,
1391 "Maximal number of stored backtrace frames." },
1392 { SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." },
11f77bfc
MD
1393 { SCM_OPTION_BOOLEAN, "backtrace", 0, "Show backtrace on error." },
1394 { SCM_OPTION_BOOLEAN, "debug", 0, "Use the debugging evaluator." },
a74145b8 1395 { SCM_OPTION_INTEGER, "stack", 20000, "Stack size limit (measured in words; 0 = no check)." }
6dbd0af5
MD
1396};
1397
1398scm_option scm_evaluator_trap_table[] = {
b6d75948 1399 { SCM_OPTION_BOOLEAN, "traps", 0, "Enable evaluator traps." },
b7ff98dd
MD
1400 { SCM_OPTION_BOOLEAN, "enter-frame", 0, "Trap when eval enters new frame." },
1401 { SCM_OPTION_BOOLEAN, "apply-frame", 0, "Trap when entering apply." },
1402 { SCM_OPTION_BOOLEAN, "exit-frame", 0, "Trap when exiting eval or apply." }
6dbd0af5
MD
1403};
1404
33b97402
MD
1405SCM_PROC (s_eval_options_interface, "eval-options-interface", 0, 1, 0, scm_eval_options_interface);
1406
1407SCM
8ecf1f13 1408scm_eval_options_interface (SCM setting)
33b97402
MD
1409{
1410 SCM ans;
1411 SCM_DEFER_INTS;
1412 ans = scm_options (setting,
1413 scm_eval_opts,
1414 SCM_N_EVAL_OPTIONS,
1415 s_eval_options_interface);
a74145b8 1416 scm_eval_stack = SCM_EVAL_STACK * sizeof (void *);
33b97402
MD
1417 SCM_ALLOW_INTS;
1418 return ans;
1419}
1420
1421SCM_PROC (s_evaluator_traps, "evaluator-traps-interface", 0, 1, 0, scm_evaluator_traps);
1422
1423SCM
1424scm_evaluator_traps (setting)
1425 SCM setting;
1426{
1427 SCM ans;
1428 SCM_DEFER_INTS;
1429 ans = scm_options (setting,
1430 scm_evaluator_trap_table,
1431 SCM_N_EVALUATOR_TRAPS,
1432 s_evaluator_traps);
1433 SCM_RESET_DEBUG_MODE;
1434 SCM_ALLOW_INTS
1435 return ans;
1436}
1437
6dbd0af5 1438SCM
680ed4a8
MD
1439scm_deval_args (l, env, proc, lloc)
1440 SCM l, env, proc, *lloc;
0f2d19dd 1441{
680ed4a8 1442 SCM *results = lloc, res;
0f2d19dd
JB
1443 while (SCM_NIMP (l))
1444 {
cf7c17e9 1445#ifdef SCM_CAUTIOUS
680ed4a8
MD
1446 if (SCM_IMP (l))
1447 goto wrongnumargs;
1448 else if (SCM_CONSP (l))
1449 {
1450 if (SCM_IMP (SCM_CAR (l)))
6cb702da 1451 res = SCM_EVALIM (SCM_CAR (l), env);
680ed4a8
MD
1452 else
1453 res = EVALCELLCAR (l, env);
1454 }
1455 else if (SCM_TYP3 (l) == 1)
1456 {
1457 if ((res = SCM_GLOC_VAL (SCM_CAR (l))) == 0)
1458 res = SCM_CAR (l); /* struct planted in code */
1459 }
1460 else
1461 goto wrongnumargs;
1462#else
1463 res = EVALCAR (l, env);
1464#endif
1465 *lloc = scm_cons (res, SCM_EOL);
a23afe53 1466 lloc = SCM_CDRLOC (*lloc);
0f2d19dd
JB
1467 l = SCM_CDR (l);
1468 }
cf7c17e9 1469#ifdef SCM_CAUTIOUS
680ed4a8
MD
1470 if (SCM_NNULLP (l))
1471 {
1472 wrongnumargs:
1473 scm_wrong_num_args (proc);
1474 }
1475#endif
1476 return *results;
0f2d19dd
JB
1477}
1478
6dbd0af5
MD
1479#endif /* !DEVAL */
1480
1481
1482/* SECTION: Some local definitions for the evaluator.
1483 */
1484
1485#ifndef DEVAL
1486#ifdef SCM_FLOATS
1487#define CHECK_EQVISH(A,B) (((A) == (B)) || (SCM_NFALSEP (scm_eqv_p ((A), (B)))))
1488#else
1489#define CHECK_EQVISH(A,B) ((A) == (B))
1490#endif
1491#endif /* DEVAL */
1492
399dedcc 1493#define BUILTIN_RPASUBR /* Handle rpsubrs and asubrs without calling apply */
6dbd0af5
MD
1494
1495/* SECTION: This is the evaluator. Like any real monster, it has
1496 * three heads. This code is compiled twice.
1497 */
1498
0f2d19dd 1499#if 0
1cc91f1b 1500
0f2d19dd
JB
1501SCM
1502scm_ceval (x, env)
1503 SCM x;
1504 SCM env;
0f2d19dd
JB
1505{}
1506#endif
1507#if 0
1cc91f1b 1508
0f2d19dd
JB
1509SCM
1510scm_deval (x, env)
1511 SCM x;
1512 SCM env;
0f2d19dd
JB
1513{}
1514#endif
1515
6dbd0af5 1516SCM
0f2d19dd
JB
1517SCM_CEVAL (x, env)
1518 SCM x;
1519 SCM env;
1520{
1521 union
1522 {
1523 SCM *lloc;
1524 SCM arg1;
f8769b1d 1525 } t;
6dbd0af5
MD
1526 SCM proc, arg2;
1527#ifdef DEVAL
c0ab1b8d
JB
1528 scm_debug_frame debug;
1529 scm_debug_info *debug_info_end;
1646d37b 1530 debug.prev = scm_last_debug_frame;
6dbd0af5 1531 debug.status = scm_debug_eframe_size;
c0ab1b8d
JB
1532 debug.vect = (scm_debug_info *) alloca (scm_debug_eframe_size
1533 * sizeof (debug.vect[0]));
1534 debug.info = debug.vect;
1535 debug_info_end = debug.vect + scm_debug_eframe_size;
1536 scm_last_debug_frame = &debug;
6dbd0af5 1537#endif
b7ff98dd
MD
1538#ifdef EVAL_STACK_CHECKING
1539 if (SCM_STACK_OVERFLOW_P ((SCM_STACKITEM *) &proc)
1540 && scm_stack_checking_enabled_p)
6dbd0af5 1541 {
b7ff98dd 1542#ifdef DEVAL
6dbd0af5
MD
1543 debug.info->e.exp = x;
1544 debug.info->e.env = env;
b7ff98dd 1545#endif
6dbd0af5
MD
1546 scm_report_stack_overflow ();
1547 }
1548#endif
1549#ifdef DEVAL
1550 goto start;
1551#endif
1552loopnoap:
1553 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1554loop:
1555#ifdef DEVAL
b7ff98dd
MD
1556 SCM_CLEAR_ARGSREADY (debug);
1557 if (SCM_OVERFLOWP (debug))
6dbd0af5 1558 --debug.info;
c0ab1b8d 1559 else if (++debug.info >= debug_info_end)
6dbd0af5 1560 {
b7ff98dd 1561 SCM_SET_OVERFLOW (debug);
6dbd0af5
MD
1562 debug.info -= 2;
1563 }
1564start:
1565 debug.info->e.exp = x;
1566 debug.info->e.env = env;
b6d75948 1567 if (CHECK_ENTRY && SCM_TRAPS_P)
b7ff98dd 1568 if (SCM_ENTER_FRAME_P || (SCM_BREAKPOINTS_P && SRCBRKP (x)))
6dbd0af5 1569 {
b7ff98dd
MD
1570 SCM tail = SCM_TAILRECP (debug) ? SCM_BOOL_T : SCM_BOOL_F;
1571 SCM_SET_TAILREC (debug);
b7ff98dd 1572 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 1573 t.arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
1574 else
1575 {
1576 scm_make_cont (&t.arg1);
ca6ef71a 1577 if (setjmp (SCM_JMPBUF (t.arg1)))
6dbd0af5
MD
1578 {
1579 x = SCM_THROW_VALUE (t.arg1);
1580 if (SCM_IMP (x))
1581 {
1582 RETURN (x);
1583 }
1584 else
1585 /* This gives the possibility for the debugger to
1586 modify the source expression before evaluation. */
1587 goto dispatch;
1588 }
1589 }
1590 scm_ithrow (scm_i_enter_frame,
1591 scm_cons2 (t.arg1, tail,
1592 scm_cons (scm_unmemocopy (x, env), SCM_EOL)),
1593 0);
1594 }
6dbd0af5 1595#endif
e3173f93 1596#if defined (USE_THREADS) || defined (DEVAL)
f8769b1d 1597dispatch:
e3173f93 1598#endif
9cb5124f 1599 SCM_TICK;
0f2d19dd
JB
1600 switch (SCM_TYP7 (x))
1601 {
1602 case scm_tcs_symbols:
1603 /* Only happens when called at top level.
1604 */
1605 x = scm_cons (x, SCM_UNDEFINED);
1606 goto retval;
1607
1608 case (127 & SCM_IM_AND):
1609 x = SCM_CDR (x);
1610 t.arg1 = x;
1611 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1612 if (SCM_FALSEP (EVALCAR (x, env)))
1613 {
1614 RETURN (SCM_BOOL_F);
1615 }
1616 else
1617 x = t.arg1;
6dbd0af5 1618 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1619 goto carloop;
1620
1621 case (127 & SCM_IM_BEGIN):
6dbd0af5
MD
1622 cdrxnoap:
1623 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1624 cdrxbegin:
1625 x = SCM_CDR (x);
1626
1627 begin:
1628 t.arg1 = x;
1629 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1630 {
1631 SIDEVAL (SCM_CAR (x), env);
1632 x = t.arg1;
1633 }
1634
1635 carloop: /* scm_eval car of last form in list */
1636 if (SCM_NCELLP (SCM_CAR (x)))
1637 {
1638 x = SCM_CAR (x);
6cb702da 1639 RETURN (SCM_IMP (x) ? SCM_EVALIM (x, env) : SCM_GLOC_VAL (x))
0f2d19dd
JB
1640 }
1641
1642 if (SCM_SYMBOLP (SCM_CAR (x)))
1643 {
1644 retval:
6dbd0af5 1645 RETURN (*scm_lookupcar (x, env))
0f2d19dd
JB
1646 }
1647
1648 x = SCM_CAR (x);
1649 goto loop; /* tail recurse */
1650
1651
1652 case (127 & SCM_IM_CASE):
1653 x = SCM_CDR (x);
1654 t.arg1 = EVALCAR (x, env);
1655 while (SCM_NIMP (x = SCM_CDR (x)))
1656 {
1657 proc = SCM_CAR (x);
1658 if (scm_i_else == SCM_CAR (proc))
1659 {
1660 x = SCM_CDR (proc);
6dbd0af5 1661 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1662 goto begin;
1663 }
1664 proc = SCM_CAR (proc);
1665 while (SCM_NIMP (proc))
1666 {
1667 if (CHECK_EQVISH (SCM_CAR (proc), t.arg1))
1668 {
1669 x = SCM_CDR (SCM_CAR (x));
6dbd0af5 1670 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1671 goto begin;
1672 }
1673 proc = SCM_CDR (proc);
1674 }
1675 }
6dbd0af5 1676 RETURN (SCM_UNSPECIFIED)
0f2d19dd
JB
1677
1678
1679 case (127 & SCM_IM_COND):
1680 while (SCM_NIMP (x = SCM_CDR (x)))
1681 {
1682 proc = SCM_CAR (x);
1683 t.arg1 = EVALCAR (proc, env);
1684 if (SCM_NFALSEP (t.arg1))
1685 {
1686 x = SCM_CDR (proc);
6dbd0af5 1687 if SCM_NULLP (x)
0f2d19dd 1688 {
6dbd0af5 1689 RETURN (t.arg1)
0f2d19dd
JB
1690 }
1691 if (scm_i_arrow != SCM_CAR (x))
6dbd0af5
MD
1692 {
1693 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1694 goto begin;
1695 }
0f2d19dd
JB
1696 proc = SCM_CDR (x);
1697 proc = EVALCAR (proc, env);
1698 SCM_ASRTGO (SCM_NIMP (proc), badfun);
6dbd0af5
MD
1699 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
1700 ENTER_APPLY;
0f2d19dd
JB
1701 goto evap1;
1702 }
1703 }
6dbd0af5 1704 RETURN (SCM_UNSPECIFIED)
0f2d19dd
JB
1705
1706
1707 case (127 & SCM_IM_DO):
1708 x = SCM_CDR (x);
1709 proc = SCM_CAR (SCM_CDR (x)); /* inits */
1710 t.arg1 = SCM_EOL; /* values */
1711 while (SCM_NIMP (proc))
1712 {
1713 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
1714 proc = SCM_CDR (proc);
1715 }
e2806c10 1716 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
0f2d19dd
JB
1717 x = SCM_CDR (SCM_CDR (x));
1718 while (proc = SCM_CAR (x), SCM_FALSEP (EVALCAR (proc, env)))
1719 {
1720 for (proc = SCM_CAR (SCM_CDR (x)); SCM_NIMP (proc); proc = SCM_CDR (proc))
1721 {
1722 t.arg1 = SCM_CAR (proc); /* body */
1723 SIDEVAL (t.arg1, env);
1724 }
1725 for (t.arg1 = SCM_EOL, proc = SCM_CDR (SCM_CDR (x)); SCM_NIMP (proc); proc = SCM_CDR (proc))
1726 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1); /* steps */
e2806c10 1727 env = EXTEND_ENV (SCM_CAR (SCM_CAR (env)), t.arg1, SCM_CDR (env));
0f2d19dd
JB
1728 }
1729 x = SCM_CDR (proc);
1730 if (SCM_NULLP (x))
6dbd0af5
MD
1731 RETURN (SCM_UNSPECIFIED);
1732 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1733 goto begin;
1734
1735
1736 case (127 & SCM_IM_IF):
1737 x = SCM_CDR (x);
1738 if (SCM_NFALSEP (EVALCAR (x, env)))
1739 x = SCM_CDR (x);
1740 else if (SCM_IMP (x = SCM_CDR (SCM_CDR (x))))
1741 {
1742 RETURN (SCM_UNSPECIFIED);
1743 }
6dbd0af5 1744 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1745 goto carloop;
1746
1747
1748 case (127 & SCM_IM_LET):
1749 x = SCM_CDR (x);
1750 proc = SCM_CAR (SCM_CDR (x));
1751 t.arg1 = SCM_EOL;
1752 do
1753 {
1754 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
1755 }
1756 while (SCM_NIMP (proc = SCM_CDR (proc)));
e2806c10 1757 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
0f2d19dd 1758 x = SCM_CDR (x);
6dbd0af5 1759 goto cdrxnoap;
0f2d19dd
JB
1760
1761
1762 case (127 & SCM_IM_LETREC):
1763 x = SCM_CDR (x);
e2806c10 1764 env = EXTEND_ENV (SCM_CAR (x), scm_undefineds, env);
0f2d19dd
JB
1765 x = SCM_CDR (x);
1766 proc = SCM_CAR (x);
1767 t.arg1 = SCM_EOL;
1768 do
1769 {
1770 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
1771 }
1772 while (SCM_NIMP (proc = SCM_CDR (proc)));
a23afe53 1773 SCM_SETCDR (SCM_CAR (env), t.arg1);
6dbd0af5 1774 goto cdrxnoap;
0f2d19dd
JB
1775
1776
1777 case (127 & SCM_IM_LETSTAR):
1778 x = SCM_CDR (x);
1779 proc = SCM_CAR (x);
1780 if (SCM_IMP (proc))
1781 {
e2806c10 1782 env = EXTEND_ENV (SCM_EOL, SCM_EOL, env);
6dbd0af5 1783 goto cdrxnoap;
0f2d19dd
JB
1784 }
1785 do
1786 {
1787 t.arg1 = SCM_CAR (proc);
1788 proc = SCM_CDR (proc);
e2806c10 1789 env = EXTEND_ENV (t.arg1, EVALCAR (proc, env), env);
0f2d19dd
JB
1790 }
1791 while (SCM_NIMP (proc = SCM_CDR (proc)));
6dbd0af5 1792 goto cdrxnoap;
0f2d19dd
JB
1793
1794 case (127 & SCM_IM_OR):
1795 x = SCM_CDR (x);
1796 t.arg1 = x;
1797 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1798 {
1799 x = EVALCAR (x, env);
1800 if (SCM_NFALSEP (x))
1801 {
1802 RETURN (x);
1803 }
1804 x = t.arg1;
1805 }
6dbd0af5 1806 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1807 goto carloop;
1808
1809
1810 case (127 & SCM_IM_LAMBDA):
1811 RETURN (scm_closure (SCM_CDR (x), env));
1812
1813
1814 case (127 & SCM_IM_QUOTE):
1815 RETURN (SCM_CAR (SCM_CDR (x)));
1816
1817
1818 case (127 & SCM_IM_SET):
0f2d19dd
JB
1819 x = SCM_CDR (x);
1820 proc = SCM_CAR (x);
6dbd0af5 1821 switch (7 & (int) proc)
0f2d19dd
JB
1822 {
1823 case 0:
1824 t.lloc = scm_lookupcar (x, env);
1825 break;
1826 case 1:
a23afe53 1827 t.lloc = SCM_GLOC_VAL_LOC (proc);
0f2d19dd
JB
1828 break;
1829#ifdef MEMOIZE_LOCALS
1830 case 4:
1831 t.lloc = scm_ilookup (proc, env);
1832 break;
1833#endif
1834 }
1835 x = SCM_CDR (x);
1836 *t.lloc = EVALCAR (x, env);
0f2d19dd
JB
1837#ifdef SICP
1838 RETURN (*t.lloc);
1839#else
1840 RETURN (SCM_UNSPECIFIED);
1841#endif
1842
1843
1844 case (127 & SCM_IM_DEFINE): /* only for internal defines */
1845 x = SCM_CDR (x);
1846 proc = SCM_CAR (x);
1847 x = SCM_CDR (x);
1848 x = evalcar (x, env);
6dbd0af5 1849#ifdef DEBUG_EXTENSIONS
80ea260c
MD
1850 if (SCM_REC_PROCNAMES_P && SCM_NIMP (x))
1851 {
1852 t.arg1 = x;
1853 proc:
1854 if (SCM_CLOSUREP (t.arg1)
1855 /* Only the first definition determines the name. */
1856 && (scm_procedure_property (t.arg1, scm_i_inner_name)
1857 == SCM_BOOL_F))
1858 scm_set_procedure_property_x (t.arg1, scm_i_inner_name, proc);
1859 else if (SCM_TYP16 (t.arg1) == scm_tc16_macro
1860 && SCM_CDR (t.arg1) != t.arg1)
1861 {
1862 t.arg1 = SCM_CDR (t.arg1);
1863 goto proc;
1864 }
1865 }
6dbd0af5 1866#endif
0f2d19dd
JB
1867 env = SCM_CAR (env);
1868 SCM_DEFER_INTS;
a23afe53
MD
1869 SCM_SETCAR (env, scm_cons (proc, SCM_CAR (env)));
1870 SCM_SETCDR (env, scm_cons (x, SCM_CDR (env)));
0f2d19dd
JB
1871 SCM_ALLOW_INTS;
1872 RETURN (SCM_UNSPECIFIED);
1873
1874
0f2d19dd
JB
1875 /* new syntactic forms go here. */
1876 case (127 & SCM_MAKISYM (0)):
1877 proc = SCM_CAR (x);
1878 SCM_ASRTGO (SCM_ISYMP (proc), badfun);
1879 switch SCM_ISYMNUM (proc)
1880 {
1881#if 0
1882 case (SCM_ISYMNUM (IM_VREF)):
1883 {
1884 SCM var;
1885 var = SCM_CAR (SCM_CDR (x));
1886 RETURN (SCM_CDR(var));
1887 }
1888 case (SCM_ISYMNUM (IM_VSET)):
1889 SCM_CDR (SCM_CAR ( SCM_CDR (x))) = EVALCAR( SCM_CDR ( SCM_CDR (x)), env);
1890 SCM_CAR (SCM_CAR ( SCM_CDR (x))) = scm_tc16_variable;
6dbd0af5 1891 RETURN (SCM_UNSPECIFIED)
0f2d19dd
JB
1892#endif
1893
1894 case (SCM_ISYMNUM (SCM_IM_APPLY)):
1895 proc = SCM_CDR (x);
1896 proc = EVALCAR (proc, env);
1897 SCM_ASRTGO (SCM_NIMP (proc), badfun);
1898 if (SCM_CLOSUREP (proc))
1899 {
1609038c 1900 SCM argl, tl;
6dbd0af5 1901 PREP_APPLY (proc, SCM_EOL);
0f2d19dd
JB
1902 t.arg1 = SCM_CDR (SCM_CDR (x));
1903 t.arg1 = EVALCAR (t.arg1, env);
6dbd0af5
MD
1904#ifdef DEVAL
1905 debug.info->a.args = t.arg1;
1906#endif
cf7c17e9 1907#ifndef SCM_RECKLESS
0f2d19dd
JB
1908 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), t.arg1))
1909 goto wrongnumargs;
1910#endif
1609038c
MD
1911 /* Copy argument list */
1912 if (SCM_IMP (t.arg1))
1913 argl = t.arg1;
1914 else
1915 {
1916 argl = tl = scm_cons (SCM_CAR (t.arg1), SCM_UNSPECIFIED);
1917 while (SCM_NIMP (t.arg1 = SCM_CDR (t.arg1))
1918 && SCM_CONSP (t.arg1))
1919 {
1920 SCM_SETCDR (tl, scm_cons (SCM_CAR (t.arg1),
1921 SCM_UNSPECIFIED));
1922 tl = SCM_CDR (tl);
1923 }
1924 SCM_SETCDR (tl, t.arg1);
1925 }
1926
1927 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), argl, SCM_ENV (proc));
0f2d19dd
JB
1928 x = SCM_CODE (proc);
1929 goto cdrxbegin;
1930 }
1931 proc = scm_i_apply;
1932 goto evapply;
1933
1934 case (SCM_ISYMNUM (SCM_IM_CONT)):
1935 scm_make_cont (&t.arg1);
ca6ef71a 1936 if (setjmp (SCM_JMPBUF (t.arg1)))
0f2d19dd
JB
1937 {
1938 SCM val;
1939 val = SCM_THROW_VALUE (t.arg1);
6dbd0af5 1940 RETURN (val);
0f2d19dd
JB
1941 }
1942 proc = SCM_CDR (x);
1943 proc = evalcar (proc, env);
1944 SCM_ASRTGO (SCM_NIMP (proc), badfun);
6dbd0af5
MD
1945 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
1946 ENTER_APPLY;
0f2d19dd
JB
1947 goto evap1;
1948
1949 default:
1950 goto badfun;
1951 }
1952
1953 default:
1954 proc = x;
1955 badfun:
f5bf2977 1956 /* scm_everr (x, env,...) */
523f5266
GH
1957 scm_misc_error (NULL,
1958 "Wrong type to apply: %S",
1959 scm_listify (proc, SCM_UNDEFINED));
0f2d19dd
JB
1960 case scm_tc7_vector:
1961 case scm_tc7_wvect:
1962 case scm_tc7_bvect:
1963 case scm_tc7_byvect:
1964 case scm_tc7_svect:
1965 case scm_tc7_ivect:
1966 case scm_tc7_uvect:
1967 case scm_tc7_fvect:
1968 case scm_tc7_dvect:
1969 case scm_tc7_cvect:
1970#ifdef LONGLONGS
1971 case scm_tc7_llvect:
1972#endif
1973 case scm_tc7_string:
0f2d19dd 1974 case scm_tc7_substring:
0f2d19dd
JB
1975 case scm_tc7_smob:
1976 case scm_tcs_closures:
224822be
MD
1977#ifdef CCLO
1978 case scm_tc7_cclo:
1979#endif
0f2d19dd
JB
1980 case scm_tcs_subrs:
1981 RETURN (x);
1982
1983#ifdef MEMOIZE_LOCALS
1984 case (127 & SCM_ILOC00):
1985 proc = *scm_ilookup (SCM_CAR (x), env);
1986 SCM_ASRTGO (SCM_NIMP (proc), badfun);
cf7c17e9
JB
1987#ifndef SCM_RECKLESS
1988#ifdef SCM_CAUTIOUS
0f2d19dd
JB
1989 goto checkargs;
1990#endif
1991#endif
1992 break;
1993#endif /* ifdef MEMOIZE_LOCALS */
1994
1995
1996 case scm_tcs_cons_gloc:
1997 proc = SCM_GLOC_VAL (SCM_CAR (x));
aa00bd1e
MD
1998 if (proc == 0)
1999 /* This is a struct implanted in the code, not a gloc. */
2000 RETURN (x);
0f2d19dd 2001 SCM_ASRTGO (SCM_NIMP (proc), badfun);
cf7c17e9
JB
2002#ifndef SCM_RECKLESS
2003#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2004 goto checkargs;
2005#endif
2006#endif
2007 break;
2008
2009
2010 case scm_tcs_cons_nimcar:
2011 if (SCM_SYMBOLP (SCM_CAR (x)))
2012 {
f8769b1d
MV
2013#ifdef USE_THREADS
2014 t.lloc = scm_lookupcar1 (x, env);
2015 if (t.lloc == NULL)
2016 {
2017 /* we have lost the race, start again. */
2018 goto dispatch;
2019 }
2020 proc = *t.lloc;
2021#else
0f2d19dd 2022 proc = *scm_lookupcar (x, env);
f8769b1d
MV
2023#endif
2024
0f2d19dd
JB
2025 if (SCM_IMP (proc))
2026 {
2027 unmemocar (x, env);
2028 goto badfun;
2029 }
2030 if (scm_tc16_macro == SCM_TYP16 (proc))
2031 {
2032 unmemocar (x, env);
2033
2034 handle_a_macro:
368bf056 2035#ifdef DEVAL
7c354052
MD
2036 /* Set a flag during macro expansion so that macro
2037 application frames can be deleted from the backtrace. */
2038 SCM_SET_MACROEXP (debug);
368bf056 2039#endif
f8769b1d
MV
2040 t.arg1 = SCM_APPLY (SCM_CDR (proc), x,
2041 scm_cons (env, scm_listofnull));
2042
7c354052
MD
2043#ifdef DEVAL
2044 SCM_CLEAR_MACROEXP (debug);
2045#endif
0f2d19dd
JB
2046 switch ((int) (SCM_CAR (proc) >> 16))
2047 {
2048 case 2:
2049 if (scm_ilength (t.arg1) <= 0)
2050 t.arg1 = scm_cons2 (SCM_IM_BEGIN, t.arg1, SCM_EOL);
6dbd0af5
MD
2051#ifdef DEVAL
2052 if (!SCM_CLOSUREP (SCM_CDR (proc)))
2053 {
f8769b1d 2054
6dbd0af5
MD
2055#if 0 /* Top-level defines doesn't very often occur in backtraces */
2056 if (scm_m_define == SCM_SUBRF (SCM_CDR (proc)) && SCM_TOP_LEVEL (env))
2057 /* Prevent memoizing result of define macro */
2058 {
2059 debug.info->e.exp = scm_cons (SCM_CAR (x), SCM_CDR (x));
2060 scm_set_source_properties_x (debug.info->e.exp,
2061 scm_source_properties (x));
2062 }
2063#endif
2064 SCM_DEFER_INTS;
a23afe53
MD
2065 SCM_SETCAR (x, SCM_CAR (t.arg1));
2066 SCM_SETCDR (x, SCM_CDR (t.arg1));
6dbd0af5
MD
2067 SCM_ALLOW_INTS;
2068 goto dispatch;
2069 }
2070 /* Prevent memoizing of debug info expression. */
2071 debug.info->e.exp = scm_cons (SCM_CAR (x), SCM_CDR (x));
2072 scm_set_source_properties_x (debug.info->e.exp,
2073 scm_source_properties (x));
2074#endif
0f2d19dd 2075 SCM_DEFER_INTS;
a23afe53
MD
2076 SCM_SETCAR (x, SCM_CAR (t.arg1));
2077 SCM_SETCDR (x, SCM_CDR (t.arg1));
0f2d19dd 2078 SCM_ALLOW_INTS;
6dbd0af5 2079 goto loopnoap;
0f2d19dd
JB
2080 case 1:
2081 if (SCM_NIMP (x = t.arg1))
6dbd0af5 2082 goto loopnoap;
0f2d19dd
JB
2083 case 0:
2084 RETURN (t.arg1);
2085 }
2086 }
2087 }
2088 else
2089 proc = SCM_CEVAL (SCM_CAR (x), env);
2090 SCM_ASRTGO (SCM_NIMP (proc), badfun);
cf7c17e9
JB
2091#ifndef SCM_RECKLESS
2092#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2093 checkargs:
2094#endif
2095 if (SCM_CLOSUREP (proc))
2096 {
2097 arg2 = SCM_CAR (SCM_CODE (proc));
2098 t.arg1 = SCM_CDR (x);
2099 while (SCM_NIMP (arg2))
2100 {
2101 if (SCM_NCONSP (arg2))
2102 goto evapply;
2103 if (SCM_IMP (t.arg1))
2104 goto umwrongnumargs;
2105 arg2 = SCM_CDR (arg2);
2106 t.arg1 = SCM_CDR (t.arg1);
2107 }
2108 if (SCM_NNULLP (t.arg1))
2109 goto umwrongnumargs;
2110 }
2111 else if (scm_tc16_macro == SCM_TYP16 (proc))
2112 goto handle_a_macro;
2113#endif
2114 }
2115
2116
6dbd0af5
MD
2117evapply:
2118 PREP_APPLY (proc, SCM_EOL);
2119 if (SCM_NULLP (SCM_CDR (x))) {
2120 ENTER_APPLY;
0f2d19dd
JB
2121 switch (SCM_TYP7 (proc))
2122 { /* no arguments given */
2123 case scm_tc7_subr_0:
2124 RETURN (SCM_SUBRF (proc) ());
2125 case scm_tc7_subr_1o:
2126 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED));
2127 case scm_tc7_lsubr:
2128 RETURN (SCM_SUBRF (proc) (SCM_EOL));
2129 case scm_tc7_rpsubr:
2130 RETURN (SCM_BOOL_T);
2131 case scm_tc7_asubr:
2132 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED));
6dbd0af5 2133#ifdef CCLO
0f2d19dd
JB
2134 case scm_tc7_cclo:
2135 t.arg1 = proc;
2136 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
2137#ifdef DEVAL
2138 debug.info->a.proc = proc;
2139 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2140#endif
0f2d19dd 2141 goto evap1;
6dbd0af5 2142#endif
0f2d19dd
JB
2143 case scm_tcs_closures:
2144 x = SCM_CODE (proc);
e2806c10 2145 env = EXTEND_ENV (SCM_CAR (x), SCM_EOL, SCM_ENV (proc));
0f2d19dd 2146 goto cdrxbegin;
da7f71d7 2147 case scm_tcs_cons_gloc:
9b07e212
MD
2148 if (!SCM_I_OPERATORP (proc))
2149 goto badfun;
2150 else
da7f71d7
MD
2151 {
2152 x = (SCM_I_ENTITYP (proc)
2153 ? SCM_ENTITY_PROC_0 (proc)
2154 : SCM_OPERATOR_PROC_0 (proc));
2155 if (SCM_NIMP (x))
33b97402
MD
2156 {
2157 if (SCM_TYP7 (x) == scm_tc7_subr_1)
2158 RETURN (SCM_SUBRF (x) (proc))
2159 else if (SCM_CLOSUREP (x))
2160 {
2161 t.arg1 = proc;
2162 proc = x;
da7f71d7 2163#ifdef DEVAL
33b97402
MD
2164 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2165 debug.info->a.proc = proc;
da7f71d7 2166#endif
33b97402
MD
2167 goto clos1;
2168 }
2169 }
da7f71d7
MD
2170 /* Fall through. */
2171 }
0f2d19dd
JB
2172 case scm_tc7_contin:
2173 case scm_tc7_subr_1:
2174 case scm_tc7_subr_2:
2175 case scm_tc7_subr_2o:
2176 case scm_tc7_cxr:
2177 case scm_tc7_subr_3:
2178 case scm_tc7_lsubr_2:
2179 umwrongnumargs:
2180 unmemocar (x, env);
2181 wrongnumargs:
f5bf2977
GH
2182 /* scm_everr (x, env,...) */
2183 scm_wrong_num_args (proc);
0f2d19dd
JB
2184 default:
2185 /* handle macros here */
2186 goto badfun;
2187 }
6dbd0af5 2188 }
0f2d19dd
JB
2189
2190 /* must handle macros by here */
2191 x = SCM_CDR (x);
cf7c17e9 2192#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2193 if (SCM_IMP (x))
2194 goto wrongnumargs;
680ed4a8
MD
2195 else if (SCM_CONSP (x))
2196 {
2197 if (SCM_IMP (SCM_CAR (x)))
6cb702da 2198 t.arg1 = SCM_EVALIM (SCM_CAR (x), env);
680ed4a8
MD
2199 else
2200 t.arg1 = EVALCELLCAR (x, env);
2201 }
2202 else if (SCM_TYP3 (x) == 1)
2203 {
2204 if ((t.arg1 = SCM_GLOC_VAL (SCM_CAR (x))) == 0)
2205 t.arg1 = SCM_CAR (x); /* struct planted in code */
2206 }
2207 else
2208 goto wrongnumargs;
2209#else
0f2d19dd 2210 t.arg1 = EVALCAR (x, env);
680ed4a8 2211#endif
6dbd0af5
MD
2212#ifdef DEVAL
2213 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
2214#endif
0f2d19dd
JB
2215 x = SCM_CDR (x);
2216 if (SCM_NULLP (x))
2217 {
6dbd0af5 2218 ENTER_APPLY;
0f2d19dd
JB
2219 evap1:
2220 switch (SCM_TYP7 (proc))
6dbd0af5 2221 { /* have one argument in t.arg1 */
0f2d19dd
JB
2222 case scm_tc7_subr_2o:
2223 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
2224 case scm_tc7_subr_1:
2225 case scm_tc7_subr_1o:
2226 RETURN (SCM_SUBRF (proc) (t.arg1));
2227 case scm_tc7_cxr:
2228#ifdef SCM_FLOATS
2229 if (SCM_SUBRF (proc))
2230 {
2231 if (SCM_INUMP (t.arg1))
2232 {
2233 RETURN (scm_makdbl (SCM_DSUBRF (proc) ((double) SCM_INUM (t.arg1)),
2234 0.0));
2235 }
2236 SCM_ASRTGO (SCM_NIMP (t.arg1), floerr);
2237 if (SCM_REALP (t.arg1))
2238 {
2239 RETURN (scm_makdbl (SCM_DSUBRF (proc) (SCM_REALPART (t.arg1)), 0.0));
2240 }
2241#ifdef SCM_BIGDIG
2242 if (SCM_BIGP (t.arg1))
2243 {
2244 RETURN (scm_makdbl (SCM_DSUBRF (proc) (scm_big2dbl (t.arg1)), 0.0));
2245 }
2246#endif
2247 floerr:
2248 scm_wta (t.arg1, (char *) SCM_ARG1, SCM_CHARS (SCM_SNAME (proc)));
2249 }
2250#endif
2251 proc = (SCM) SCM_SNAME (proc);
2252 {
2253 char *chrs = SCM_CHARS (proc) + SCM_LENGTH (proc) - 1;
2254 while ('c' != *--chrs)
2255 {
2256 SCM_ASSERT (SCM_NIMP (t.arg1) && SCM_CONSP (t.arg1),
2257 t.arg1, SCM_ARG1, SCM_CHARS (proc));
2258 t.arg1 = ('a' == *chrs) ? SCM_CAR (t.arg1) : SCM_CDR (t.arg1);
2259 }
2260 RETURN (t.arg1);
2261 }
2262 case scm_tc7_rpsubr:
2263 RETURN (SCM_BOOL_T);
2264 case scm_tc7_asubr:
2265 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
2266 case scm_tc7_lsubr:
2267#ifdef DEVAL
6dbd0af5 2268 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
0f2d19dd
JB
2269#else
2270 RETURN (SCM_SUBRF (proc) (scm_cons (t.arg1, SCM_EOL)));
2271#endif
6dbd0af5 2272#ifdef CCLO
0f2d19dd
JB
2273 case scm_tc7_cclo:
2274 arg2 = t.arg1;
2275 t.arg1 = proc;
2276 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
2277#ifdef DEVAL
2278 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
2279 debug.info->a.proc = proc;
2280#endif
0f2d19dd 2281 goto evap2;
6dbd0af5 2282#endif
0f2d19dd 2283 case scm_tcs_closures:
da7f71d7 2284 clos1:
0f2d19dd
JB
2285 x = SCM_CODE (proc);
2286#ifdef DEVAL
e2806c10 2287 env = EXTEND_ENV (SCM_CAR (x), debug.info->a.args, SCM_ENV (proc));
0f2d19dd 2288#else
e2806c10 2289 env = EXTEND_ENV (SCM_CAR (x), scm_cons (t.arg1, SCM_EOL), SCM_ENV (proc));
0f2d19dd
JB
2290#endif
2291 goto cdrxbegin;
65e41721
MD
2292 case scm_tc7_contin:
2293 scm_call_continuation (proc, t.arg1);
0c32d76c 2294 case scm_tcs_cons_gloc:
9b07e212
MD
2295 if (!SCM_I_OPERATORP (proc))
2296 goto badfun;
2297 else
0c32d76c 2298 {
da7f71d7
MD
2299 x = (SCM_I_ENTITYP (proc)
2300 ? SCM_ENTITY_PROC_1 (proc)
2301 : SCM_OPERATOR_PROC_1 (proc));
2302 if (SCM_NIMP (x))
33b97402
MD
2303 {
2304 if (SCM_TYP7 (x) == scm_tc7_subr_2)
2305 RETURN (SCM_SUBRF (x) (proc, t.arg1))
2306 else if (SCM_CLOSUREP (x))
2307 {
2308 arg2 = t.arg1;
2309 t.arg1 = proc;
2310 proc = x;
0c32d76c 2311#ifdef DEVAL
33b97402
MD
2312 debug.info->a.args = scm_cons (t.arg1,
2313 debug.info->a.args);
2314 debug.info->a.proc = proc;
0c32d76c 2315#endif
33b97402
MD
2316 goto clos2;
2317 }
2318 }
0c32d76c
MD
2319 /* Fall through. */
2320 }
0f2d19dd
JB
2321 case scm_tc7_subr_2:
2322 case scm_tc7_subr_0:
2323 case scm_tc7_subr_3:
2324 case scm_tc7_lsubr_2:
2325 goto wrongnumargs;
2326 default:
2327 goto badfun;
2328 }
2329 }
cf7c17e9 2330#ifdef SCM_CAUTIOUS
0f2d19dd
JB
2331 if (SCM_IMP (x))
2332 goto wrongnumargs;
680ed4a8
MD
2333 else if (SCM_CONSP (x))
2334 {
2335 if (SCM_IMP (SCM_CAR (x)))
6cb702da 2336 arg2 = SCM_EVALIM (SCM_CAR (x), env);
680ed4a8
MD
2337 else
2338 arg2 = EVALCELLCAR (x, env);
2339 }
2340 else if (SCM_TYP3 (x) == 1)
2341 {
2342 if ((arg2 = SCM_GLOC_VAL (SCM_CAR (x))) == 0)
2343 arg2 = SCM_CAR (x); /* struct planted in code */
2344 }
2345 else
2346 goto wrongnumargs;
2347#else
2348 arg2 = EVALCAR (x, env);
0f2d19dd
JB
2349#endif
2350 { /* have two or more arguments */
6dbd0af5
MD
2351#ifdef DEVAL
2352 debug.info->a.args = scm_cons2 (t.arg1, arg2, SCM_EOL);
2353#endif
0f2d19dd
JB
2354 x = SCM_CDR (x);
2355 if (SCM_NULLP (x)) {
6dbd0af5 2356 ENTER_APPLY;
0f2d19dd
JB
2357#ifdef CCLO
2358 evap2:
2359#endif
6dbd0af5
MD
2360 switch (SCM_TYP7 (proc))
2361 { /* have two arguments */
2362 case scm_tc7_subr_2:
2363 case scm_tc7_subr_2o:
2364 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2365 case scm_tc7_lsubr:
0f2d19dd 2366#ifdef DEVAL
6dbd0af5
MD
2367 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
2368#else
2369 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1, arg2, SCM_EOL)));
0f2d19dd 2370#endif
6dbd0af5
MD
2371 case scm_tc7_lsubr_2:
2372 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, SCM_EOL));
2373 case scm_tc7_rpsubr:
2374 case scm_tc7_asubr:
2375 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2376#ifdef CCLO
2377 cclon:
2378 case scm_tc7_cclo:
0f2d19dd 2379#ifdef DEVAL
6dbd0af5
MD
2380 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc), proc,
2381 scm_cons (debug.info->a.args, SCM_EOL)));
0f2d19dd 2382#else
6dbd0af5
MD
2383 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc), proc,
2384 scm_cons2 (t.arg1, arg2,
680ed4a8 2385 scm_cons (scm_eval_args (x, env, proc),
da7f71d7 2386 SCM_EOL))));
0f2d19dd 2387#endif
6dbd0af5
MD
2388 /* case scm_tc7_cclo:
2389 x = scm_cons(arg2, scm_eval_args(x, env));
2390 arg2 = t.arg1;
2391 t.arg1 = proc;
2392 proc = SCM_CCLO_SUBR(proc);
2393 goto evap3; */
2394#endif
0c32d76c 2395 case scm_tcs_cons_gloc:
9b07e212
MD
2396 if (!SCM_I_OPERATORP (proc))
2397 goto badfun;
2398 else
0c32d76c 2399 {
da7f71d7
MD
2400 x = (SCM_I_ENTITYP (proc)
2401 ? SCM_ENTITY_PROC_2 (proc)
2402 : SCM_OPERATOR_PROC_2 (proc));
2403 if (SCM_NIMP (x))
33b97402
MD
2404 {
2405 if (SCM_TYP7 (x) == scm_tc7_subr_3)
2406 RETURN (SCM_SUBRF (x) (proc, t.arg1, arg2))
2407 else if (SCM_CLOSUREP (x))
2408 {
0c32d76c 2409#ifdef DEVAL
33b97402
MD
2410 SCM_SET_ARGSREADY (debug);
2411 debug.info->a.args = scm_cons (proc,
2412 debug.info->a.args);
2413 debug.info->a.proc = x;
2414#endif
2415 env = EXTEND_ENV (SCM_CAR (SCM_CODE (x)),
2416 scm_cons2 (proc, t.arg1,
65e41721 2417 scm_cons (arg2, SCM_EOL)),
33b97402
MD
2418 SCM_ENV (x));
2419 x = SCM_CODE (x);
2420 goto cdrxbegin;
2421 }
2422 }
0c32d76c
MD
2423 /* Fall through. */
2424 }
6dbd0af5
MD
2425 case scm_tc7_subr_0:
2426 case scm_tc7_cxr:
2427 case scm_tc7_subr_1o:
2428 case scm_tc7_subr_1:
2429 case scm_tc7_subr_3:
2430 case scm_tc7_contin:
2431 goto wrongnumargs;
2432 default:
2433 goto badfun;
2434 case scm_tcs_closures:
0c32d76c 2435 clos2:
0f2d19dd 2436#ifdef DEVAL
da7f71d7
MD
2437 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
2438 debug.info->a.args,
2439 SCM_ENV (proc));
0f2d19dd 2440#else
da7f71d7
MD
2441 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
2442 scm_cons2 (t.arg1, arg2, SCM_EOL), SCM_ENV (proc));
0f2d19dd 2443#endif
6dbd0af5
MD
2444 x = SCM_CODE (proc);
2445 goto cdrxbegin;
2446 }
0f2d19dd 2447 }
cf7c17e9 2448#ifdef SCM_CAUTIOUS
680ed4a8
MD
2449 if (SCM_IMP (x) || SCM_NECONSP (x))
2450 goto wrongnumargs;
2451#endif
0f2d19dd 2452#ifdef DEVAL
6dbd0af5 2453 debug.info->a.args = scm_cons2 (t.arg1, arg2,
680ed4a8
MD
2454 scm_deval_args (x, env, proc,
2455 SCM_CDRLOC (SCM_CDR (debug.info->a.args))));
0f2d19dd 2456#endif
6dbd0af5
MD
2457 ENTER_APPLY;
2458 switch (SCM_TYP7 (proc))
2459 { /* have 3 or more arguments */
0f2d19dd 2460#ifdef DEVAL
6dbd0af5
MD
2461 case scm_tc7_subr_3:
2462 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
da7f71d7
MD
2463 RETURN (SCM_SUBRF (proc) (t.arg1, arg2,
2464 SCM_CADDR (debug.info->a.args)));
6dbd0af5 2465 case scm_tc7_asubr:
399dedcc
MD
2466#ifdef BUILTIN_RPASUBR
2467 t.arg1 = SCM_SUBRF(proc)(t.arg1, arg2);
2468 arg2 = SCM_CDR (SCM_CDR (debug.info->a.args));
da7f71d7
MD
2469 do
2470 {
2471 t.arg1 = SCM_SUBRF(proc)(t.arg1, SCM_CAR (arg2));
2472 arg2 = SCM_CDR (arg2);
2473 }
2474 while (SCM_NIMP (arg2));
399dedcc
MD
2475 RETURN (t.arg1)
2476#endif /* BUILTIN_RPASUBR */
6dbd0af5 2477 case scm_tc7_rpsubr:
71d3aa6d
MD
2478#ifdef BUILTIN_RPASUBR
2479 if (SCM_FALSEP (SCM_SUBRF (proc) (t.arg1, arg2)))
2480 RETURN (SCM_BOOL_F)
2481 t.arg1 = SCM_CDR (SCM_CDR (debug.info->a.args));
da7f71d7
MD
2482 do
2483 {
2484 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, SCM_CAR (t.arg1))))
2485 RETURN (SCM_BOOL_F)
2486 arg2 = SCM_CAR (t.arg1);
2487 t.arg1 = SCM_CDR (t.arg1);
2488 }
2489 while (SCM_NIMP (t.arg1));
71d3aa6d
MD
2490 RETURN (SCM_BOOL_T)
2491#else /* BUILTIN_RPASUBR */
da7f71d7
MD
2492 RETURN (SCM_APPLY (proc, t.arg1,
2493 scm_acons (arg2,
2494 SCM_CDR (SCM_CDR (debug.info->a.args)),
2495 SCM_EOL)))
71d3aa6d 2496#endif /* BUILTIN_RPASUBR */
399dedcc 2497 case scm_tc7_lsubr_2:
da7f71d7
MD
2498 RETURN (SCM_SUBRF (proc) (t.arg1, arg2,
2499 SCM_CDR (SCM_CDR (debug.info->a.args))))
399dedcc
MD
2500 case scm_tc7_lsubr:
2501 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
0f2d19dd 2502#ifdef CCLO
6dbd0af5
MD
2503 case scm_tc7_cclo:
2504 goto cclon;
0f2d19dd 2505#endif
6dbd0af5 2506 case scm_tcs_closures:
b7ff98dd 2507 SCM_SET_ARGSREADY (debug);
e2806c10 2508 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
6dbd0af5
MD
2509 debug.info->a.args,
2510 SCM_ENV (proc));
2511 x = SCM_CODE (proc);
2512 goto cdrxbegin;
2513#else /* DEVAL */
2514 case scm_tc7_subr_3:
2515 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
2516 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, EVALCAR (x, env)));
2517 case scm_tc7_asubr:
399dedcc 2518#ifdef BUILTIN_RPASUBR
da7f71d7
MD
2519 t.arg1 = SCM_SUBRF (proc) (t.arg1, arg2);
2520 do
2521 {
2522 t.arg1 = SCM_SUBRF(proc)(t.arg1, EVALCAR(x, env));
2523 x = SCM_CDR(x);
2524 }
2525 while (SCM_NIMP (x));
399dedcc
MD
2526 RETURN (t.arg1)
2527#endif /* BUILTIN_RPASUBR */
6dbd0af5 2528 case scm_tc7_rpsubr:
71d3aa6d
MD
2529#ifdef BUILTIN_RPASUBR
2530 if (SCM_FALSEP (SCM_SUBRF (proc) (t.arg1, arg2)))
2531 RETURN (SCM_BOOL_F)
da7f71d7
MD
2532 do
2533 {
2534 t.arg1 = EVALCAR (x, env);
2535 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, t.arg1)))
2536 RETURN (SCM_BOOL_F)
2537 arg2 = t.arg1;
2538 x = SCM_CDR (x);
2539 }
2540 while (SCM_NIMP (x));
71d3aa6d
MD
2541 RETURN (SCM_BOOL_T)
2542#else /* BUILTIN_RPASUBR */
da7f71d7 2543 RETURN (SCM_APPLY (proc, t.arg1,
680ed4a8
MD
2544 scm_acons (arg2,
2545 scm_eval_args (x, env, proc),
2546 SCM_EOL)));
71d3aa6d 2547#endif /* BUILTIN_RPASUBR */
6dbd0af5 2548 case scm_tc7_lsubr_2:
680ed4a8 2549 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, scm_eval_args (x, env, proc)));
6dbd0af5 2550 case scm_tc7_lsubr:
680ed4a8
MD
2551 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1,
2552 arg2,
2553 scm_eval_args (x, env, proc))));
0f2d19dd 2554#ifdef CCLO
6dbd0af5
MD
2555 case scm_tc7_cclo:
2556 goto cclon;
0f2d19dd 2557#endif
6dbd0af5
MD
2558 case scm_tcs_closures:
2559#ifdef DEVAL
b7ff98dd 2560 SCM_SET_ARGSREADY (debug);
6dbd0af5 2561#endif
e2806c10 2562 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
680ed4a8
MD
2563 scm_cons2 (t.arg1,
2564 arg2,
2565 scm_eval_args (x, env, proc)),
6dbd0af5
MD
2566 SCM_ENV (proc));
2567 x = SCM_CODE (proc);
2568 goto cdrxbegin;
0f2d19dd 2569#endif /* DEVAL */
0c32d76c 2570 case scm_tcs_cons_gloc:
9b07e212
MD
2571 if (!SCM_I_OPERATORP (proc))
2572 goto badfun;
2573 else
da7f71d7
MD
2574 {
2575 SCM p = (SCM_I_ENTITYP (proc)
2576 ? SCM_ENTITY_PROC_3 (proc)
2577 : SCM_OPERATOR_PROC_3 (proc));
2578 if (SCM_NIMP (p))
33b97402
MD
2579 {
2580 if (SCM_TYP7 (p) == scm_tc7_lsubr_2)
da7f71d7 2581#ifdef DEVAL
33b97402
MD
2582 RETURN (SCM_SUBRF (p) (proc, t.arg1,
2583 scm_cons (arg2, SCM_CDDR (debug.info->a.args))))
da7f71d7 2584#else
33b97402
MD
2585 RETURN (SCM_SUBRF (p) (proc, t.arg1,
2586 scm_cons (arg2,
680ed4a8 2587 scm_eval_args (x, env, proc))))
da7f71d7 2588#endif
33b97402
MD
2589 else if (SCM_CLOSUREP (p))
2590 {
da7f71d7 2591#ifdef DEVAL
33b97402
MD
2592 SCM_SET_ARGSREADY (debug);
2593 debug.info->a.args = scm_cons (proc, debug.info->a.args);
2594 debug.info->a.proc = p;
2595 env = EXTEND_ENV (SCM_CAR (SCM_CODE (p)),
2596 scm_cons2 (proc, t.arg1,
2597 scm_cons (arg2,
2598 SCM_CDDDR (debug.info->a.args))),
2599 SCM_ENV (p));
da7f71d7 2600#else
33b97402
MD
2601 env = EXTEND_ENV (SCM_CAR (SCM_CODE (p)),
2602 scm_cons2 (proc, t.arg1,
2603 scm_cons (arg2,
680ed4a8 2604 scm_eval_args (x, env, proc))),
33b97402
MD
2605 SCM_ENV (p));
2606#endif
2607 x = SCM_CODE (p);
2608 goto cdrxbegin;
2609 }
2610 }
da7f71d7
MD
2611 /* Fall through. */
2612 }
6dbd0af5
MD
2613 case scm_tc7_subr_2:
2614 case scm_tc7_subr_1o:
2615 case scm_tc7_subr_2o:
2616 case scm_tc7_subr_0:
2617 case scm_tc7_cxr:
2618 case scm_tc7_subr_1:
2619 case scm_tc7_contin:
2620 goto wrongnumargs;
2621 default:
2622 goto badfun;
2623 }
0f2d19dd
JB
2624 }
2625#ifdef DEVAL
6dbd0af5 2626exit:
b6d75948 2627 if (CHECK_EXIT && SCM_TRAPS_P)
b7ff98dd 2628 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 2629 {
b7ff98dd
MD
2630 SCM_CLEAR_TRACED_FRAME (debug);
2631 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 2632 t.arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
2633 else
2634 {
2635 scm_make_cont (&t.arg1);
ca6ef71a 2636 if (setjmp (SCM_JMPBUF (t.arg1)))
6dbd0af5
MD
2637 {
2638 proc = SCM_THROW_VALUE (t.arg1);
2639 goto ret;
2640 }
2641 }
2642 scm_ithrow (scm_i_exit_frame, scm_cons2 (t.arg1, proc, SCM_EOL), 0);
2643 }
2644ret:
1646d37b 2645 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
2646 return proc;
2647#endif
2648}
2649
6dbd0af5
MD
2650
2651/* SECTION: This code is compiled once.
2652 */
2653
0f2d19dd
JB
2654#ifndef DEVAL
2655
82a2622a 2656/* This code processes the arguments to apply:
b145c172
JB
2657
2658 (apply PROC ARG1 ... ARGS)
2659
82a2622a
JB
2660 Given a list (ARG1 ... ARGS), this function conses the ARG1
2661 ... arguments onto the front of ARGS, and returns the resulting
2662 list. Note that ARGS is a list; thus, the argument to this
2663 function is a list whose last element is a list.
2664
2665 Apply calls this function, and applies PROC to the elements of the
b145c172
JB
2666 result. apply:nconc2last takes care of building the list of
2667 arguments, given (ARG1 ... ARGS).
2668
82a2622a
JB
2669 Rather than do new consing, apply:nconc2last destroys its argument.
2670 On that topic, this code came into my care with the following
2671 beautifully cryptic comment on that topic: "This will only screw
2672 you if you do (scm_apply scm_apply '( ... ))" If you know what
2673 they're referring to, send me a patch to this comment. */
b145c172 2674
0f2d19dd 2675SCM_PROC(s_nconc2last, "apply:nconc2last", 1, 0, 0, scm_nconc2last);
1cc91f1b 2676
0f2d19dd
JB
2677SCM
2678scm_nconc2last (lst)
2679 SCM lst;
0f2d19dd
JB
2680{
2681 SCM *lloc;
b145c172 2682 SCM_ASSERT (scm_ilength (lst) > 0, lst, SCM_ARG1, s_nconc2last);
0f2d19dd
JB
2683 lloc = &lst;
2684 while (SCM_NNULLP (SCM_CDR (*lloc)))
a23afe53 2685 lloc = SCM_CDRLOC (*lloc);
b145c172 2686 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, s_nconc2last);
0f2d19dd
JB
2687 *lloc = SCM_CAR (*lloc);
2688 return lst;
2689}
2690
2691#endif /* !DEVAL */
2692
6dbd0af5
MD
2693
2694/* SECTION: When DEVAL is defined this code yields scm_dapply.
2695 * It is compiled twice.
2696 */
2697
0f2d19dd 2698#if 0
1cc91f1b 2699
0f2d19dd
JB
2700SCM
2701scm_apply (proc, arg1, args)
2702 SCM proc;
2703 SCM arg1;
2704 SCM args;
0f2d19dd
JB
2705{}
2706#endif
2707
2708#if 0
1cc91f1b 2709
0f2d19dd
JB
2710SCM
2711scm_dapply (proc, arg1, args)
2712 SCM proc;
2713 SCM arg1;
2714 SCM args;
0f2d19dd
JB
2715{}
2716#endif
2717
1cc91f1b 2718
82a2622a
JB
2719/* Apply a function to a list of arguments.
2720
2721 This function is exported to the Scheme level as taking two
2722 required arguments and a tail argument, as if it were:
2723 (lambda (proc arg1 . args) ...)
2724 Thus, if you just have a list of arguments to pass to a procedure,
2725 pass the list as ARG1, and '() for ARGS. If you have some fixed
2726 args, pass the first as ARG1, then cons any remaining fixed args
2727 onto the front of your argument list, and pass that as ARGS. */
2728
0f2d19dd
JB
2729SCM
2730SCM_APPLY (proc, arg1, args)
2731 SCM proc;
2732 SCM arg1;
2733 SCM args;
0f2d19dd
JB
2734{
2735#ifdef DEBUG_EXTENSIONS
2736#ifdef DEVAL
6dbd0af5 2737 scm_debug_frame debug;
c0ab1b8d 2738 scm_debug_info debug_vect_body;
1646d37b 2739 debug.prev = scm_last_debug_frame;
b7ff98dd 2740 debug.status = SCM_APPLYFRAME;
c0ab1b8d 2741 debug.vect = &debug_vect_body;
6dbd0af5
MD
2742 debug.vect[0].a.proc = proc;
2743 debug.vect[0].a.args = SCM_EOL;
1646d37b 2744 scm_last_debug_frame = &debug;
0f2d19dd 2745#else
b7ff98dd 2746 if (SCM_DEBUGGINGP)
0f2d19dd
JB
2747 return scm_dapply (proc, arg1, args);
2748#endif
2749#endif
2750
2751 SCM_ASRTGO (SCM_NIMP (proc), badproc);
82a2622a
JB
2752
2753 /* If ARGS is the empty list, then we're calling apply with only two
2754 arguments --- ARG1 is the list of arguments for PROC. Whatever
2755 the case, futz with things so that ARG1 is the first argument to
2756 give to PROC (or SCM_UNDEFINED if no args), and ARGS contains the
30000774
JB
2757 rest.
2758
2759 Setting the debug apply frame args this way is pretty messy.
2760 Perhaps we should store arg1 and args directly in the frame as
2761 received, and let scm_frame_arguments unpack them, because that's
2762 a relatively rare operation. This works for now; if the Guile
2763 developer archives are still around, see Mikael's post of
2764 11-Apr-97. */
0f2d19dd
JB
2765 if (SCM_NULLP (args))
2766 {
2767 if (SCM_NULLP (arg1))
30000774
JB
2768 {
2769 arg1 = SCM_UNDEFINED;
2770#ifdef DEVAL
2771 debug.vect[0].a.args = SCM_EOL;
2772#endif
2773 }
0f2d19dd
JB
2774 else
2775 {
30000774
JB
2776#ifdef DEVAL
2777 debug.vect[0].a.args = arg1;
2778#endif
0f2d19dd
JB
2779 args = SCM_CDR (arg1);
2780 arg1 = SCM_CAR (arg1);
2781 }
2782 }
2783 else
2784 {
82a2622a 2785 /* SCM_ASRTGO(SCM_NIMP(args) && SCM_CONSP(args), wrongnumargs); */
0f2d19dd 2786 args = scm_nconc2last (args);
30000774
JB
2787#ifdef DEVAL
2788 debug.vect[0].a.args = scm_cons (arg1, args);
2789#endif
0f2d19dd 2790 }
0f2d19dd 2791#ifdef DEVAL
b6d75948 2792 if (SCM_ENTER_FRAME_P && SCM_TRAPS_P)
6dbd0af5
MD
2793 {
2794 SCM tmp;
b7ff98dd 2795 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 2796 tmp = scm_make_debugobj (&debug);
6dbd0af5
MD
2797 else
2798 {
2799 scm_make_cont (&tmp);
ca6ef71a 2800 if (setjmp (SCM_JMPBUF (tmp)))
6dbd0af5
MD
2801 goto entap;
2802 }
2803 scm_ithrow (scm_i_enter_frame, scm_cons (tmp, SCM_EOL), 0);
2804 }
2805entap:
2806 ENTER_APPLY;
2807#endif
2808#ifdef CCLO
2809tail:
0f2d19dd
JB
2810#endif
2811 switch (SCM_TYP7 (proc))
2812 {
2813 case scm_tc7_subr_2o:
2814 args = SCM_NULLP (args) ? SCM_UNDEFINED : SCM_CAR (args);
2815 RETURN (SCM_SUBRF (proc) (arg1, args))
2816 case scm_tc7_subr_2:
269861c7
MD
2817 SCM_ASRTGO (SCM_NNULLP (args) && SCM_NULLP (SCM_CDR (args)),
2818 wrongnumargs);
0f2d19dd
JB
2819 args = SCM_CAR (args);
2820 RETURN (SCM_SUBRF (proc) (arg1, args))
2821 case scm_tc7_subr_0:
2822 SCM_ASRTGO (SCM_UNBNDP (arg1), wrongnumargs);
2823 RETURN (SCM_SUBRF (proc) ())
2824 case scm_tc7_subr_1:
2825 case scm_tc7_subr_1o:
2826 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
2827 RETURN (SCM_SUBRF (proc) (arg1))
2828 case scm_tc7_cxr:
2829 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
2830#ifdef SCM_FLOATS
2831 if (SCM_SUBRF (proc))
2832 {
6dbd0af5
MD
2833 if (SCM_INUMP (arg1))
2834 {
2835 RETURN (scm_makdbl (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1)), 0.0));
2836 }
0f2d19dd 2837 SCM_ASRTGO (SCM_NIMP (arg1), floerr);
6dbd0af5
MD
2838 if (SCM_REALP (arg1))
2839 {
2840 RETURN (scm_makdbl (SCM_DSUBRF (proc) (SCM_REALPART (arg1)), 0.0));
2841 }
0f2d19dd
JB
2842#ifdef SCM_BIGDIG
2843 if SCM_BIGP
2844 (arg1)
2845 RETURN (scm_makdbl (SCM_DSUBRF (proc) (scm_big2dbl (arg1)), 0.0))
2846#endif
2847 floerr:
2848 scm_wta (arg1, (char *) SCM_ARG1, SCM_CHARS (SCM_SNAME (proc)));
2849 }
2850#endif
2851 proc = (SCM) SCM_SNAME (proc);
2852 {
2853 char *chrs = SCM_CHARS (proc) + SCM_LENGTH (proc) - 1;
2854 while ('c' != *--chrs)
2855 {
2856 SCM_ASSERT (SCM_NIMP (arg1) && SCM_CONSP (arg1),
2857 arg1, SCM_ARG1, SCM_CHARS (proc));
2858 arg1 = ('a' == *chrs) ? SCM_CAR (arg1) : SCM_CDR (arg1);
2859 }
2860 RETURN (arg1)
2861 }
2862 case scm_tc7_subr_3:
2863 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CAR (SCM_CDR (args))))
2864 case scm_tc7_lsubr:
2865#ifdef DEVAL
6dbd0af5 2866 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args))
0f2d19dd
JB
2867#else
2868 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args)))
2869#endif
2870 case scm_tc7_lsubr_2:
2871 SCM_ASRTGO (SCM_NIMP (args) && SCM_CONSP (args), wrongnumargs);
2872 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CDR (args)))
2873 case scm_tc7_asubr:
2874 if (SCM_NULLP (args))
2875 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED))
2876 while (SCM_NIMP (args))
2877 {
2878 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
2879 arg1 = SCM_SUBRF (proc) (arg1, SCM_CAR (args));
2880 args = SCM_CDR (args);
2881 }
2882 RETURN (arg1);
2883 case scm_tc7_rpsubr:
2884 if (SCM_NULLP (args))
2885 RETURN (SCM_BOOL_T);
2886 while (SCM_NIMP (args))
2887 {
2888 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
2889 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, SCM_CAR (args))))
2890 RETURN (SCM_BOOL_F);
2891 arg1 = SCM_CAR (args);
2892 args = SCM_CDR (args);
2893 }
2894 RETURN (SCM_BOOL_T);
2895 case scm_tcs_closures:
2896#ifdef DEVAL
6dbd0af5 2897 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args);
0f2d19dd
JB
2898#else
2899 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args));
2900#endif
cf7c17e9 2901#ifndef SCM_RECKLESS
0f2d19dd
JB
2902 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), arg1))
2903 goto wrongnumargs;
2904#endif
1609038c
MD
2905
2906 /* Copy argument list */
2907 if (SCM_IMP (arg1))
2908 args = arg1;
2909 else
2910 {
2911 SCM tl = args = scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED);
2912 while (SCM_NIMP (arg1 = SCM_CDR (arg1))
2913 && SCM_CONSP (arg1))
2914 {
2915 SCM_SETCDR (tl, scm_cons (SCM_CAR (arg1),
2916 SCM_UNSPECIFIED));
2917 tl = SCM_CDR (tl);
2918 }
2919 SCM_SETCDR (tl, arg1);
2920 }
2921
2922 args = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), args, SCM_ENV (proc));
0f2d19dd
JB
2923 proc = SCM_CODE (proc);
2924 while (SCM_NNULLP (proc = SCM_CDR (proc)))
2925 arg1 = EVALCAR (proc, args);
2926 RETURN (arg1);
2927 case scm_tc7_contin:
2928 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
2929 scm_call_continuation (proc, arg1);
2930#ifdef CCLO
2931 case scm_tc7_cclo:
2932#ifdef DEVAL
6dbd0af5
MD
2933 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
2934 arg1 = proc;
2935 proc = SCM_CCLO_SUBR (proc);
2936 debug.vect[0].a.proc = proc;
2937 debug.vect[0].a.args = scm_cons (arg1, args);
0f2d19dd
JB
2938#else
2939 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
0f2d19dd
JB
2940 arg1 = proc;
2941 proc = SCM_CCLO_SUBR (proc);
6dbd0af5 2942#endif
0f2d19dd
JB
2943 goto tail;
2944#endif
0c32d76c 2945 case scm_tcs_cons_gloc:
9b07e212
MD
2946 if (!SCM_I_OPERATORP (proc))
2947 goto badproc;
2948 else
da7f71d7
MD
2949 {
2950#ifdef DEVAL
2951 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
2952#else
2953 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
2954#endif
2955 arg1 = proc;
2956 proc = (SCM_NULLP (args)
2957 ? (SCM_I_ENTITYP (proc)
2958 ? SCM_ENTITY_PROC_0 (proc)
2959 : SCM_OPERATOR_PROC_0 (proc))
2960 : SCM_NULLP (SCM_CDR (args))
2961 ? (SCM_I_ENTITYP (proc)
2962 ? SCM_ENTITY_PROC_1 (proc)
2963 : SCM_OPERATOR_PROC_1 (proc))
2964 : SCM_NULLP (SCM_CDDR (args))
2965 ? (SCM_I_ENTITYP (proc)
2966 ? SCM_ENTITY_PROC_2 (proc)
2967 : SCM_OPERATOR_PROC_2 (proc))
2968 : (SCM_I_ENTITYP (proc)
2969 ? SCM_ENTITY_PROC_3 (proc)
2970 : SCM_OPERATOR_PROC_3 (proc)));
2971#ifdef DEVAL
2972 debug.vect[0].a.proc = proc;
2973 debug.vect[0].a.args = scm_cons (arg1, args);
2974#endif
2975 goto tail;
2976 }
0f2d19dd 2977 wrongnumargs:
f5bf2977 2978 scm_wrong_num_args (proc);
0f2d19dd
JB
2979 default:
2980 badproc:
2981 scm_wta (proc, (char *) SCM_ARG1, "apply");
2982 RETURN (arg1);
2983 }
2984#ifdef DEVAL
6dbd0af5 2985exit:
b6d75948 2986 if (CHECK_EXIT && SCM_TRAPS_P)
b7ff98dd 2987 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 2988 {
b7ff98dd
MD
2989 SCM_CLEAR_TRACED_FRAME (debug);
2990 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 2991 arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
2992 else
2993 {
2994 scm_make_cont (&arg1);
ca6ef71a 2995 if (setjmp (SCM_JMPBUF (arg1)))
6dbd0af5
MD
2996 {
2997 proc = SCM_THROW_VALUE (arg1);
2998 goto ret;
2999 }
3000 }
3001 scm_ithrow (scm_i_exit_frame, scm_cons2 (arg1, proc, SCM_EOL), 0);
3002 }
3003ret:
1646d37b 3004 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
3005 return proc;
3006#endif
3007}
3008
6dbd0af5
MD
3009
3010/* SECTION: The rest of this file is only read once.
3011 */
3012
0f2d19dd
JB
3013#ifndef DEVAL
3014
6cb702da 3015SCM_PROC (s_map, "map", 2, 0, 1, scm_map);
1cc91f1b 3016
368bf056
MD
3017/* Note: Currently, scm_map applies PROC to the argument list(s)
3018 sequentially, starting with the first element(s). This is used in
3019 evalext.c where the Scheme procedure `serial-map', which guarantees
3020 sequential behaviour, is implemented using scm_map. If the
3021 behaviour changes, we need to update `serial-map'.
3022*/
3023
0f2d19dd
JB
3024SCM
3025scm_map (proc, arg1, args)
3026 SCM proc;
3027 SCM arg1;
3028 SCM args;
0f2d19dd
JB
3029{
3030 long i;
3031 SCM res = SCM_EOL;
3032 SCM *pres = &res;
3033 SCM *ve = &args; /* Keep args from being optimized away. */
3034
3035 if (SCM_NULLP (arg1))
3036 return res;
3037 SCM_ASSERT (SCM_NIMP (arg1), arg1, SCM_ARG2, s_map);
3038 if (SCM_NULLP (args))
3039 {
3040 while (SCM_NIMP (arg1))
3041 {
3042 SCM_ASSERT (SCM_CONSP (arg1), arg1, SCM_ARG2, s_map);
3043 *pres = scm_cons (scm_apply (proc, SCM_CAR (arg1), scm_listofnull), SCM_EOL);
a23afe53 3044 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
3045 arg1 = SCM_CDR (arg1);
3046 }
3047 return res;
3048 }
3049 args = scm_vector (scm_cons (arg1, args));
3050 ve = SCM_VELTS (args);
cf7c17e9 3051#ifndef SCM_RECKLESS
0f2d19dd
JB
3052 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
3053 SCM_ASSERT (SCM_NIMP (ve[i]) && SCM_CONSP (ve[i]), args, SCM_ARG2, s_map);
3054#endif
3055 while (1)
3056 {
3057 arg1 = SCM_EOL;
3058 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
3059 {
3060 if SCM_IMP
3061 (ve[i]) return res;
3062 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
3063 ve[i] = SCM_CDR (ve[i]);
3064 }
3065 *pres = scm_cons (scm_apply (proc, arg1, SCM_EOL), SCM_EOL);
a23afe53 3066 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
3067 }
3068}
3069
3070
3071SCM_PROC(s_for_each, "for-each", 2, 0, 1, scm_for_each);
1cc91f1b 3072
0f2d19dd
JB
3073SCM
3074scm_for_each (proc, arg1, args)
3075 SCM proc;
3076 SCM arg1;
3077 SCM args;
0f2d19dd
JB
3078{
3079 SCM *ve = &args; /* Keep args from being optimized away. */
3080 long i;
3081 if SCM_NULLP (arg1)
3082 return SCM_UNSPECIFIED;
3083 SCM_ASSERT (SCM_NIMP (arg1), arg1, SCM_ARG2, s_for_each);
3084 if SCM_NULLP (args)
3085 {
3086 while SCM_NIMP (arg1)
3087 {
3088 SCM_ASSERT (SCM_CONSP (arg1), arg1, SCM_ARG2, s_for_each);
3089 scm_apply (proc, SCM_CAR (arg1), scm_listofnull);
3090 arg1 = SCM_CDR (arg1);
3091 }
3092 return SCM_UNSPECIFIED;
3093 }
3094 args = scm_vector (scm_cons (arg1, args));
3095 ve = SCM_VELTS (args);
cf7c17e9 3096#ifndef SCM_RECKLESS
0f2d19dd
JB
3097 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
3098 SCM_ASSERT (SCM_NIMP (ve[i]) && SCM_CONSP (ve[i]), args, SCM_ARG2, s_for_each);
3099#endif
3100 while (1)
3101 {
3102 arg1 = SCM_EOL;
3103 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
3104 {
3105 if SCM_IMP
3106 (ve[i]) return SCM_UNSPECIFIED;
3107 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
3108 ve[i] = SCM_CDR (ve[i]);
3109 }
3110 scm_apply (proc, arg1, SCM_EOL);
3111 }
3112}
3113
3114
1cc91f1b 3115
0f2d19dd
JB
3116SCM
3117scm_closure (code, env)
3118 SCM code;
3119 SCM env;
0f2d19dd
JB
3120{
3121 register SCM z;
3122 SCM_NEWCELL (z);
3123 SCM_SETCODE (z, code);
a23afe53 3124 SCM_SETENV (z, env);
0f2d19dd
JB
3125 return z;
3126}
3127
3128
3129long scm_tc16_promise;
1cc91f1b 3130
0f2d19dd
JB
3131SCM
3132scm_makprom (code)
3133 SCM code;
0f2d19dd
JB
3134{
3135 register SCM z;
3136 SCM_NEWCELL (z);
f83e2737 3137 SCM_ENTER_A_SECTION;
a23afe53
MD
3138 SCM_SETCDR (z, code);
3139 SCM_SETCAR (z, scm_tc16_promise);
f83e2737 3140 SCM_EXIT_A_SECTION;
0f2d19dd
JB
3141 return z;
3142}
3143
3144
1cc91f1b
JB
3145
3146static int prinprom SCM_P ((SCM exp, SCM port, scm_print_state *pstate));
3147
0f2d19dd 3148static int
19402679 3149prinprom (exp, port, pstate)
0f2d19dd
JB
3150 SCM exp;
3151 SCM port;
19402679 3152 scm_print_state *pstate;
0f2d19dd 3153{
19402679 3154 int writingp = SCM_WRITINGP (pstate);
b7f3516f 3155 scm_puts ("#<promise ", port);
19402679
MD
3156 SCM_SET_WRITINGP (pstate, 1);
3157 scm_iprin1 (SCM_CDR (exp), port, pstate);
3158 SCM_SET_WRITINGP (pstate, writingp);
b7f3516f 3159 scm_putc ('>', port);
0f2d19dd
JB
3160 return !0;
3161}
3162
3163
0f2d19dd 3164SCM_PROC(s_force, "force", 1, 0, 0, scm_force);
1cc91f1b 3165
0f2d19dd
JB
3166SCM
3167scm_force (x)
3168 SCM x;
0f2d19dd 3169{
eed6e03e
JB
3170 SCM_ASSERT (SCM_NIMP(x) && SCM_TYP16 (x) == scm_tc16_promise,
3171 x, SCM_ARG1, s_force);
0f2d19dd
JB
3172 if (!((1L << 16) & SCM_CAR (x)))
3173 {
3174 SCM ans = scm_apply (SCM_CDR (x), SCM_EOL, SCM_EOL);
3175 if (!((1L << 16) & SCM_CAR (x)))
3176 {
3177 SCM_DEFER_INTS;
a23afe53
MD
3178 SCM_SETCDR (x, ans);
3179 SCM_SETOR_CAR (x, (1L << 16));
0f2d19dd
JB
3180 SCM_ALLOW_INTS;
3181 }
3182 }
3183 return SCM_CDR (x);
3184}
3185
3186SCM_PROC (s_promise_p, "promise?", 1, 0, 0, scm_promise_p);
1cc91f1b 3187
0f2d19dd
JB
3188SCM
3189scm_promise_p (x)
3190 SCM x;
0f2d19dd
JB
3191{
3192 return ((SCM_NIMP (x) && (SCM_TYP16 (x) == scm_tc16_promise))
3193 ? SCM_BOOL_T
3194 : SCM_BOOL_F);
3195}
3196
3197SCM_PROC(s_copy_tree, "copy-tree", 1, 0, 0, scm_copy_tree);
1cc91f1b 3198
0f2d19dd
JB
3199SCM
3200scm_copy_tree (obj)
3201 SCM obj;
0f2d19dd
JB
3202{
3203 SCM ans, tl;
3204 if SCM_IMP
3205 (obj) return obj;
3910272e
MD
3206 if (SCM_VECTORP (obj))
3207 {
3208 scm_sizet i = SCM_LENGTH (obj);
3209 ans = scm_make_vector (SCM_MAKINUM (i), SCM_UNSPECIFIED);
3210 while (i--)
3211 SCM_VELTS (ans)[i] = scm_copy_tree (SCM_VELTS (obj)[i]);
3212 return ans;
3213 }
0f2d19dd
JB
3214 if SCM_NCONSP (obj)
3215 return obj;
3216/* return scm_cons(scm_copy_tree(SCM_CAR(obj)), scm_copy_tree(SCM_CDR(obj))); */
3217 ans = tl = scm_cons (scm_copy_tree (SCM_CAR (obj)), SCM_UNSPECIFIED);
067affe3
MD
3218 {
3219 /* Copy source properties possibly associated with head pair. */
3220 SCM p = scm_whash_lookup (scm_source_whash, obj);
3221 if (SCM_NIMP (p))
3222 scm_whash_insert (scm_source_whash, ans, p);
3223 }
0f2d19dd 3224 while (SCM_NIMP (obj = SCM_CDR (obj)) && SCM_CONSP (obj))
a23afe53
MD
3225 {
3226 SCM_SETCDR (tl, scm_cons (scm_copy_tree (SCM_CAR (obj)),
3227 SCM_UNSPECIFIED));
3228 tl = SCM_CDR (tl);
3229 }
3230 SCM_SETCDR (tl, obj);
0f2d19dd
JB
3231 return ans;
3232}
3233
1cc91f1b 3234
0f2d19dd
JB
3235SCM
3236scm_eval_3 (obj, copyp, env)
3237 SCM obj;
3238 int copyp;
3239 SCM env;
0f2d19dd
JB
3240{
3241 if (SCM_NIMP (SCM_CDR (scm_system_transformer)))
3242 obj = scm_apply (SCM_CDR (scm_system_transformer), obj, scm_listofnull);
3243 else if (copyp)
3244 obj = scm_copy_tree (obj);
6cb702da 3245 return SCM_XEVAL (obj, env);
0f2d19dd
JB
3246}
3247
1cc91f1b 3248
0f2d19dd
JB
3249SCM
3250scm_top_level_env (thunk)
3251 SCM thunk;
0f2d19dd
JB
3252{
3253 if (SCM_IMP(thunk))
3254 return SCM_EOL;
3255 else
3256 return scm_cons(thunk, (SCM)SCM_EOL);
3257}
3258
3259SCM_PROC(s_eval2, "eval2", 2, 0, 0, scm_eval2);
1cc91f1b 3260
0f2d19dd
JB
3261SCM
3262scm_eval2 (obj, env_thunk)
3263 SCM obj;
3264 SCM env_thunk;
0f2d19dd
JB
3265{
3266 return scm_eval_3 (obj, 1, scm_top_level_env(env_thunk));
3267}
3268
3269SCM_PROC(s_eval, "eval", 1, 0, 0, scm_eval);
1cc91f1b 3270
0f2d19dd
JB
3271SCM
3272scm_eval (obj)
3273 SCM obj;
0f2d19dd
JB
3274{
3275 return
dc19d1d2 3276 scm_eval_3(obj, 1, scm_top_level_env(SCM_CDR(scm_top_level_lookup_closure_var)));
0f2d19dd
JB
3277}
3278
11f77bfc 3279/* SCM_PROC(s_eval_x, "eval!", 1, 0, 0, scm_eval_x); */
1cc91f1b 3280
0f2d19dd
JB
3281SCM
3282scm_eval_x (obj)
3283 SCM obj;
0f2d19dd
JB
3284{
3285 return
3286 scm_eval_3(obj,
3287 0,
dc19d1d2 3288 scm_top_level_env (SCM_CDR (scm_top_level_lookup_closure_var)));
0f2d19dd
JB
3289}
3290
7332df66 3291static scm_smobfuns promsmob = {scm_markcdr, scm_free0, prinprom};
0f2d19dd 3292
6dbd0af5
MD
3293
3294/* At this point, scm_deval and scm_dapply are generated.
3295 */
3296
0f2d19dd 3297#ifdef DEBUG_EXTENSIONS
6dbd0af5
MD
3298# define DEVAL
3299# include "eval.c"
0f2d19dd
JB
3300#endif
3301
3302
1cc91f1b 3303
0f2d19dd
JB
3304void
3305scm_init_eval ()
0f2d19dd 3306{
33b97402
MD
3307 scm_init_opts (scm_evaluator_traps,
3308 scm_evaluator_trap_table,
3309 SCM_N_EVALUATOR_TRAPS);
3310 scm_init_opts (scm_eval_options_interface,
3311 scm_eval_opts,
3312 SCM_N_EVAL_OPTIONS);
3313
0f2d19dd 3314 scm_tc16_promise = scm_newsmob (&promsmob);
0f2d19dd
JB
3315 scm_i_apply = scm_make_subr ("apply", scm_tc7_lsubr_2, scm_apply);
3316 scm_system_transformer = scm_sysintern ("scm:eval-transformer", SCM_UNDEFINED);
3317 scm_i_dot = SCM_CAR (scm_sysintern (".", SCM_UNDEFINED));
3318 scm_i_arrow = SCM_CAR (scm_sysintern ("=>", SCM_UNDEFINED));
3319 scm_i_else = SCM_CAR (scm_sysintern ("else", SCM_UNDEFINED));
3320 scm_i_unquote = SCM_CAR (scm_sysintern ("unquote", SCM_UNDEFINED));
3321 scm_i_uq_splicing = SCM_CAR (scm_sysintern ("unquote-splicing", SCM_UNDEFINED));
3322
3323 /* acros */
3324 scm_i_quasiquote = scm_make_synt (s_quasiquote, scm_makacro, scm_m_quasiquote);
0f2d19dd
JB
3325 scm_make_synt (s_delay, scm_makacro, scm_m_delay);
3326 /* end of acros */
3327
dc19d1d2
JB
3328 scm_top_level_lookup_closure_var =
3329 scm_sysintern("*top-level-lookup-closure*", SCM_BOOL_F);
9b8d3288 3330 scm_can_use_top_level_lookup_closure_var = 1;
0f2d19dd 3331
6dbd0af5
MD
3332 scm_i_and = scm_make_synt ("and", scm_makmmacro, scm_m_and);
3333 scm_i_begin = scm_make_synt ("begin", scm_makmmacro, scm_m_begin);
3334 scm_i_case = scm_make_synt ("case", scm_makmmacro, scm_m_case);
3335 scm_i_cond = scm_make_synt ("cond", scm_makmmacro, scm_m_cond);
3336 scm_i_define = scm_make_synt ("define", scm_makmmacro, scm_m_define);
3337 scm_i_do = scm_make_synt ("do", scm_makmmacro, scm_m_do);
3338 scm_i_if = scm_make_synt ("if", scm_makmmacro, scm_m_if);
0f2d19dd
JB
3339 scm_i_lambda = scm_make_synt ("lambda", scm_makmmacro, scm_m_lambda);
3340 scm_i_let = scm_make_synt ("let", scm_makmmacro, scm_m_let);
6dbd0af5
MD
3341 scm_i_letrec = scm_make_synt ("letrec", scm_makmmacro, scm_m_letrec);
3342 scm_i_letstar = scm_make_synt ("let*", scm_makmmacro, scm_m_letstar);
3343 scm_i_or = scm_make_synt ("or", scm_makmmacro, scm_m_or);
0f2d19dd 3344 scm_i_quote = scm_make_synt ("quote", scm_makmmacro, scm_m_quote);
6dbd0af5
MD
3345 scm_i_set = scm_make_synt ("set!", scm_makmmacro, scm_m_set);
3346 scm_i_atapply = scm_make_synt ("@apply", scm_makmmacro, scm_m_apply);
3347 scm_i_atcall_cc = scm_make_synt ("@call-with-current-continuation",
3348 scm_makmmacro, scm_m_cont);
3349
6dbd0af5
MD
3350#ifdef DEBUG_EXTENSIONS
3351 scm_i_enter_frame = SCM_CAR (scm_sysintern ("enter-frame", SCM_UNDEFINED));
3352 scm_i_apply_frame = SCM_CAR (scm_sysintern ("apply-frame", SCM_UNDEFINED));
3353 scm_i_exit_frame = SCM_CAR (scm_sysintern ("exit-frame", SCM_UNDEFINED));
3354 scm_i_trace = SCM_CAR (scm_sysintern ("trace", SCM_UNDEFINED));
3355#endif
3356
0f2d19dd 3357#include "eval.x"
25eaf21a
MD
3358
3359 scm_add_feature ("delay");
0f2d19dd 3360}
0f2d19dd 3361
6dbd0af5 3362#endif /* !DEVAL */