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