Experimental hacks emulating the Guile-iii Tk interface.
[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);
677 /* !!! might need a check here to be sure that form isn't a struct. */
678 SCM_ASSERT (SCM_NIMP (form) && SCM_ECONSP (form) && SCM_NULLP (SCM_CDR (form)),
679 form, SCM_ARG1, s_quasiquote);
680 if (0 == depth)
681 return evalcar (form, env);
682 return scm_cons2 (tmp, iqq (SCM_CAR (form), env, depth), SCM_EOL);
683 }
684 if (SCM_NIMP (tmp) && (scm_i_uq_splicing == SCM_CAR (tmp)))
685 {
686 tmp = SCM_CDR (tmp);
687 if (0 == --edepth)
688 return scm_append (scm_cons2 (evalcar (tmp, env), iqq (SCM_CDR (form), env, depth), SCM_EOL));
689 }
690 return scm_cons (iqq (SCM_CAR (form), env, edepth), iqq (SCM_CDR (form), env, depth));
691}
692
693/* Here are acros which return values rather than code. */
694
1cc91f1b 695
0f2d19dd
JB
696SCM
697scm_m_quasiquote (xorig, env)
698 SCM xorig;
699 SCM env;
0f2d19dd
JB
700{
701 SCM x = SCM_CDR (xorig);
702 ASSYNT (scm_ilength (x) == 1, xorig, s_expression, s_quasiquote);
703 return iqq (SCM_CAR (x), env, 1);
704}
705
1cc91f1b 706
0f2d19dd
JB
707SCM
708scm_m_delay (xorig, env)
709 SCM xorig;
710 SCM env;
0f2d19dd
JB
711{
712 ASSYNT (scm_ilength (xorig) == 2, xorig, s_expression, s_delay);
713 xorig = SCM_CDR (xorig);
714 return scm_makprom (scm_closure (scm_cons2 (SCM_EOL, SCM_CAR (xorig), SCM_CDR (xorig)),
715 env));
716}
717
1cc91f1b
JB
718
719static SCM env_top_level SCM_P ((SCM env));
720
0f2d19dd
JB
721static SCM
722env_top_level (env)
723 SCM env;
0f2d19dd
JB
724{
725 while (SCM_NIMP(env))
726 {
727 if (SCM_BOOL_T == scm_procedure_p (SCM_CAR(env)))
728 return SCM_CAR(env);
729 env = SCM_CDR (env);
730 }
731 return SCM_BOOL_F;
732}
733
1cc91f1b 734
0f2d19dd
JB
735SCM
736scm_m_define (x, env)
737 SCM x;
738 SCM env;
0f2d19dd
JB
739{
740 SCM proc, arg1 = x;
741 x = SCM_CDR (x);
742 /* ASSYNT(SCM_NULLP(env), x, "bad placement", s_define);*/
743 ASSYNT (scm_ilength (x) >= 2, arg1, s_expression, "define");
744 proc = SCM_CAR (x);
745 x = SCM_CDR (x);
746 while (SCM_NIMP (proc) && SCM_CONSP (proc))
747 { /* nested define syntax */
748 x = scm_cons (scm_cons2 (scm_i_lambda, SCM_CDR (proc), x), SCM_EOL);
749 proc = SCM_CAR (proc);
750 }
751 ASSYNT (SCM_NIMP (proc) && SCM_SYMBOLP (proc), arg1, s_variable, "define");
752 ASSYNT (1 == scm_ilength (x), arg1, s_expression, "define");
753 if (SCM_TOP_LEVEL (env))
754 {
755 x = evalcar (x, env);
6dbd0af5 756#ifdef DEBUG_EXTENSIONS
38bd0b3b 757 if (SCM_REC_PROCNAMES_P)
6dbd0af5
MD
758 scm_set_procedure_property_x (x, scm_i_name, proc);
759#endif
0f2d19dd
JB
760 arg1 = scm_sym2vcell (proc, env_top_level (env), SCM_BOOL_T);
761#if 0
762#ifndef RECKLESS
763 if (SCM_NIMP (SCM_CDR (arg1)) && ((SCM) SCM_SNAME (SCM_CDR (arg1)) == proc)
764 && (SCM_CDR (arg1) != x))
765 scm_warn ("redefining built-in ", SCM_CHARS (proc));
766 else
767#endif
768 if (5 <= scm_verbose && SCM_UNDEFINED != SCM_CDR (arg1))
769 scm_warn ("redefining ", SCM_CHARS (proc));
0f2d19dd 770#endif
a23afe53 771 SCM_SETCDR (arg1, x);
0f2d19dd
JB
772#ifdef SICP
773 return scm_cons2 (scm_i_quote, SCM_CAR (arg1), SCM_EOL);
774#else
775 return SCM_UNSPECIFIED;
776#endif
777 }
778 return scm_cons2 (SCM_IM_DEFINE, proc, x);
779}
6dbd0af5
MD
780
781SCM
782scm_m_undefine (x, env)
783 SCM x, env;
784{
785 SCM arg1 = x;
786 x = SCM_CDR (x);
787 ASSYNT (SCM_TOP_LEVEL (env), arg1, "bad placement ", s_undefine);
788 ASSYNT (SCM_NIMP (x) && SCM_CONSP (x) && SCM_CDR (x) == SCM_EOL,
789 arg1, s_expression, s_undefine);
790 x = SCM_CAR (x);
791 ASSYNT (SCM_NIMP (x) && SCM_SYMBOLP (x), arg1, s_variable, s_undefine);
792 arg1 = scm_sym2vcell (x, env_top_level (env), SCM_BOOL_F);
793 ASSYNT (SCM_NFALSEP (arg1) && !SCM_UNBNDP (SCM_CDR (arg1)),
794 x, "variable already unbound ", s_undefine);
795#if 0
796#ifndef RECKLESS
797 if (SCM_NIMP (SCM_CDR (arg1)) && ((SCM) SCM_SNAME (SCM_CDR (arg1)) == x))
798 scm_warn ("undefining built-in ", SCM_CHARS (x));
799 else
800#endif
801 if (5 <= scm_verbose && SCM_UNDEFINED != SCM_CDR (arg1))
802 scm_warn ("redefining ", SCM_CHARS (x));
803#endif
a23afe53 804 SCM_SETCDR (arg1, SCM_UNDEFINED);
6dbd0af5
MD
805#ifdef SICP
806 return SCM_CAR (arg1);
807#else
808 return SCM_UNSPECIFIED;
809#endif
810}
811
0f2d19dd
JB
812/* end of acros */
813
1cc91f1b 814
0f2d19dd
JB
815SCM
816scm_m_letrec (xorig, env)
817 SCM xorig;
818 SCM env;
0f2d19dd
JB
819{
820 SCM cdrx = SCM_CDR (xorig); /* locally mutable version of form */
821 char *what = SCM_CHARS (SCM_CAR (xorig));
822 SCM x = cdrx, proc, arg1; /* structure traversers */
823 SCM vars = SCM_EOL, inits = SCM_EOL, *initloc = &inits;
824
825 ASRTSYNTAX (scm_ilength (x) >= 2, s_body);
826 proc = SCM_CAR (x);
827 if SCM_NULLP
828 (proc) return scm_m_letstar (xorig, env); /* null binding, let* faster */
829 ASRTSYNTAX (scm_ilength (proc) >= 1, s_bindings);
830 do
831 {
832 /* vars scm_list reversed here, inits reversed at evaluation */
833 arg1 = SCM_CAR (proc);
834 ASRTSYNTAX (2 == scm_ilength (arg1), s_bindings);
835 ASRTSYNTAX (SCM_NIMP (SCM_CAR (arg1)) && SCM_SYMBOLP (SCM_CAR (arg1)), s_variable);
836 vars = scm_cons (SCM_CAR (arg1), vars);
837 *initloc = scm_cons (SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
a23afe53 838 initloc = SCM_CDRLOC (*initloc);
0f2d19dd
JB
839 }
840 while SCM_NIMP
841 (proc = SCM_CDR (proc));
842 cdrx = scm_cons2 (vars, inits, SCM_CDR (x));
a23afe53 843 bodycheck (xorig, SCM_CDRLOC (SCM_CDR (cdrx)), what);
0f2d19dd
JB
844 return scm_cons (SCM_IM_LETREC, cdrx);
845}
846
1cc91f1b 847
0f2d19dd
JB
848SCM
849scm_m_let (xorig, env)
850 SCM xorig;
851 SCM env;
0f2d19dd
JB
852{
853 SCM cdrx = SCM_CDR (xorig); /* locally mutable version of form */
854 SCM x = cdrx, proc, arg1, name; /* structure traversers */
855 SCM vars = SCM_EOL, inits = SCM_EOL, *varloc = &vars, *initloc = &inits;
856
857 ASSYNT (scm_ilength (x) >= 2, xorig, s_body, "let");
858 proc = SCM_CAR (x);
859 if (SCM_NULLP (proc)
860 || (SCM_NIMP (proc) && SCM_CONSP (proc)
861 && SCM_NIMP (SCM_CAR (proc)) && SCM_CONSP (SCM_CAR (proc)) && SCM_NULLP (SCM_CDR (proc))))
862 return scm_m_letstar (xorig, env); /* null or single binding, let* is faster */
863 ASSYNT (SCM_NIMP (proc), xorig, s_bindings, "let");
864 if (SCM_CONSP (proc)) /* plain let, proc is <bindings> */
865 return scm_cons (SCM_IM_LET, SCM_CDR (scm_m_letrec (xorig, env)));
866 if (!SCM_SYMBOLP (proc))
867 scm_wta (xorig, s_bindings, "let"); /* bad let */
868 name = proc; /* named let, build equiv letrec */
869 x = SCM_CDR (x);
870 ASSYNT (scm_ilength (x) >= 2, xorig, s_body, "let");
871 proc = SCM_CAR (x); /* bindings scm_list */
872 ASSYNT (scm_ilength (proc) >= 0, xorig, s_bindings, "let");
873 while SCM_NIMP
874 (proc)
875 { /* vars and inits both in order */
876 arg1 = SCM_CAR (proc);
877 ASSYNT (2 == scm_ilength (arg1), xorig, s_bindings, "let");
878 ASSYNT (SCM_NIMP (SCM_CAR (arg1)) && SCM_SYMBOLP (SCM_CAR (arg1)), xorig, s_variable, "let");
879 *varloc = scm_cons (SCM_CAR (arg1), SCM_EOL);
a23afe53 880 varloc = SCM_CDRLOC (*varloc);
0f2d19dd 881 *initloc = scm_cons (SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
a23afe53 882 initloc = SCM_CDRLOC (*initloc);
0f2d19dd
JB
883 proc = SCM_CDR (proc);
884 }
885 return
886 scm_m_letrec (scm_cons2 (scm_i_let,
887 scm_cons (scm_cons2 (name, scm_cons2 (scm_i_lambda, vars, SCM_CDR (x)), SCM_EOL), SCM_EOL),
888 scm_acons (name, inits, SCM_EOL)), /* body */
889 env);
890}
891
892
1cc91f1b 893
0f2d19dd
JB
894SCM
895scm_m_apply (xorig, env)
896 SCM xorig;
897 SCM env;
0f2d19dd
JB
898{
899 ASSYNT (scm_ilength (SCM_CDR (xorig)) == 2, xorig, s_expression, "@apply");
900 return scm_cons (SCM_IM_APPLY, SCM_CDR (xorig));
901}
902
e2806c10 903#define s_atcall_cc (SCM_ISYMCHARS(SCM_IM_CONT)+1)
0f2d19dd 904
1cc91f1b 905
0f2d19dd
JB
906SCM
907scm_m_cont (xorig, env)
908 SCM xorig;
909 SCM env;
0f2d19dd
JB
910{
911 ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1, xorig, s_expression, "@call-with-current-continuation");
912 return scm_cons (SCM_IM_CONT, SCM_CDR (xorig));
913}
914
6dbd0af5
MD
915/* scm_unmemocopy takes a memoized expression together with its
916 * environment and rewrites it to its original form. Thus, it is the
917 * inversion of the rewrite rules above. The procedure is not
918 * optimized for speed. It's used in scm_iprin1 when printing the
919 * code of a closure, in scm_procedure_source and in scm_expr_stack
920 * when generating the source for a stackframe.
921 */
922
1cc91f1b
JB
923
924static SCM unmemocopy SCM_P ((SCM x, SCM env));
925
6dbd0af5
MD
926static SCM
927unmemocopy (x, env)
928 SCM x;
929 SCM env;
6dbd0af5
MD
930{
931 SCM ls, z;
932#ifdef DEBUG_EXTENSIONS
933 SCM p;
934#endif
935 if (SCM_NCELLP (x) || SCM_NECONSP (x))
936 return x;
937#ifdef DEBUG_EXTENSIONS
938 p = scm_whash_lookup (scm_source_whash, x);
939#endif
940 switch (SCM_TYP7 (x))
941 {
942 case (127 & SCM_IM_AND):
943 ls = z = scm_cons (scm_i_and, SCM_UNSPECIFIED);
944 break;
945 case (127 & SCM_IM_BEGIN):
946 ls = z = scm_cons (scm_i_begin, SCM_UNSPECIFIED);
947 break;
948 case (127 & SCM_IM_CASE):
949 ls = z = scm_cons (scm_i_case, SCM_UNSPECIFIED);
950 break;
951 case (127 & SCM_IM_COND):
952 ls = z = scm_cons (scm_i_cond, SCM_UNSPECIFIED);
953 break;
954 case (127 & SCM_IM_DO):
955 ls = scm_cons (scm_i_do, SCM_UNSPECIFIED);
956 goto transform;
957 case (127 & SCM_IM_IF):
958 ls = z = scm_cons (scm_i_if, SCM_UNSPECIFIED);
959 break;
960 case (127 & SCM_IM_LET):
961 ls = scm_cons (scm_i_let, SCM_UNSPECIFIED);
962 goto transform;
963 case (127 & SCM_IM_LETREC):
964 {
965 SCM f, v, e, s;
966 ls = scm_cons (scm_i_letrec, SCM_UNSPECIFIED);
967 transform:
968 x = SCM_CDR (x);
969 f = v = SCM_CAR (x);
970 x = SCM_CDR (x);
e2806c10 971 z = EXTEND_ENV (f, SCM_EOL, env);
6dbd0af5
MD
972 e = scm_reverse (unmemocopy (SCM_CAR (x),
973 SCM_CAR (ls) == scm_i_letrec ? z : env));
974 env = z;
975 s = SCM_CAR (ls) == scm_i_do
976 ? scm_reverse (unmemocopy (SCM_CDR (SCM_CDR (SCM_CDR (x))), env))
977 : f;
978 z = SCM_EOL;
979 do
980 {
981 z = scm_acons (SCM_CAR (v),
982 scm_cons (SCM_CAR (e),
983 SCM_CAR (s) == SCM_CAR (v)
984 ? SCM_EOL
985 : scm_cons (SCM_CAR (s), SCM_EOL)),
986 z);
987 v = SCM_CDR (v);
988 e = SCM_CDR (e);
989 s = SCM_CDR (s);
990 }
991 while SCM_NIMP (v);
a23afe53
MD
992 z = scm_cons (z, SCM_UNSPECIFIED);
993 SCM_SETCDR (ls, z);
6dbd0af5
MD
994 if (SCM_CAR (ls) == scm_i_do)
995 {
996 x = SCM_CDR (x);
a23afe53 997 SCM_SETCDR (z, scm_cons (unmemocopy (SCM_CAR (x), env),
6dbd0af5 998 SCM_UNSPECIFIED));
a23afe53
MD
999 z = SCM_CDR (z);
1000 x = (SCM) (SCM_CARLOC (SCM_CDR (x)) - 1);
6dbd0af5
MD
1001 }
1002 break;
1003 }
1004 case (127 & SCM_IM_LETSTAR):
1005 {
1006 SCM b, y;
1007 x = SCM_CDR (x);
1008 b = SCM_CAR (x);
1009 y = SCM_EOL;
1010 if SCM_IMP (b)
1011 {
e2806c10 1012 env = EXTEND_ENV (SCM_EOL, SCM_EOL, env);
6dbd0af5
MD
1013 goto letstar;
1014 }
1015 y = z = scm_acons (SCM_CAR (b),
1016 unmemocar (
1017 scm_cons (unmemocopy (SCM_CAR (SCM_CDR (b)), env), SCM_EOL), env),
1018 SCM_UNSPECIFIED);
e2806c10 1019 env = EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
6dbd0af5
MD
1020 b = SCM_CDR (SCM_CDR (b));
1021 if (SCM_IMP (b))
1022 {
1023 SCM_SETCDR (y, SCM_EOL);
1024 ls = scm_cons (scm_i_let, z = scm_cons (y, SCM_UNSPECIFIED));
1025 break;
1026 }
1027 do
1028 {
a23afe53
MD
1029 SCM_SETCDR (z, scm_acons (SCM_CAR (b),
1030 unmemocar (
6dbd0af5 1031 scm_cons (unmemocopy (SCM_CAR (SCM_CDR (b)), env), SCM_EOL), env),
a23afe53
MD
1032 SCM_UNSPECIFIED));
1033 z = SCM_CDR (z);
e2806c10 1034 env = EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
6dbd0af5
MD
1035 b = SCM_CDR (SCM_CDR (b));
1036 }
1037 while SCM_NIMP (b);
a23afe53 1038 SCM_SETCDR (z, SCM_EOL);
6dbd0af5
MD
1039 letstar:
1040 ls = scm_cons (scm_i_letstar, z = scm_cons (y, SCM_UNSPECIFIED));
1041 break;
1042 }
1043 case (127 & SCM_IM_OR):
1044 ls = z = scm_cons (scm_i_or, SCM_UNSPECIFIED);
1045 break;
1046 case (127 & SCM_IM_LAMBDA):
1047 x = SCM_CDR (x);
1048 ls = scm_cons (scm_i_lambda,
1049 z = scm_cons (SCM_CAR (x), SCM_UNSPECIFIED));
e2806c10 1050 env = EXTEND_ENV (SCM_CAR (x), SCM_EOL, env);
6dbd0af5
MD
1051 break;
1052 case (127 & SCM_IM_QUOTE):
1053 ls = z = scm_cons (scm_i_quote, SCM_UNSPECIFIED);
1054 break;
1055 case (127 & SCM_IM_SET):
1056 ls = z = scm_cons (scm_i_set, SCM_UNSPECIFIED);
1057 break;
1058 case (127 & SCM_IM_DEFINE):
1059 {
1060 SCM n;
1061 x = SCM_CDR (x);
1062 ls = scm_cons (scm_i_define,
1063 z = scm_cons (n = SCM_CAR (x), SCM_UNSPECIFIED));
1064 if (SCM_NNULLP (env))
a23afe53 1065 SCM_SETCAR (SCM_CAR (env), scm_cons (n, SCM_CAR (SCM_CAR (env))));
6dbd0af5
MD
1066 break;
1067 }
1068 case (127 & SCM_MAKISYM (0)):
1069 z = SCM_CAR (x);
1070 if (!SCM_ISYMP (z))
1071 goto unmemo;
1072 switch SCM_ISYMNUM (z)
1073 {
1074 case (SCM_ISYMNUM (SCM_IM_APPLY)):
1075 ls = z = scm_cons (scm_i_atapply, SCM_UNSPECIFIED);
1076 goto loop;
1077 case (SCM_ISYMNUM (SCM_IM_CONT)):
1078 ls = z = scm_cons (scm_i_atcall_cc, SCM_UNSPECIFIED);
1079 goto loop;
1080 default:
fa888178 1081 /* appease the Sun compiler god: */ ;
6dbd0af5
MD
1082 }
1083 unmemo:
1084 default:
1085 ls = z = unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env),
1086 SCM_UNSPECIFIED),
1087 env);
1088 }
1089loop:
1090 while (SCM_CELLP (x = SCM_CDR (x)) && SCM_ECONSP (x))
a23afe53
MD
1091 {
1092 SCM_SETCDR (z, unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env),
1093 SCM_UNSPECIFIED),
1094 env));
1095 z = SCM_CDR (z);
1096 }
1097 SCM_SETCDR (z, x);
6dbd0af5
MD
1098#ifdef DEBUG_EXTENSIONS
1099 if (SCM_NFALSEP (p))
1100 scm_whash_insert (scm_source_whash, ls, p);
1101#endif
1102 return ls;
1103}
1104
1cc91f1b 1105
6dbd0af5
MD
1106SCM
1107scm_unmemocopy (x, env)
1108 SCM x;
1109 SCM env;
6dbd0af5
MD
1110{
1111 if (SCM_NNULLP (env))
1112 /* Make a copy of the lowest frame to protect it from
1113 modifications by SCM_IM_DEFINE */
1114 return unmemocopy (x, scm_cons (SCM_CAR (env), SCM_CDR (env)));
1115 else
1116 return unmemocopy (x, env);
1117}
1118
0f2d19dd 1119#ifndef RECKLESS
1cc91f1b 1120
0f2d19dd
JB
1121int
1122scm_badargsp (formals, args)
1123 SCM formals;
1124 SCM args;
0f2d19dd
JB
1125{
1126 while SCM_NIMP
1127 (formals)
1128 {
1129 if SCM_NCONSP
1130 (formals) return 0;
1131 if SCM_IMP
1132 (args) return 1;
1133 formals = SCM_CDR (formals);
1134 args = SCM_CDR (args);
1135 }
1136 return SCM_NNULLP (args) ? 1 : 0;
1137}
1138#endif
1139
1140
1141\f
1142long scm_tc16_macro;
1143
1cc91f1b 1144
6dbd0af5
MD
1145SCM
1146scm_eval_args (l, env)
1147 SCM l;
1148 SCM env;
6dbd0af5
MD
1149{
1150 SCM res = SCM_EOL, *lloc = &res;
1151 while (SCM_NIMP (l))
1152 {
1153 *lloc = scm_cons (EVALCAR (l, env), SCM_EOL);
a23afe53 1154 lloc = SCM_CDRLOC (*lloc);
6dbd0af5
MD
1155 l = SCM_CDR (l);
1156 }
1157 return res;
1158}
c4ac4d88
JB
1159
1160
1161/* The SCM_CEVAL and SCM_APPLY functions use this function instead of
1162 calling setjmp directly, to make sure that local variables don't
1163 have their values clobbered by a longjmp.
1164
1165 According to Harbison & Steele, "Automatic variables local to the
1166 function containing setjmp are guaranteed to have their correct
1167 value in ANSI C only if they have a volatile-qualified type or if
1168 their values were not changed between the original call to setjmp
1169 and the corresponding longjmp call."
1170
1171 SCM_CEVAL and SCM_APPLY are too complex for me to see how to meet
1172 the second condition, and making x and env volatile would be a
1173 speed problem, so we'll just trivially meet the first, by having no
1174 "automatic variables local to the function containing setjmp." */
1175static int
1176safe_setjmp (jmp_buf env)
1177{
1178 /* I think ANSI requires us to write the function this way, instead
1179 of just saying "return setjmp (env)". Maybe I'm being silly.
1180 See Harbison & Steele, third edition, p. 353. */
1181 int val;
1182 val = setjmp (env);
1183 return val;
1184}
1185
1186
0f2d19dd
JB
1187#endif /* !DEVAL */
1188
6dbd0af5
MD
1189
1190/* SECTION: This code is specific for the debugging support. One
1191 * branch is read when DEVAL isn't defined, the other when DEVAL is
1192 * defined.
1193 */
1194
1195#ifndef DEVAL
1196
1197#define SCM_APPLY scm_apply
1198#define PREP_APPLY(proc, args)
1199#define ENTER_APPLY
1200#define RETURN(x) return x;
b7ff98dd
MD
1201#ifdef STACK_CHECKING
1202#ifndef NO_CEVAL_STACK_CHECKING
1203#define EVAL_STACK_CHECKING
1204#endif
6dbd0af5
MD
1205#endif
1206
1207#else /* !DEVAL */
1208
0f2d19dd
JB
1209#undef SCM_CEVAL
1210#define SCM_CEVAL scm_deval /* Substitute all uses of scm_ceval */
1211#undef SCM_APPLY
1212#define SCM_APPLY scm_dapply
6dbd0af5
MD
1213#undef PREP_APPLY
1214#define PREP_APPLY(p, l) \
1215{ ++debug.info; debug.info->a.proc = p; debug.info->a.args = l; }
1216#undef ENTER_APPLY
1217#define ENTER_APPLY \
1218{\
b7ff98dd 1219 SCM_SET_ARGSREADY (debug);\
6dbd0af5 1220 if (CHECK_APPLY)\
b7ff98dd 1221 if (SCM_APPLY_FRAME_P || (SCM_TRACE_P && PROCTRACEP (proc)))\
6dbd0af5 1222 {\
b7ff98dd
MD
1223 SCM tmp, tail = SCM_TRACED_FRAME_P (debug) ? SCM_BOOL_T : SCM_BOOL_F;\
1224 SCM_SET_TRACED_FRAME (debug);\
1225 if (SCM_CHEAPTRAPS_P)\
6dbd0af5 1226 {\
c0ab1b8d 1227 tmp = scm_make_debugobj (&debug);\
6dbd0af5
MD
1228 scm_ithrow (scm_i_apply_frame, scm_cons2 (tmp, tail, SCM_EOL), 0);\
1229 }\
1230 else\
1231 {\
1232 scm_make_cont (&tmp);\
c4ac4d88 1233 if (!safe_setjmp (SCM_JMPBUF (tmp)))\
6dbd0af5
MD
1234 scm_ithrow (scm_i_apply_frame, scm_cons2 (tmp, tail, SCM_EOL), 0);\
1235 }\
1236 }\
1237}
0f2d19dd
JB
1238#undef RETURN
1239#define RETURN(e) {proc = (e); goto exit;}
b7ff98dd
MD
1240#ifdef STACK_CHECKING
1241#ifndef EVAL_STACK_CHECKING
1242#define EVAL_STACK_CHECKING
1243#endif
6dbd0af5
MD
1244#endif
1245
1246/* scm_ceval_ptr points to the currently selected evaluator.
1247 * *fixme*: Although efficiency is important here, this state variable
1248 * should probably not be a global. It should be related to the
1249 * current repl.
1250 */
1251
1cc91f1b
JB
1252
1253SCM (*scm_ceval_ptr) SCM_P ((SCM x, SCM env));
0f2d19dd 1254
1646d37b 1255/* scm_last_debug_frame contains a pointer to the last debugging
6dbd0af5
MD
1256 * information stack frame. It is accessed very often from the
1257 * debugging evaluator, so it should probably not be indirectly
1258 * addressed. Better to save and restore it from the current root at
1259 * any stack swaps.
1260 */
1261
1646d37b
MD
1262#ifndef USE_THREADS
1263scm_debug_frame *scm_last_debug_frame;
1264#endif
6dbd0af5
MD
1265
1266/* scm_debug_eframe_size is the number of slots available for pseudo
1267 * stack frames at each real stack frame.
1268 */
1269
1270int scm_debug_eframe_size;
1271
b7ff98dd 1272int scm_debug_mode, scm_check_entry_p, scm_check_apply_p, scm_check_exit_p;
6dbd0af5
MD
1273
1274scm_option scm_debug_opts[] = {
b7ff98dd
MD
1275 { SCM_OPTION_BOOLEAN, "cheap", 1,
1276 "*Flyweight representation of the stack at traps." },
1277 { SCM_OPTION_BOOLEAN, "breakpoints", 0, "*Check for breakpoints." },
1278 { SCM_OPTION_BOOLEAN, "trace", 0, "*Trace mode." },
1279 { SCM_OPTION_BOOLEAN, "procnames", 1,
1280 "Record procedure names at definition." },
1281 { SCM_OPTION_BOOLEAN, "backwards", 0,
1282 "Display backtrace in anti-chronological order." },
4e646a03
MD
1283 { SCM_OPTION_INTEGER, "indent", 10, "Maximal indentation in backtrace." },
1284 { SCM_OPTION_INTEGER, "frames", 3,
b7ff98dd 1285 "Maximum number of tail-recursive frames in backtrace." },
4e646a03
MD
1286 { SCM_OPTION_INTEGER, "maxdepth", 1000,
1287 "Maximal number of stored backtrace frames." },
1288 { SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." },
11f77bfc
MD
1289 { SCM_OPTION_BOOLEAN, "backtrace", 0, "Show backtrace on error." },
1290 { SCM_OPTION_BOOLEAN, "debug", 0, "Use the debugging evaluator." },
b7ff98dd 1291 { SCM_OPTION_INTEGER, "stack", 20000, "Stack size limit (0 = no check)." }
6dbd0af5
MD
1292};
1293
1294scm_option scm_evaluator_trap_table[] = {
b7ff98dd
MD
1295 { SCM_OPTION_BOOLEAN, "enter-frame", 0, "Trap when eval enters new frame." },
1296 { SCM_OPTION_BOOLEAN, "apply-frame", 0, "Trap when entering apply." },
1297 { SCM_OPTION_BOOLEAN, "exit-frame", 0, "Trap when exiting eval or apply." }
6dbd0af5
MD
1298};
1299
1300SCM
1301scm_deval_args (l, env, lloc)
1302 SCM l, env, *lloc;
0f2d19dd 1303{
6dbd0af5 1304 SCM *res = lloc;
0f2d19dd
JB
1305 while (SCM_NIMP (l))
1306 {
1307 *lloc = scm_cons (EVALCAR (l, env), SCM_EOL);
a23afe53 1308 lloc = SCM_CDRLOC (*lloc);
0f2d19dd
JB
1309 l = SCM_CDR (l);
1310 }
6dbd0af5 1311 return *res;
0f2d19dd
JB
1312}
1313
6dbd0af5
MD
1314#endif /* !DEVAL */
1315
1316
1317/* SECTION: Some local definitions for the evaluator.
1318 */
1319
1320#ifndef DEVAL
1321#ifdef SCM_FLOATS
1322#define CHECK_EQVISH(A,B) (((A) == (B)) || (SCM_NFALSEP (scm_eqv_p ((A), (B)))))
1323#else
1324#define CHECK_EQVISH(A,B) ((A) == (B))
1325#endif
1326#endif /* DEVAL */
1327
1328
1329/* SECTION: This is the evaluator. Like any real monster, it has
1330 * three heads. This code is compiled twice.
1331 */
1332
0f2d19dd 1333#if 0
1cc91f1b 1334
0f2d19dd
JB
1335SCM
1336scm_ceval (x, env)
1337 SCM x;
1338 SCM env;
0f2d19dd
JB
1339{}
1340#endif
1341#if 0
1cc91f1b 1342
0f2d19dd
JB
1343SCM
1344scm_deval (x, env)
1345 SCM x;
1346 SCM env;
0f2d19dd
JB
1347{}
1348#endif
1349
1cc91f1b 1350
6dbd0af5 1351SCM
0f2d19dd
JB
1352SCM_CEVAL (x, env)
1353 SCM x;
1354 SCM env;
1355{
1356 union
1357 {
1358 SCM *lloc;
1359 SCM arg1;
1360 } t;
6dbd0af5
MD
1361 SCM proc, arg2;
1362#ifdef DEVAL
c0ab1b8d
JB
1363 scm_debug_frame debug;
1364 scm_debug_info *debug_info_end;
1646d37b 1365 debug.prev = scm_last_debug_frame;
6dbd0af5 1366 debug.status = scm_debug_eframe_size;
c0ab1b8d
JB
1367 debug.vect = (scm_debug_info *) alloca (scm_debug_eframe_size
1368 * sizeof (debug.vect[0]));
1369 debug.info = debug.vect;
1370 debug_info_end = debug.vect + scm_debug_eframe_size;
1371 scm_last_debug_frame = &debug;
6dbd0af5 1372#endif
b7ff98dd
MD
1373#ifdef EVAL_STACK_CHECKING
1374 if (SCM_STACK_OVERFLOW_P ((SCM_STACKITEM *) &proc)
1375 && scm_stack_checking_enabled_p)
6dbd0af5 1376 {
b7ff98dd 1377#ifdef DEVAL
6dbd0af5
MD
1378 debug.info->e.exp = x;
1379 debug.info->e.env = env;
b7ff98dd 1380#endif
6dbd0af5
MD
1381 scm_report_stack_overflow ();
1382 }
1383#endif
1384#ifdef DEVAL
1385 goto start;
1386#endif
1387loopnoap:
1388 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1389loop:
1390#ifdef DEVAL
1391#if 0 /* This will probably never have any practical use ... */
1392 if (CHECK_EXIT)
1393 {
b7ff98dd 1394 if (SINGLE_STEP || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5
MD
1395 {
1396 SINGLE_STEP = 0;
b7ff98dd
MD
1397 SCM_RESET_DEBUG_MODE;
1398 SCM_CLEAR_TRACED_FRAME (debug);
6dbd0af5 1399 scm_make_cont (&t.arg1);
c4ac4d88 1400 if (!safe_setjmp (SCM_JMPBUF (t.arg1)))
6dbd0af5
MD
1401 scm_ithrow (scm_i_exit_tail, scm_cons (t.arg1, SCM_EOL), 0);
1402 }
1403 }
1404nextframe:
1405#endif
b7ff98dd
MD
1406 SCM_CLEAR_ARGSREADY (debug);
1407 if (SCM_OVERFLOWP (debug))
6dbd0af5 1408 --debug.info;
c0ab1b8d 1409 else if (++debug.info >= debug_info_end)
6dbd0af5 1410 {
b7ff98dd 1411 SCM_SET_OVERFLOW (debug);
6dbd0af5
MD
1412 debug.info -= 2;
1413 }
1414start:
1415 debug.info->e.exp = x;
1416 debug.info->e.env = env;
1417 if (CHECK_ENTRY)
b7ff98dd 1418 if (SCM_ENTER_FRAME_P || (SCM_BREAKPOINTS_P && SRCBRKP (x)))
6dbd0af5 1419 {
b7ff98dd
MD
1420 SCM tail = SCM_TAILRECP (debug) ? SCM_BOOL_T : SCM_BOOL_F;
1421 SCM_SET_TAILREC (debug);
1422 SCM_ENTER_FRAME_P = 0;
1423 SCM_RESET_DEBUG_MODE;
1424 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 1425 t.arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
1426 else
1427 {
1428 scm_make_cont (&t.arg1);
c4ac4d88 1429 if (safe_setjmp (SCM_JMPBUF (t.arg1)))
6dbd0af5
MD
1430 {
1431 x = SCM_THROW_VALUE (t.arg1);
1432 if (SCM_IMP (x))
1433 {
1434 RETURN (x);
1435 }
1436 else
1437 /* This gives the possibility for the debugger to
1438 modify the source expression before evaluation. */
1439 goto dispatch;
1440 }
1441 }
1442 scm_ithrow (scm_i_enter_frame,
1443 scm_cons2 (t.arg1, tail,
1444 scm_cons (scm_unmemocopy (x, env), SCM_EOL)),
1445 0);
1446 }
1447dispatch:
1448#endif
0f2d19dd 1449 SCM_ASYNC_TICK;
0f2d19dd
JB
1450 switch (SCM_TYP7 (x))
1451 {
1452 case scm_tcs_symbols:
1453 /* Only happens when called at top level.
1454 */
1455 x = scm_cons (x, SCM_UNDEFINED);
1456 goto retval;
1457
1458 case (127 & SCM_IM_AND):
1459 x = SCM_CDR (x);
1460 t.arg1 = x;
1461 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1462 if (SCM_FALSEP (EVALCAR (x, env)))
1463 {
1464 RETURN (SCM_BOOL_F);
1465 }
1466 else
1467 x = t.arg1;
6dbd0af5 1468 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1469 goto carloop;
1470
1471 case (127 & SCM_IM_BEGIN):
6dbd0af5
MD
1472 cdrxnoap:
1473 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1474 cdrxbegin:
1475 x = SCM_CDR (x);
1476
1477 begin:
1478 t.arg1 = x;
1479 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1480 {
1481 SIDEVAL (SCM_CAR (x), env);
1482 x = t.arg1;
1483 }
1484
1485 carloop: /* scm_eval car of last form in list */
1486 if (SCM_NCELLP (SCM_CAR (x)))
1487 {
1488 x = SCM_CAR (x);
6dbd0af5 1489 RETURN (SCM_IMP (x) ? EVALIM (x, env) : SCM_GLOC_VAL (x))
0f2d19dd
JB
1490 }
1491
1492 if (SCM_SYMBOLP (SCM_CAR (x)))
1493 {
1494 retval:
6dbd0af5 1495 RETURN (*scm_lookupcar (x, env))
0f2d19dd
JB
1496 }
1497
1498 x = SCM_CAR (x);
1499 goto loop; /* tail recurse */
1500
1501
1502 case (127 & SCM_IM_CASE):
1503 x = SCM_CDR (x);
1504 t.arg1 = EVALCAR (x, env);
1505 while (SCM_NIMP (x = SCM_CDR (x)))
1506 {
1507 proc = SCM_CAR (x);
1508 if (scm_i_else == SCM_CAR (proc))
1509 {
1510 x = SCM_CDR (proc);
6dbd0af5 1511 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1512 goto begin;
1513 }
1514 proc = SCM_CAR (proc);
1515 while (SCM_NIMP (proc))
1516 {
1517 if (CHECK_EQVISH (SCM_CAR (proc), t.arg1))
1518 {
1519 x = SCM_CDR (SCM_CAR (x));
6dbd0af5 1520 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1521 goto begin;
1522 }
1523 proc = SCM_CDR (proc);
1524 }
1525 }
6dbd0af5 1526 RETURN (SCM_UNSPECIFIED)
0f2d19dd
JB
1527
1528
1529 case (127 & SCM_IM_COND):
1530 while (SCM_NIMP (x = SCM_CDR (x)))
1531 {
1532 proc = SCM_CAR (x);
1533 t.arg1 = EVALCAR (proc, env);
1534 if (SCM_NFALSEP (t.arg1))
1535 {
1536 x = SCM_CDR (proc);
6dbd0af5 1537 if SCM_NULLP (x)
0f2d19dd 1538 {
6dbd0af5 1539 RETURN (t.arg1)
0f2d19dd
JB
1540 }
1541 if (scm_i_arrow != SCM_CAR (x))
6dbd0af5
MD
1542 {
1543 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1544 goto begin;
1545 }
0f2d19dd
JB
1546 proc = SCM_CDR (x);
1547 proc = EVALCAR (proc, env);
1548 SCM_ASRTGO (SCM_NIMP (proc), badfun);
6dbd0af5
MD
1549 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
1550 ENTER_APPLY;
0f2d19dd
JB
1551 goto evap1;
1552 }
1553 }
6dbd0af5 1554 RETURN (SCM_UNSPECIFIED)
0f2d19dd
JB
1555
1556
1557 case (127 & SCM_IM_DO):
1558 x = SCM_CDR (x);
1559 proc = SCM_CAR (SCM_CDR (x)); /* inits */
1560 t.arg1 = SCM_EOL; /* values */
1561 while (SCM_NIMP (proc))
1562 {
1563 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
1564 proc = SCM_CDR (proc);
1565 }
e2806c10 1566 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
0f2d19dd
JB
1567 x = SCM_CDR (SCM_CDR (x));
1568 while (proc = SCM_CAR (x), SCM_FALSEP (EVALCAR (proc, env)))
1569 {
1570 for (proc = SCM_CAR (SCM_CDR (x)); SCM_NIMP (proc); proc = SCM_CDR (proc))
1571 {
1572 t.arg1 = SCM_CAR (proc); /* body */
1573 SIDEVAL (t.arg1, env);
1574 }
1575 for (t.arg1 = SCM_EOL, proc = SCM_CDR (SCM_CDR (x)); SCM_NIMP (proc); proc = SCM_CDR (proc))
1576 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1); /* steps */
e2806c10 1577 env = EXTEND_ENV (SCM_CAR (SCM_CAR (env)), t.arg1, SCM_CDR (env));
0f2d19dd
JB
1578 }
1579 x = SCM_CDR (proc);
1580 if (SCM_NULLP (x))
6dbd0af5
MD
1581 RETURN (SCM_UNSPECIFIED);
1582 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1583 goto begin;
1584
1585
1586 case (127 & SCM_IM_IF):
1587 x = SCM_CDR (x);
1588 if (SCM_NFALSEP (EVALCAR (x, env)))
1589 x = SCM_CDR (x);
1590 else if (SCM_IMP (x = SCM_CDR (SCM_CDR (x))))
1591 {
1592 RETURN (SCM_UNSPECIFIED);
1593 }
6dbd0af5 1594 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1595 goto carloop;
1596
1597
1598 case (127 & SCM_IM_LET):
1599 x = SCM_CDR (x);
1600 proc = SCM_CAR (SCM_CDR (x));
1601 t.arg1 = SCM_EOL;
1602 do
1603 {
1604 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
1605 }
1606 while (SCM_NIMP (proc = SCM_CDR (proc)));
e2806c10 1607 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
0f2d19dd 1608 x = SCM_CDR (x);
6dbd0af5 1609 goto cdrxnoap;
0f2d19dd
JB
1610
1611
1612 case (127 & SCM_IM_LETREC):
1613 x = SCM_CDR (x);
e2806c10 1614 env = EXTEND_ENV (SCM_CAR (x), scm_undefineds, env);
0f2d19dd
JB
1615 x = SCM_CDR (x);
1616 proc = SCM_CAR (x);
1617 t.arg1 = SCM_EOL;
1618 do
1619 {
1620 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
1621 }
1622 while (SCM_NIMP (proc = SCM_CDR (proc)));
a23afe53 1623 SCM_SETCDR (SCM_CAR (env), t.arg1);
6dbd0af5 1624 goto cdrxnoap;
0f2d19dd
JB
1625
1626
1627 case (127 & SCM_IM_LETSTAR):
1628 x = SCM_CDR (x);
1629 proc = SCM_CAR (x);
1630 if (SCM_IMP (proc))
1631 {
e2806c10 1632 env = EXTEND_ENV (SCM_EOL, SCM_EOL, env);
6dbd0af5 1633 goto cdrxnoap;
0f2d19dd
JB
1634 }
1635 do
1636 {
1637 t.arg1 = SCM_CAR (proc);
1638 proc = SCM_CDR (proc);
e2806c10 1639 env = EXTEND_ENV (t.arg1, EVALCAR (proc, env), env);
0f2d19dd
JB
1640 }
1641 while (SCM_NIMP (proc = SCM_CDR (proc)));
6dbd0af5 1642 goto cdrxnoap;
0f2d19dd
JB
1643
1644 case (127 & SCM_IM_OR):
1645 x = SCM_CDR (x);
1646 t.arg1 = x;
1647 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1648 {
1649 x = EVALCAR (x, env);
1650 if (SCM_NFALSEP (x))
1651 {
1652 RETURN (x);
1653 }
1654 x = t.arg1;
1655 }
6dbd0af5 1656 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1657 goto carloop;
1658
1659
1660 case (127 & SCM_IM_LAMBDA):
1661 RETURN (scm_closure (SCM_CDR (x), env));
1662
1663
1664 case (127 & SCM_IM_QUOTE):
1665 RETURN (SCM_CAR (SCM_CDR (x)));
1666
1667
1668 case (127 & SCM_IM_SET):
0f2d19dd
JB
1669 x = SCM_CDR (x);
1670 proc = SCM_CAR (x);
6dbd0af5 1671 switch (7 & (int) proc)
0f2d19dd
JB
1672 {
1673 case 0:
1674 t.lloc = scm_lookupcar (x, env);
1675 break;
1676 case 1:
a23afe53 1677 t.lloc = SCM_GLOC_VAL_LOC (proc);
0f2d19dd
JB
1678 break;
1679#ifdef MEMOIZE_LOCALS
1680 case 4:
1681 t.lloc = scm_ilookup (proc, env);
1682 break;
1683#endif
1684 }
1685 x = SCM_CDR (x);
1686 *t.lloc = EVALCAR (x, env);
0f2d19dd
JB
1687#ifdef SICP
1688 RETURN (*t.lloc);
1689#else
1690 RETURN (SCM_UNSPECIFIED);
1691#endif
1692
1693
1694 case (127 & SCM_IM_DEFINE): /* only for internal defines */
1695 x = SCM_CDR (x);
1696 proc = SCM_CAR (x);
1697 x = SCM_CDR (x);
1698 x = evalcar (x, env);
6dbd0af5 1699#ifdef DEBUG_EXTENSIONS
b7ff98dd 1700 if (SCM_REC_PROCNAMES_P && SCM_NIMP (x) && SCM_CLOSUREP (x))
6dbd0af5
MD
1701 scm_set_procedure_property_x (x, scm_i_name, proc);
1702#endif
0f2d19dd
JB
1703 env = SCM_CAR (env);
1704 SCM_DEFER_INTS;
a23afe53
MD
1705 SCM_SETCAR (env, scm_cons (proc, SCM_CAR (env)));
1706 SCM_SETCDR (env, scm_cons (x, SCM_CDR (env)));
0f2d19dd
JB
1707 SCM_ALLOW_INTS;
1708 RETURN (SCM_UNSPECIFIED);
1709
1710
0f2d19dd
JB
1711 /* new syntactic forms go here. */
1712 case (127 & SCM_MAKISYM (0)):
1713 proc = SCM_CAR (x);
1714 SCM_ASRTGO (SCM_ISYMP (proc), badfun);
1715 switch SCM_ISYMNUM (proc)
1716 {
1717#if 0
1718 case (SCM_ISYMNUM (IM_VREF)):
1719 {
1720 SCM var;
1721 var = SCM_CAR (SCM_CDR (x));
1722 RETURN (SCM_CDR(var));
1723 }
1724 case (SCM_ISYMNUM (IM_VSET)):
1725 SCM_CDR (SCM_CAR ( SCM_CDR (x))) = EVALCAR( SCM_CDR ( SCM_CDR (x)), env);
1726 SCM_CAR (SCM_CAR ( SCM_CDR (x))) = scm_tc16_variable;
6dbd0af5 1727 RETURN (SCM_UNSPECIFIED)
0f2d19dd
JB
1728#endif
1729
1730 case (SCM_ISYMNUM (SCM_IM_APPLY)):
1731 proc = SCM_CDR (x);
1732 proc = EVALCAR (proc, env);
1733 SCM_ASRTGO (SCM_NIMP (proc), badfun);
1734 if (SCM_CLOSUREP (proc))
1735 {
6dbd0af5 1736 PREP_APPLY (proc, SCM_EOL);
0f2d19dd
JB
1737 t.arg1 = SCM_CDR (SCM_CDR (x));
1738 t.arg1 = EVALCAR (t.arg1, env);
6dbd0af5
MD
1739#ifdef DEVAL
1740 debug.info->a.args = t.arg1;
1741#endif
0f2d19dd
JB
1742#ifndef RECKLESS
1743 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), t.arg1))
1744 goto wrongnumargs;
1745#endif
e2806c10 1746 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), t.arg1, SCM_ENV (proc));
0f2d19dd
JB
1747 x = SCM_CODE (proc);
1748 goto cdrxbegin;
1749 }
1750 proc = scm_i_apply;
1751 goto evapply;
1752
1753 case (SCM_ISYMNUM (SCM_IM_CONT)):
1754 scm_make_cont (&t.arg1);
c4ac4d88 1755 if (safe_setjmp (SCM_JMPBUF (t.arg1)))
0f2d19dd
JB
1756 {
1757 SCM val;
1758 val = SCM_THROW_VALUE (t.arg1);
6dbd0af5 1759 RETURN (val);
0f2d19dd
JB
1760 }
1761 proc = SCM_CDR (x);
1762 proc = evalcar (proc, env);
1763 SCM_ASRTGO (SCM_NIMP (proc), badfun);
6dbd0af5
MD
1764 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
1765 ENTER_APPLY;
0f2d19dd
JB
1766 goto evap1;
1767
1768 default:
1769 goto badfun;
1770 }
1771
1772 default:
1773 proc = x;
1774 badfun:
f5bf2977 1775 /* scm_everr (x, env,...) */
523f5266
GH
1776 scm_misc_error (NULL,
1777 "Wrong type to apply: %S",
1778 scm_listify (proc, SCM_UNDEFINED));
0f2d19dd
JB
1779 case scm_tc7_vector:
1780 case scm_tc7_wvect:
1781 case scm_tc7_bvect:
1782 case scm_tc7_byvect:
1783 case scm_tc7_svect:
1784 case scm_tc7_ivect:
1785 case scm_tc7_uvect:
1786 case scm_tc7_fvect:
1787 case scm_tc7_dvect:
1788 case scm_tc7_cvect:
1789#ifdef LONGLONGS
1790 case scm_tc7_llvect:
1791#endif
1792 case scm_tc7_string:
1793 case scm_tc7_mb_string:
1794 case scm_tc7_substring:
1795 case scm_tc7_mb_substring:
1796 case scm_tc7_smob:
1797 case scm_tcs_closures:
1798 case scm_tcs_subrs:
1799 RETURN (x);
1800
1801#ifdef MEMOIZE_LOCALS
1802 case (127 & SCM_ILOC00):
1803 proc = *scm_ilookup (SCM_CAR (x), env);
1804 SCM_ASRTGO (SCM_NIMP (proc), badfun);
1805#ifndef RECKLESS
1806#ifdef CAUTIOUS
1807 goto checkargs;
1808#endif
1809#endif
1810 break;
1811#endif /* ifdef MEMOIZE_LOCALS */
1812
1813
1814 case scm_tcs_cons_gloc:
1815 proc = SCM_GLOC_VAL (SCM_CAR (x));
1816 SCM_ASRTGO (SCM_NIMP (proc), badfun);
1817#ifndef RECKLESS
1818#ifdef CAUTIOUS
1819 goto checkargs;
1820#endif
1821#endif
1822 break;
1823
1824
1825 case scm_tcs_cons_nimcar:
1826 if (SCM_SYMBOLP (SCM_CAR (x)))
1827 {
1828 proc = *scm_lookupcar (x, env);
1829 if (SCM_IMP (proc))
1830 {
1831 unmemocar (x, env);
1832 goto badfun;
1833 }
1834 if (scm_tc16_macro == SCM_TYP16 (proc))
1835 {
1836 unmemocar (x, env);
1837
1838 handle_a_macro:
1839 t.arg1 = SCM_APPLY (SCM_CDR (proc), x, scm_cons (env, scm_listofnull));
1840 switch ((int) (SCM_CAR (proc) >> 16))
1841 {
1842 case 2:
1843 if (scm_ilength (t.arg1) <= 0)
1844 t.arg1 = scm_cons2 (SCM_IM_BEGIN, t.arg1, SCM_EOL);
6dbd0af5
MD
1845#ifdef DEVAL
1846 if (!SCM_CLOSUREP (SCM_CDR (proc)))
1847 {
1848#if 0 /* Top-level defines doesn't very often occur in backtraces */
1849 if (scm_m_define == SCM_SUBRF (SCM_CDR (proc)) && SCM_TOP_LEVEL (env))
1850 /* Prevent memoizing result of define macro */
1851 {
1852 debug.info->e.exp = scm_cons (SCM_CAR (x), SCM_CDR (x));
1853 scm_set_source_properties_x (debug.info->e.exp,
1854 scm_source_properties (x));
1855 }
1856#endif
1857 SCM_DEFER_INTS;
a23afe53
MD
1858 SCM_SETCAR (x, SCM_CAR (t.arg1));
1859 SCM_SETCDR (x, SCM_CDR (t.arg1));
6dbd0af5
MD
1860 SCM_ALLOW_INTS;
1861 goto dispatch;
1862 }
1863 /* Prevent memoizing of debug info expression. */
1864 debug.info->e.exp = scm_cons (SCM_CAR (x), SCM_CDR (x));
1865 scm_set_source_properties_x (debug.info->e.exp,
1866 scm_source_properties (x));
1867#endif
0f2d19dd 1868 SCM_DEFER_INTS;
a23afe53
MD
1869 SCM_SETCAR (x, SCM_CAR (t.arg1));
1870 SCM_SETCDR (x, SCM_CDR (t.arg1));
0f2d19dd 1871 SCM_ALLOW_INTS;
6dbd0af5 1872 goto loopnoap;
0f2d19dd
JB
1873 case 1:
1874 if (SCM_NIMP (x = t.arg1))
6dbd0af5 1875 goto loopnoap;
0f2d19dd
JB
1876 case 0:
1877 RETURN (t.arg1);
1878 }
1879 }
1880 }
1881 else
1882 proc = SCM_CEVAL (SCM_CAR (x), env);
1883 SCM_ASRTGO (SCM_NIMP (proc), badfun);
1884#ifndef RECKLESS
1885#ifdef CAUTIOUS
1886 checkargs:
1887#endif
1888 if (SCM_CLOSUREP (proc))
1889 {
1890 arg2 = SCM_CAR (SCM_CODE (proc));
1891 t.arg1 = SCM_CDR (x);
1892 while (SCM_NIMP (arg2))
1893 {
1894 if (SCM_NCONSP (arg2))
1895 goto evapply;
1896 if (SCM_IMP (t.arg1))
1897 goto umwrongnumargs;
1898 arg2 = SCM_CDR (arg2);
1899 t.arg1 = SCM_CDR (t.arg1);
1900 }
1901 if (SCM_NNULLP (t.arg1))
1902 goto umwrongnumargs;
1903 }
1904 else if (scm_tc16_macro == SCM_TYP16 (proc))
1905 goto handle_a_macro;
1906#endif
1907 }
1908
1909
6dbd0af5
MD
1910evapply:
1911 PREP_APPLY (proc, SCM_EOL);
1912 if (SCM_NULLP (SCM_CDR (x))) {
1913 ENTER_APPLY;
0f2d19dd
JB
1914 switch (SCM_TYP7 (proc))
1915 { /* no arguments given */
1916 case scm_tc7_subr_0:
1917 RETURN (SCM_SUBRF (proc) ());
1918 case scm_tc7_subr_1o:
1919 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED));
1920 case scm_tc7_lsubr:
1921 RETURN (SCM_SUBRF (proc) (SCM_EOL));
1922 case scm_tc7_rpsubr:
1923 RETURN (SCM_BOOL_T);
1924 case scm_tc7_asubr:
1925 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED));
6dbd0af5 1926#ifdef CCLO
0f2d19dd
JB
1927 case scm_tc7_cclo:
1928 t.arg1 = proc;
1929 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
1930#ifdef DEVAL
1931 debug.info->a.proc = proc;
1932 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
1933#endif
0f2d19dd 1934 goto evap1;
6dbd0af5 1935#endif
0f2d19dd
JB
1936 case scm_tcs_closures:
1937 x = SCM_CODE (proc);
e2806c10 1938 env = EXTEND_ENV (SCM_CAR (x), SCM_EOL, SCM_ENV (proc));
0f2d19dd
JB
1939 goto cdrxbegin;
1940 case scm_tc7_contin:
1941 case scm_tc7_subr_1:
1942 case scm_tc7_subr_2:
1943 case scm_tc7_subr_2o:
1944 case scm_tc7_cxr:
1945 case scm_tc7_subr_3:
1946 case scm_tc7_lsubr_2:
1947 umwrongnumargs:
1948 unmemocar (x, env);
1949 wrongnumargs:
f5bf2977
GH
1950 /* scm_everr (x, env,...) */
1951 scm_wrong_num_args (proc);
0f2d19dd
JB
1952 default:
1953 /* handle macros here */
1954 goto badfun;
1955 }
6dbd0af5 1956 }
0f2d19dd
JB
1957
1958 /* must handle macros by here */
1959 x = SCM_CDR (x);
1960#ifdef CAUTIOUS
1961 if (SCM_IMP (x))
1962 goto wrongnumargs;
1963#endif
1964 t.arg1 = EVALCAR (x, env);
6dbd0af5
MD
1965#ifdef DEVAL
1966 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
1967#endif
0f2d19dd
JB
1968 x = SCM_CDR (x);
1969 if (SCM_NULLP (x))
1970 {
6dbd0af5 1971 ENTER_APPLY;
0f2d19dd
JB
1972 evap1:
1973 switch (SCM_TYP7 (proc))
6dbd0af5 1974 { /* have one argument in t.arg1 */
0f2d19dd
JB
1975 case scm_tc7_subr_2o:
1976 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
1977 case scm_tc7_subr_1:
1978 case scm_tc7_subr_1o:
1979 RETURN (SCM_SUBRF (proc) (t.arg1));
1980 case scm_tc7_cxr:
1981#ifdef SCM_FLOATS
1982 if (SCM_SUBRF (proc))
1983 {
1984 if (SCM_INUMP (t.arg1))
1985 {
1986 RETURN (scm_makdbl (SCM_DSUBRF (proc) ((double) SCM_INUM (t.arg1)),
1987 0.0));
1988 }
1989 SCM_ASRTGO (SCM_NIMP (t.arg1), floerr);
1990 if (SCM_REALP (t.arg1))
1991 {
1992 RETURN (scm_makdbl (SCM_DSUBRF (proc) (SCM_REALPART (t.arg1)), 0.0));
1993 }
1994#ifdef SCM_BIGDIG
1995 if (SCM_BIGP (t.arg1))
1996 {
1997 RETURN (scm_makdbl (SCM_DSUBRF (proc) (scm_big2dbl (t.arg1)), 0.0));
1998 }
1999#endif
2000 floerr:
2001 scm_wta (t.arg1, (char *) SCM_ARG1, SCM_CHARS (SCM_SNAME (proc)));
2002 }
2003#endif
2004 proc = (SCM) SCM_SNAME (proc);
2005 {
2006 char *chrs = SCM_CHARS (proc) + SCM_LENGTH (proc) - 1;
2007 while ('c' != *--chrs)
2008 {
2009 SCM_ASSERT (SCM_NIMP (t.arg1) && SCM_CONSP (t.arg1),
2010 t.arg1, SCM_ARG1, SCM_CHARS (proc));
2011 t.arg1 = ('a' == *chrs) ? SCM_CAR (t.arg1) : SCM_CDR (t.arg1);
2012 }
2013 RETURN (t.arg1);
2014 }
2015 case scm_tc7_rpsubr:
2016 RETURN (SCM_BOOL_T);
2017 case scm_tc7_asubr:
2018 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
2019 case scm_tc7_lsubr:
2020#ifdef DEVAL
6dbd0af5 2021 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
0f2d19dd
JB
2022#else
2023 RETURN (SCM_SUBRF (proc) (scm_cons (t.arg1, SCM_EOL)));
2024#endif
6dbd0af5 2025#ifdef CCLO
0f2d19dd
JB
2026 case scm_tc7_cclo:
2027 arg2 = t.arg1;
2028 t.arg1 = proc;
2029 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
2030#ifdef DEVAL
2031 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
2032 debug.info->a.proc = proc;
2033#endif
0f2d19dd 2034 goto evap2;
6dbd0af5 2035#endif
0f2d19dd
JB
2036 case scm_tcs_closures:
2037 x = SCM_CODE (proc);
2038#ifdef DEVAL
e2806c10 2039 env = EXTEND_ENV (SCM_CAR (x), debug.info->a.args, SCM_ENV (proc));
0f2d19dd 2040#else
e2806c10 2041 env = EXTEND_ENV (SCM_CAR (x), scm_cons (t.arg1, SCM_EOL), SCM_ENV (proc));
0f2d19dd
JB
2042#endif
2043 goto cdrxbegin;
2044 case scm_tc7_contin:
2045 scm_call_continuation (proc, t.arg1);
2046 case scm_tc7_subr_2:
2047 case scm_tc7_subr_0:
2048 case scm_tc7_subr_3:
2049 case scm_tc7_lsubr_2:
2050 goto wrongnumargs;
2051 default:
2052 goto badfun;
2053 }
2054 }
2055#ifdef CAUTIOUS
2056 if (SCM_IMP (x))
2057 goto wrongnumargs;
2058#endif
2059 { /* have two or more arguments */
2060 arg2 = EVALCAR (x, env);
6dbd0af5
MD
2061#ifdef DEVAL
2062 debug.info->a.args = scm_cons2 (t.arg1, arg2, SCM_EOL);
2063#endif
0f2d19dd
JB
2064 x = SCM_CDR (x);
2065 if (SCM_NULLP (x)) {
6dbd0af5 2066 ENTER_APPLY;
0f2d19dd
JB
2067#ifdef CCLO
2068 evap2:
2069#endif
6dbd0af5
MD
2070 switch (SCM_TYP7 (proc))
2071 { /* have two arguments */
2072 case scm_tc7_subr_2:
2073 case scm_tc7_subr_2o:
2074 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2075 case scm_tc7_lsubr:
0f2d19dd 2076#ifdef DEVAL
6dbd0af5
MD
2077 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
2078#else
2079 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1, arg2, SCM_EOL)));
0f2d19dd 2080#endif
6dbd0af5
MD
2081 case scm_tc7_lsubr_2:
2082 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, SCM_EOL));
2083 case scm_tc7_rpsubr:
2084 case scm_tc7_asubr:
2085 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2086#ifdef CCLO
2087 cclon:
2088 case scm_tc7_cclo:
0f2d19dd 2089#ifdef DEVAL
6dbd0af5
MD
2090 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc), proc,
2091 scm_cons (debug.info->a.args, SCM_EOL)));
0f2d19dd 2092#else
6dbd0af5
MD
2093 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc), proc,
2094 scm_cons2 (t.arg1, arg2,
2095 scm_cons (scm_eval_args (x, env), SCM_EOL))));
0f2d19dd 2096#endif
6dbd0af5
MD
2097 /* case scm_tc7_cclo:
2098 x = scm_cons(arg2, scm_eval_args(x, env));
2099 arg2 = t.arg1;
2100 t.arg1 = proc;
2101 proc = SCM_CCLO_SUBR(proc);
2102 goto evap3; */
2103#endif
2104 case scm_tc7_subr_0:
2105 case scm_tc7_cxr:
2106 case scm_tc7_subr_1o:
2107 case scm_tc7_subr_1:
2108 case scm_tc7_subr_3:
2109 case scm_tc7_contin:
2110 goto wrongnumargs;
2111 default:
2112 goto badfun;
2113 case scm_tcs_closures:
0f2d19dd 2114#ifdef DEVAL
e2806c10 2115 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), debug.info->a.args, SCM_ENV (proc));
0f2d19dd 2116#else
e2806c10 2117 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), scm_cons2 (t.arg1, arg2, SCM_EOL), SCM_ENV (proc));
0f2d19dd 2118#endif
6dbd0af5
MD
2119 x = SCM_CODE (proc);
2120 goto cdrxbegin;
2121 }
0f2d19dd
JB
2122 }
2123#ifdef DEVAL
6dbd0af5 2124 debug.info->a.args = scm_cons2 (t.arg1, arg2,
a23afe53 2125 scm_deval_args (x, env, SCM_CDRLOC (SCM_CDR (debug.info->a.args))));
0f2d19dd 2126#endif
6dbd0af5
MD
2127 ENTER_APPLY;
2128 switch (SCM_TYP7 (proc))
2129 { /* have 3 or more arguments */
0f2d19dd 2130#ifdef DEVAL
6dbd0af5
MD
2131 case scm_tc7_subr_3:
2132 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
2133 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, SCM_CAR (SCM_CDR (SCM_CDR (debug.info->a.args)))));
2134 case scm_tc7_asubr:
2135 /* t.arg1 = SCM_SUBRF(proc)(t.arg1, arg2);
2136 while SCM_NIMP(x) {
2137 t.arg1 = SCM_SUBRF(proc)(t.arg1, EVALCAR(x, env));
2138 x = SCM_CDR(x);
2139 }
2140 RETURN (t.arg1) */
2141 case scm_tc7_rpsubr:
2142 RETURN (SCM_APPLY (proc, t.arg1, scm_acons (arg2, SCM_CDR (SCM_CDR (debug.info->a.args)), SCM_EOL)))
2143 case scm_tc7_lsubr_2:
2144 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, SCM_CDR (SCM_CDR (debug.info->a.args))))
2145 case scm_tc7_lsubr:
2146 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
0f2d19dd 2147#ifdef CCLO
6dbd0af5
MD
2148 case scm_tc7_cclo:
2149 goto cclon;
0f2d19dd 2150#endif
6dbd0af5 2151 case scm_tcs_closures:
b7ff98dd 2152 SCM_SET_ARGSREADY (debug);
e2806c10 2153 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
6dbd0af5
MD
2154 debug.info->a.args,
2155 SCM_ENV (proc));
2156 x = SCM_CODE (proc);
2157 goto cdrxbegin;
2158#else /* DEVAL */
2159 case scm_tc7_subr_3:
2160 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
2161 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, EVALCAR (x, env)));
2162 case scm_tc7_asubr:
2163 /* t.arg1 = SCM_SUBRF(proc)(t.arg1, arg2);
2164 while SCM_NIMP(x) {
2165 t.arg1 = SCM_SUBRF(proc)(t.arg1, EVALCAR(x, env));
2166 x = SCM_CDR(x);
2167 }
2168 RETURN (t.arg1) */
2169 case scm_tc7_rpsubr:
2170 RETURN (SCM_APPLY (proc, t.arg1, scm_acons (arg2, scm_eval_args (x, env), SCM_EOL)));
2171 case scm_tc7_lsubr_2:
2172 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, scm_eval_args (x, env)));
2173 case scm_tc7_lsubr:
2174 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1, arg2, scm_eval_args (x, env))));
0f2d19dd 2175#ifdef CCLO
6dbd0af5
MD
2176 case scm_tc7_cclo:
2177 goto cclon;
0f2d19dd 2178#endif
6dbd0af5
MD
2179 case scm_tcs_closures:
2180#ifdef DEVAL
b7ff98dd 2181 SCM_SET_ARGSREADY (debug);
6dbd0af5 2182#endif
e2806c10 2183 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
6dbd0af5
MD
2184 scm_cons2 (t.arg1, arg2, scm_eval_args (x, env)),
2185 SCM_ENV (proc));
2186 x = SCM_CODE (proc);
2187 goto cdrxbegin;
0f2d19dd 2188#endif /* DEVAL */
6dbd0af5
MD
2189 case scm_tc7_subr_2:
2190 case scm_tc7_subr_1o:
2191 case scm_tc7_subr_2o:
2192 case scm_tc7_subr_0:
2193 case scm_tc7_cxr:
2194 case scm_tc7_subr_1:
2195 case scm_tc7_contin:
2196 goto wrongnumargs;
2197 default:
2198 goto badfun;
2199 }
0f2d19dd
JB
2200 }
2201#ifdef DEVAL
6dbd0af5
MD
2202exit:
2203 if (CHECK_EXIT)
b7ff98dd 2204 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 2205 {
b7ff98dd
MD
2206 SCM_EXIT_FRAME_P = 0;
2207 SCM_RESET_DEBUG_MODE;
2208 SCM_CLEAR_TRACED_FRAME (debug);
2209 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 2210 t.arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
2211 else
2212 {
2213 scm_make_cont (&t.arg1);
c4ac4d88 2214 if (safe_setjmp (SCM_JMPBUF (t.arg1)))
6dbd0af5
MD
2215 {
2216 proc = SCM_THROW_VALUE (t.arg1);
2217 goto ret;
2218 }
2219 }
2220 scm_ithrow (scm_i_exit_frame, scm_cons2 (t.arg1, proc, SCM_EOL), 0);
2221 }
2222ret:
1646d37b 2223 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
2224 return proc;
2225#endif
2226}
2227
6dbd0af5
MD
2228
2229/* SECTION: This code is compiled once.
2230 */
2231
0f2d19dd
JB
2232#ifndef DEVAL
2233
2234SCM_PROC(s_procedure_documentation, "procedure-documentation", 1, 0, 0, scm_procedure_documentation);
1cc91f1b 2235
0f2d19dd
JB
2236SCM
2237scm_procedure_documentation (proc)
2238 SCM proc;
0f2d19dd
JB
2239{
2240 SCM code;
2241 SCM_ASSERT (SCM_BOOL_T == scm_procedure_p (proc) && SCM_NIMP (proc) && SCM_TYP7 (proc) != scm_tc7_contin,
2242 proc, SCM_ARG1, s_procedure_documentation);
2243 switch (SCM_TYP7 (proc))
2244 {
2245 case scm_tcs_closures:
2246 code = SCM_CDR (SCM_CODE (proc));
2247 if (SCM_IMP (SCM_CDR (code)))
2248 return SCM_BOOL_F;
2249 code = SCM_CAR (code);
2250 if (SCM_IMP (code))
2251 return SCM_BOOL_F;
2252 if (SCM_STRINGP (code))
2253 return code;
2254 default:
2255 return SCM_BOOL_F;
2256/*
2257 case scm_tcs_subrs:
2258#ifdef CCLO
2259 case scm_tc7_cclo:
2260#endif
2261*/
2262 }
2263}
2264
b145c172
JB
2265/* This code processes the 'arg ...' parameters to apply.
2266
2267 (apply PROC ARG1 ... ARGS)
2268
2269 The ARG1 ... arguments are consed on to the front of ARGS (which
2270 must be a list), and then PROC is applied to the elements of the
2271 result. apply:nconc2last takes care of building the list of
2272 arguments, given (ARG1 ... ARGS).
2273
2274 apply:nconc2last destroys its argument. On that topic, this code
2275 came into my care with the following beautifully cryptic comment on
2276 that topic: "This will only screw you if you do (scm_apply
2277 scm_apply '( ... ))" If you know what they're referring to, send
2278 me a patch to this comment. */
2279
0f2d19dd 2280SCM_PROC(s_nconc2last, "apply:nconc2last", 1, 0, 0, scm_nconc2last);
1cc91f1b 2281
0f2d19dd
JB
2282SCM
2283scm_nconc2last (lst)
2284 SCM lst;
0f2d19dd
JB
2285{
2286 SCM *lloc;
b145c172 2287 SCM_ASSERT (scm_ilength (lst) > 0, lst, SCM_ARG1, s_nconc2last);
0f2d19dd
JB
2288 lloc = &lst;
2289 while (SCM_NNULLP (SCM_CDR (*lloc)))
a23afe53 2290 lloc = SCM_CDRLOC (*lloc);
b145c172 2291 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, s_nconc2last);
0f2d19dd
JB
2292 *lloc = SCM_CAR (*lloc);
2293 return lst;
2294}
2295
2296#endif /* !DEVAL */
2297
6dbd0af5
MD
2298
2299/* SECTION: When DEVAL is defined this code yields scm_dapply.
2300 * It is compiled twice.
2301 */
2302
0f2d19dd 2303#if 0
1cc91f1b 2304
0f2d19dd
JB
2305SCM
2306scm_apply (proc, arg1, args)
2307 SCM proc;
2308 SCM arg1;
2309 SCM args;
0f2d19dd
JB
2310{}
2311#endif
2312
2313#if 0
1cc91f1b 2314
0f2d19dd
JB
2315SCM
2316scm_dapply (proc, arg1, args)
2317 SCM proc;
2318 SCM arg1;
2319 SCM args;
0f2d19dd
JB
2320{}
2321#endif
2322
1cc91f1b 2323
0f2d19dd
JB
2324SCM
2325SCM_APPLY (proc, arg1, args)
2326 SCM proc;
2327 SCM arg1;
2328 SCM args;
0f2d19dd
JB
2329{
2330#ifdef DEBUG_EXTENSIONS
2331#ifdef DEVAL
6dbd0af5 2332 scm_debug_frame debug;
c0ab1b8d 2333 scm_debug_info debug_vect_body;
1646d37b 2334 debug.prev = scm_last_debug_frame;
b7ff98dd 2335 debug.status = SCM_APPLYFRAME;
c0ab1b8d 2336 debug.vect = &debug_vect_body;
6dbd0af5
MD
2337 debug.vect[0].a.proc = proc;
2338 debug.vect[0].a.args = SCM_EOL;
1646d37b 2339 scm_last_debug_frame = &debug;
0f2d19dd 2340#else
b7ff98dd 2341 if (SCM_DEBUGGINGP)
0f2d19dd
JB
2342 return scm_dapply (proc, arg1, args);
2343#endif
2344#endif
2345
2346 SCM_ASRTGO (SCM_NIMP (proc), badproc);
2347 if (SCM_NULLP (args))
2348 {
2349 if (SCM_NULLP (arg1))
2350 arg1 = SCM_UNDEFINED;
2351 else
2352 {
2353 args = SCM_CDR (arg1);
2354 arg1 = SCM_CAR (arg1);
2355 }
2356 }
2357 else
2358 {
2359 /* SCM_ASRTGO(SCM_NIMP(args) && SCM_CONSP(args), wrongnumargs); */
2360 args = scm_nconc2last (args);
2361 }
0f2d19dd 2362#ifdef DEVAL
6dbd0af5 2363 debug.vect[0].a.args = scm_cons (arg1, args);
b7ff98dd 2364 if (SCM_ENTER_FRAME_P)
6dbd0af5
MD
2365 {
2366 SCM tmp;
b7ff98dd
MD
2367 SCM_ENTER_FRAME_P = 0;
2368 SCM_RESET_DEBUG_MODE;
2369 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 2370 tmp = scm_make_debugobj (&debug);
6dbd0af5
MD
2371 else
2372 {
2373 scm_make_cont (&tmp);
c4ac4d88 2374 if (safe_setjmp (SCM_JMPBUF (tmp)))
6dbd0af5
MD
2375 goto entap;
2376 }
2377 scm_ithrow (scm_i_enter_frame, scm_cons (tmp, SCM_EOL), 0);
2378 }
2379entap:
2380 ENTER_APPLY;
2381#endif
2382#ifdef CCLO
2383tail:
0f2d19dd
JB
2384#endif
2385 switch (SCM_TYP7 (proc))
2386 {
2387 case scm_tc7_subr_2o:
2388 args = SCM_NULLP (args) ? SCM_UNDEFINED : SCM_CAR (args);
2389 RETURN (SCM_SUBRF (proc) (arg1, args))
2390 case scm_tc7_subr_2:
2391 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args)), wrongnumargs);
2392 args = SCM_CAR (args);
2393 RETURN (SCM_SUBRF (proc) (arg1, args))
2394 case scm_tc7_subr_0:
2395 SCM_ASRTGO (SCM_UNBNDP (arg1), wrongnumargs);
2396 RETURN (SCM_SUBRF (proc) ())
2397 case scm_tc7_subr_1:
2398 case scm_tc7_subr_1o:
2399 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
2400 RETURN (SCM_SUBRF (proc) (arg1))
2401 case scm_tc7_cxr:
2402 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
2403#ifdef SCM_FLOATS
2404 if (SCM_SUBRF (proc))
2405 {
6dbd0af5
MD
2406 if (SCM_INUMP (arg1))
2407 {
2408 RETURN (scm_makdbl (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1)), 0.0));
2409 }
0f2d19dd 2410 SCM_ASRTGO (SCM_NIMP (arg1), floerr);
6dbd0af5
MD
2411 if (SCM_REALP (arg1))
2412 {
2413 RETURN (scm_makdbl (SCM_DSUBRF (proc) (SCM_REALPART (arg1)), 0.0));
2414 }
0f2d19dd
JB
2415#ifdef SCM_BIGDIG
2416 if SCM_BIGP
2417 (arg1)
2418 RETURN (scm_makdbl (SCM_DSUBRF (proc) (scm_big2dbl (arg1)), 0.0))
2419#endif
2420 floerr:
2421 scm_wta (arg1, (char *) SCM_ARG1, SCM_CHARS (SCM_SNAME (proc)));
2422 }
2423#endif
2424 proc = (SCM) SCM_SNAME (proc);
2425 {
2426 char *chrs = SCM_CHARS (proc) + SCM_LENGTH (proc) - 1;
2427 while ('c' != *--chrs)
2428 {
2429 SCM_ASSERT (SCM_NIMP (arg1) && SCM_CONSP (arg1),
2430 arg1, SCM_ARG1, SCM_CHARS (proc));
2431 arg1 = ('a' == *chrs) ? SCM_CAR (arg1) : SCM_CDR (arg1);
2432 }
2433 RETURN (arg1)
2434 }
2435 case scm_tc7_subr_3:
2436 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CAR (SCM_CDR (args))))
2437 case scm_tc7_lsubr:
2438#ifdef DEVAL
6dbd0af5 2439 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args))
0f2d19dd
JB
2440#else
2441 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args)))
2442#endif
2443 case scm_tc7_lsubr_2:
2444 SCM_ASRTGO (SCM_NIMP (args) && SCM_CONSP (args), wrongnumargs);
2445 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CDR (args)))
2446 case scm_tc7_asubr:
2447 if (SCM_NULLP (args))
2448 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED))
2449 while (SCM_NIMP (args))
2450 {
2451 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
2452 arg1 = SCM_SUBRF (proc) (arg1, SCM_CAR (args));
2453 args = SCM_CDR (args);
2454 }
2455 RETURN (arg1);
2456 case scm_tc7_rpsubr:
2457 if (SCM_NULLP (args))
2458 RETURN (SCM_BOOL_T);
2459 while (SCM_NIMP (args))
2460 {
2461 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
2462 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, SCM_CAR (args))))
2463 RETURN (SCM_BOOL_F);
2464 arg1 = SCM_CAR (args);
2465 args = SCM_CDR (args);
2466 }
2467 RETURN (SCM_BOOL_T);
2468 case scm_tcs_closures:
2469#ifdef DEVAL
6dbd0af5 2470 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args);
0f2d19dd
JB
2471#else
2472 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args));
2473#endif
2474#ifndef RECKLESS
2475 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), arg1))
2476 goto wrongnumargs;
2477#endif
e2806c10 2478 args = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), arg1, SCM_ENV (proc));
0f2d19dd
JB
2479 proc = SCM_CODE (proc);
2480 while (SCM_NNULLP (proc = SCM_CDR (proc)))
2481 arg1 = EVALCAR (proc, args);
2482 RETURN (arg1);
2483 case scm_tc7_contin:
2484 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
2485 scm_call_continuation (proc, arg1);
2486#ifdef CCLO
2487 case scm_tc7_cclo:
2488#ifdef DEVAL
6dbd0af5
MD
2489 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
2490 arg1 = proc;
2491 proc = SCM_CCLO_SUBR (proc);
2492 debug.vect[0].a.proc = proc;
2493 debug.vect[0].a.args = scm_cons (arg1, args);
0f2d19dd
JB
2494#else
2495 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
0f2d19dd
JB
2496 arg1 = proc;
2497 proc = SCM_CCLO_SUBR (proc);
6dbd0af5 2498#endif
0f2d19dd
JB
2499 goto tail;
2500#endif
2501 wrongnumargs:
f5bf2977 2502 scm_wrong_num_args (proc);
0f2d19dd
JB
2503 default:
2504 badproc:
2505 scm_wta (proc, (char *) SCM_ARG1, "apply");
2506 RETURN (arg1);
2507 }
2508#ifdef DEVAL
6dbd0af5
MD
2509exit:
2510 if (CHECK_EXIT)
b7ff98dd 2511 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 2512 {
b7ff98dd
MD
2513 SCM_EXIT_FRAME_P = 0;
2514 SCM_RESET_DEBUG_MODE;
2515 SCM_CLEAR_TRACED_FRAME (debug);
2516 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 2517 arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
2518 else
2519 {
2520 scm_make_cont (&arg1);
c4ac4d88 2521 if (safe_setjmp (SCM_JMPBUF (arg1)))
6dbd0af5
MD
2522 {
2523 proc = SCM_THROW_VALUE (arg1);
2524 goto ret;
2525 }
2526 }
2527 scm_ithrow (scm_i_exit_frame, scm_cons2 (arg1, proc, SCM_EOL), 0);
2528 }
2529ret:
1646d37b 2530 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
2531 return proc;
2532#endif
2533}
2534
6dbd0af5
MD
2535
2536/* SECTION: The rest of this file is only read once.
2537 */
2538
0f2d19dd
JB
2539#ifndef DEVAL
2540
2541SCM_PROC(s_map, "map", 2, 0, 1, scm_map);
1cc91f1b 2542
0f2d19dd
JB
2543SCM
2544scm_map (proc, arg1, args)
2545 SCM proc;
2546 SCM arg1;
2547 SCM args;
0f2d19dd
JB
2548{
2549 long i;
2550 SCM res = SCM_EOL;
2551 SCM *pres = &res;
2552 SCM *ve = &args; /* Keep args from being optimized away. */
2553
2554 if (SCM_NULLP (arg1))
2555 return res;
2556 SCM_ASSERT (SCM_NIMP (arg1), arg1, SCM_ARG2, s_map);
2557 if (SCM_NULLP (args))
2558 {
2559 while (SCM_NIMP (arg1))
2560 {
2561 SCM_ASSERT (SCM_CONSP (arg1), arg1, SCM_ARG2, s_map);
2562 *pres = scm_cons (scm_apply (proc, SCM_CAR (arg1), scm_listofnull), SCM_EOL);
a23afe53 2563 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
2564 arg1 = SCM_CDR (arg1);
2565 }
2566 return res;
2567 }
2568 args = scm_vector (scm_cons (arg1, args));
2569 ve = SCM_VELTS (args);
2570#ifndef RECKLESS
2571 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
2572 SCM_ASSERT (SCM_NIMP (ve[i]) && SCM_CONSP (ve[i]), args, SCM_ARG2, s_map);
2573#endif
2574 while (1)
2575 {
2576 arg1 = SCM_EOL;
2577 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
2578 {
2579 if SCM_IMP
2580 (ve[i]) return res;
2581 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
2582 ve[i] = SCM_CDR (ve[i]);
2583 }
2584 *pres = scm_cons (scm_apply (proc, arg1, SCM_EOL), SCM_EOL);
a23afe53 2585 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
2586 }
2587}
2588
2589
2590SCM_PROC(s_for_each, "for-each", 2, 0, 1, scm_for_each);
1cc91f1b 2591
0f2d19dd
JB
2592SCM
2593scm_for_each (proc, arg1, args)
2594 SCM proc;
2595 SCM arg1;
2596 SCM args;
0f2d19dd
JB
2597{
2598 SCM *ve = &args; /* Keep args from being optimized away. */
2599 long i;
2600 if SCM_NULLP (arg1)
2601 return SCM_UNSPECIFIED;
2602 SCM_ASSERT (SCM_NIMP (arg1), arg1, SCM_ARG2, s_for_each);
2603 if SCM_NULLP (args)
2604 {
2605 while SCM_NIMP (arg1)
2606 {
2607 SCM_ASSERT (SCM_CONSP (arg1), arg1, SCM_ARG2, s_for_each);
2608 scm_apply (proc, SCM_CAR (arg1), scm_listofnull);
2609 arg1 = SCM_CDR (arg1);
2610 }
2611 return SCM_UNSPECIFIED;
2612 }
2613 args = scm_vector (scm_cons (arg1, args));
2614 ve = SCM_VELTS (args);
2615#ifndef RECKLESS
2616 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
2617 SCM_ASSERT (SCM_NIMP (ve[i]) && SCM_CONSP (ve[i]), args, SCM_ARG2, s_for_each);
2618#endif
2619 while (1)
2620 {
2621 arg1 = SCM_EOL;
2622 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
2623 {
2624 if SCM_IMP
2625 (ve[i]) return SCM_UNSPECIFIED;
2626 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
2627 ve[i] = SCM_CDR (ve[i]);
2628 }
2629 scm_apply (proc, arg1, SCM_EOL);
2630 }
2631}
2632
2633
1cc91f1b 2634
0f2d19dd
JB
2635SCM
2636scm_closure (code, env)
2637 SCM code;
2638 SCM env;
0f2d19dd
JB
2639{
2640 register SCM z;
2641 SCM_NEWCELL (z);
2642 SCM_SETCODE (z, code);
a23afe53 2643 SCM_SETENV (z, env);
0f2d19dd
JB
2644 return z;
2645}
2646
2647
2648long scm_tc16_promise;
1cc91f1b 2649
0f2d19dd
JB
2650SCM
2651scm_makprom (code)
2652 SCM code;
0f2d19dd
JB
2653{
2654 register SCM z;
2655 SCM_NEWCELL (z);
a23afe53
MD
2656 SCM_SETCDR (z, code);
2657 SCM_SETCAR (z, scm_tc16_promise);
0f2d19dd
JB
2658 return z;
2659}
2660
2661
1cc91f1b
JB
2662
2663static int prinprom SCM_P ((SCM exp, SCM port, scm_print_state *pstate));
2664
0f2d19dd 2665static int
19402679 2666prinprom (exp, port, pstate)
0f2d19dd
JB
2667 SCM exp;
2668 SCM port;
19402679 2669 scm_print_state *pstate;
0f2d19dd 2670{
19402679 2671 int writingp = SCM_WRITINGP (pstate);
0f2d19dd 2672 scm_gen_puts (scm_regular_string, "#<promise ", port);
19402679
MD
2673 SCM_SET_WRITINGP (pstate, 1);
2674 scm_iprin1 (SCM_CDR (exp), port, pstate);
2675 SCM_SET_WRITINGP (pstate, writingp);
0f2d19dd
JB
2676 scm_gen_putc ('>', port);
2677 return !0;
2678}
2679
2680
2681SCM_PROC(s_makacro, "procedure->syntax", 1, 0, 0, scm_makacro);
1cc91f1b 2682
0f2d19dd
JB
2683SCM
2684scm_makacro (code)
2685 SCM code;
0f2d19dd
JB
2686{
2687 register SCM z;
2688 SCM_NEWCELL (z);
a23afe53
MD
2689 SCM_SETCDR (z, code);
2690 SCM_SETCAR (z, scm_tc16_macro);
0f2d19dd
JB
2691 return z;
2692}
2693
2694
2695SCM_PROC(s_makmacro, "procedure->macro", 1, 0, 0, scm_makmacro);
1cc91f1b 2696
0f2d19dd
JB
2697SCM
2698scm_makmacro (code)
2699 SCM code;
0f2d19dd
JB
2700{
2701 register SCM z;
2702 SCM_NEWCELL (z);
a23afe53
MD
2703 SCM_SETCDR (z, code);
2704 SCM_SETCAR (z, scm_tc16_macro | (1L << 16));
0f2d19dd
JB
2705 return z;
2706}
2707
2708
2709SCM_PROC(s_makmmacro, "procedure->memoizing-macro", 1, 0, 0, scm_makmmacro);
1cc91f1b 2710
0f2d19dd
JB
2711SCM
2712scm_makmmacro (code)
2713 SCM code;
0f2d19dd
JB
2714{
2715 register SCM z;
2716 SCM_NEWCELL (z);
a23afe53
MD
2717 SCM_SETCDR (z, code);
2718 SCM_SETCAR (z, scm_tc16_macro | (2L << 16));
0f2d19dd
JB
2719 return z;
2720}
2721
2722
1cc91f1b
JB
2723
2724static int prinmacro SCM_P ((SCM exp, SCM port, scm_print_state *pstate));
2725
0f2d19dd 2726static int
19402679 2727prinmacro (exp, port, pstate)
0f2d19dd
JB
2728 SCM exp;
2729 SCM port;
19402679 2730 scm_print_state *pstate;
0f2d19dd 2731{
19402679 2732 int writingp = SCM_WRITINGP (pstate);
0f2d19dd
JB
2733 if (SCM_CAR (exp) & (3L << 16))
2734 scm_gen_puts (scm_regular_string, "#<macro", port);
2735 else
2736 scm_gen_puts (scm_regular_string, "#<syntax", port);
2737 if (SCM_CAR (exp) & (2L << 16))
2738 scm_gen_putc ('!', port);
2739 scm_gen_putc (' ', port);
19402679
MD
2740 SCM_SET_WRITINGP (pstate, 1);
2741 scm_iprin1 (SCM_CDR (exp), port, pstate);
2742 SCM_SET_WRITINGP (pstate, writingp);
0f2d19dd
JB
2743 scm_gen_putc ('>', port);
2744 return !0;
2745}
2746
2747SCM_PROC(s_force, "force", 1, 0, 0, scm_force);
1cc91f1b 2748
0f2d19dd
JB
2749SCM
2750scm_force (x)
2751 SCM x;
0f2d19dd
JB
2752{
2753 SCM_ASSERT ((SCM_TYP16 (x) == scm_tc16_promise), x, SCM_ARG1, s_force);
2754 if (!((1L << 16) & SCM_CAR (x)))
2755 {
2756 SCM ans = scm_apply (SCM_CDR (x), SCM_EOL, SCM_EOL);
2757 if (!((1L << 16) & SCM_CAR (x)))
2758 {
2759 SCM_DEFER_INTS;
a23afe53
MD
2760 SCM_SETCDR (x, ans);
2761 SCM_SETOR_CAR (x, (1L << 16));
0f2d19dd
JB
2762 SCM_ALLOW_INTS;
2763 }
2764 }
2765 return SCM_CDR (x);
2766}
2767
2768SCM_PROC (s_promise_p, "promise?", 1, 0, 0, scm_promise_p);
1cc91f1b 2769
0f2d19dd
JB
2770SCM
2771scm_promise_p (x)
2772 SCM x;
0f2d19dd
JB
2773{
2774 return ((SCM_NIMP (x) && (SCM_TYP16 (x) == scm_tc16_promise))
2775 ? SCM_BOOL_T
2776 : SCM_BOOL_F);
2777}
2778
2779SCM_PROC(s_copy_tree, "copy-tree", 1, 0, 0, scm_copy_tree);
1cc91f1b 2780
0f2d19dd
JB
2781SCM
2782scm_copy_tree (obj)
2783 SCM obj;
0f2d19dd
JB
2784{
2785 SCM ans, tl;
2786 if SCM_IMP
2787 (obj) return obj;
2788 if (SCM_VECTORP (obj))
2789 {
2790 scm_sizet i = SCM_LENGTH (obj);
2791 ans = scm_make_vector (SCM_MAKINUM (i), SCM_UNSPECIFIED, SCM_UNDEFINED);
2792 while (i--)
2793 SCM_VELTS (ans)[i] = scm_copy_tree (SCM_VELTS (obj)[i]);
2794 return ans;
2795 }
2796 if SCM_NCONSP (obj)
2797 return obj;
2798/* return scm_cons(scm_copy_tree(SCM_CAR(obj)), scm_copy_tree(SCM_CDR(obj))); */
2799 ans = tl = scm_cons (scm_copy_tree (SCM_CAR (obj)), SCM_UNSPECIFIED);
2800 while (SCM_NIMP (obj = SCM_CDR (obj)) && SCM_CONSP (obj))
a23afe53
MD
2801 {
2802 SCM_SETCDR (tl, scm_cons (scm_copy_tree (SCM_CAR (obj)),
2803 SCM_UNSPECIFIED));
2804 tl = SCM_CDR (tl);
2805 }
2806 SCM_SETCDR (tl, obj);
0f2d19dd
JB
2807 return ans;
2808}
2809
1cc91f1b 2810
0f2d19dd
JB
2811SCM
2812scm_eval_3 (obj, copyp, env)
2813 SCM obj;
2814 int copyp;
2815 SCM env;
0f2d19dd
JB
2816{
2817 if (SCM_NIMP (SCM_CDR (scm_system_transformer)))
2818 obj = scm_apply (SCM_CDR (scm_system_transformer), obj, scm_listofnull);
2819 else if (copyp)
2820 obj = scm_copy_tree (obj);
6dbd0af5 2821 return XEVAL (obj, env);
0f2d19dd
JB
2822}
2823
1cc91f1b 2824
0f2d19dd
JB
2825SCM
2826scm_top_level_env (thunk)
2827 SCM thunk;
0f2d19dd
JB
2828{
2829 if (SCM_IMP(thunk))
2830 return SCM_EOL;
2831 else
2832 return scm_cons(thunk, (SCM)SCM_EOL);
2833}
2834
2835SCM_PROC(s_eval2, "eval2", 2, 0, 0, scm_eval2);
1cc91f1b 2836
0f2d19dd
JB
2837SCM
2838scm_eval2 (obj, env_thunk)
2839 SCM obj;
2840 SCM env_thunk;
0f2d19dd
JB
2841{
2842 return scm_eval_3 (obj, 1, scm_top_level_env(env_thunk));
2843}
2844
2845SCM_PROC(s_eval, "eval", 1, 0, 0, scm_eval);
1cc91f1b 2846
0f2d19dd
JB
2847SCM
2848scm_eval (obj)
2849 SCM obj;
0f2d19dd
JB
2850{
2851 return
dc19d1d2 2852 scm_eval_3(obj, 1, scm_top_level_env(SCM_CDR(scm_top_level_lookup_closure_var)));
0f2d19dd
JB
2853}
2854
11f77bfc 2855/* SCM_PROC(s_eval_x, "eval!", 1, 0, 0, scm_eval_x); */
1cc91f1b 2856
0f2d19dd
JB
2857SCM
2858scm_eval_x (obj)
2859 SCM obj;
0f2d19dd
JB
2860{
2861 return
2862 scm_eval_3(obj,
2863 0,
dc19d1d2 2864 scm_top_level_env (SCM_CDR (scm_top_level_lookup_closure_var)));
0f2d19dd
JB
2865}
2866
2867SCM_PROC (s_macro_eval_x, "macro-eval!", 2, 0, 0, scm_macro_eval_x);
1cc91f1b 2868
0f2d19dd
JB
2869SCM
2870scm_macro_eval_x (exp, env)
2871 SCM exp;
2872 SCM env;
0f2d19dd
JB
2873{
2874 return scm_eval_3 (exp, 0, env);
2875}
2876
1cc91f1b 2877
ee33f8fa
MV
2878SCM_PROC (s_definedp, "defined?", 1, 0, 0, scm_definedp);
2879
0f2d19dd 2880SCM
ee33f8fa
MV
2881scm_definedp (sym)
2882 SCM sym;
0f2d19dd 2883{
ee33f8fa
MV
2884 SCM vcell;
2885
2886 if (SCM_ISYMP (sym))
0f2d19dd 2887 return SCM_BOOL_T;
ee33f8fa
MV
2888
2889 SCM_ASSERT (SCM_NIMP (sym) && SCM_SYMBOLP (sym), sym, SCM_ARG1, s_definedp);
2890
2891 vcell = scm_sym2vcell(sym,
0aa1e432 2892 SCM_CDR (scm_top_level_lookup_closure_var),
ee33f8fa
MV
2893 SCM_BOOL_F);
2894 return (vcell == SCM_BOOL_F || SCM_UNBNDP(SCM_CDR(vcell))) ?
2895 SCM_BOOL_F : SCM_BOOL_T;
0f2d19dd
JB
2896}
2897
2898static scm_smobfuns promsmob =
2899{scm_markcdr, scm_free0, prinprom};
2900
2901static scm_smobfuns macrosmob =
2902{scm_markcdr, scm_free0, prinmacro};
2903
1cc91f1b 2904
0f2d19dd
JB
2905SCM
2906scm_make_synt (name, macroizer, fcn)
2907 char *name;
2908 SCM (*macroizer) ();
2909 SCM (*fcn) ();
0f2d19dd
JB
2910{
2911 SCM symcell = scm_sysintern (name, SCM_UNDEFINED);
2912 long tmp = ((((SCM_CELLPTR) (SCM_CAR (symcell))) - scm_heap_org) << 8);
2913 register SCM z;
2914 if ((tmp >> 8) != ((SCM_CELLPTR) (SCM_CAR (symcell)) - scm_heap_org))
2915 tmp = 0;
2916 SCM_NEWCELL (z);
2917 SCM_SUBRF (z) = fcn;
a23afe53
MD
2918 SCM_SETCAR (z, tmp + scm_tc7_subr_2);
2919 SCM_SETCDR (symcell, macroizer (z));
0f2d19dd
JB
2920 return SCM_CAR (symcell);
2921}
2922
6dbd0af5
MD
2923
2924/* At this point, scm_deval and scm_dapply are generated.
2925 */
2926
0f2d19dd 2927#ifdef DEBUG_EXTENSIONS
6dbd0af5
MD
2928# define DEVAL
2929# include "eval.c"
0f2d19dd
JB
2930#endif
2931
2932
1cc91f1b 2933
0f2d19dd
JB
2934void
2935scm_init_eval ()
0f2d19dd 2936{
0f2d19dd
JB
2937 scm_tc16_promise = scm_newsmob (&promsmob);
2938 scm_tc16_macro = scm_newsmob (&macrosmob);
2939 scm_i_apply = scm_make_subr ("apply", scm_tc7_lsubr_2, scm_apply);
2940 scm_system_transformer = scm_sysintern ("scm:eval-transformer", SCM_UNDEFINED);
2941 scm_i_dot = SCM_CAR (scm_sysintern (".", SCM_UNDEFINED));
2942 scm_i_arrow = SCM_CAR (scm_sysintern ("=>", SCM_UNDEFINED));
2943 scm_i_else = SCM_CAR (scm_sysintern ("else", SCM_UNDEFINED));
2944 scm_i_unquote = SCM_CAR (scm_sysintern ("unquote", SCM_UNDEFINED));
2945 scm_i_uq_splicing = SCM_CAR (scm_sysintern ("unquote-splicing", SCM_UNDEFINED));
2946
2947 /* acros */
2948 scm_i_quasiquote = scm_make_synt (s_quasiquote, scm_makacro, scm_m_quasiquote);
6dbd0af5 2949 scm_make_synt (s_undefine, scm_makacro, scm_m_undefine);
0f2d19dd
JB
2950 scm_make_synt (s_delay, scm_makacro, scm_m_delay);
2951 /* end of acros */
2952
dc19d1d2
JB
2953 scm_top_level_lookup_closure_var =
2954 scm_sysintern("*top-level-lookup-closure*", SCM_BOOL_F);
9b8d3288 2955 scm_can_use_top_level_lookup_closure_var = 1;
0f2d19dd 2956
6dbd0af5
MD
2957 scm_i_and = scm_make_synt ("and", scm_makmmacro, scm_m_and);
2958 scm_i_begin = scm_make_synt ("begin", scm_makmmacro, scm_m_begin);
2959 scm_i_case = scm_make_synt ("case", scm_makmmacro, scm_m_case);
2960 scm_i_cond = scm_make_synt ("cond", scm_makmmacro, scm_m_cond);
2961 scm_i_define = scm_make_synt ("define", scm_makmmacro, scm_m_define);
2962 scm_i_do = scm_make_synt ("do", scm_makmmacro, scm_m_do);
2963 scm_i_if = scm_make_synt ("if", scm_makmmacro, scm_m_if);
0f2d19dd
JB
2964 scm_i_lambda = scm_make_synt ("lambda", scm_makmmacro, scm_m_lambda);
2965 scm_i_let = scm_make_synt ("let", scm_makmmacro, scm_m_let);
6dbd0af5
MD
2966 scm_i_letrec = scm_make_synt ("letrec", scm_makmmacro, scm_m_letrec);
2967 scm_i_letstar = scm_make_synt ("let*", scm_makmmacro, scm_m_letstar);
2968 scm_i_or = scm_make_synt ("or", scm_makmmacro, scm_m_or);
0f2d19dd 2969 scm_i_quote = scm_make_synt ("quote", scm_makmmacro, scm_m_quote);
6dbd0af5
MD
2970 scm_i_set = scm_make_synt ("set!", scm_makmmacro, scm_m_set);
2971 scm_i_atapply = scm_make_synt ("@apply", scm_makmmacro, scm_m_apply);
2972 scm_i_atcall_cc = scm_make_synt ("@call-with-current-continuation",
2973 scm_makmmacro, scm_m_cont);
2974
6dbd0af5
MD
2975#ifdef DEBUG_EXTENSIONS
2976 scm_i_enter_frame = SCM_CAR (scm_sysintern ("enter-frame", SCM_UNDEFINED));
2977 scm_i_apply_frame = SCM_CAR (scm_sysintern ("apply-frame", SCM_UNDEFINED));
2978 scm_i_exit_frame = SCM_CAR (scm_sysintern ("exit-frame", SCM_UNDEFINED));
2979 scm_i_trace = SCM_CAR (scm_sysintern ("trace", SCM_UNDEFINED));
2980#endif
2981
0f2d19dd
JB
2982#include "eval.x"
2983}
0f2d19dd 2984
6dbd0af5 2985#endif /* !DEVAL */