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