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