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