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