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