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