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