*** empty log message ***
[bpt/guile.git] / libguile / eval.c
1 /* Copyright (C) 1995,1996,1997 Free Software Foundation, Inc.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
15 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
16 *
17 * As a special exception, the Free Software Foundation gives permission
18 * for additional uses of the text contained in its release of GUILE.
19 *
20 * The exception is that, if you link the GUILE library with other files
21 * to produce an executable, this does not by itself cause the
22 * resulting executable to be covered by the GNU General Public License.
23 * Your use of that executable is in no way restricted on account of
24 * linking the GUILE library code into it.
25 *
26 * This exception does not however invalidate any other reasons why
27 * the executable file might be covered by the GNU General Public License.
28 *
29 * This exception applies only to the code released by the
30 * Free Software Foundation under the name GUILE. If you copy
31 * code from other Free Software Foundation releases into a copy of
32 * GUILE, as the General Public License permits, the exception does
33 * not apply to the code that you add in this way. To avoid misleading
34 * anyone as to the status of such modified files, you must delete
35 * this exception notice from them.
36 *
37 * If you write modifications of your own for GUILE, it is your choice
38 * whether to permit this exception to apply to your modifications.
39 * If you do not wish that, delete this exception notice.
40 */
41 \f
42
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.
53 */
54
55 #ifndef DEVAL
56
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. */
60 #ifndef __GNUC__
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 */
68 char *alloca ();
69 # endif
70 # endif
71 # endif
72 #endif
73
74 #include <stdio.h>
75 #include "_scm.h"
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"
87 #include "hash.h"
88
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"
97 \f
98
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
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
140 #define EVALIM(x, env) (SCM_ILOCP(x)?*scm_ilookup((x), env):x)
141 #else
142 #define EVALIM(x, env) x
143 #endif
144 #define EVALCAR(x, env) (SCM_NCELLP(SCM_CAR(x))\
145 ? (SCM_IMP(SCM_CAR(x)) \
146 ? EVALIM(SCM_CAR(x), env) \
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)) \
152 ? EVALIM(SCM_CAR(x), env) \
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
161 #define EXTEND_ENV SCM_EXTEND_ENV
162
163 #ifdef MEMOIZE_LOCALS
164
165 SCM *
166 scm_ilookup (iloc, env)
167 SCM iloc;
168 SCM env;
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))
178 return SCM_CDRLOC (er);
179 return SCM_CARLOC (SCM_CDR (er));
180 }
181 #endif
182
183
184 SCM *
185 scm_lookupcar (vloc, genv)
186 SCM vloc;
187 SCM genv;
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;
198 al = SCM_CARLOC (env);
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
205 SCM_SETCAR (vloc, iloc + SCM_ICDR);
206 #endif
207 return SCM_CDRLOC (*al);
208 }
209 else
210 break;
211 al = SCM_CDRLOC (*al);
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
222 SCM_SETCAR (vloc, iloc);
223 #endif
224 return SCM_CARLOC (*al);
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:
254 /* scm_everr (vloc, genv,...) */
255 scm_misc_error (NULL,
256 SCM_NULLP (env)
257 ? "Unbound variable: %S"
258 : "Damaged environment: %S",
259 scm_listify (var, SCM_UNDEFINED));
260 }
261 #endif
262 SCM_SETCAR (vloc, var + 1);
263 /* Except wait...what if the var is not a vcell,
264 * but syntax or something....
265 */
266 return SCM_CDRLOC (var);
267 }
268
269 #define unmemocar scm_unmemocar
270
271 SCM
272 scm_unmemocar (form, env)
273 SCM form;
274 SCM env;
275 {
276 #ifdef DEBUG_EXTENSIONS
277 register int ir;
278 #endif
279 SCM c;
280
281 if (SCM_IMP (form))
282 return form;
283 c = SCM_CAR (form);
284 if (1 == (c & 7))
285 SCM_SETCAR (form, SCM_CAR (c - 1));
286 #ifdef MEMOIZE_LOCALS
287 #ifdef DEBUG_EXTENSIONS
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);
295 SCM_SETCAR (form, SCM_ICDRP (c) ? env : SCM_CAR (env));
296 }
297 #endif
298 #endif
299 return form;
300 }
301
302
303 SCM
304 scm_eval_car (pair, env)
305 SCM pair;
306 SCM env;
307 {
308 return XEVALCAR (pair, env);
309 }
310
311 \f
312 /*
313 * The following rewrite expressions and
314 * some memoized forms have different syntax
315 */
316
317 static char s_expression[] = "missing or extra expression";
318 static char s_test[] = "bad test";
319 static char s_body[] = "bad body";
320 static char s_bindings[] = "bad bindings";
321 static char s_variable[] = "bad variable";
322 static char s_clauses[] = "bad or missing clauses";
323 static char s_formals[] = "bad formals";
324 #define ASSYNT(_cond, _arg, _pos, _subr) if(!(_cond))scm_wta(_arg, (char *)_pos, _subr);
325
326 SCM 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;
328 SCM 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;
331 static char s_quasiquote[] = "quasiquote";
332 static char s_delay[] = "delay";
333 static char s_undefine[] = "undefine";
334 #ifdef DEBUG_EXTENSIONS
335 SCM scm_i_enter_frame, scm_i_apply_frame, scm_i_exit_frame;
336 SCM scm_i_trace;
337 #endif
338
339 #define ASRTSYNTAX(cond_, msg_) if(!(cond_))scm_wta(xorig, (msg_), what);
340
341
342
343 static void bodycheck SCM_P ((SCM xorig, SCM *bodyloc, char *what));
344
345 static void
346 bodycheck (xorig, bodyloc, what)
347 SCM xorig;
348 SCM *bodyloc;
349 char *what;
350 {
351 ASRTSYNTAX (scm_ilength (*bodyloc) >= 1, s_expression);
352 }
353
354
355
356 SCM
357 scm_m_quote (xorig, env)
358 SCM xorig;
359 SCM env;
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
366
367 SCM
368 scm_m_begin (xorig, env)
369 SCM xorig;
370 SCM env;
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
377
378 SCM
379 scm_m_if (xorig, env)
380 SCM xorig;
381 SCM env;
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
389
390 SCM
391 scm_m_set (xorig, env)
392 SCM xorig;
393 SCM env;
394 {
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!");
399 return scm_cons (SCM_IM_SET, x);
400 }
401
402
403 #if 0
404
405 SCM
406 scm_m_vref (xorig, env)
407 SCM xorig;
408 SCM env;
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 {
414 /* scm_everr (SCM_UNDEFINED, env,..., "global variable reference") */
415 scm_misc_error (NULL,
416 "Bad variable: %S",
417 scm_listify (SCM_CAR (SCM_CDR (x)), SCM_UNDEFINED));
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
426
427 SCM
428 scm_m_vset (xorig, env)
429 SCM xorig;
430 SCM env;
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
442
443 SCM
444 scm_m_and (xorig, env)
445 SCM xorig;
446 SCM env;
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
457
458 SCM
459 scm_m_or (xorig, env)
460 SCM xorig;
461 SCM env;
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
472
473 SCM
474 scm_m_case (xorig, env)
475 SCM xorig;
476 SCM env;
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
491
492 SCM
493 scm_m_cond (xorig, env)
494 SCM xorig;
495 SCM env;
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");
508 SCM_SETCAR (arg1, SCM_BOOL_T);
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
519
520 SCM
521 scm_m_lambda (xorig, env)
522 SCM xorig;
523 SCM env;
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");
553 memlambda:
554 bodycheck (xorig, SCM_CDRLOC (x), "lambda");
555 return scm_cons (SCM_IM_LAMBDA, SCM_CDR (xorig));
556 }
557
558
559
560 SCM
561 scm_m_letstar (xorig, env)
562 SCM xorig;
563 SCM env;
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*");
570 while SCM_NIMP (proc)
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);
576 varloc = SCM_CDRLOC (SCM_CDR (*varloc));
577 proc = SCM_CDR (proc);
578 }
579 x = scm_cons (vars, SCM_CDR (x));
580 bodycheck (xorig, SCM_CDRLOC (x), "let*");
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
599
600 SCM
601 scm_m_do (xorig, env)
602 SCM xorig;
603 SCM env;
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 */
623 initloc = SCM_CDRLOC (*initloc);
624 arg1 = SCM_CDR (arg1);
625 *steploc = scm_cons (SCM_IMP (arg1) ? SCM_CAR (vars) : SCM_CAR (arg1), SCM_EOL); /* step */
626 steploc = SCM_CDRLOC (*steploc);
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);
633 bodycheck (xorig, SCM_CARLOC (SCM_CDR (SCM_CDR (x))), "do");
634 return scm_cons (SCM_IM_DO, x);
635 }
636
637 /* evalcar is small version of inline EVALCAR when we don't care about
638 * speed
639 */
640 #define evalcar scm_eval_car
641
642
643 static SCM iqq SCM_P ((SCM form, SCM env, int depth));
644
645 static SCM
646 iqq (form, env, depth)
647 SCM form;
648 SCM env;
649 int depth;
650 {
651 SCM tmp;
652 int edepth = depth;
653 if SCM_IMP
654 (form) return form;
655 if (SCM_VECTORP (form))
656 {
657 long i = SCM_LENGTH (form);
658 SCM *data = SCM_VELTS (form);
659 tmp = SCM_EOL;
660 for (; --i >= 0;)
661 tmp = scm_cons (data[i], tmp);
662 return scm_vector (iqq (tmp, env, depth));
663 }
664 if SCM_NCONSP
665 (form) return form;
666 tmp = SCM_CAR (form);
667 if (scm_i_quasiquote == tmp)
668 {
669 depth++;
670 goto label;
671 }
672 if (scm_i_unquote == tmp)
673 {
674 --depth;
675 label:
676 form = SCM_CDR (form);
677 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
694
695 SCM
696 scm_m_quasiquote (xorig, env)
697 SCM xorig;
698 SCM env;
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
705
706 SCM
707 scm_m_delay (xorig, env)
708 SCM xorig;
709 SCM env;
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
717
718 static SCM env_top_level SCM_P ((SCM env));
719
720 static SCM
721 env_top_level (env)
722 SCM env;
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
733
734 SCM
735 scm_m_define (x, env)
736 SCM x;
737 SCM env;
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);
755 #ifdef DEBUG_EXTENSIONS
756 if (SCM_REC_PROCNAMES_P && SCM_NIMP (x) && SCM_CLOSUREP (x))
757 scm_set_procedure_property_x (x, scm_i_name, proc);
758 #endif
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));
769 #endif
770 SCM_SETCDR (arg1, x);
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 }
779
780 SCM
781 scm_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
803 SCM_SETCDR (arg1, SCM_UNDEFINED);
804 #ifdef SICP
805 return SCM_CAR (arg1);
806 #else
807 return SCM_UNSPECIFIED;
808 #endif
809 }
810
811 /* end of acros */
812
813
814 SCM
815 scm_m_letrec (xorig, env)
816 SCM xorig;
817 SCM env;
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);
837 initloc = SCM_CDRLOC (*initloc);
838 }
839 while SCM_NIMP
840 (proc = SCM_CDR (proc));
841 cdrx = scm_cons2 (vars, inits, SCM_CDR (x));
842 bodycheck (xorig, SCM_CDRLOC (SCM_CDR (cdrx)), what);
843 return scm_cons (SCM_IM_LETREC, cdrx);
844 }
845
846
847 SCM
848 scm_m_let (xorig, env)
849 SCM xorig;
850 SCM env;
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);
879 varloc = SCM_CDRLOC (*varloc);
880 *initloc = scm_cons (SCM_CAR (SCM_CDR (arg1)), SCM_EOL);
881 initloc = SCM_CDRLOC (*initloc);
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
892
893 SCM
894 scm_m_apply (xorig, env)
895 SCM xorig;
896 SCM env;
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
902 #define s_atcall_cc (SCM_ISYMCHARS(SCM_IM_CONT)+1)
903
904
905 SCM
906 scm_m_cont (xorig, env)
907 SCM xorig;
908 SCM env;
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
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
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.
921 */
922
923 static SCM unmemocopy SCM_P ((SCM x, SCM env));
924
925 static SCM
926 unmemocopy (x, env)
927 SCM x;
928 SCM env;
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);
970 z = EXTEND_ENV (f, SCM_EOL, env);
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);
991 z = scm_cons (z, SCM_UNSPECIFIED);
992 SCM_SETCDR (ls, z);
993 if (SCM_CAR (ls) == scm_i_do)
994 {
995 x = SCM_CDR (x);
996 SCM_SETCDR (z, scm_cons (unmemocopy (SCM_CAR (x), env),
997 SCM_UNSPECIFIED));
998 z = SCM_CDR (z);
999 x = (SCM) (SCM_CARLOC (SCM_CDR (x)) - 1);
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 {
1011 env = EXTEND_ENV (SCM_EOL, SCM_EOL, env);
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);
1018 env = EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
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 {
1028 SCM_SETCDR (z, scm_acons (SCM_CAR (b),
1029 unmemocar (
1030 scm_cons (unmemocopy (SCM_CAR (SCM_CDR (b)), env), SCM_EOL), env),
1031 SCM_UNSPECIFIED));
1032 z = SCM_CDR (z);
1033 env = EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
1034 b = SCM_CDR (SCM_CDR (b));
1035 }
1036 while SCM_NIMP (b);
1037 SCM_SETCDR (z, SCM_EOL);
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));
1049 env = EXTEND_ENV (SCM_CAR (x), SCM_EOL, env);
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))
1064 SCM_SETCAR (SCM_CAR (env), scm_cons (n, SCM_CAR (SCM_CAR (env))));
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:
1080 /* appease the Sun compiler god: */ ;
1081 }
1082 unmemo:
1083 default:
1084 ls = z = unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env),
1085 SCM_UNSPECIFIED),
1086 env);
1087 }
1088 loop:
1089 while (SCM_CELLP (x = SCM_CDR (x)) && SCM_ECONSP (x))
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);
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
1104
1105 SCM
1106 scm_unmemocopy (x, env)
1107 SCM x;
1108 SCM env;
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
1118 #ifndef RECKLESS
1119
1120 int
1121 scm_badargsp (formals, args)
1122 SCM formals;
1123 SCM args;
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
1141 long scm_tc16_macro;
1142
1143
1144 SCM
1145 scm_eval_args (l, env)
1146 SCM l;
1147 SCM env;
1148 {
1149 SCM res = SCM_EOL, *lloc = &res;
1150 while (SCM_NIMP (l))
1151 {
1152 *lloc = scm_cons (EVALCAR (l, env), SCM_EOL);
1153 lloc = SCM_CDRLOC (*lloc);
1154 l = SCM_CDR (l);
1155 }
1156 return res;
1157 }
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." */
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 */
1179 #define safe_setjmp(x) setjmp (x)
1180 static int
1181 unsafe_setjmp (jmp_buf env)
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
1192 #endif /* !DEVAL */
1193
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;
1206 #ifdef STACK_CHECKING
1207 #ifndef NO_CEVAL_STACK_CHECKING
1208 #define EVAL_STACK_CHECKING
1209 #endif
1210 #endif
1211
1212 #else /* !DEVAL */
1213
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
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 {\
1224 SCM_SET_ARGSREADY (debug);\
1225 if (CHECK_APPLY)\
1226 if (SCM_APPLY_FRAME_P || (SCM_TRACE_P && PROCTRACEP (proc)))\
1227 {\
1228 SCM tmp, tail = SCM_TRACED_FRAME_P (debug) ? SCM_BOOL_T : SCM_BOOL_F;\
1229 SCM_SET_TRACED_FRAME (debug); \
1230 SCM_APPLY_FRAME_P = 0; \
1231 SCM_TRACE_P = 0; \
1232 SCM_RESET_DEBUG_MODE; \
1233 if (SCM_CHEAPTRAPS_P)\
1234 {\
1235 tmp = scm_make_debugobj (&debug);\
1236 scm_ithrow (scm_i_apply_frame, scm_cons2 (tmp, tail, SCM_EOL), 0);\
1237 }\
1238 else\
1239 {\
1240 scm_make_cont (&tmp);\
1241 if (!safe_setjmp (SCM_JMPBUF (tmp)))\
1242 scm_ithrow (scm_i_apply_frame, scm_cons2 (tmp, tail, SCM_EOL), 0);\
1243 }\
1244 }\
1245 }
1246 #undef RETURN
1247 #define RETURN(e) {proc = (e); goto exit;}
1248 #ifdef STACK_CHECKING
1249 #ifndef EVAL_STACK_CHECKING
1250 #define EVAL_STACK_CHECKING
1251 #endif
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
1260
1261 SCM (*scm_ceval_ptr) SCM_P ((SCM x, SCM env));
1262
1263 /* scm_last_debug_frame contains a pointer to the last debugging
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
1270 #ifndef USE_THREADS
1271 scm_debug_frame *scm_last_debug_frame;
1272 #endif
1273
1274 /* scm_debug_eframe_size is the number of slots available for pseudo
1275 * stack frames at each real stack frame.
1276 */
1277
1278 int scm_debug_eframe_size;
1279
1280 int scm_debug_mode, scm_check_entry_p, scm_check_apply_p, scm_check_exit_p;
1281
1282 scm_option scm_debug_opts[] = {
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." },
1291 { SCM_OPTION_INTEGER, "indent", 10, "Maximal indentation in backtrace." },
1292 { SCM_OPTION_INTEGER, "frames", 3,
1293 "Maximum number of tail-recursive frames in backtrace." },
1294 { SCM_OPTION_INTEGER, "maxdepth", 1000,
1295 "Maximal number of stored backtrace frames." },
1296 { SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." },
1297 { SCM_OPTION_BOOLEAN, "backtrace", 0, "Show backtrace on error." },
1298 { SCM_OPTION_BOOLEAN, "debug", 0, "Use the debugging evaluator." },
1299 { SCM_OPTION_INTEGER, "stack", 20000, "Stack size limit (0 = no check)." }
1300 };
1301
1302 scm_option scm_evaluator_trap_table[] = {
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." }
1306 };
1307
1308 SCM
1309 scm_deval_args (l, env, lloc)
1310 SCM l, env, *lloc;
1311 {
1312 SCM *res = lloc;
1313 while (SCM_NIMP (l))
1314 {
1315 *lloc = scm_cons (EVALCAR (l, env), SCM_EOL);
1316 lloc = SCM_CDRLOC (*lloc);
1317 l = SCM_CDR (l);
1318 }
1319 return *res;
1320 }
1321
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
1336 #define BUILTIN_RPASUBR /* Handle rpsubrs and asubrs without calling apply */
1337
1338 /* SECTION: This is the evaluator. Like any real monster, it has
1339 * three heads. This code is compiled twice.
1340 */
1341
1342 #if 0
1343
1344 SCM
1345 scm_ceval (x, env)
1346 SCM x;
1347 SCM env;
1348 {}
1349 #endif
1350 #if 0
1351
1352 SCM
1353 scm_deval (x, env)
1354 SCM x;
1355 SCM env;
1356 {}
1357 #endif
1358
1359
1360 SCM
1361 SCM_CEVAL (x, env)
1362 SCM x;
1363 SCM env;
1364 {
1365 union
1366 {
1367 SCM *lloc;
1368 SCM arg1;
1369 } t;
1370 SCM proc, arg2;
1371 #ifdef DEVAL
1372 scm_debug_frame debug;
1373 scm_debug_info *debug_info_end;
1374 debug.prev = scm_last_debug_frame;
1375 debug.status = scm_debug_eframe_size;
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;
1381 #endif
1382 #ifdef EVAL_STACK_CHECKING
1383 if (SCM_STACK_OVERFLOW_P ((SCM_STACKITEM *) &proc)
1384 && scm_stack_checking_enabled_p)
1385 {
1386 #ifdef DEVAL
1387 debug.info->e.exp = x;
1388 debug.info->e.env = env;
1389 #endif
1390 scm_report_stack_overflow ();
1391 }
1392 #endif
1393 #ifdef DEVAL
1394 goto start;
1395 #endif
1396 loopnoap:
1397 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1398 loop:
1399 #ifdef DEVAL
1400 SCM_CLEAR_ARGSREADY (debug);
1401 if (SCM_OVERFLOWP (debug))
1402 --debug.info;
1403 else if (++debug.info >= debug_info_end)
1404 {
1405 SCM_SET_OVERFLOW (debug);
1406 debug.info -= 2;
1407 }
1408 start:
1409 debug.info->e.exp = x;
1410 debug.info->e.env = env;
1411 if (CHECK_ENTRY)
1412 if (SCM_ENTER_FRAME_P || (SCM_BREAKPOINTS_P && SRCBRKP (x)))
1413 {
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)
1419 t.arg1 = scm_make_debugobj (&debug);
1420 else
1421 {
1422 scm_make_cont (&t.arg1);
1423 if (safe_setjmp (SCM_JMPBUF (t.arg1)))
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 }
1441 dispatch:
1442 #endif
1443 SCM_ASYNC_TICK;
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;
1462 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1463 goto carloop;
1464
1465 case (127 & SCM_IM_BEGIN):
1466 cdrxnoap:
1467 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
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);
1483 RETURN (SCM_IMP (x) ? EVALIM (x, env) : SCM_GLOC_VAL (x))
1484 }
1485
1486 if (SCM_SYMBOLP (SCM_CAR (x)))
1487 {
1488 retval:
1489 RETURN (*scm_lookupcar (x, env))
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);
1505 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
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));
1514 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1515 goto begin;
1516 }
1517 proc = SCM_CDR (proc);
1518 }
1519 }
1520 RETURN (SCM_UNSPECIFIED)
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);
1531 if SCM_NULLP (x)
1532 {
1533 RETURN (t.arg1)
1534 }
1535 if (scm_i_arrow != SCM_CAR (x))
1536 {
1537 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
1538 goto begin;
1539 }
1540 proc = SCM_CDR (x);
1541 proc = EVALCAR (proc, env);
1542 SCM_ASRTGO (SCM_NIMP (proc), badfun);
1543 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
1544 ENTER_APPLY;
1545 goto evap1;
1546 }
1547 }
1548 RETURN (SCM_UNSPECIFIED)
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 }
1560 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
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 */
1571 env = EXTEND_ENV (SCM_CAR (SCM_CAR (env)), t.arg1, SCM_CDR (env));
1572 }
1573 x = SCM_CDR (proc);
1574 if (SCM_NULLP (x))
1575 RETURN (SCM_UNSPECIFIED);
1576 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
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 }
1588 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
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)));
1601 env = EXTEND_ENV (SCM_CAR (x), t.arg1, env);
1602 x = SCM_CDR (x);
1603 goto cdrxnoap;
1604
1605
1606 case (127 & SCM_IM_LETREC):
1607 x = SCM_CDR (x);
1608 env = EXTEND_ENV (SCM_CAR (x), scm_undefineds, env);
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)));
1617 SCM_SETCDR (SCM_CAR (env), t.arg1);
1618 goto cdrxnoap;
1619
1620
1621 case (127 & SCM_IM_LETSTAR):
1622 x = SCM_CDR (x);
1623 proc = SCM_CAR (x);
1624 if (SCM_IMP (proc))
1625 {
1626 env = EXTEND_ENV (SCM_EOL, SCM_EOL, env);
1627 goto cdrxnoap;
1628 }
1629 do
1630 {
1631 t.arg1 = SCM_CAR (proc);
1632 proc = SCM_CDR (proc);
1633 env = EXTEND_ENV (t.arg1, EVALCAR (proc, env), env);
1634 }
1635 while (SCM_NIMP (proc = SCM_CDR (proc)));
1636 goto cdrxnoap;
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 }
1650 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
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):
1663 x = SCM_CDR (x);
1664 proc = SCM_CAR (x);
1665 switch (7 & (int) proc)
1666 {
1667 case 0:
1668 t.lloc = scm_lookupcar (x, env);
1669 break;
1670 case 1:
1671 t.lloc = SCM_GLOC_VAL_LOC (proc);
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);
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);
1693 #ifdef DEBUG_EXTENSIONS
1694 if (SCM_REC_PROCNAMES_P && SCM_NIMP (x) && SCM_CLOSUREP (x))
1695 scm_set_procedure_property_x (x, scm_i_name, proc);
1696 #endif
1697 env = SCM_CAR (env);
1698 SCM_DEFER_INTS;
1699 SCM_SETCAR (env, scm_cons (proc, SCM_CAR (env)));
1700 SCM_SETCDR (env, scm_cons (x, SCM_CDR (env)));
1701 SCM_ALLOW_INTS;
1702 RETURN (SCM_UNSPECIFIED);
1703
1704
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;
1721 RETURN (SCM_UNSPECIFIED)
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 {
1730 PREP_APPLY (proc, SCM_EOL);
1731 t.arg1 = SCM_CDR (SCM_CDR (x));
1732 t.arg1 = EVALCAR (t.arg1, env);
1733 #ifdef DEVAL
1734 debug.info->a.args = t.arg1;
1735 #endif
1736 #ifndef RECKLESS
1737 if (scm_badargsp (SCM_CAR (SCM_CODE (proc)), t.arg1))
1738 goto wrongnumargs;
1739 #endif
1740 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), t.arg1, SCM_ENV (proc));
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);
1749 if (safe_setjmp (SCM_JMPBUF (t.arg1)))
1750 {
1751 SCM val;
1752 val = SCM_THROW_VALUE (t.arg1);
1753 RETURN (val);
1754 }
1755 proc = SCM_CDR (x);
1756 proc = evalcar (proc, env);
1757 SCM_ASRTGO (SCM_NIMP (proc), badfun);
1758 PREP_APPLY (proc, scm_cons (t.arg1, SCM_EOL));
1759 ENTER_APPLY;
1760 goto evap1;
1761
1762 default:
1763 goto badfun;
1764 }
1765
1766 default:
1767 proc = x;
1768 badfun:
1769 /* scm_everr (x, env,...) */
1770 scm_misc_error (NULL,
1771 "Wrong type to apply: %S",
1772 scm_listify (proc, SCM_UNDEFINED));
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);
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;
1852 SCM_SETCAR (x, SCM_CAR (t.arg1));
1853 SCM_SETCDR (x, SCM_CDR (t.arg1));
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
1862 SCM_DEFER_INTS;
1863 SCM_SETCAR (x, SCM_CAR (t.arg1));
1864 SCM_SETCDR (x, SCM_CDR (t.arg1));
1865 SCM_ALLOW_INTS;
1866 goto loopnoap;
1867 case 1:
1868 if (SCM_NIMP (x = t.arg1))
1869 goto loopnoap;
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
1904 evapply:
1905 PREP_APPLY (proc, SCM_EOL);
1906 if (SCM_NULLP (SCM_CDR (x))) {
1907 ENTER_APPLY;
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));
1920 #ifdef CCLO
1921 case scm_tc7_cclo:
1922 t.arg1 = proc;
1923 proc = SCM_CCLO_SUBR (proc);
1924 #ifdef DEVAL
1925 debug.info->a.proc = proc;
1926 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
1927 #endif
1928 goto evap1;
1929 #endif
1930 case scm_tcs_closures:
1931 x = SCM_CODE (proc);
1932 env = EXTEND_ENV (SCM_CAR (x), SCM_EOL, SCM_ENV (proc));
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:
1944 /* scm_everr (x, env,...) */
1945 scm_wrong_num_args (proc);
1946 default:
1947 /* handle macros here */
1948 goto badfun;
1949 }
1950 }
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);
1959 #ifdef DEVAL
1960 debug.info->a.args = scm_cons (t.arg1, SCM_EOL);
1961 #endif
1962 x = SCM_CDR (x);
1963 if (SCM_NULLP (x))
1964 {
1965 ENTER_APPLY;
1966 evap1:
1967 switch (SCM_TYP7 (proc))
1968 { /* have one argument in t.arg1 */
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
2015 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
2016 #else
2017 RETURN (SCM_SUBRF (proc) (scm_cons (t.arg1, SCM_EOL)));
2018 #endif
2019 #ifdef CCLO
2020 case scm_tc7_cclo:
2021 arg2 = t.arg1;
2022 t.arg1 = proc;
2023 proc = SCM_CCLO_SUBR (proc);
2024 #ifdef DEVAL
2025 debug.info->a.args = scm_cons (t.arg1, debug.info->a.args);
2026 debug.info->a.proc = proc;
2027 #endif
2028 goto evap2;
2029 #endif
2030 case scm_tcs_closures:
2031 x = SCM_CODE (proc);
2032 #ifdef DEVAL
2033 env = EXTEND_ENV (SCM_CAR (x), debug.info->a.args, SCM_ENV (proc));
2034 #else
2035 env = EXTEND_ENV (SCM_CAR (x), scm_cons (t.arg1, SCM_EOL), SCM_ENV (proc));
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);
2055 #ifdef DEVAL
2056 debug.info->a.args = scm_cons2 (t.arg1, arg2, SCM_EOL);
2057 #endif
2058 x = SCM_CDR (x);
2059 if (SCM_NULLP (x)) {
2060 ENTER_APPLY;
2061 #ifdef CCLO
2062 evap2:
2063 #endif
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:
2070 #ifdef DEVAL
2071 RETURN (SCM_SUBRF (proc) (debug.info->a.args))
2072 #else
2073 RETURN (SCM_SUBRF (proc) (scm_cons2 (t.arg1, arg2, SCM_EOL)));
2074 #endif
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:
2083 #ifdef DEVAL
2084 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc), proc,
2085 scm_cons (debug.info->a.args, SCM_EOL)));
2086 #else
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))));
2090 #endif
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:
2108 #ifdef DEVAL
2109 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), debug.info->a.args, SCM_ENV (proc));
2110 #else
2111 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), scm_cons2 (t.arg1, arg2, SCM_EOL), SCM_ENV (proc));
2112 #endif
2113 x = SCM_CODE (proc);
2114 goto cdrxbegin;
2115 }
2116 }
2117 #ifdef DEVAL
2118 debug.info->a.args = scm_cons2 (t.arg1, arg2,
2119 scm_deval_args (x, env, SCM_CDRLOC (SCM_CDR (debug.info->a.args))));
2120 #endif
2121 ENTER_APPLY;
2122 switch (SCM_TYP7 (proc))
2123 { /* have 3 or more arguments */
2124 #ifdef DEVAL
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:
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 */
2138 case scm_tc7_rpsubr:
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 */
2151 RETURN (SCM_APPLY (proc, t.arg1, scm_acons (arg2, SCM_CDR (SCM_CDR (debug.info->a.args)), SCM_EOL)))
2152 #endif /* BUILTIN_RPASUBR */
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))
2157 #ifdef CCLO
2158 case scm_tc7_cclo:
2159 goto cclon;
2160 #endif
2161 case scm_tcs_closures:
2162 SCM_SET_ARGSREADY (debug);
2163 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
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:
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 */
2181 case scm_tc7_rpsubr:
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 */
2194 RETURN (SCM_APPLY (proc, t.arg1, scm_acons (arg2, scm_eval_args (x, env), SCM_EOL)));
2195 #endif /* BUILTIN_RPASUBR */
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))));
2200 #ifdef CCLO
2201 case scm_tc7_cclo:
2202 goto cclon;
2203 #endif
2204 case scm_tcs_closures:
2205 #ifdef DEVAL
2206 SCM_SET_ARGSREADY (debug);
2207 #endif
2208 env = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)),
2209 scm_cons2 (t.arg1, arg2, scm_eval_args (x, env)),
2210 SCM_ENV (proc));
2211 x = SCM_CODE (proc);
2212 goto cdrxbegin;
2213 #endif /* DEVAL */
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 }
2225 }
2226 #ifdef DEVAL
2227 exit:
2228 if (CHECK_EXIT)
2229 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
2230 {
2231 SCM_EXIT_FRAME_P = 0;
2232 SCM_TRACE_P = 0;
2233 SCM_RESET_DEBUG_MODE;
2234 SCM_CLEAR_TRACED_FRAME (debug);
2235 if (SCM_CHEAPTRAPS_P)
2236 t.arg1 = scm_make_debugobj (&debug);
2237 else
2238 {
2239 scm_make_cont (&t.arg1);
2240 if (safe_setjmp (SCM_JMPBUF (t.arg1)))
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 }
2248 ret:
2249 scm_last_debug_frame = debug.prev;
2250 return proc;
2251 #endif
2252 }
2253
2254
2255 /* SECTION: This code is compiled once.
2256 */
2257
2258 #ifndef DEVAL
2259
2260 SCM_PROC(s_procedure_documentation, "procedure-documentation", 1, 0, 0, scm_procedure_documentation);
2261
2262 SCM
2263 scm_procedure_documentation (proc)
2264 SCM proc;
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
2291 /* This code processes the arguments to apply:
2292
2293 (apply PROC ARG1 ... ARGS)
2294
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
2301 result. apply:nconc2last takes care of building the list of
2302 arguments, given (ARG1 ... ARGS).
2303
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. */
2309
2310 SCM_PROC(s_nconc2last, "apply:nconc2last", 1, 0, 0, scm_nconc2last);
2311
2312 SCM
2313 scm_nconc2last (lst)
2314 SCM lst;
2315 {
2316 SCM *lloc;
2317 SCM_ASSERT (scm_ilength (lst) > 0, lst, SCM_ARG1, s_nconc2last);
2318 lloc = &lst;
2319 while (SCM_NNULLP (SCM_CDR (*lloc)))
2320 lloc = SCM_CDRLOC (*lloc);
2321 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, s_nconc2last);
2322 *lloc = SCM_CAR (*lloc);
2323 return lst;
2324 }
2325
2326 #endif /* !DEVAL */
2327
2328
2329 /* SECTION: When DEVAL is defined this code yields scm_dapply.
2330 * It is compiled twice.
2331 */
2332
2333 #if 0
2334
2335 SCM
2336 scm_apply (proc, arg1, args)
2337 SCM proc;
2338 SCM arg1;
2339 SCM args;
2340 {}
2341 #endif
2342
2343 #if 0
2344
2345 SCM
2346 scm_dapply (proc, arg1, args)
2347 SCM proc;
2348 SCM arg1;
2349 SCM args;
2350 {}
2351 #endif
2352
2353
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
2364 SCM
2365 SCM_APPLY (proc, arg1, args)
2366 SCM proc;
2367 SCM arg1;
2368 SCM args;
2369 {
2370 #ifdef DEBUG_EXTENSIONS
2371 #ifdef DEVAL
2372 scm_debug_frame debug;
2373 scm_debug_info debug_vect_body;
2374 debug.prev = scm_last_debug_frame;
2375 debug.status = SCM_APPLYFRAME;
2376 debug.vect = &debug_vect_body;
2377 debug.vect[0].a.proc = proc;
2378 debug.vect[0].a.args = SCM_EOL;
2379 scm_last_debug_frame = &debug;
2380 #else
2381 if (SCM_DEBUGGINGP)
2382 return scm_dapply (proc, arg1, args);
2383 #endif
2384 #endif
2385
2386 SCM_ASRTGO (SCM_NIMP (proc), badproc);
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
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. */
2400 if (SCM_NULLP (args))
2401 {
2402 if (SCM_NULLP (arg1))
2403 {
2404 arg1 = SCM_UNDEFINED;
2405 #ifdef DEVAL
2406 debug.vect[0].a.args = SCM_EOL;
2407 #endif
2408 }
2409 else
2410 {
2411 #ifdef DEVAL
2412 debug.vect[0].a.args = arg1;
2413 #endif
2414 args = SCM_CDR (arg1);
2415 arg1 = SCM_CAR (arg1);
2416 }
2417 }
2418 else
2419 {
2420 /* SCM_ASRTGO(SCM_NIMP(args) && SCM_CONSP(args), wrongnumargs); */
2421 args = scm_nconc2last (args);
2422 #ifdef DEVAL
2423 debug.vect[0].a.args = scm_cons (arg1, args);
2424 #endif
2425 }
2426 #ifdef DEVAL
2427 if (SCM_ENTER_FRAME_P)
2428 {
2429 SCM tmp;
2430 SCM_ENTER_FRAME_P = 0;
2431 SCM_RESET_DEBUG_MODE;
2432 if (SCM_CHEAPTRAPS_P)
2433 tmp = scm_make_debugobj (&debug);
2434 else
2435 {
2436 scm_make_cont (&tmp);
2437 if (safe_setjmp (SCM_JMPBUF (tmp)))
2438 goto entap;
2439 }
2440 scm_ithrow (scm_i_enter_frame, scm_cons (tmp, SCM_EOL), 0);
2441 }
2442 entap:
2443 ENTER_APPLY;
2444 #endif
2445 #ifdef CCLO
2446 tail:
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 {
2469 if (SCM_INUMP (arg1))
2470 {
2471 RETURN (scm_makdbl (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1)), 0.0));
2472 }
2473 SCM_ASRTGO (SCM_NIMP (arg1), floerr);
2474 if (SCM_REALP (arg1))
2475 {
2476 RETURN (scm_makdbl (SCM_DSUBRF (proc) (SCM_REALPART (arg1)), 0.0));
2477 }
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
2502 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args))
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
2533 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args);
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
2541 args = EXTEND_ENV (SCM_CAR (SCM_CODE (proc)), arg1, SCM_ENV (proc));
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
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);
2557 #else
2558 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
2559 arg1 = proc;
2560 proc = SCM_CCLO_SUBR (proc);
2561 #endif
2562 goto tail;
2563 #endif
2564 wrongnumargs:
2565 scm_wrong_num_args (proc);
2566 default:
2567 badproc:
2568 scm_wta (proc, (char *) SCM_ARG1, "apply");
2569 RETURN (arg1);
2570 }
2571 #ifdef DEVAL
2572 exit:
2573 if (CHECK_EXIT)
2574 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
2575 {
2576 SCM_EXIT_FRAME_P = 0;
2577 SCM_RESET_DEBUG_MODE;
2578 SCM_CLEAR_TRACED_FRAME (debug);
2579 if (SCM_CHEAPTRAPS_P)
2580 arg1 = scm_make_debugobj (&debug);
2581 else
2582 {
2583 scm_make_cont (&arg1);
2584 if (safe_setjmp (SCM_JMPBUF (arg1)))
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 }
2592 ret:
2593 scm_last_debug_frame = debug.prev;
2594 return proc;
2595 #endif
2596 }
2597
2598
2599 /* SECTION: The rest of this file is only read once.
2600 */
2601
2602 #ifndef DEVAL
2603
2604 SCM_PROC(s_map, "map", 2, 0, 1, scm_map);
2605
2606 SCM
2607 scm_map (proc, arg1, args)
2608 SCM proc;
2609 SCM arg1;
2610 SCM args;
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);
2626 pres = SCM_CDRLOC (*pres);
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);
2648 pres = SCM_CDRLOC (*pres);
2649 }
2650 }
2651
2652
2653 SCM_PROC(s_for_each, "for-each", 2, 0, 1, scm_for_each);
2654
2655 SCM
2656 scm_for_each (proc, arg1, args)
2657 SCM proc;
2658 SCM arg1;
2659 SCM args;
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
2697
2698 SCM
2699 scm_closure (code, env)
2700 SCM code;
2701 SCM env;
2702 {
2703 register SCM z;
2704 SCM_NEWCELL (z);
2705 SCM_SETCODE (z, code);
2706 SCM_SETENV (z, env);
2707 return z;
2708 }
2709
2710
2711 long scm_tc16_promise;
2712
2713 SCM
2714 scm_makprom (code)
2715 SCM code;
2716 {
2717 register SCM z;
2718 SCM_NEWCELL (z);
2719 SCM_SETCDR (z, code);
2720 SCM_SETCAR (z, scm_tc16_promise);
2721 return z;
2722 }
2723
2724
2725
2726 static int prinprom SCM_P ((SCM exp, SCM port, scm_print_state *pstate));
2727
2728 static int
2729 prinprom (exp, port, pstate)
2730 SCM exp;
2731 SCM port;
2732 scm_print_state *pstate;
2733 {
2734 int writingp = SCM_WRITINGP (pstate);
2735 scm_gen_puts (scm_regular_string, "#<promise ", port);
2736 SCM_SET_WRITINGP (pstate, 1);
2737 scm_iprin1 (SCM_CDR (exp), port, pstate);
2738 SCM_SET_WRITINGP (pstate, writingp);
2739 scm_gen_putc ('>', port);
2740 return !0;
2741 }
2742
2743
2744 SCM_PROC(s_makacro, "procedure->syntax", 1, 0, 0, scm_makacro);
2745
2746 SCM
2747 scm_makacro (code)
2748 SCM code;
2749 {
2750 register SCM z;
2751 SCM_NEWCELL (z);
2752 SCM_SETCDR (z, code);
2753 SCM_SETCAR (z, scm_tc16_macro);
2754 return z;
2755 }
2756
2757
2758 SCM_PROC(s_makmacro, "procedure->macro", 1, 0, 0, scm_makmacro);
2759
2760 SCM
2761 scm_makmacro (code)
2762 SCM code;
2763 {
2764 register SCM z;
2765 SCM_NEWCELL (z);
2766 SCM_SETCDR (z, code);
2767 SCM_SETCAR (z, scm_tc16_macro | (1L << 16));
2768 return z;
2769 }
2770
2771
2772 SCM_PROC(s_makmmacro, "procedure->memoizing-macro", 1, 0, 0, scm_makmmacro);
2773
2774 SCM
2775 scm_makmmacro (code)
2776 SCM code;
2777 {
2778 register SCM z;
2779 SCM_NEWCELL (z);
2780 SCM_SETCDR (z, code);
2781 SCM_SETCAR (z, scm_tc16_macro | (2L << 16));
2782 return z;
2783 }
2784
2785
2786
2787 static int prinmacro SCM_P ((SCM exp, SCM port, scm_print_state *pstate));
2788
2789 static int
2790 prinmacro (exp, port, pstate)
2791 SCM exp;
2792 SCM port;
2793 scm_print_state *pstate;
2794 {
2795 int writingp = SCM_WRITINGP (pstate);
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);
2803 SCM_SET_WRITINGP (pstate, 1);
2804 scm_iprin1 (SCM_CDR (exp), port, pstate);
2805 SCM_SET_WRITINGP (pstate, writingp);
2806 scm_gen_putc ('>', port);
2807 return !0;
2808 }
2809
2810 SCM_PROC(s_force, "force", 1, 0, 0, scm_force);
2811
2812 SCM
2813 scm_force (x)
2814 SCM x;
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;
2823 SCM_SETCDR (x, ans);
2824 SCM_SETOR_CAR (x, (1L << 16));
2825 SCM_ALLOW_INTS;
2826 }
2827 }
2828 return SCM_CDR (x);
2829 }
2830
2831 SCM_PROC (s_promise_p, "promise?", 1, 0, 0, scm_promise_p);
2832
2833 SCM
2834 scm_promise_p (x)
2835 SCM x;
2836 {
2837 return ((SCM_NIMP (x) && (SCM_TYP16 (x) == scm_tc16_promise))
2838 ? SCM_BOOL_T
2839 : SCM_BOOL_F);
2840 }
2841
2842 SCM_PROC(s_copy_tree, "copy-tree", 1, 0, 0, scm_copy_tree);
2843
2844 SCM
2845 scm_copy_tree (obj)
2846 SCM obj;
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))
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);
2870 return ans;
2871 }
2872
2873
2874 SCM
2875 scm_eval_3 (obj, copyp, env)
2876 SCM obj;
2877 int copyp;
2878 SCM env;
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);
2884 return XEVAL (obj, env);
2885 }
2886
2887
2888 SCM
2889 scm_top_level_env (thunk)
2890 SCM thunk;
2891 {
2892 if (SCM_IMP(thunk))
2893 return SCM_EOL;
2894 else
2895 return scm_cons(thunk, (SCM)SCM_EOL);
2896 }
2897
2898 SCM_PROC(s_eval2, "eval2", 2, 0, 0, scm_eval2);
2899
2900 SCM
2901 scm_eval2 (obj, env_thunk)
2902 SCM obj;
2903 SCM env_thunk;
2904 {
2905 return scm_eval_3 (obj, 1, scm_top_level_env(env_thunk));
2906 }
2907
2908 SCM_PROC(s_eval, "eval", 1, 0, 0, scm_eval);
2909
2910 SCM
2911 scm_eval (obj)
2912 SCM obj;
2913 {
2914 return
2915 scm_eval_3(obj, 1, scm_top_level_env(SCM_CDR(scm_top_level_lookup_closure_var)));
2916 }
2917
2918 /* SCM_PROC(s_eval_x, "eval!", 1, 0, 0, scm_eval_x); */
2919
2920 SCM
2921 scm_eval_x (obj)
2922 SCM obj;
2923 {
2924 return
2925 scm_eval_3(obj,
2926 0,
2927 scm_top_level_env (SCM_CDR (scm_top_level_lookup_closure_var)));
2928 }
2929
2930 SCM_PROC (s_macro_eval_x, "macro-eval!", 2, 0, 0, scm_macro_eval_x);
2931
2932 SCM
2933 scm_macro_eval_x (exp, env)
2934 SCM exp;
2935 SCM env;
2936 {
2937 return scm_eval_3 (exp, 0, env);
2938 }
2939
2940
2941 SCM_PROC (s_definedp, "defined?", 1, 0, 0, scm_definedp);
2942
2943 SCM
2944 scm_definedp (sym)
2945 SCM sym;
2946 {
2947 SCM vcell;
2948
2949 if (SCM_ISYMP (sym))
2950 return SCM_BOOL_T;
2951
2952 SCM_ASSERT (SCM_NIMP (sym) && SCM_SYMBOLP (sym), sym, SCM_ARG1, s_definedp);
2953
2954 vcell = scm_sym2vcell(sym,
2955 SCM_CDR (scm_top_level_lookup_closure_var),
2956 SCM_BOOL_F);
2957 return (vcell == SCM_BOOL_F || SCM_UNBNDP(SCM_CDR(vcell))) ?
2958 SCM_BOOL_F : SCM_BOOL_T;
2959 }
2960
2961 static scm_smobfuns promsmob =
2962 {scm_markcdr, scm_free0, prinprom};
2963
2964 static scm_smobfuns macrosmob =
2965 {scm_markcdr, scm_free0, prinmacro};
2966
2967
2968 SCM
2969 scm_make_synt (name, macroizer, fcn)
2970 char *name;
2971 SCM (*macroizer) ();
2972 SCM (*fcn) ();
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;
2981 SCM_SETCAR (z, tmp + scm_tc7_subr_2);
2982 SCM_SETCDR (symcell, macroizer (z));
2983 return SCM_CAR (symcell);
2984 }
2985
2986
2987 /* At this point, scm_deval and scm_dapply are generated.
2988 */
2989
2990 #ifdef DEBUG_EXTENSIONS
2991 # define DEVAL
2992 # include "eval.c"
2993 #endif
2994
2995
2996
2997 void
2998 scm_init_eval ()
2999 {
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);
3012 scm_make_synt (s_undefine, scm_makacro, scm_m_undefine);
3013 scm_make_synt (s_delay, scm_makacro, scm_m_delay);
3014 /* end of acros */
3015
3016 scm_top_level_lookup_closure_var =
3017 scm_sysintern("*top-level-lookup-closure*", SCM_BOOL_F);
3018 scm_can_use_top_level_lookup_closure_var = 1;
3019
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);
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);
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);
3032 scm_i_quote = scm_make_synt ("quote", scm_makmmacro, scm_m_quote);
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
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
3045 #include "eval.x"
3046 }
3047
3048 #endif /* !DEVAL */