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