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