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