* * net_db.c (scm_lnaof): change scheme name from lnaof to inet-lnaof.
[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
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:
fa888178 1064 /* appease the Sun compiler god: */ ;
6dbd0af5
MD
1065 }
1066 unmemo:
1067 default:
1068 ls = z = unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env),
1069 SCM_UNSPECIFIED),
1070 env);
1071 }
1072loop:
1073 while (SCM_CELLP (x = SCM_CDR (x)) && SCM_ECONSP (x))
a23afe53
MD
1074 {
1075 SCM_SETCDR (z, unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env),
1076 SCM_UNSPECIFIED),
1077 env));
1078 z = SCM_CDR (z);
1079 }
1080 SCM_SETCDR (z, x);
6dbd0af5
MD
1081#ifdef DEBUG_EXTENSIONS
1082 if (SCM_NFALSEP (p))
1083 scm_whash_insert (scm_source_whash, ls, p);
1084#endif
1085 return ls;
1086}
1087
1cc91f1b 1088
6dbd0af5
MD
1089SCM
1090scm_unmemocopy (x, env)
1091 SCM x;
1092 SCM env;
6dbd0af5
MD
1093{
1094 if (SCM_NNULLP (env))
1095 /* Make a copy of the lowest frame to protect it from
1096 modifications by SCM_IM_DEFINE */
1097 return unmemocopy (x, scm_cons (SCM_CAR (env), SCM_CDR (env)));
1098 else
1099 return unmemocopy (x, env);
1100}
1101
0f2d19dd 1102#ifndef RECKLESS
1cc91f1b 1103
0f2d19dd
JB
1104int
1105scm_badargsp (formals, args)
1106 SCM formals;
1107 SCM args;
0f2d19dd
JB
1108{
1109 while SCM_NIMP
1110 (formals)
1111 {
1112 if SCM_NCONSP
1113 (formals) return 0;
1114 if SCM_IMP
1115 (args) return 1;
1116 formals = SCM_CDR (formals);
1117 args = SCM_CDR (args);
1118 }
1119 return SCM_NNULLP (args) ? 1 : 0;
1120}
1121#endif
1122
1123
1124\f
1125long scm_tc16_macro;
1126
1cc91f1b 1127
6dbd0af5
MD
1128SCM
1129scm_eval_args (l, env)
1130 SCM l;
1131 SCM env;
6dbd0af5
MD
1132{
1133 SCM res = SCM_EOL, *lloc = &res;
1134 while (SCM_NIMP (l))
1135 {
1136 *lloc = scm_cons (EVALCAR (l, env), SCM_EOL);
a23afe53 1137 lloc = SCM_CDRLOC (*lloc);
6dbd0af5
MD
1138 l = SCM_CDR (l);
1139 }
1140 return res;
1141}
0f2d19dd
JB
1142#endif /* !DEVAL */
1143
6dbd0af5
MD
1144
1145/* SECTION: This code is specific for the debugging support. One
1146 * branch is read when DEVAL isn't defined, the other when DEVAL is
1147 * defined.
1148 */
1149
1150#ifndef DEVAL
1151
1152#define SCM_APPLY scm_apply
1153#define PREP_APPLY(proc, args)
1154#define ENTER_APPLY
1155#define RETURN(x) return x;
b7ff98dd
MD
1156#ifdef STACK_CHECKING
1157#ifndef NO_CEVAL_STACK_CHECKING
1158#define EVAL_STACK_CHECKING
1159#endif
6dbd0af5
MD
1160#endif
1161
1162#else /* !DEVAL */
1163
0f2d19dd
JB
1164#undef SCM_CEVAL
1165#define SCM_CEVAL scm_deval /* Substitute all uses of scm_ceval */
1166#undef SCM_APPLY
1167#define SCM_APPLY scm_dapply
6dbd0af5
MD
1168#undef PREP_APPLY
1169#define PREP_APPLY(p, l) \
1170{ ++debug.info; debug.info->a.proc = p; debug.info->a.args = l; }
1171#undef ENTER_APPLY
1172#define ENTER_APPLY \
1173{\
b7ff98dd 1174 SCM_SET_ARGSREADY (debug);\
6dbd0af5 1175 if (CHECK_APPLY)\
b7ff98dd 1176 if (SCM_APPLY_FRAME_P || (SCM_TRACE_P && PROCTRACEP (proc)))\
6dbd0af5 1177 {\
b7ff98dd
MD
1178 SCM tmp, tail = SCM_TRACED_FRAME_P (debug) ? SCM_BOOL_T : SCM_BOOL_F;\
1179 SCM_SET_TRACED_FRAME (debug);\
1180 if (SCM_CHEAPTRAPS_P)\
6dbd0af5 1181 {\
c0ab1b8d 1182 tmp = scm_make_debugobj (&debug);\
6dbd0af5
MD
1183 scm_ithrow (scm_i_apply_frame, scm_cons2 (tmp, tail, SCM_EOL), 0);\
1184 }\
1185 else\
1186 {\
1187 scm_make_cont (&tmp);\
1188 if (!setjmp (SCM_JMPBUF (tmp)))\
1189 scm_ithrow (scm_i_apply_frame, scm_cons2 (tmp, tail, SCM_EOL), 0);\
1190 }\
1191 }\
1192}
0f2d19dd
JB
1193#undef RETURN
1194#define RETURN(e) {proc = (e); goto exit;}
b7ff98dd
MD
1195#ifdef STACK_CHECKING
1196#ifndef EVAL_STACK_CHECKING
1197#define EVAL_STACK_CHECKING
1198#endif
6dbd0af5
MD
1199#endif
1200
1201/* scm_ceval_ptr points to the currently selected evaluator.
1202 * *fixme*: Although efficiency is important here, this state variable
1203 * should probably not be a global. It should be related to the
1204 * current repl.
1205 */
1206
1cc91f1b
JB
1207
1208SCM (*scm_ceval_ptr) SCM_P ((SCM x, SCM env));
0f2d19dd 1209
1646d37b 1210/* scm_last_debug_frame contains a pointer to the last debugging
6dbd0af5
MD
1211 * information stack frame. It is accessed very often from the
1212 * debugging evaluator, so it should probably not be indirectly
1213 * addressed. Better to save and restore it from the current root at
1214 * any stack swaps.
1215 */
1216
1646d37b
MD
1217#ifndef USE_THREADS
1218scm_debug_frame *scm_last_debug_frame;
1219#endif
6dbd0af5
MD
1220
1221/* scm_debug_eframe_size is the number of slots available for pseudo
1222 * stack frames at each real stack frame.
1223 */
1224
1225int scm_debug_eframe_size;
1226
b7ff98dd 1227int scm_debug_mode, scm_check_entry_p, scm_check_apply_p, scm_check_exit_p;
6dbd0af5
MD
1228
1229scm_option scm_debug_opts[] = {
b7ff98dd
MD
1230 { SCM_OPTION_BOOLEAN, "cheap", 1,
1231 "*Flyweight representation of the stack at traps." },
1232 { SCM_OPTION_BOOLEAN, "breakpoints", 0, "*Check for breakpoints." },
1233 { SCM_OPTION_BOOLEAN, "trace", 0, "*Trace mode." },
1234 { SCM_OPTION_BOOLEAN, "procnames", 1,
1235 "Record procedure names at definition." },
1236 { SCM_OPTION_BOOLEAN, "backwards", 0,
1237 "Display backtrace in anti-chronological order." },
4e646a03
MD
1238 { SCM_OPTION_INTEGER, "indent", 10, "Maximal indentation in backtrace." },
1239 { SCM_OPTION_INTEGER, "frames", 3,
b7ff98dd 1240 "Maximum number of tail-recursive frames in backtrace." },
4e646a03
MD
1241 { SCM_OPTION_INTEGER, "maxdepth", 1000,
1242 "Maximal number of stored backtrace frames." },
1243 { SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." },
11f77bfc
MD
1244 { SCM_OPTION_BOOLEAN, "backtrace", 0, "Show backtrace on error." },
1245 { SCM_OPTION_BOOLEAN, "debug", 0, "Use the debugging evaluator." },
b7ff98dd 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
c0ab1b8d
JB
1318 scm_debug_frame debug;
1319 scm_debug_info *debug_info_end;
1646d37b 1320 debug.prev = scm_last_debug_frame;
6dbd0af5 1321 debug.status = scm_debug_eframe_size;
c0ab1b8d
JB
1322 debug.vect = (scm_debug_info *) alloca (scm_debug_eframe_size
1323 * sizeof (debug.vect[0]));
1324 debug.info = debug.vect;
1325 debug_info_end = debug.vect + scm_debug_eframe_size;
1326 scm_last_debug_frame = &debug;
6dbd0af5 1327#endif
b7ff98dd
MD
1328#ifdef EVAL_STACK_CHECKING
1329 if (SCM_STACK_OVERFLOW_P ((SCM_STACKITEM *) &proc)
1330 && scm_stack_checking_enabled_p)
6dbd0af5 1331 {
b7ff98dd 1332#ifdef DEVAL
6dbd0af5
MD
1333 debug.info->e.exp = x;
1334 debug.info->e.env = env;
b7ff98dd 1335#endif
6dbd0af5
MD
1336 scm_report_stack_overflow ();
1337 }
1338#endif
1339#ifdef DEVAL
1340 goto start;
1341#endif
1342loopnoap:
1343 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1344loop:
1345#ifdef DEVAL
1346#if 0 /* This will probably never have any practical use ... */
1347 if (CHECK_EXIT)
1348 {
b7ff98dd 1349 if (SINGLE_STEP || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5
MD
1350 {
1351 SINGLE_STEP = 0;
b7ff98dd
MD
1352 SCM_RESET_DEBUG_MODE;
1353 SCM_CLEAR_TRACED_FRAME (debug);
6dbd0af5
MD
1354 scm_make_cont (&t.arg1);
1355 if (!setjmp (SCM_JMPBUF (t.arg1)))
1356 scm_ithrow (scm_i_exit_tail, scm_cons (t.arg1, SCM_EOL), 0);
1357 }
1358 }
1359nextframe:
1360#endif
b7ff98dd
MD
1361 SCM_CLEAR_ARGSREADY (debug);
1362 if (SCM_OVERFLOWP (debug))
6dbd0af5 1363 --debug.info;
c0ab1b8d 1364 else if (++debug.info >= debug_info_end)
6dbd0af5 1365 {
b7ff98dd 1366 SCM_SET_OVERFLOW (debug);
6dbd0af5
MD
1367 debug.info -= 2;
1368 }
1369start:
1370 debug.info->e.exp = x;
1371 debug.info->e.env = env;
1372 if (CHECK_ENTRY)
b7ff98dd 1373 if (SCM_ENTER_FRAME_P || (SCM_BREAKPOINTS_P && SRCBRKP (x)))
6dbd0af5 1374 {
b7ff98dd
MD
1375 SCM tail = SCM_TAILRECP (debug) ? SCM_BOOL_T : SCM_BOOL_F;
1376 SCM_SET_TAILREC (debug);
1377 SCM_ENTER_FRAME_P = 0;
1378 SCM_RESET_DEBUG_MODE;
1379 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 1380 t.arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
1381 else
1382 {
1383 scm_make_cont (&t.arg1);
1384 if (setjmp (SCM_JMPBUF (t.arg1)))
1385 {
1386 x = SCM_THROW_VALUE (t.arg1);
1387 if (SCM_IMP (x))
1388 {
1389 RETURN (x);
1390 }
1391 else
1392 /* This gives the possibility for the debugger to
1393 modify the source expression before evaluation. */
1394 goto dispatch;
1395 }
1396 }
1397 scm_ithrow (scm_i_enter_frame,
1398 scm_cons2 (t.arg1, tail,
1399 scm_cons (scm_unmemocopy (x, env), SCM_EOL)),
1400 0);
1401 }
1402dispatch:
1403#endif
0f2d19dd 1404 SCM_ASYNC_TICK;
0f2d19dd
JB
1405 switch (SCM_TYP7 (x))
1406 {
1407 case scm_tcs_symbols:
1408 /* Only happens when called at top level.
1409 */
1410 x = scm_cons (x, SCM_UNDEFINED);
1411 goto retval;
1412
1413 case (127 & SCM_IM_AND):
1414 x = SCM_CDR (x);
1415 t.arg1 = x;
1416 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1417 if (SCM_FALSEP (EVALCAR (x, env)))
1418 {
1419 RETURN (SCM_BOOL_F);
1420 }
1421 else
1422 x = t.arg1;
6dbd0af5 1423 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1424 goto carloop;
1425
1426 case (127 & SCM_IM_BEGIN):
6dbd0af5
MD
1427 cdrxnoap:
1428 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1429 cdrxbegin:
1430 x = SCM_CDR (x);
1431
1432 begin:
1433 t.arg1 = x;
1434 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1435 {
1436 SIDEVAL (SCM_CAR (x), env);
1437 x = t.arg1;
1438 }
1439
1440 carloop: /* scm_eval car of last form in list */
1441 if (SCM_NCELLP (SCM_CAR (x)))
1442 {
1443 x = SCM_CAR (x);
6dbd0af5 1444 RETURN (SCM_IMP (x) ? EVALIM (x, env) : SCM_GLOC_VAL (x))
0f2d19dd
JB
1445 }
1446
1447 if (SCM_SYMBOLP (SCM_CAR (x)))
1448 {
1449 retval:
6dbd0af5 1450 RETURN (*scm_lookupcar (x, env))
0f2d19dd
JB
1451 }
1452
1453 x = SCM_CAR (x);
1454 goto loop; /* tail recurse */
1455
1456
1457 case (127 & SCM_IM_CASE):
1458 x = SCM_CDR (x);
1459 t.arg1 = EVALCAR (x, env);
1460 while (SCM_NIMP (x = SCM_CDR (x)))
1461 {
1462 proc = SCM_CAR (x);
1463 if (scm_i_else == SCM_CAR (proc))
1464 {
1465 x = SCM_CDR (proc);
6dbd0af5 1466 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1467 goto begin;
1468 }
1469 proc = SCM_CAR (proc);
1470 while (SCM_NIMP (proc))
1471 {
1472 if (CHECK_EQVISH (SCM_CAR (proc), t.arg1))
1473 {
1474 x = SCM_CDR (SCM_CAR (x));
6dbd0af5 1475 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1476 goto begin;
1477 }
1478 proc = SCM_CDR (proc);
1479 }
1480 }
6dbd0af5 1481 RETURN (SCM_UNSPECIFIED)
0f2d19dd
JB
1482
1483
1484 case (127 & SCM_IM_COND):
1485 while (SCM_NIMP (x = SCM_CDR (x)))
1486 {
1487 proc = SCM_CAR (x);
1488 t.arg1 = EVALCAR (proc, env);
1489 if (SCM_NFALSEP (t.arg1))
1490 {
1491 x = SCM_CDR (proc);
6dbd0af5 1492 if SCM_NULLP (x)
0f2d19dd 1493 {
6dbd0af5 1494 RETURN (t.arg1)
0f2d19dd
JB
1495 }
1496 if (scm_i_arrow != SCM_CAR (x))
6dbd0af5
MD
1497 {
1498 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1499 goto begin;
1500 }
0f2d19dd
JB
1501 proc = SCM_CDR (x);
1502 proc = EVALCAR (proc, env);
1503 SCM_ASRTGO (SCM_NIMP (proc), badfun);
6dbd0af5
MD
1504 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
1505 ENTER_APPLY;
0f2d19dd
JB
1506 goto evap1;
1507 }
1508 }
6dbd0af5 1509 RETURN (SCM_UNSPECIFIED)
0f2d19dd
JB
1510
1511
1512 case (127 & SCM_IM_DO):
1513 x = SCM_CDR (x);
1514 proc = SCM_CAR (SCM_CDR (x)); /* inits */
1515 t.arg1 = SCM_EOL; /* values */
1516 while (SCM_NIMP (proc))
1517 {
1518 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
1519 proc = SCM_CDR (proc);
1520 }
e2806c10 1521 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
0f2d19dd
JB
1522 x = SCM_CDR (SCM_CDR (x));
1523 while (proc = SCM_CAR (x), SCM_FALSEP (EVALCAR (proc, env)))
1524 {
1525 for (proc = SCM_CAR (SCM_CDR (x)); SCM_NIMP (proc); proc = SCM_CDR (proc))
1526 {
1527 t.arg1 = SCM_CAR (proc); /* body */
1528 SIDEVAL (t.arg1, env);
1529 }
1530 for (t.arg1 = SCM_EOL, proc = SCM_CDR (SCM_CDR (x)); SCM_NIMP (proc); proc = SCM_CDR (proc))
1531 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1); /* steps */
e2806c10 1532 env = EXTEND_ENV (SCM_CAR (SCM_CAR (env)), t.arg1, SCM_CDR (env));
0f2d19dd
JB
1533 }
1534 x = SCM_CDR (proc);
1535 if (SCM_NULLP (x))
6dbd0af5
MD
1536 RETURN (SCM_UNSPECIFIED);
1537 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1538 goto begin;
1539
1540
1541 case (127 & SCM_IM_IF):
1542 x = SCM_CDR (x);
1543 if (SCM_NFALSEP (EVALCAR (x, env)))
1544 x = SCM_CDR (x);
1545 else if (SCM_IMP (x = SCM_CDR (SCM_CDR (x))))
1546 {
1547 RETURN (SCM_UNSPECIFIED);
1548 }
6dbd0af5 1549 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1550 goto carloop;
1551
1552
1553 case (127 & SCM_IM_LET):
1554 x = SCM_CDR (x);
1555 proc = SCM_CAR (SCM_CDR (x));
1556 t.arg1 = SCM_EOL;
1557 do
1558 {
1559 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
1560 }
1561 while (SCM_NIMP (proc = SCM_CDR (proc)));
e2806c10 1562 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
0f2d19dd 1563 x = SCM_CDR (x);
6dbd0af5 1564 goto cdrxnoap;
0f2d19dd
JB
1565
1566
1567 case (127 & SCM_IM_LETREC):
1568 x = SCM_CDR (x);
e2806c10 1569 env = EXTEND_ENV (SCM_CAR (x), scm_undefineds, env);
0f2d19dd
JB
1570 x = SCM_CDR (x);
1571 proc = SCM_CAR (x);
1572 t.arg1 = SCM_EOL;
1573 do
1574 {
1575 t.arg1 = scm_cons (EVALCAR (proc, env), t.arg1);
1576 }
1577 while (SCM_NIMP (proc = SCM_CDR (proc)));
a23afe53 1578 SCM_SETCDR (SCM_CAR (env), t.arg1);
6dbd0af5 1579 goto cdrxnoap;
0f2d19dd
JB
1580
1581
1582 case (127 & SCM_IM_LETSTAR):
1583 x = SCM_CDR (x);
1584 proc = SCM_CAR (x);
1585 if (SCM_IMP (proc))
1586 {
e2806c10 1587 env = EXTEND_ENV (SCM_EOL, SCM_EOL, env);
6dbd0af5 1588 goto cdrxnoap;
0f2d19dd
JB
1589 }
1590 do
1591 {
1592 t.arg1 = SCM_CAR (proc);
1593 proc = SCM_CDR (proc);
e2806c10 1594 env = EXTEND_ENV (t.arg1, EVALCAR (proc, env), env);
0f2d19dd
JB
1595 }
1596 while (SCM_NIMP (proc = SCM_CDR (proc)));
6dbd0af5 1597 goto cdrxnoap;
0f2d19dd
JB
1598
1599 case (127 & SCM_IM_OR):
1600 x = SCM_CDR (x);
1601 t.arg1 = x;
1602 while (SCM_NNULLP (t.arg1 = SCM_CDR (t.arg1)))
1603 {
1604 x = EVALCAR (x, env);
1605 if (SCM_NFALSEP (x))
1606 {
1607 RETURN (x);
1608 }
1609 x = t.arg1;
1610 }
6dbd0af5 1611 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
1612 goto carloop;
1613
1614
1615 case (127 & SCM_IM_LAMBDA):
1616 RETURN (scm_closure (SCM_CDR (x), env));
1617
1618
1619 case (127 & SCM_IM_QUOTE):
1620 RETURN (SCM_CAR (SCM_CDR (x)));
1621
1622
1623 case (127 & SCM_IM_SET):
0f2d19dd
JB
1624 x = SCM_CDR (x);
1625 proc = SCM_CAR (x);
6dbd0af5 1626 switch (7 & (int) proc)
0f2d19dd
JB
1627 {
1628 case 0:
1629 t.lloc = scm_lookupcar (x, env);
1630 break;
1631 case 1:
a23afe53 1632 t.lloc = SCM_GLOC_VAL_LOC (proc);
0f2d19dd
JB
1633 break;
1634#ifdef MEMOIZE_LOCALS
1635 case 4:
1636 t.lloc = scm_ilookup (proc, env);
1637 break;
1638#endif
1639 }
1640 x = SCM_CDR (x);
1641 *t.lloc = EVALCAR (x, env);
0f2d19dd
JB
1642#ifdef SICP
1643 RETURN (*t.lloc);
1644#else
1645 RETURN (SCM_UNSPECIFIED);
1646#endif
1647
1648
1649 case (127 & SCM_IM_DEFINE): /* only for internal defines */
1650 x = SCM_CDR (x);
1651 proc = SCM_CAR (x);
1652 x = SCM_CDR (x);
1653 x = evalcar (x, env);
6dbd0af5 1654#ifdef DEBUG_EXTENSIONS
b7ff98dd 1655 if (SCM_REC_PROCNAMES_P && SCM_NIMP (x) && SCM_CLOSUREP (x))
6dbd0af5
MD
1656 scm_set_procedure_property_x (x, scm_i_name, proc);
1657#endif
0f2d19dd
JB
1658 env = SCM_CAR (env);
1659 SCM_DEFER_INTS;
a23afe53
MD
1660 SCM_SETCAR (env, scm_cons (proc, SCM_CAR (env)));
1661 SCM_SETCDR (env, scm_cons (x, SCM_CDR (env)));
0f2d19dd
JB
1662 SCM_ALLOW_INTS;
1663 RETURN (SCM_UNSPECIFIED);
1664
1665
0f2d19dd
JB
1666 /* new syntactic forms go here. */
1667 case (127 & SCM_MAKISYM (0)):
1668 proc = SCM_CAR (x);
1669 SCM_ASRTGO (SCM_ISYMP (proc), badfun);
1670 switch SCM_ISYMNUM (proc)
1671 {
1672#if 0
1673 case (SCM_ISYMNUM (IM_VREF)):
1674 {
1675 SCM var;
1676 var = SCM_CAR (SCM_CDR (x));
1677 RETURN (SCM_CDR(var));
1678 }
1679 case (SCM_ISYMNUM (IM_VSET)):
1680 SCM_CDR (SCM_CAR ( SCM_CDR (x))) = EVALCAR( SCM_CDR ( SCM_CDR (x)), env);
1681 SCM_CAR (SCM_CAR ( SCM_CDR (x))) = scm_tc16_variable;
6dbd0af5 1682 RETURN (SCM_UNSPECIFIED)
0f2d19dd
JB
1683#endif
1684
1685 case (SCM_ISYMNUM (SCM_IM_APPLY)):
1686 proc = SCM_CDR (x);
1687 proc = EVALCAR (proc, env);
1688 SCM_ASRTGO (SCM_NIMP (proc), badfun);
1689 if (SCM_CLOSUREP (proc))
1690 {
6dbd0af5 1691 PREP_APPLY (proc, SCM_EOL);
0f2d19dd
JB
1692 t.arg1 = SCM_CDR (SCM_CDR (x));
1693 t.arg1 = EVALCAR (t.arg1, env);
6dbd0af5
MD
1694#ifdef DEVAL
1695 debug.info->a.args = t.arg1;
1696#endif
0f2d19dd
JB
1697#ifndef RECKLESS
1698 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), t.arg1))
1699 goto wrongnumargs;
1700#endif
e2806c10 1701 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), t.arg1, SCM_ENV (proc));
0f2d19dd
JB
1702 x = SCM_CODE (proc);
1703 goto cdrxbegin;
1704 }
1705 proc = scm_i_apply;
1706 goto evapply;
1707
1708 case (SCM_ISYMNUM (SCM_IM_CONT)):
1709 scm_make_cont (&t.arg1);
1710 if (setjmp (SCM_JMPBUF (t.arg1)))
1711 {
1712 SCM val;
1713 val = SCM_THROW_VALUE (t.arg1);
6dbd0af5 1714 RETURN (val);
0f2d19dd
JB
1715 }
1716 proc = SCM_CDR (x);
1717 proc = evalcar (proc, env);
1718 SCM_ASRTGO (SCM_NIMP (proc), badfun);
6dbd0af5
MD
1719 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
1720 ENTER_APPLY;
0f2d19dd
JB
1721 goto evap1;
1722
1723 default:
1724 goto badfun;
1725 }
1726
1727 default:
1728 proc = x;
1729 badfun:
f5bf2977 1730 /* scm_everr (x, env,...) */
523f5266
GH
1731 scm_misc_error (NULL,
1732 "Wrong type to apply: %S",
1733 scm_listify (proc, SCM_UNDEFINED));
0f2d19dd
JB
1734 case scm_tc7_vector:
1735 case scm_tc7_wvect:
1736 case scm_tc7_bvect:
1737 case scm_tc7_byvect:
1738 case scm_tc7_svect:
1739 case scm_tc7_ivect:
1740 case scm_tc7_uvect:
1741 case scm_tc7_fvect:
1742 case scm_tc7_dvect:
1743 case scm_tc7_cvect:
1744#ifdef LONGLONGS
1745 case scm_tc7_llvect:
1746#endif
1747 case scm_tc7_string:
1748 case scm_tc7_mb_string:
1749 case scm_tc7_substring:
1750 case scm_tc7_mb_substring:
1751 case scm_tc7_smob:
1752 case scm_tcs_closures:
1753 case scm_tcs_subrs:
1754 RETURN (x);
1755
1756#ifdef MEMOIZE_LOCALS
1757 case (127 & SCM_ILOC00):
1758 proc = *scm_ilookup (SCM_CAR (x), env);
1759 SCM_ASRTGO (SCM_NIMP (proc), badfun);
1760#ifndef RECKLESS
1761#ifdef CAUTIOUS
1762 goto checkargs;
1763#endif
1764#endif
1765 break;
1766#endif /* ifdef MEMOIZE_LOCALS */
1767
1768
1769 case scm_tcs_cons_gloc:
1770 proc = SCM_GLOC_VAL (SCM_CAR (x));
1771 SCM_ASRTGO (SCM_NIMP (proc), badfun);
1772#ifndef RECKLESS
1773#ifdef CAUTIOUS
1774 goto checkargs;
1775#endif
1776#endif
1777 break;
1778
1779
1780 case scm_tcs_cons_nimcar:
1781 if (SCM_SYMBOLP (SCM_CAR (x)))
1782 {
1783 proc = *scm_lookupcar (x, env);
1784 if (SCM_IMP (proc))
1785 {
1786 unmemocar (x, env);
1787 goto badfun;
1788 }
1789 if (scm_tc16_macro == SCM_TYP16 (proc))
1790 {
1791 unmemocar (x, env);
1792
1793 handle_a_macro:
1794 t.arg1 = SCM_APPLY (SCM_CDR (proc), x, scm_cons (env, scm_listofnull));
1795 switch ((int) (SCM_CAR (proc) >> 16))
1796 {
1797 case 2:
1798 if (scm_ilength (t.arg1) <= 0)
1799 t.arg1 = scm_cons2 (SCM_IM_BEGIN, t.arg1, SCM_EOL);
6dbd0af5
MD
1800#ifdef DEVAL
1801 if (!SCM_CLOSUREP (SCM_CDR (proc)))
1802 {
1803#if 0 /* Top-level defines doesn't very often occur in backtraces */
1804 if (scm_m_define == SCM_SUBRF (SCM_CDR (proc)) && SCM_TOP_LEVEL (env))
1805 /* Prevent memoizing result of define macro */
1806 {
1807 debug.info->e.exp = scm_cons (SCM_CAR (x), SCM_CDR (x));
1808 scm_set_source_properties_x (debug.info->e.exp,
1809 scm_source_properties (x));
1810 }
1811#endif
1812 SCM_DEFER_INTS;
a23afe53
MD
1813 SCM_SETCAR (x, SCM_CAR (t.arg1));
1814 SCM_SETCDR (x, SCM_CDR (t.arg1));
6dbd0af5
MD
1815 SCM_ALLOW_INTS;
1816 goto dispatch;
1817 }
1818 /* Prevent memoizing of debug info expression. */
1819 debug.info->e.exp = scm_cons (SCM_CAR (x), SCM_CDR (x));
1820 scm_set_source_properties_x (debug.info->e.exp,
1821 scm_source_properties (x));
1822#endif
0f2d19dd 1823 SCM_DEFER_INTS;
a23afe53
MD
1824 SCM_SETCAR (x, SCM_CAR (t.arg1));
1825 SCM_SETCDR (x, SCM_CDR (t.arg1));
0f2d19dd 1826 SCM_ALLOW_INTS;
6dbd0af5 1827 goto loopnoap;
0f2d19dd
JB
1828 case 1:
1829 if (SCM_NIMP (x = t.arg1))
6dbd0af5 1830 goto loopnoap;
0f2d19dd
JB
1831 case 0:
1832 RETURN (t.arg1);
1833 }
1834 }
1835 }
1836 else
1837 proc = SCM_CEVAL (SCM_CAR (x), env);
1838 SCM_ASRTGO (SCM_NIMP (proc), badfun);
1839#ifndef RECKLESS
1840#ifdef CAUTIOUS
1841 checkargs:
1842#endif
1843 if (SCM_CLOSUREP (proc))
1844 {
1845 arg2 = SCM_CAR (SCM_CODE (proc));
1846 t.arg1 = SCM_CDR (x);
1847 while (SCM_NIMP (arg2))
1848 {
1849 if (SCM_NCONSP (arg2))
1850 goto evapply;
1851 if (SCM_IMP (t.arg1))
1852 goto umwrongnumargs;
1853 arg2 = SCM_CDR (arg2);
1854 t.arg1 = SCM_CDR (t.arg1);
1855 }
1856 if (SCM_NNULLP (t.arg1))
1857 goto umwrongnumargs;
1858 }
1859 else if (scm_tc16_macro == SCM_TYP16 (proc))
1860 goto handle_a_macro;
1861#endif
1862 }
1863
1864
6dbd0af5
MD
1865evapply:
1866 PREP_APPLY (proc, SCM_EOL);
1867 if (SCM_NULLP (SCM_CDR (x))) {
1868 ENTER_APPLY;
0f2d19dd
JB
1869 switch (SCM_TYP7 (proc))
1870 { /* no arguments given */
1871 case scm_tc7_subr_0:
1872 RETURN (SCM_SUBRF (proc) ());
1873 case scm_tc7_subr_1o:
1874 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED));
1875 case scm_tc7_lsubr:
1876 RETURN (SCM_SUBRF (proc) (SCM_EOL));
1877 case scm_tc7_rpsubr:
1878 RETURN (SCM_BOOL_T);
1879 case scm_tc7_asubr:
1880 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED));
6dbd0af5 1881#ifdef CCLO
0f2d19dd
JB
1882 case scm_tc7_cclo:
1883 t.arg1 = proc;
1884 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
1885#ifdef DEVAL
1886 debug.info->a.proc = proc;
1887 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
1888#endif
0f2d19dd 1889 goto evap1;
6dbd0af5 1890#endif
0f2d19dd
JB
1891 case scm_tcs_closures:
1892 x = SCM_CODE (proc);
e2806c10 1893 env = EXTEND_ENV (SCM_CAR (x), SCM_EOL, SCM_ENV (proc));
0f2d19dd
JB
1894 goto cdrxbegin;
1895 case scm_tc7_contin:
1896 case scm_tc7_subr_1:
1897 case scm_tc7_subr_2:
1898 case scm_tc7_subr_2o:
1899 case scm_tc7_cxr:
1900 case scm_tc7_subr_3:
1901 case scm_tc7_lsubr_2:
1902 umwrongnumargs:
1903 unmemocar (x, env);
1904 wrongnumargs:
f5bf2977
GH
1905 /* scm_everr (x, env,...) */
1906 scm_wrong_num_args (proc);
0f2d19dd
JB
1907 default:
1908 /* handle macros here */
1909 goto badfun;
1910 }
6dbd0af5 1911 }
0f2d19dd
JB
1912
1913 /* must handle macros by here */
1914 x = SCM_CDR (x);
1915#ifdef CAUTIOUS
1916 if (SCM_IMP (x))
1917 goto wrongnumargs;
1918#endif
1919 t.arg1 = EVALCAR (x, env);
6dbd0af5
MD
1920#ifdef DEVAL
1921 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
1922#endif
0f2d19dd
JB
1923 x = SCM_CDR (x);
1924 if (SCM_NULLP (x))
1925 {
6dbd0af5 1926 ENTER_APPLY;
0f2d19dd
JB
1927 evap1:
1928 switch (SCM_TYP7 (proc))
6dbd0af5 1929 { /* have one argument in t.arg1 */
0f2d19dd
JB
1930 case scm_tc7_subr_2o:
1931 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
1932 case scm_tc7_subr_1:
1933 case scm_tc7_subr_1o:
1934 RETURN (SCM_SUBRF (proc) (t.arg1));
1935 case scm_tc7_cxr:
1936#ifdef SCM_FLOATS
1937 if (SCM_SUBRF (proc))
1938 {
1939 if (SCM_INUMP (t.arg1))
1940 {
1941 RETURN (scm_makdbl (SCM_DSUBRF (proc) ((double) SCM_INUM (t.arg1)),
1942 0.0));
1943 }
1944 SCM_ASRTGO (SCM_NIMP (t.arg1), floerr);
1945 if (SCM_REALP (t.arg1))
1946 {
1947 RETURN (scm_makdbl (SCM_DSUBRF (proc) (SCM_REALPART (t.arg1)), 0.0));
1948 }
1949#ifdef SCM_BIGDIG
1950 if (SCM_BIGP (t.arg1))
1951 {
1952 RETURN (scm_makdbl (SCM_DSUBRF (proc) (scm_big2dbl (t.arg1)), 0.0));
1953 }
1954#endif
1955 floerr:
1956 scm_wta (t.arg1, (char *) SCM_ARG1, SCM_CHARS (SCM_SNAME (proc)));
1957 }
1958#endif
1959 proc = (SCM) SCM_SNAME (proc);
1960 {
1961 char *chrs = SCM_CHARS (proc) + SCM_LENGTH (proc) - 1;
1962 while ('c' != *--chrs)
1963 {
1964 SCM_ASSERT (SCM_NIMP (t.arg1) && SCM_CONSP (t.arg1),
1965 t.arg1, SCM_ARG1, SCM_CHARS (proc));
1966 t.arg1 = ('a' == *chrs) ? SCM_CAR (t.arg1) : SCM_CDR (t.arg1);
1967 }
1968 RETURN (t.arg1);
1969 }
1970 case scm_tc7_rpsubr:
1971 RETURN (SCM_BOOL_T);
1972 case scm_tc7_asubr:
1973 RETURN (SCM_SUBRF (proc) (t.arg1, SCM_UNDEFINED));
1974 case scm_tc7_lsubr:
1975#ifdef DEVAL
6dbd0af5 1976 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
0f2d19dd
JB
1977#else
1978 RETURN (SCM_SUBRF (proc) (scm_cons (t.arg1, SCM_EOL)));
1979#endif
6dbd0af5 1980#ifdef CCLO
0f2d19dd
JB
1981 case scm_tc7_cclo:
1982 arg2 = t.arg1;
1983 t.arg1 = proc;
1984 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
1985#ifdef DEVAL
1986 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
1987 debug.info->a.proc = proc;
1988#endif
0f2d19dd 1989 goto evap2;
6dbd0af5 1990#endif
0f2d19dd
JB
1991 case scm_tcs_closures:
1992 x = SCM_CODE (proc);
1993#ifdef DEVAL
e2806c10 1994 env = EXTEND_ENV (SCM_CAR (x), debug.info->a.args, SCM_ENV (proc));
0f2d19dd 1995#else
e2806c10 1996 env = EXTEND_ENV (SCM_CAR (x), scm_cons (t.arg1, SCM_EOL), SCM_ENV (proc));
0f2d19dd
JB
1997#endif
1998 goto cdrxbegin;
1999 case scm_tc7_contin:
2000 scm_call_continuation (proc, t.arg1);
2001 case scm_tc7_subr_2:
2002 case scm_tc7_subr_0:
2003 case scm_tc7_subr_3:
2004 case scm_tc7_lsubr_2:
2005 goto wrongnumargs;
2006 default:
2007 goto badfun;
2008 }
2009 }
2010#ifdef CAUTIOUS
2011 if (SCM_IMP (x))
2012 goto wrongnumargs;
2013#endif
2014 { /* have two or more arguments */
2015 arg2 = EVALCAR (x, env);
6dbd0af5
MD
2016#ifdef DEVAL
2017 debug.info->a.args = scm_cons2 (t.arg1, arg2, SCM_EOL);
2018#endif
0f2d19dd
JB
2019 x = SCM_CDR (x);
2020 if (SCM_NULLP (x)) {
6dbd0af5 2021 ENTER_APPLY;
0f2d19dd
JB
2022#ifdef CCLO
2023 evap2:
2024#endif
6dbd0af5
MD
2025 switch (SCM_TYP7 (proc))
2026 { /* have two arguments */
2027 case scm_tc7_subr_2:
2028 case scm_tc7_subr_2o:
2029 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2030 case scm_tc7_lsubr:
0f2d19dd 2031#ifdef DEVAL
6dbd0af5
MD
2032 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
2033#else
2034 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1, arg2, SCM_EOL)));
0f2d19dd 2035#endif
6dbd0af5
MD
2036 case scm_tc7_lsubr_2:
2037 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, SCM_EOL));
2038 case scm_tc7_rpsubr:
2039 case scm_tc7_asubr:
2040 RETURN (SCM_SUBRF (proc) (t.arg1, arg2));
2041#ifdef CCLO
2042 cclon:
2043 case scm_tc7_cclo:
0f2d19dd 2044#ifdef DEVAL
6dbd0af5
MD
2045 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc), proc,
2046 scm_cons (debug.info->a.args, SCM_EOL)));
0f2d19dd 2047#else
6dbd0af5
MD
2048 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc), proc,
2049 scm_cons2 (t.arg1, arg2,
2050 scm_cons (scm_eval_args (x, env), SCM_EOL))));
0f2d19dd 2051#endif
6dbd0af5
MD
2052 /* case scm_tc7_cclo:
2053 x = scm_cons(arg2, scm_eval_args(x, env));
2054 arg2 = t.arg1;
2055 t.arg1 = proc;
2056 proc = SCM_CCLO_SUBR(proc);
2057 goto evap3; */
2058#endif
2059 case scm_tc7_subr_0:
2060 case scm_tc7_cxr:
2061 case scm_tc7_subr_1o:
2062 case scm_tc7_subr_1:
2063 case scm_tc7_subr_3:
2064 case scm_tc7_contin:
2065 goto wrongnumargs;
2066 default:
2067 goto badfun;
2068 case scm_tcs_closures:
0f2d19dd 2069#ifdef DEVAL
e2806c10 2070 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), debug.info->a.args, SCM_ENV (proc));
0f2d19dd 2071#else
e2806c10 2072 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), scm_cons2 (t.arg1, arg2, SCM_EOL), SCM_ENV (proc));
0f2d19dd 2073#endif
6dbd0af5
MD
2074 x = SCM_CODE (proc);
2075 goto cdrxbegin;
2076 }
0f2d19dd
JB
2077 }
2078#ifdef DEVAL
6dbd0af5 2079 debug.info->a.args = scm_cons2 (t.arg1, arg2,
a23afe53 2080 scm_deval_args (x, env, SCM_CDRLOC (SCM_CDR (debug.info->a.args))));
0f2d19dd 2081#endif
6dbd0af5
MD
2082 ENTER_APPLY;
2083 switch (SCM_TYP7 (proc))
2084 { /* have 3 or more arguments */
0f2d19dd 2085#ifdef DEVAL
6dbd0af5
MD
2086 case scm_tc7_subr_3:
2087 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
2088 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, SCM_CAR (SCM_CDR (SCM_CDR (debug.info->a.args)))));
2089 case scm_tc7_asubr:
2090 /* t.arg1 = SCM_SUBRF(proc)(t.arg1, arg2);
2091 while SCM_NIMP(x) {
2092 t.arg1 = SCM_SUBRF(proc)(t.arg1, EVALCAR(x, env));
2093 x = SCM_CDR(x);
2094 }
2095 RETURN (t.arg1) */
2096 case scm_tc7_rpsubr:
2097 RETURN (SCM_APPLY (proc, t.arg1, scm_acons (arg2, SCM_CDR (SCM_CDR (debug.info->a.args)), SCM_EOL)))
2098 case scm_tc7_lsubr_2:
2099 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, SCM_CDR (SCM_CDR (debug.info->a.args))))
2100 case scm_tc7_lsubr:
2101 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
0f2d19dd 2102#ifdef CCLO
6dbd0af5
MD
2103 case scm_tc7_cclo:
2104 goto cclon;
0f2d19dd 2105#endif
6dbd0af5 2106 case scm_tcs_closures:
b7ff98dd 2107 SCM_SET_ARGSREADY (debug);
e2806c10 2108 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
6dbd0af5
MD
2109 debug.info->a.args,
2110 SCM_ENV (proc));
2111 x = SCM_CODE (proc);
2112 goto cdrxbegin;
2113#else /* DEVAL */
2114 case scm_tc7_subr_3:
2115 SCM_ASRTGO (SCM_NULLP (SCM_CDR (x)), wrongnumargs);
2116 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, EVALCAR (x, env)));
2117 case scm_tc7_asubr:
2118 /* t.arg1 = SCM_SUBRF(proc)(t.arg1, arg2);
2119 while SCM_NIMP(x) {
2120 t.arg1 = SCM_SUBRF(proc)(t.arg1, EVALCAR(x, env));
2121 x = SCM_CDR(x);
2122 }
2123 RETURN (t.arg1) */
2124 case scm_tc7_rpsubr:
2125 RETURN (SCM_APPLY (proc, t.arg1, scm_acons (arg2, scm_eval_args (x, env), SCM_EOL)));
2126 case scm_tc7_lsubr_2:
2127 RETURN (SCM_SUBRF (proc) (t.arg1, arg2, scm_eval_args (x, env)));
2128 case scm_tc7_lsubr:
2129 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1, arg2, scm_eval_args (x, env))));
0f2d19dd 2130#ifdef CCLO
6dbd0af5
MD
2131 case scm_tc7_cclo:
2132 goto cclon;
0f2d19dd 2133#endif
6dbd0af5
MD
2134 case scm_tcs_closures:
2135#ifdef DEVAL
b7ff98dd 2136 SCM_SET_ARGSREADY (debug);
6dbd0af5 2137#endif
e2806c10 2138 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
6dbd0af5
MD
2139 scm_cons2 (t.arg1, arg2, scm_eval_args (x, env)),
2140 SCM_ENV (proc));
2141 x = SCM_CODE (proc);
2142 goto cdrxbegin;
0f2d19dd 2143#endif /* DEVAL */
6dbd0af5
MD
2144 case scm_tc7_subr_2:
2145 case scm_tc7_subr_1o:
2146 case scm_tc7_subr_2o:
2147 case scm_tc7_subr_0:
2148 case scm_tc7_cxr:
2149 case scm_tc7_subr_1:
2150 case scm_tc7_contin:
2151 goto wrongnumargs;
2152 default:
2153 goto badfun;
2154 }
0f2d19dd
JB
2155 }
2156#ifdef DEVAL
6dbd0af5
MD
2157exit:
2158 if (CHECK_EXIT)
b7ff98dd 2159 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 2160 {
b7ff98dd
MD
2161 SCM_EXIT_FRAME_P = 0;
2162 SCM_RESET_DEBUG_MODE;
2163 SCM_CLEAR_TRACED_FRAME (debug);
2164 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 2165 t.arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
2166 else
2167 {
2168 scm_make_cont (&t.arg1);
2169 if (setjmp (SCM_JMPBUF (t.arg1)))
2170 {
2171 proc = SCM_THROW_VALUE (t.arg1);
2172 goto ret;
2173 }
2174 }
2175 scm_ithrow (scm_i_exit_frame, scm_cons2 (t.arg1, proc, SCM_EOL), 0);
2176 }
2177ret:
1646d37b 2178 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
2179 return proc;
2180#endif
2181}
2182
6dbd0af5
MD
2183
2184/* SECTION: This code is compiled once.
2185 */
2186
0f2d19dd
JB
2187#ifndef DEVAL
2188
2189SCM_PROC(s_procedure_documentation, "procedure-documentation", 1, 0, 0, scm_procedure_documentation);
1cc91f1b 2190
0f2d19dd
JB
2191SCM
2192scm_procedure_documentation (proc)
2193 SCM proc;
0f2d19dd
JB
2194{
2195 SCM code;
2196 SCM_ASSERT (SCM_BOOL_T == scm_procedure_p (proc) && SCM_NIMP (proc) && SCM_TYP7 (proc) != scm_tc7_contin,
2197 proc, SCM_ARG1, s_procedure_documentation);
2198 switch (SCM_TYP7 (proc))
2199 {
2200 case scm_tcs_closures:
2201 code = SCM_CDR (SCM_CODE (proc));
2202 if (SCM_IMP (SCM_CDR (code)))
2203 return SCM_BOOL_F;
2204 code = SCM_CAR (code);
2205 if (SCM_IMP (code))
2206 return SCM_BOOL_F;
2207 if (SCM_STRINGP (code))
2208 return code;
2209 default:
2210 return SCM_BOOL_F;
2211/*
2212 case scm_tcs_subrs:
2213#ifdef CCLO
2214 case scm_tc7_cclo:
2215#endif
2216*/
2217 }
2218}
2219
b145c172
JB
2220/* This code processes the 'arg ...' parameters to apply.
2221
2222 (apply PROC ARG1 ... ARGS)
2223
2224 The ARG1 ... arguments are consed on to the front of ARGS (which
2225 must be a list), and then PROC is applied to the elements of the
2226 result. apply:nconc2last takes care of building the list of
2227 arguments, given (ARG1 ... ARGS).
2228
2229 apply:nconc2last destroys its argument. On that topic, this code
2230 came into my care with the following beautifully cryptic comment on
2231 that topic: "This will only screw you if you do (scm_apply
2232 scm_apply '( ... ))" If you know what they're referring to, send
2233 me a patch to this comment. */
2234
0f2d19dd 2235SCM_PROC(s_nconc2last, "apply:nconc2last", 1, 0, 0, scm_nconc2last);
1cc91f1b 2236
0f2d19dd
JB
2237SCM
2238scm_nconc2last (lst)
2239 SCM lst;
0f2d19dd
JB
2240{
2241 SCM *lloc;
b145c172 2242 SCM_ASSERT (scm_ilength (lst) > 0, lst, SCM_ARG1, s_nconc2last);
0f2d19dd
JB
2243 lloc = &lst;
2244 while (SCM_NNULLP (SCM_CDR (*lloc)))
a23afe53 2245 lloc = SCM_CDRLOC (*lloc);
b145c172 2246 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, s_nconc2last);
0f2d19dd
JB
2247 *lloc = SCM_CAR (*lloc);
2248 return lst;
2249}
2250
2251#endif /* !DEVAL */
2252
6dbd0af5
MD
2253
2254/* SECTION: When DEVAL is defined this code yields scm_dapply.
2255 * It is compiled twice.
2256 */
2257
0f2d19dd 2258#if 0
1cc91f1b 2259
0f2d19dd
JB
2260SCM
2261scm_apply (proc, arg1, args)
2262 SCM proc;
2263 SCM arg1;
2264 SCM args;
0f2d19dd
JB
2265{}
2266#endif
2267
2268#if 0
1cc91f1b 2269
0f2d19dd
JB
2270SCM
2271scm_dapply (proc, arg1, args)
2272 SCM proc;
2273 SCM arg1;
2274 SCM args;
0f2d19dd
JB
2275{}
2276#endif
2277
1cc91f1b 2278
0f2d19dd
JB
2279SCM
2280SCM_APPLY (proc, arg1, args)
2281 SCM proc;
2282 SCM arg1;
2283 SCM args;
0f2d19dd
JB
2284{
2285#ifdef DEBUG_EXTENSIONS
2286#ifdef DEVAL
6dbd0af5 2287 scm_debug_frame debug;
c0ab1b8d 2288 scm_debug_info debug_vect_body;
1646d37b 2289 debug.prev = scm_last_debug_frame;
b7ff98dd 2290 debug.status = SCM_APPLYFRAME;
c0ab1b8d 2291 debug.vect = &debug_vect_body;
6dbd0af5
MD
2292 debug.vect[0].a.proc = proc;
2293 debug.vect[0].a.args = SCM_EOL;
1646d37b 2294 scm_last_debug_frame = &debug;
0f2d19dd 2295#else
b7ff98dd 2296 if (SCM_DEBUGGINGP)
0f2d19dd
JB
2297 return scm_dapply (proc, arg1, args);
2298#endif
2299#endif
2300
2301 SCM_ASRTGO (SCM_NIMP (proc), badproc);
2302 if (SCM_NULLP (args))
2303 {
2304 if (SCM_NULLP (arg1))
2305 arg1 = SCM_UNDEFINED;
2306 else
2307 {
2308 args = SCM_CDR (arg1);
2309 arg1 = SCM_CAR (arg1);
2310 }
2311 }
2312 else
2313 {
2314 /* SCM_ASRTGO(SCM_NIMP(args) && SCM_CONSP(args), wrongnumargs); */
2315 args = scm_nconc2last (args);
2316 }
0f2d19dd 2317#ifdef DEVAL
6dbd0af5 2318 debug.vect[0].a.args = scm_cons (arg1, args);
b7ff98dd 2319 if (SCM_ENTER_FRAME_P)
6dbd0af5
MD
2320 {
2321 SCM tmp;
b7ff98dd
MD
2322 SCM_ENTER_FRAME_P = 0;
2323 SCM_RESET_DEBUG_MODE;
2324 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 2325 tmp = scm_make_debugobj (&debug);
6dbd0af5
MD
2326 else
2327 {
2328 scm_make_cont (&tmp);
2329 if (setjmp (SCM_JMPBUF (tmp)))
2330 goto entap;
2331 }
2332 scm_ithrow (scm_i_enter_frame, scm_cons (tmp, SCM_EOL), 0);
2333 }
2334entap:
2335 ENTER_APPLY;
2336#endif
2337#ifdef CCLO
2338tail:
0f2d19dd
JB
2339#endif
2340 switch (SCM_TYP7 (proc))
2341 {
2342 case scm_tc7_subr_2o:
2343 args = SCM_NULLP (args) ? SCM_UNDEFINED : SCM_CAR (args);
2344 RETURN (SCM_SUBRF (proc) (arg1, args))
2345 case scm_tc7_subr_2:
2346 SCM_ASRTGO (SCM_NULLP (SCM_CDR (args)), wrongnumargs);
2347 args = SCM_CAR (args);
2348 RETURN (SCM_SUBRF (proc) (arg1, args))
2349 case scm_tc7_subr_0:
2350 SCM_ASRTGO (SCM_UNBNDP (arg1), wrongnumargs);
2351 RETURN (SCM_SUBRF (proc) ())
2352 case scm_tc7_subr_1:
2353 case scm_tc7_subr_1o:
2354 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
2355 RETURN (SCM_SUBRF (proc) (arg1))
2356 case scm_tc7_cxr:
2357 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
2358#ifdef SCM_FLOATS
2359 if (SCM_SUBRF (proc))
2360 {
6dbd0af5
MD
2361 if (SCM_INUMP (arg1))
2362 {
2363 RETURN (scm_makdbl (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1)), 0.0));
2364 }
0f2d19dd 2365 SCM_ASRTGO (SCM_NIMP (arg1), floerr);
6dbd0af5
MD
2366 if (SCM_REALP (arg1))
2367 {
2368 RETURN (scm_makdbl (SCM_DSUBRF (proc) (SCM_REALPART (arg1)), 0.0));
2369 }
0f2d19dd
JB
2370#ifdef SCM_BIGDIG
2371 if SCM_BIGP
2372 (arg1)
2373 RETURN (scm_makdbl (SCM_DSUBRF (proc) (scm_big2dbl (arg1)), 0.0))
2374#endif
2375 floerr:
2376 scm_wta (arg1, (char *) SCM_ARG1, SCM_CHARS (SCM_SNAME (proc)));
2377 }
2378#endif
2379 proc = (SCM) SCM_SNAME (proc);
2380 {
2381 char *chrs = SCM_CHARS (proc) + SCM_LENGTH (proc) - 1;
2382 while ('c' != *--chrs)
2383 {
2384 SCM_ASSERT (SCM_NIMP (arg1) && SCM_CONSP (arg1),
2385 arg1, SCM_ARG1, SCM_CHARS (proc));
2386 arg1 = ('a' == *chrs) ? SCM_CAR (arg1) : SCM_CDR (arg1);
2387 }
2388 RETURN (arg1)
2389 }
2390 case scm_tc7_subr_3:
2391 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CAR (SCM_CDR (args))))
2392 case scm_tc7_lsubr:
2393#ifdef DEVAL
6dbd0af5 2394 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args))
0f2d19dd
JB
2395#else
2396 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args)))
2397#endif
2398 case scm_tc7_lsubr_2:
2399 SCM_ASRTGO (SCM_NIMP (args) && SCM_CONSP (args), wrongnumargs);
2400 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CDR (args)))
2401 case scm_tc7_asubr:
2402 if (SCM_NULLP (args))
2403 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED))
2404 while (SCM_NIMP (args))
2405 {
2406 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
2407 arg1 = SCM_SUBRF (proc) (arg1, SCM_CAR (args));
2408 args = SCM_CDR (args);
2409 }
2410 RETURN (arg1);
2411 case scm_tc7_rpsubr:
2412 if (SCM_NULLP (args))
2413 RETURN (SCM_BOOL_T);
2414 while (SCM_NIMP (args))
2415 {
2416 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
2417 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, SCM_CAR (args))))
2418 RETURN (SCM_BOOL_F);
2419 arg1 = SCM_CAR (args);
2420 args = SCM_CDR (args);
2421 }
2422 RETURN (SCM_BOOL_T);
2423 case scm_tcs_closures:
2424#ifdef DEVAL
6dbd0af5 2425 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args);
0f2d19dd
JB
2426#else
2427 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args));
2428#endif
2429#ifndef RECKLESS
2430 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), arg1))
2431 goto wrongnumargs;
2432#endif
e2806c10 2433 args = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), arg1, SCM_ENV (proc));
0f2d19dd
JB
2434 proc = SCM_CODE (proc);
2435 while (SCM_NNULLP (proc = SCM_CDR (proc)))
2436 arg1 = EVALCAR (proc, args);
2437 RETURN (arg1);
2438 case scm_tc7_contin:
2439 SCM_ASRTGO (SCM_NULLP (args), wrongnumargs);
2440 scm_call_continuation (proc, arg1);
2441#ifdef CCLO
2442 case scm_tc7_cclo:
2443#ifdef DEVAL
6dbd0af5
MD
2444 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
2445 arg1 = proc;
2446 proc = SCM_CCLO_SUBR (proc);
2447 debug.vect[0].a.proc = proc;
2448 debug.vect[0].a.args = scm_cons (arg1, args);
0f2d19dd
JB
2449#else
2450 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
0f2d19dd
JB
2451 arg1 = proc;
2452 proc = SCM_CCLO_SUBR (proc);
6dbd0af5 2453#endif
0f2d19dd
JB
2454 goto tail;
2455#endif
2456 wrongnumargs:
f5bf2977 2457 scm_wrong_num_args (proc);
0f2d19dd
JB
2458 default:
2459 badproc:
2460 scm_wta (proc, (char *) SCM_ARG1, "apply");
2461 RETURN (arg1);
2462 }
2463#ifdef DEVAL
6dbd0af5
MD
2464exit:
2465 if (CHECK_EXIT)
b7ff98dd 2466 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 2467 {
b7ff98dd
MD
2468 SCM_EXIT_FRAME_P = 0;
2469 SCM_RESET_DEBUG_MODE;
2470 SCM_CLEAR_TRACED_FRAME (debug);
2471 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 2472 arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
2473 else
2474 {
2475 scm_make_cont (&arg1);
2476 if (setjmp (SCM_JMPBUF (arg1)))
2477 {
2478 proc = SCM_THROW_VALUE (arg1);
2479 goto ret;
2480 }
2481 }
2482 scm_ithrow (scm_i_exit_frame, scm_cons2 (arg1, proc, SCM_EOL), 0);
2483 }
2484ret:
1646d37b 2485 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
2486 return proc;
2487#endif
2488}
2489
6dbd0af5
MD
2490
2491/* SECTION: The rest of this file is only read once.
2492 */
2493
0f2d19dd
JB
2494#ifndef DEVAL
2495
2496SCM_PROC(s_map, "map", 2, 0, 1, scm_map);
1cc91f1b 2497
0f2d19dd
JB
2498SCM
2499scm_map (proc, arg1, args)
2500 SCM proc;
2501 SCM arg1;
2502 SCM args;
0f2d19dd
JB
2503{
2504 long i;
2505 SCM res = SCM_EOL;
2506 SCM *pres = &res;
2507 SCM *ve = &args; /* Keep args from being optimized away. */
2508
2509 if (SCM_NULLP (arg1))
2510 return res;
2511 SCM_ASSERT (SCM_NIMP (arg1), arg1, SCM_ARG2, s_map);
2512 if (SCM_NULLP (args))
2513 {
2514 while (SCM_NIMP (arg1))
2515 {
2516 SCM_ASSERT (SCM_CONSP (arg1), arg1, SCM_ARG2, s_map);
2517 *pres = scm_cons (scm_apply (proc, SCM_CAR (arg1), scm_listofnull), SCM_EOL);
a23afe53 2518 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
2519 arg1 = SCM_CDR (arg1);
2520 }
2521 return res;
2522 }
2523 args = scm_vector (scm_cons (arg1, args));
2524 ve = SCM_VELTS (args);
2525#ifndef RECKLESS
2526 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
2527 SCM_ASSERT (SCM_NIMP (ve[i]) && SCM_CONSP (ve[i]), args, SCM_ARG2, s_map);
2528#endif
2529 while (1)
2530 {
2531 arg1 = SCM_EOL;
2532 for (i = SCM_LENGTH (args) - 1; i >= 0; i--)
2533 {
2534 if SCM_IMP
2535 (ve[i]) return res;
2536 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
2537 ve[i] = SCM_CDR (ve[i]);
2538 }
2539 *pres = scm_cons (scm_apply (proc, arg1, SCM_EOL), SCM_EOL);
a23afe53 2540 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
2541 }
2542}
2543
2544
2545SCM_PROC(s_for_each, "for-each", 2, 0, 1, scm_for_each);
1cc91f1b 2546
0f2d19dd
JB
2547SCM
2548scm_for_each (proc, arg1, args)
2549 SCM proc;
2550 SCM arg1;
2551 SCM args;
0f2d19dd
JB
2552{
2553 SCM *ve = &args; /* Keep args from being optimized away. */
2554 long i;
2555 if SCM_NULLP (arg1)
2556 return SCM_UNSPECIFIED;
2557 SCM_ASSERT (SCM_NIMP (arg1), arg1, SCM_ARG2, s_for_each);
2558 if SCM_NULLP (args)
2559 {
2560 while SCM_NIMP (arg1)
2561 {
2562 SCM_ASSERT (SCM_CONSP (arg1), arg1, SCM_ARG2, s_for_each);
2563 scm_apply (proc, SCM_CAR (arg1), scm_listofnull);
2564 arg1 = SCM_CDR (arg1);
2565 }
2566 return SCM_UNSPECIFIED;
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_for_each);
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 SCM_UNSPECIFIED;
2581 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
2582 ve[i] = SCM_CDR (ve[i]);
2583 }
2584 scm_apply (proc, arg1, SCM_EOL);
2585 }
2586}
2587
2588
1cc91f1b 2589
0f2d19dd
JB
2590SCM
2591scm_closure (code, env)
2592 SCM code;
2593 SCM env;
0f2d19dd
JB
2594{
2595 register SCM z;
2596 SCM_NEWCELL (z);
2597 SCM_SETCODE (z, code);
a23afe53 2598 SCM_SETENV (z, env);
0f2d19dd
JB
2599 return z;
2600}
2601
2602
2603long scm_tc16_promise;
1cc91f1b 2604
0f2d19dd
JB
2605SCM
2606scm_makprom (code)
2607 SCM code;
0f2d19dd
JB
2608{
2609 register SCM z;
2610 SCM_NEWCELL (z);
a23afe53
MD
2611 SCM_SETCDR (z, code);
2612 SCM_SETCAR (z, scm_tc16_promise);
0f2d19dd
JB
2613 return z;
2614}
2615
2616
1cc91f1b
JB
2617
2618static int prinprom SCM_P ((SCM exp, SCM port, scm_print_state *pstate));
2619
0f2d19dd 2620static int
19402679 2621prinprom (exp, port, pstate)
0f2d19dd
JB
2622 SCM exp;
2623 SCM port;
19402679 2624 scm_print_state *pstate;
0f2d19dd 2625{
19402679 2626 int writingp = SCM_WRITINGP (pstate);
0f2d19dd 2627 scm_gen_puts (scm_regular_string, "#<promise ", port);
19402679
MD
2628 SCM_SET_WRITINGP (pstate, 1);
2629 scm_iprin1 (SCM_CDR (exp), port, pstate);
2630 SCM_SET_WRITINGP (pstate, writingp);
0f2d19dd
JB
2631 scm_gen_putc ('>', port);
2632 return !0;
2633}
2634
2635
2636SCM_PROC(s_makacro, "procedure->syntax", 1, 0, 0, scm_makacro);
1cc91f1b 2637
0f2d19dd
JB
2638SCM
2639scm_makacro (code)
2640 SCM code;
0f2d19dd
JB
2641{
2642 register SCM z;
2643 SCM_NEWCELL (z);
a23afe53
MD
2644 SCM_SETCDR (z, code);
2645 SCM_SETCAR (z, scm_tc16_macro);
0f2d19dd
JB
2646 return z;
2647}
2648
2649
2650SCM_PROC(s_makmacro, "procedure->macro", 1, 0, 0, scm_makmacro);
1cc91f1b 2651
0f2d19dd
JB
2652SCM
2653scm_makmacro (code)
2654 SCM code;
0f2d19dd
JB
2655{
2656 register SCM z;
2657 SCM_NEWCELL (z);
a23afe53
MD
2658 SCM_SETCDR (z, code);
2659 SCM_SETCAR (z, scm_tc16_macro | (1L << 16));
0f2d19dd
JB
2660 return z;
2661}
2662
2663
2664SCM_PROC(s_makmmacro, "procedure->memoizing-macro", 1, 0, 0, scm_makmmacro);
1cc91f1b 2665
0f2d19dd
JB
2666SCM
2667scm_makmmacro (code)
2668 SCM code;
0f2d19dd
JB
2669{
2670 register SCM z;
2671 SCM_NEWCELL (z);
a23afe53
MD
2672 SCM_SETCDR (z, code);
2673 SCM_SETCAR (z, scm_tc16_macro | (2L << 16));
0f2d19dd
JB
2674 return z;
2675}
2676
2677
1cc91f1b
JB
2678
2679static int prinmacro SCM_P ((SCM exp, SCM port, scm_print_state *pstate));
2680
0f2d19dd 2681static int
19402679 2682prinmacro (exp, port, pstate)
0f2d19dd
JB
2683 SCM exp;
2684 SCM port;
19402679 2685 scm_print_state *pstate;
0f2d19dd 2686{
19402679 2687 int writingp = SCM_WRITINGP (pstate);
0f2d19dd
JB
2688 if (SCM_CAR (exp) & (3L << 16))
2689 scm_gen_puts (scm_regular_string, "#<macro", port);
2690 else
2691 scm_gen_puts (scm_regular_string, "#<syntax", port);
2692 if (SCM_CAR (exp) & (2L << 16))
2693 scm_gen_putc ('!', port);
2694 scm_gen_putc (' ', port);
19402679
MD
2695 SCM_SET_WRITINGP (pstate, 1);
2696 scm_iprin1 (SCM_CDR (exp), port, pstate);
2697 SCM_SET_WRITINGP (pstate, writingp);
0f2d19dd
JB
2698 scm_gen_putc ('>', port);
2699 return !0;
2700}
2701
2702SCM_PROC(s_force, "force", 1, 0, 0, scm_force);
1cc91f1b 2703
0f2d19dd
JB
2704SCM
2705scm_force (x)
2706 SCM x;
0f2d19dd
JB
2707{
2708 SCM_ASSERT ((SCM_TYP16 (x) == scm_tc16_promise), x, SCM_ARG1, s_force);
2709 if (!((1L << 16) & SCM_CAR (x)))
2710 {
2711 SCM ans = scm_apply (SCM_CDR (x), SCM_EOL, SCM_EOL);
2712 if (!((1L << 16) & SCM_CAR (x)))
2713 {
2714 SCM_DEFER_INTS;
a23afe53
MD
2715 SCM_SETCDR (x, ans);
2716 SCM_SETOR_CAR (x, (1L << 16));
0f2d19dd
JB
2717 SCM_ALLOW_INTS;
2718 }
2719 }
2720 return SCM_CDR (x);
2721}
2722
2723SCM_PROC (s_promise_p, "promise?", 1, 0, 0, scm_promise_p);
1cc91f1b 2724
0f2d19dd
JB
2725SCM
2726scm_promise_p (x)
2727 SCM x;
0f2d19dd
JB
2728{
2729 return ((SCM_NIMP (x) && (SCM_TYP16 (x) == scm_tc16_promise))
2730 ? SCM_BOOL_T
2731 : SCM_BOOL_F);
2732}
2733
2734SCM_PROC(s_copy_tree, "copy-tree", 1, 0, 0, scm_copy_tree);
1cc91f1b 2735
0f2d19dd
JB
2736SCM
2737scm_copy_tree (obj)
2738 SCM obj;
0f2d19dd
JB
2739{
2740 SCM ans, tl;
2741 if SCM_IMP
2742 (obj) return obj;
2743 if (SCM_VECTORP (obj))
2744 {
2745 scm_sizet i = SCM_LENGTH (obj);
2746 ans = scm_make_vector (SCM_MAKINUM (i), SCM_UNSPECIFIED, SCM_UNDEFINED);
2747 while (i--)
2748 SCM_VELTS (ans)[i] = scm_copy_tree (SCM_VELTS (obj)[i]);
2749 return ans;
2750 }
2751 if SCM_NCONSP (obj)
2752 return obj;
2753/* return scm_cons(scm_copy_tree(SCM_CAR(obj)), scm_copy_tree(SCM_CDR(obj))); */
2754 ans = tl = scm_cons (scm_copy_tree (SCM_CAR (obj)), SCM_UNSPECIFIED);
2755 while (SCM_NIMP (obj = SCM_CDR (obj)) && SCM_CONSP (obj))
a23afe53
MD
2756 {
2757 SCM_SETCDR (tl, scm_cons (scm_copy_tree (SCM_CAR (obj)),
2758 SCM_UNSPECIFIED));
2759 tl = SCM_CDR (tl);
2760 }
2761 SCM_SETCDR (tl, obj);
0f2d19dd
JB
2762 return ans;
2763}
2764
1cc91f1b 2765
0f2d19dd
JB
2766SCM
2767scm_eval_3 (obj, copyp, env)
2768 SCM obj;
2769 int copyp;
2770 SCM env;
0f2d19dd
JB
2771{
2772 if (SCM_NIMP (SCM_CDR (scm_system_transformer)))
2773 obj = scm_apply (SCM_CDR (scm_system_transformer), obj, scm_listofnull);
2774 else if (copyp)
2775 obj = scm_copy_tree (obj);
6dbd0af5 2776 return XEVAL (obj, env);
0f2d19dd
JB
2777}
2778
1cc91f1b 2779
0f2d19dd
JB
2780SCM
2781scm_top_level_env (thunk)
2782 SCM thunk;
0f2d19dd
JB
2783{
2784 if (SCM_IMP(thunk))
2785 return SCM_EOL;
2786 else
2787 return scm_cons(thunk, (SCM)SCM_EOL);
2788}
2789
2790SCM_PROC(s_eval2, "eval2", 2, 0, 0, scm_eval2);
1cc91f1b 2791
0f2d19dd
JB
2792SCM
2793scm_eval2 (obj, env_thunk)
2794 SCM obj;
2795 SCM env_thunk;
0f2d19dd
JB
2796{
2797 return scm_eval_3 (obj, 1, scm_top_level_env(env_thunk));
2798}
2799
2800SCM_PROC(s_eval, "eval", 1, 0, 0, scm_eval);
1cc91f1b 2801
0f2d19dd
JB
2802SCM
2803scm_eval (obj)
2804 SCM obj;
0f2d19dd
JB
2805{
2806 return
dc19d1d2 2807 scm_eval_3(obj, 1, scm_top_level_env(SCM_CDR(scm_top_level_lookup_closure_var)));
0f2d19dd
JB
2808}
2809
11f77bfc 2810/* SCM_PROC(s_eval_x, "eval!", 1, 0, 0, scm_eval_x); */
1cc91f1b 2811
0f2d19dd
JB
2812SCM
2813scm_eval_x (obj)
2814 SCM obj;
0f2d19dd
JB
2815{
2816 return
2817 scm_eval_3(obj,
2818 0,
dc19d1d2 2819 scm_top_level_env (SCM_CDR (scm_top_level_lookup_closure_var)));
0f2d19dd
JB
2820}
2821
2822SCM_PROC (s_macro_eval_x, "macro-eval!", 2, 0, 0, scm_macro_eval_x);
1cc91f1b 2823
0f2d19dd
JB
2824SCM
2825scm_macro_eval_x (exp, env)
2826 SCM exp;
2827 SCM env;
0f2d19dd
JB
2828{
2829 return scm_eval_3 (exp, 0, env);
2830}
2831
1cc91f1b 2832
ee33f8fa
MV
2833SCM_PROC (s_definedp, "defined?", 1, 0, 0, scm_definedp);
2834
0f2d19dd 2835SCM
ee33f8fa
MV
2836scm_definedp (sym)
2837 SCM sym;
0f2d19dd 2838{
ee33f8fa
MV
2839 SCM vcell;
2840
2841 if (SCM_ISYMP (sym))
0f2d19dd 2842 return SCM_BOOL_T;
ee33f8fa
MV
2843
2844 SCM_ASSERT (SCM_NIMP (sym) && SCM_SYMBOLP (sym), sym, SCM_ARG1, s_definedp);
2845
2846 vcell = scm_sym2vcell(sym,
0aa1e432 2847 SCM_CDR (scm_top_level_lookup_closure_var),
ee33f8fa
MV
2848 SCM_BOOL_F);
2849 return (vcell == SCM_BOOL_F || SCM_UNBNDP(SCM_CDR(vcell))) ?
2850 SCM_BOOL_F : SCM_BOOL_T;
0f2d19dd
JB
2851}
2852
2853static scm_smobfuns promsmob =
2854{scm_markcdr, scm_free0, prinprom};
2855
2856static scm_smobfuns macrosmob =
2857{scm_markcdr, scm_free0, prinmacro};
2858
1cc91f1b 2859
0f2d19dd
JB
2860SCM
2861scm_make_synt (name, macroizer, fcn)
2862 char *name;
2863 SCM (*macroizer) ();
2864 SCM (*fcn) ();
0f2d19dd
JB
2865{
2866 SCM symcell = scm_sysintern (name, SCM_UNDEFINED);
2867 long tmp = ((((SCM_CELLPTR) (SCM_CAR (symcell))) - scm_heap_org) << 8);
2868 register SCM z;
2869 if ((tmp >> 8) != ((SCM_CELLPTR) (SCM_CAR (symcell)) - scm_heap_org))
2870 tmp = 0;
2871 SCM_NEWCELL (z);
2872 SCM_SUBRF (z) = fcn;
a23afe53
MD
2873 SCM_SETCAR (z, tmp + scm_tc7_subr_2);
2874 SCM_SETCDR (symcell, macroizer (z));
0f2d19dd
JB
2875 return SCM_CAR (symcell);
2876}
2877
6dbd0af5
MD
2878
2879/* At this point, scm_deval and scm_dapply are generated.
2880 */
2881
0f2d19dd 2882#ifdef DEBUG_EXTENSIONS
6dbd0af5
MD
2883# define DEVAL
2884# include "eval.c"
0f2d19dd
JB
2885#endif
2886
2887
1cc91f1b 2888
0f2d19dd
JB
2889void
2890scm_init_eval ()
0f2d19dd 2891{
0f2d19dd
JB
2892 scm_tc16_promise = scm_newsmob (&promsmob);
2893 scm_tc16_macro = scm_newsmob (&macrosmob);
2894 scm_i_apply = scm_make_subr ("apply", scm_tc7_lsubr_2, scm_apply);
2895 scm_system_transformer = scm_sysintern ("scm:eval-transformer", SCM_UNDEFINED);
2896 scm_i_dot = SCM_CAR (scm_sysintern (".", SCM_UNDEFINED));
2897 scm_i_arrow = SCM_CAR (scm_sysintern ("=>", SCM_UNDEFINED));
2898 scm_i_else = SCM_CAR (scm_sysintern ("else", SCM_UNDEFINED));
2899 scm_i_unquote = SCM_CAR (scm_sysintern ("unquote", SCM_UNDEFINED));
2900 scm_i_uq_splicing = SCM_CAR (scm_sysintern ("unquote-splicing", SCM_UNDEFINED));
2901
2902 /* acros */
2903 scm_i_quasiquote = scm_make_synt (s_quasiquote, scm_makacro, scm_m_quasiquote);
6dbd0af5 2904 scm_make_synt (s_undefine, scm_makacro, scm_m_undefine);
0f2d19dd
JB
2905 scm_make_synt (s_delay, scm_makacro, scm_m_delay);
2906 /* end of acros */
2907
dc19d1d2
JB
2908 scm_top_level_lookup_closure_var =
2909 scm_sysintern("*top-level-lookup-closure*", SCM_BOOL_F);
9b8d3288 2910 scm_can_use_top_level_lookup_closure_var = 1;
0f2d19dd 2911
6dbd0af5
MD
2912 scm_i_and = scm_make_synt ("and", scm_makmmacro, scm_m_and);
2913 scm_i_begin = scm_make_synt ("begin", scm_makmmacro, scm_m_begin);
2914 scm_i_case = scm_make_synt ("case", scm_makmmacro, scm_m_case);
2915 scm_i_cond = scm_make_synt ("cond", scm_makmmacro, scm_m_cond);
2916 scm_i_define = scm_make_synt ("define", scm_makmmacro, scm_m_define);
2917 scm_i_do = scm_make_synt ("do", scm_makmmacro, scm_m_do);
2918 scm_i_if = scm_make_synt ("if", scm_makmmacro, scm_m_if);
0f2d19dd
JB
2919 scm_i_lambda = scm_make_synt ("lambda", scm_makmmacro, scm_m_lambda);
2920 scm_i_let = scm_make_synt ("let", scm_makmmacro, scm_m_let);
6dbd0af5
MD
2921 scm_i_letrec = scm_make_synt ("letrec", scm_makmmacro, scm_m_letrec);
2922 scm_i_letstar = scm_make_synt ("let*", scm_makmmacro, scm_m_letstar);
2923 scm_i_or = scm_make_synt ("or", scm_makmmacro, scm_m_or);
0f2d19dd 2924 scm_i_quote = scm_make_synt ("quote", scm_makmmacro, scm_m_quote);
6dbd0af5
MD
2925 scm_i_set = scm_make_synt ("set!", scm_makmmacro, scm_m_set);
2926 scm_i_atapply = scm_make_synt ("@apply", scm_makmmacro, scm_m_apply);
2927 scm_i_atcall_cc = scm_make_synt ("@call-with-current-continuation",
2928 scm_makmmacro, scm_m_cont);
2929
6dbd0af5
MD
2930#ifdef DEBUG_EXTENSIONS
2931 scm_i_enter_frame = SCM_CAR (scm_sysintern ("enter-frame", SCM_UNDEFINED));
2932 scm_i_apply_frame = SCM_CAR (scm_sysintern ("apply-frame", SCM_UNDEFINED));
2933 scm_i_exit_frame = SCM_CAR (scm_sysintern ("exit-frame", SCM_UNDEFINED));
2934 scm_i_trace = SCM_CAR (scm_sysintern ("trace", SCM_UNDEFINED));
2935#endif
2936
0f2d19dd
JB
2937#include "eval.x"
2938}
0f2d19dd 2939
6dbd0af5 2940#endif /* !DEVAL */