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