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