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