*** empty log message ***
[bpt/guile.git] / libguile / eval.c
CommitLineData
d0b07b5d 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc.
0f2d19dd 2 *
73be1d9e
MV
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
0f2d19dd 7 *
73be1d9e
MV
8 * This library 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 GNU
11 * Lesser General Public License for more details.
0f2d19dd 12 *
73be1d9e
MV
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
1bbd0b84 17
0f2d19dd
JB
18\f
19
6dbd0af5
MD
20/* This file is read twice in order to produce debugging versions of
21 * scm_ceval and scm_apply. These functions, scm_deval and
22 * scm_dapply, are produced when we define the preprocessor macro
23 * DEVAL. The file is divided into sections which are treated
24 * differently with respect to DEVAL. The heads of these sections are
25 * marked with the string "SECTION:".
26 */
27
6dbd0af5 28/* SECTION: This code is compiled once.
0f2d19dd
JB
29 */
30
3d05f2e0
RB
31#if HAVE_CONFIG_H
32# include <config.h>
33#endif
0f2d19dd 34
3d05f2e0
RB
35#include "libguile/__scm.h"
36
37#ifndef DEVAL
d16332b3 38
48b96f4b
JB
39/* AIX requires this to be the first thing in the file. The #pragma
40 directive is indented so pre-ANSI compilers will ignore it, rather
41 than choke on it. */
5862b540 42#ifndef __GNUC__
48b96f4b
JB
43# if HAVE_ALLOCA_H
44# include <alloca.h>
45# else
46# ifdef _AIX
ac13d9d2 47# pragma alloca
48b96f4b
JB
48# else
49# ifndef alloca /* predefined by HP cc +Olibcalls */
50char *alloca ();
51# endif
52# endif
53# endif
54#endif
55
a0599745
MD
56#include "libguile/_scm.h"
57#include "libguile/debug.h"
09074dbf 58#include "libguile/dynwind.h"
a0599745
MD
59#include "libguile/alist.h"
60#include "libguile/eq.h"
61#include "libguile/continuations.h"
756414cf 62#include "libguile/futures.h"
a0599745
MD
63#include "libguile/throw.h"
64#include "libguile/smob.h"
65#include "libguile/macros.h"
66#include "libguile/procprop.h"
67#include "libguile/hashtab.h"
68#include "libguile/hash.h"
69#include "libguile/srcprop.h"
70#include "libguile/stackchk.h"
71#include "libguile/objects.h"
72#include "libguile/async.h"
73#include "libguile/feature.h"
74#include "libguile/modules.h"
75#include "libguile/ports.h"
76#include "libguile/root.h"
77#include "libguile/vectors.h"
549e6ec6 78#include "libguile/fluids.h"
f12745b6 79#include "libguile/goops.h"
a513ead3 80#include "libguile/values.h"
a0599745
MD
81
82#include "libguile/validate.h"
83#include "libguile/eval.h"
c96d76b8 84#include "libguile/lang.h"
89efbff4 85
0f2d19dd
JB
86\f
87
17fa3fcf
DH
88#define SCM_VALIDATE_NON_EMPTY_COMBINATION(x) \
89 do { \
90 if (SCM_EQ_P ((x), SCM_EOL)) \
91 scm_misc_error (NULL, scm_s_expression, SCM_EOL); \
92 } while (0)
93
94\f
95
6dbd0af5
MD
96/* The evaluator contains a plethora of EVAL symbols.
97 * This is an attempt at explanation.
98 *
99 * The following macros should be used in code which is read twice
100 * (where the choice of evaluator is hard soldered):
101 *
102 * SCM_CEVAL is the symbol used within one evaluator to call itself.
103 * Originally, it is defined to scm_ceval, but is redefined to
104 * scm_deval during the second pass.
105 *
6cb702da 106 * SCM_EVALIM is used when it is known that the expression is an
6dbd0af5
MD
107 * immediate. (This macro never calls an evaluator.)
108 *
109 * EVALCAR evaluates the car of an expression.
110 *
6dbd0af5
MD
111 * The following macros should be used in code which is read once
112 * (where the choice of evaluator is dynamic):
113 *
6cb702da 114 * SCM_XEVAL takes care of immediates without calling an evaluator. It
6dbd0af5
MD
115 * then calls scm_ceval *or* scm_deval, depending on the debugging
116 * mode.
117 *
6cb702da 118 * SCM_XEVALCAR corresponds to EVALCAR, but uses scm_ceval *or* scm_deval
6dbd0af5
MD
119 * depending on the debugging mode.
120 *
121 * The main motivation for keeping this plethora is efficiency
122 * together with maintainability (=> locality of code).
123 */
124
6cb702da 125#define SCM_CEVAL scm_ceval
0f2d19dd 126
8c494e99 127#define EVALCAR(x, env) (SCM_IMP (SCM_CAR (x)) \
904a077d 128 ? SCM_EVALIM (SCM_CAR (x), env) \
680516ba
DH
129 : (SCM_SYMBOLP (SCM_CAR (x)) \
130 ? *scm_lookupcar (x, env, 1) \
131 : SCM_CEVAL (SCM_CAR (x), env)))
0f2d19dd 132
28d52ebb 133SCM_REC_MUTEX (source_mutex);
9bc4701c 134
12841895
DH
135
136/* Lookup a given local variable in an environment. The local variable is
137 * given as an iloc, that is a triple <frame, binding, last?>, where frame
138 * indicates the relative number of the environment frame (counting upwards
139 * from the innermost environment frame), binding indicates the number of the
140 * binding within the frame, and last? (which is extracted from the iloc using
141 * the macro SCM_ICDRP) indicates whether the binding forms the binding at the
142 * very end of the improper list of bindings. */
0f2d19dd 143SCM *
6e8d25a6 144scm_ilookup (SCM iloc, SCM env)
0f2d19dd 145{
12841895
DH
146 unsigned int frame_nr = SCM_IFRAME (iloc);
147 unsigned int binding_nr = SCM_IDIST (iloc);
148 SCM frames = env;
149 SCM bindings;
150
151 for (; 0 != frame_nr; --frame_nr)
152 frames = SCM_CDR (frames);
153
154 bindings = SCM_CAR (frames);
155 for (; 0 != binding_nr; --binding_nr)
156 bindings = SCM_CDR (bindings);
157
0f2d19dd 158 if (SCM_ICDRP (iloc))
12841895
DH
159 return SCM_CDRLOC (bindings);
160 return SCM_CARLOC (SCM_CDR (bindings));
0f2d19dd 161}
0f2d19dd 162
12841895 163
f8769b1d
MV
164/* The Lookup Car Race
165 - by Eva Luator
166
167 Memoization of variables and special forms is done while executing
168 the code for the first time. As long as there is only one thread
169 everything is fine, but as soon as two threads execute the same
170 code concurrently `for the first time' they can come into conflict.
171
172 This memoization includes rewriting variable references into more
173 efficient forms and expanding macros. Furthermore, macro expansion
174 includes `compiling' special forms like `let', `cond', etc. into
175 tree-code instructions.
176
177 There shouldn't normally be a problem with memoizing local and
904a077d 178 global variable references (into ilocs and variables), because all
f8769b1d
MV
179 threads will mutate the code in *exactly* the same way and (if I
180 read the C code correctly) it is not possible to observe a half-way
181 mutated cons cell. The lookup procedure can handle this
182 transparently without any critical sections.
183
184 It is different with macro expansion, because macro expansion
185 happens outside of the lookup procedure and can't be
904a077d
MV
186 undone. Therefore the lookup procedure can't cope with it. It has
187 to indicate failure when it detects a lost race and hope that the
188 caller can handle it. Luckily, it turns out that this is the case.
f8769b1d 189
904a077d 190 An example to illustrate this: Suppose that the following form will
f8769b1d
MV
191 be memoized concurrently by two threads
192
193 (let ((x 12)) x)
194
195 Let's first examine the lookup of X in the body. The first thread
196 decides that it has to find the symbol "x" in the environment and
197 starts to scan it. Then the other thread takes over and actually
198 overtakes the first. It looks up "x" and substitutes an
199 appropriate iloc for it. Now the first thread continues and
200 completes its lookup. It comes to exactly the same conclusions as
201 the second one and could - without much ado - just overwrite the
202 iloc with the same iloc.
203
204 But let's see what will happen when the race occurs while looking
205 up the symbol "let" at the start of the form. It could happen that
206 the second thread interrupts the lookup of the first thread and not
904a077d
MV
207 only substitutes a variable for it but goes right ahead and
208 replaces it with the compiled form (#@let* (x 12) x). Now, when
209 the first thread completes its lookup, it would replace the #@let*
210 with a variable containing the "let" binding, effectively reverting
211 the form to (let (x 12) x). This is wrong. It has to detect that
212 it has lost the race and the evaluator has to reconsider the
213 changed form completely.
f8769b1d
MV
214
215 This race condition could be resolved with some kind of traffic
216 light (like mutexes) around scm_lookupcar, but I think that it is
217 best to avoid them in this case. They would serialize memoization
218 completely and because lookup involves calling arbitrary Scheme
219 code (via the lookup-thunk), threads could be blocked for an
220 arbitrary amount of time or even deadlock. But with the current
221 solution a lot of unnecessary work is potentially done. */
222
9aa82b39 223/* SCM_LOOKUPCAR1 is what SCM_LOOKUPCAR used to be but is allowed to
f8769b1d
MV
224 return NULL to indicate a failed lookup due to some race conditions
225 between threads. This only happens when VLOC is the first cell of
226 a special form that will eventually be memoized (like `let', etc.)
227 In that case the whole lookup is bogus and the caller has to
228 reconsider the complete special form.
229
230 SCM_LOOKUPCAR is still there, of course. It just calls
de513fa0 231 SCM_LOOKUPCAR1 and aborts on receiving NULL. So SCM_LOOKUPCAR
f8769b1d
MV
232 should only be called when it is known that VLOC is not the first
233 pair of a special form. Otherwise, use SCM_LOOKUPCAR1 and check
26d5b9b4
MD
234 for NULL. I think I've found the only places where this
235 applies. */
f8769b1d 236
f25f761d
GH
237SCM_SYMBOL (scm_unbound_variable_key, "unbound-variable");
238
8ecf1f13 239static SCM *
26d5b9b4 240scm_lookupcar1 (SCM vloc, SCM genv, int check)
0f2d19dd
JB
241{
242 SCM env = genv;
e3173f93 243 register SCM *al, fl, var = SCM_CAR (vloc);
0f2d19dd 244 register SCM iloc = SCM_ILOC00;
0f2d19dd
JB
245 for (; SCM_NIMP (env); env = SCM_CDR (env))
246 {
790071cd 247 if (!SCM_CONSP (SCM_CAR (env)))
0f2d19dd 248 break;
a23afe53 249 al = SCM_CARLOC (env);
0f2d19dd
JB
250 for (fl = SCM_CAR (*al); SCM_NIMP (fl); fl = SCM_CDR (fl))
251 {
01f11e02 252 if (!SCM_CONSP (fl))
33b97402 253 {
cf498326 254 if (SCM_EQ_P (fl, var))
0f2d19dd 255 {
cf498326 256 if (! SCM_EQ_P (SCM_CAR (vloc), var))
f8769b1d 257 goto race;
3201d763 258 SCM_SET_CELL_WORD_0 (vloc, SCM_UNPACK (iloc) + SCM_ICDR);
a23afe53 259 return SCM_CDRLOC (*al);
0f2d19dd 260 }
33b97402
MD
261 else
262 break;
263 }
a23afe53 264 al = SCM_CDRLOC (*al);
cf498326 265 if (SCM_EQ_P (SCM_CAR (fl), var))
0f2d19dd 266 {
0f2d19dd
JB
267 if (SCM_UNBNDP (SCM_CAR (*al)))
268 {
269 env = SCM_EOL;
270 goto errout;
271 }
c6772927 272 if (!SCM_EQ_P (SCM_CAR (vloc), var))
f8769b1d 273 goto race;
a23afe53 274 SCM_SETCAR (vloc, iloc);
a23afe53 275 return SCM_CARLOC (*al);
0f2d19dd 276 }
3201d763 277 iloc = SCM_PACK (SCM_UNPACK (iloc) + SCM_IDINC);
0f2d19dd 278 }
3201d763 279 iloc = SCM_PACK ((~SCM_IDSTMSK) & (SCM_UNPACK(iloc) + SCM_IFRINC));
0f2d19dd
JB
280 }
281 {
86d31dfe 282 SCM top_thunk, real_var;
790071cd 283 if (SCM_NIMP (env))
0f2d19dd 284 {
86d31dfe
MV
285 top_thunk = SCM_CAR (env); /* env now refers to a
286 top level env thunk */
0f2d19dd
JB
287 env = SCM_CDR (env);
288 }
289 else
290 top_thunk = SCM_BOOL_F;
86d31dfe
MV
291 real_var = scm_sym2var (var, top_thunk, SCM_BOOL_F);
292 if (SCM_FALSEP (real_var))
0f2d19dd 293 goto errout;
86d31dfe 294
01f11e02 295 if (!SCM_NULLP (env) || SCM_UNBNDP (SCM_VARIABLE_REF (real_var)))
86d31dfe
MV
296 {
297 errout:
86d31dfe
MV
298 if (check)
299 {
300 if (SCM_NULLP (env))
301 scm_error (scm_unbound_variable_key, NULL,
302 "Unbound variable: ~S",
8ea46249 303 scm_list_1 (var), SCM_BOOL_F);
86d31dfe
MV
304 else
305 scm_misc_error (NULL, "Damaged environment: ~S",
8ea46249 306 scm_list_1 (var));
86d31dfe
MV
307 }
308 else
309 {
310 /* A variable could not be found, but we shall
311 not throw an error. */
312 static SCM undef_object = SCM_UNDEFINED;
313 return &undef_object;
314 }
09e4d064 315 }
86d31dfe 316
c6772927 317 if (!SCM_EQ_P (SCM_CAR (vloc), var))
86d31dfe
MV
318 {
319 /* Some other thread has changed the very cell we are working
320 on. In effect, it must have done our job or messed it up
321 completely. */
322 race:
323 var = SCM_CAR (vloc);
d22a0ea1
MV
324 if (SCM_VARIABLEP (var))
325 return SCM_VARIABLE_LOC (var);
86d31dfe
MV
326 if (SCM_ITAG7 (var) == SCM_ITAG7 (SCM_ILOC00))
327 return scm_ilookup (var, genv);
904a077d 328 /* We can't cope with anything else than variables and ilocs. When
86d31dfe
MV
329 a special form has been memoized (i.e. `let' into `#@let') we
330 return NULL and expect the calling function to do the right
331 thing. For the evaluator, this means going back and redoing
332 the dispatch on the car of the form. */
333 return NULL;
334 }
f8769b1d 335
d22a0ea1 336 SCM_SETCAR (vloc, real_var);
86d31dfe
MV
337 return SCM_VARIABLE_LOC (real_var);
338 }
0f2d19dd
JB
339}
340
f8769b1d 341SCM *
6e8d25a6 342scm_lookupcar (SCM vloc, SCM genv, int check)
f8769b1d 343{
26d5b9b4 344 SCM *loc = scm_lookupcar1 (vloc, genv, check);
f8769b1d
MV
345 if (loc == NULL)
346 abort ();
347 return loc;
348}
f8769b1d 349
0f2d19dd 350#define unmemocar scm_unmemocar
1cc91f1b 351
86d31dfe
MV
352SCM_SYMBOL (sym_three_question_marks, "???");
353
0f2d19dd 354SCM
6e8d25a6 355scm_unmemocar (SCM form, SCM env)
0f2d19dd 356{
302c12b4 357 if (!SCM_CONSP (form))
0f2d19dd 358 return form;
302c12b4 359 else
d22a0ea1 360 {
302c12b4
DH
361 SCM c = SCM_CAR (form);
362 if (SCM_VARIABLEP (c))
363 {
364 SCM sym = scm_module_reverse_lookup (scm_env_module (env), c);
365 if (SCM_FALSEP (sym))
366 sym = sym_three_question_marks;
367 SCM_SETCAR (form, sym);
368 }
302c12b4
DH
369 else if (SCM_ILOCP (c))
370 {
371 unsigned long int ir;
372
373 for (ir = SCM_IFRAME (c); ir != 0; --ir)
374 env = SCM_CDR (env);
375 env = SCM_CAAR (env);
376 for (ir = SCM_IDIST (c); ir != 0; --ir)
377 env = SCM_CDR (env);
378 SCM_SETCAR (form, SCM_ICDRP (c) ? env : SCM_CAR (env));
379 }
302c12b4
DH
380 return form;
381 }
0f2d19dd
JB
382}
383
1cc91f1b 384
0f2d19dd 385SCM
6e8d25a6 386scm_eval_car (SCM pair, SCM env)
0f2d19dd 387{
6cb702da 388 return SCM_XEVALCAR (pair, env);
0f2d19dd
JB
389}
390
391\f
392/*
393 * The following rewrite expressions and
394 * some memoized forms have different syntax
395 */
396
3eeba8d4
JB
397const char scm_s_expression[] = "missing or extra expression";
398const char scm_s_test[] = "bad test";
399const char scm_s_body[] = "bad body";
400const char scm_s_bindings[] = "bad bindings";
185ab0ef 401const char scm_s_duplicate_bindings[] = "duplicate bindings";
3eeba8d4
JB
402const char scm_s_variable[] = "bad variable";
403const char scm_s_clauses[] = "bad or missing clauses";
404const char scm_s_formals[] = "bad formals";
5280aaca 405const char scm_s_duplicate_formals[] = "duplicate formals";
302c12b4 406static const char s_splicing[] = "bad (non-list) result for unquote-splicing";
0f2d19dd 407
85db4a2c
DH
408SCM_GLOBAL_SYMBOL (scm_sym_dot, ".");
409SCM_GLOBAL_SYMBOL (scm_sym_arrow, "=>");
410SCM_GLOBAL_SYMBOL (scm_sym_else, "else");
411SCM_GLOBAL_SYMBOL (scm_sym_unquote, "unquote");
412SCM_GLOBAL_SYMBOL (scm_sym_uq_splicing, "unquote-splicing");
81123e6d 413
85db4a2c
DH
414SCM_GLOBAL_SYMBOL (scm_sym_enter_frame, "enter-frame");
415SCM_GLOBAL_SYMBOL (scm_sym_apply_frame, "apply-frame");
416SCM_GLOBAL_SYMBOL (scm_sym_exit_frame, "exit-frame");
417SCM_GLOBAL_SYMBOL (scm_sym_trace, "trace");
0f2d19dd 418
0f2d19dd 419
26d5b9b4
MD
420/* Check that the body denoted by XORIG is valid and rewrite it into
421 its internal form. The internal form of a body is just the body
422 itself, but prefixed with an ISYM that denotes to what kind of
423 outer construct this body belongs. A lambda body starts with
424 SCM_IM_LAMBDA, for example, a body of a let starts with SCM_IM_LET,
425 etc. The one exception is a body that belongs to a letrec that has
426 been formed by rewriting internal defines: it starts with
427 SCM_IM_DEFINE. */
428
429/* XXX - Besides controlling the rewriting of internal defines, the
430 additional ISYM could be used for improved error messages.
431 This is not done yet. */
432
433static SCM
6e8d25a6 434scm_m_body (SCM op, SCM xorig, const char *what)
26d5b9b4 435{
302c12b4 436 SCM_ASSYNT (scm_ilength (xorig) >= 1, scm_s_body, what);
26d5b9b4
MD
437
438 /* Don't add another ISYM if one is present already. */
439 if (SCM_ISYMP (SCM_CAR (xorig)))
440 return xorig;
441
442 /* Retain possible doc string. */
44d3cb0d 443 if (!SCM_CONSP (SCM_CAR (xorig)))
26d5b9b4 444 {
8ea46249 445 if (!SCM_NULLP (SCM_CDR (xorig)))
26d5b9b4 446 return scm_cons (SCM_CAR (xorig),
8ea46249 447 scm_m_body (op, SCM_CDR (xorig), what));
26d5b9b4
MD
448 return xorig;
449 }
450
ab66ae47 451 return scm_cons (op, xorig);
26d5b9b4
MD
452}
453
1cc91f1b 454
9fbee57e 455/* Start of the memoizers for the standard R5RS builtin macros. */
0f2d19dd
JB
456
457
8ea46249
DH
458SCM_SYNTAX (s_and, "and", scm_makmmacro, scm_m_and);
459SCM_GLOBAL_SYMBOL (scm_sym_and, s_and);
1cc91f1b 460
8ea46249 461SCM
e81d98ec 462scm_m_and (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 463{
c014a02e 464 long len = scm_ilength (SCM_CDR (xorig));
160bb34a 465 SCM_ASSYNT (len >= 0, scm_s_test, s_and);
0f2d19dd 466 if (len >= 1)
3a3111a8 467 return scm_cons (SCM_IM_AND, SCM_CDR (xorig));
0f2d19dd
JB
468 else
469 return SCM_BOOL_T;
470}
471
1cc91f1b 472
9fbee57e
DH
473SCM_SYNTAX (s_begin, "begin", scm_makmmacro, scm_m_begin);
474SCM_GLOBAL_SYMBOL (scm_sym_begin, s_begin);
8ea46249
DH
475
476SCM
9fbee57e 477scm_m_begin (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 478{
9fbee57e
DH
479 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) >= 0, scm_s_expression, s_begin);
480 return scm_cons (SCM_IM_BEGIN, SCM_CDR (xorig));
0f2d19dd
JB
481}
482
483
8ea46249
DH
484SCM_SYNTAX (s_case, "case", scm_makmmacro, scm_m_case);
485SCM_GLOBAL_SYMBOL (scm_sym_case, s_case);
1cc91f1b 486
8ea46249 487SCM
e81d98ec 488scm_m_case (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 489{
8ea46249
DH
490 SCM clauses;
491 SCM cdrx = SCM_CDR (xorig);
492 SCM_ASSYNT (scm_ilength (cdrx) >= 2, scm_s_clauses, s_case);
493 clauses = SCM_CDR (cdrx);
494 while (!SCM_NULLP (clauses))
0f2d19dd 495 {
8ea46249
DH
496 SCM clause = SCM_CAR (clauses);
497 SCM_ASSYNT (scm_ilength (clause) >= 2, scm_s_clauses, s_case);
498 SCM_ASSYNT (scm_ilength (SCM_CAR (clause)) >= 0
499 || (SCM_EQ_P (scm_sym_else, SCM_CAR (clause))
500 && SCM_NULLP (SCM_CDR (clauses))),
160bb34a 501 scm_s_clauses, s_case);
8ea46249 502 clauses = SCM_CDR (clauses);
0f2d19dd 503 }
3a3111a8 504 return scm_cons (SCM_IM_CASE, cdrx);
0f2d19dd
JB
505}
506
507
8ea46249
DH
508SCM_SYNTAX (s_cond, "cond", scm_makmmacro, scm_m_cond);
509SCM_GLOBAL_SYMBOL (scm_sym_cond, s_cond);
1cc91f1b 510
8ea46249 511SCM
e81d98ec 512scm_m_cond (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 513{
8ea46249
DH
514 SCM cdrx = SCM_CDR (xorig);
515 SCM clauses = cdrx;
516 SCM_ASSYNT (scm_ilength (clauses) >= 1, scm_s_clauses, s_cond);
517 while (!SCM_NULLP (clauses))
0f2d19dd 518 {
8ea46249
DH
519 SCM clause = SCM_CAR (clauses);
520 long len = scm_ilength (clause);
160bb34a 521 SCM_ASSYNT (len >= 1, scm_s_clauses, s_cond);
8ea46249 522 if (SCM_EQ_P (scm_sym_else, SCM_CAR (clause)))
0f2d19dd 523 {
8ea46249
DH
524 int last_clause_p = SCM_NULLP (SCM_CDR (clauses));
525 SCM_ASSYNT (len >= 2 && last_clause_p, "bad ELSE clause", s_cond);
0f2d19dd 526 }
8ea46249
DH
527 else if (len >= 2 && SCM_EQ_P (scm_sym_arrow, SCM_CADR (clause)))
528 {
529 SCM_ASSYNT (len > 2, "missing recipient", s_cond);
530 SCM_ASSYNT (len == 3, "bad recipient", s_cond);
531 }
532 clauses = SCM_CDR (clauses);
0f2d19dd 533 }
3a3111a8 534 return scm_cons (SCM_IM_COND, cdrx);
0f2d19dd
JB
535}
536
1cc91f1b 537
9fbee57e
DH
538SCM_SYNTAX(s_define, "define", scm_makmmacro, scm_m_define);
539SCM_GLOBAL_SYMBOL(scm_sym_define, s_define);
5280aaca 540
9fbee57e
DH
541/* Guile provides an extension to R5RS' define syntax to represent function
542 * currying in a compact way. With this extension, it is allowed to write
543 * (define <nested-variable> <body>), where <nested-variable> has of one of
544 * the forms (<nested-variable> <formals>), (<nested-variable> . <formal>),
545 * (<variable> <formals>) or (<variable> . <formal>). As in R5RS, <formals>
546 * should be either a sequence of zero or more variables, or a sequence of one
547 * or more variables followed by a space-delimited period and another
548 * variable. Each level of argument nesting wraps the <body> within another
549 * lambda expression. For example, the following forms are allowed, each one
550 * followed by an equivalent, more explicit implementation.
551 * Example 1:
552 * (define ((a b . c) . d) <body>) is equivalent to
553 * (define a (lambda (b . c) (lambda d <body>)))
554 * Example 2:
555 * (define (((a) b) c . d) <body>) is equivalent to
556 * (define a (lambda () (lambda (b) (lambda (c . d) <body>))))
557 */
558/* Dirk:FIXME:: We should provide an implementation for 'define' in the R5RS
559 * module that does not implement this extension. */
560SCM
561scm_m_define (SCM x, SCM env)
5280aaca 562{
9fbee57e
DH
563 SCM name;
564 x = SCM_CDR (x);
565 SCM_ASSYNT (scm_ilength (x) >= 2, scm_s_expression, s_define);
566 name = SCM_CAR (x);
567 x = SCM_CDR (x);
568 while (SCM_CONSP (name))
5280aaca 569 {
9fbee57e
DH
570 /* This while loop realizes function currying by variable nesting. */
571 SCM formals = SCM_CDR (name);
572 x = scm_list_1 (scm_cons2 (scm_sym_lambda, formals, x));
573 name = SCM_CAR (name);
5280aaca 574 }
9fbee57e
DH
575 SCM_ASSYNT (SCM_SYMBOLP (name), scm_s_variable, s_define);
576 SCM_ASSYNT (scm_ilength (x) == 1, scm_s_expression, s_define);
577 if (SCM_TOP_LEVEL (env))
0f2d19dd 578 {
9fbee57e
DH
579 SCM var;
580 x = scm_eval_car (x, env);
581 if (SCM_REC_PROCNAMES_P)
582 {
583 SCM tmp = x;
584 while (SCM_MACROP (tmp))
585 tmp = SCM_MACRO_CODE (tmp);
586 if (SCM_CLOSUREP (tmp)
587 /* Only the first definition determines the name. */
588 && SCM_FALSEP (scm_procedure_property (tmp, scm_sym_name)))
589 scm_set_procedure_property_x (tmp, scm_sym_name, name);
590 }
591 var = scm_sym2var (name, scm_env_top_level (env), SCM_BOOL_T);
592 SCM_VARIABLE_SET (var, x);
593 return SCM_UNSPECIFIED;
26d5b9b4 594 }
9fbee57e
DH
595 else
596 return scm_cons2 (SCM_IM_DEFINE, name, x);
0f2d19dd
JB
597}
598
599
9fbee57e
DH
600SCM_SYNTAX (s_delay, "delay", scm_makmmacro, scm_m_delay);
601SCM_GLOBAL_SYMBOL (scm_sym_delay, s_delay);
1cc91f1b 602
9fbee57e
DH
603/* Promises are implemented as closures with an empty parameter list. Thus,
604 * (delay <expression>) is transformed into (#@delay '() <expression>), where
605 * the empty list represents the empty parameter list. This representation
606 * allows for easy creation of the closure during evaluation. */
8ea46249 607SCM
9fbee57e 608scm_m_delay (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 609{
9fbee57e
DH
610 SCM_ASSYNT (scm_ilength (xorig) == 2, scm_s_expression, s_delay);
611 return scm_cons2 (SCM_IM_DELAY, SCM_EOL, SCM_CDR (xorig));
0f2d19dd
JB
612}
613
8ea46249 614
302c12b4
DH
615/* DO gets the most radically altered syntax. The order of the vars is
616 * reversed here. In contrast, the order of the inits and steps is reversed
617 * during the evaluation:
618
0f2d19dd
JB
619 (do ((<var1> <init1> <step1>)
620 (<var2> <init2>)
621 ... )
622 (<test> <return>)
623 <body>)
302c12b4 624
0f2d19dd 625 ;; becomes
302c12b4
DH
626
627 (#@do (varn ... var2 var1)
0f2d19dd
JB
628 (<init1> <init2> ... <initn>)
629 (<test> <return>)
630 (<body>)
631 <step1> <step2> ... <stepn>) ;; missing steps replaced by var
302c12b4 632 */
0f2d19dd 633
b8229a3b 634SCM_SYNTAX(s_do, "do", scm_makmmacro, scm_m_do);
2f0d1375 635SCM_GLOBAL_SYMBOL(scm_sym_do, s_do);
1cc91f1b 636
0f2d19dd 637SCM
e81d98ec 638scm_m_do (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 639{
8ea46249
DH
640 SCM bindings;
641 SCM x = SCM_CDR (xorig);
642 SCM vars = SCM_EOL;
643 SCM inits = SCM_EOL;
644 SCM *initloc = &inits;
645 SCM steps = SCM_EOL;
646 SCM *steploc = &steps;
647 SCM_ASSYNT (scm_ilength (x) >= 2, scm_s_test, "do");
648 bindings = SCM_CAR (x);
649 SCM_ASSYNT (scm_ilength (bindings) >= 0, scm_s_bindings, "do");
650 while (!SCM_NULLP (bindings))
0f2d19dd 651 {
302c12b4
DH
652 SCM binding = SCM_CAR (bindings);
653 long len = scm_ilength (binding);
8ea46249 654 SCM_ASSYNT (len == 2 || len == 3, scm_s_bindings, "do");
302c12b4
DH
655 {
656 SCM name = SCM_CAR (binding);
657 SCM init = SCM_CADR (binding);
658 SCM step = (len == 2) ? name : SCM_CADDR (binding);
659 SCM_ASSYNT (SCM_SYMBOLP (name), scm_s_variable, "do");
660 vars = scm_cons (name, vars);
661 *initloc = scm_list_1 (init);
662 initloc = SCM_CDRLOC (*initloc);
663 *steploc = scm_list_1 (step);
664 steploc = SCM_CDRLOC (*steploc);
665 bindings = SCM_CDR (bindings);
666 }
0f2d19dd
JB
667 }
668 x = SCM_CDR (x);
160bb34a 669 SCM_ASSYNT (scm_ilength (SCM_CAR (x)) >= 1, scm_s_test, "do");
0f2d19dd
JB
670 x = scm_cons2 (SCM_CAR (x), SCM_CDR (x), steps);
671 x = scm_cons2 (vars, inits, x);
3a3111a8 672 return scm_cons (SCM_IM_DO, x);
0f2d19dd
JB
673}
674
b8229a3b 675
9fbee57e
DH
676SCM_SYNTAX (s_if, "if", scm_makmmacro, scm_m_if);
677SCM_GLOBAL_SYMBOL (scm_sym_if, s_if);
b8229a3b 678
9fbee57e
DH
679SCM
680scm_m_if (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 681{
9fbee57e
DH
682 long len = scm_ilength (SCM_CDR (xorig));
683 SCM_ASSYNT (len >= 2 && len <= 3, scm_s_expression, s_if);
684 return scm_cons (SCM_IM_IF, SCM_CDR (xorig));
0f2d19dd
JB
685}
686
302c12b4 687
9fbee57e
DH
688SCM_SYNTAX (s_lambda, "lambda", scm_makmmacro, scm_m_lambda);
689SCM_GLOBAL_SYMBOL (scm_sym_lambda, s_lambda);
0f2d19dd 690
9fbee57e
DH
691/* Return true if OBJ is `eq?' to one of the elements of LIST or to the
692 * cdr of the last cons. (Thus, LIST is not required to be a proper
693 * list and OBJ can also be found in the improper ending.) */
694static int
695scm_c_improper_memq (SCM obj, SCM list)
5cb22e96 696{
9fbee57e
DH
697 for (; SCM_CONSP (list); list = SCM_CDR (list))
698 {
699 if (SCM_EQ_P (SCM_CAR (list), obj))
700 return 1;
701 }
702 return SCM_EQ_P (list, obj);
5cb22e96
DH
703}
704
28d52ebb 705SCM
9fbee57e 706scm_m_lambda (SCM xorig, SCM env SCM_UNUSED)
28d52ebb 707{
9fbee57e
DH
708 SCM formals;
709 SCM x = SCM_CDR (xorig);
28d52ebb 710
9fbee57e 711 SCM_ASSYNT (SCM_CONSP (x), scm_s_formals, s_lambda);
1cc91f1b 712
9fbee57e
DH
713 formals = SCM_CAR (x);
714 while (SCM_CONSP (formals))
0f2d19dd 715 {
9fbee57e
DH
716 SCM formal = SCM_CAR (formals);
717 SCM_ASSYNT (SCM_SYMBOLP (formal), scm_s_formals, s_lambda);
718 if (scm_c_improper_memq (formal, SCM_CDR (formals)))
719 scm_misc_error (s_lambda, scm_s_duplicate_formals, SCM_EOL);
720 formals = SCM_CDR (formals);
0f2d19dd 721 }
9fbee57e
DH
722 if (!SCM_NULLP (formals) && !SCM_SYMBOLP (formals))
723 scm_misc_error (s_lambda, scm_s_formals, SCM_EOL);
724
725 return scm_cons2 (SCM_IM_LAMBDA, SCM_CAR (x),
726 scm_m_body (SCM_IM_LAMBDA, SCM_CDR (x), s_lambda));
0f2d19dd 727}
6dbd0af5 728
0f2d19dd 729
302c12b4
DH
730/* The bindings ((v1 i1) (v2 i2) ... (vn in)) are transformed to the lists
731 * (vn ... v2 v1) and (i1 i2 ... in). That is, the list of variables is
732 * reversed here, the list of inits gets reversed during evaluation. */
733static void
734transform_bindings (SCM bindings, SCM *rvarloc, SCM *initloc, const char *what)
0f2d19dd 735{
302c12b4
DH
736 SCM rvars = SCM_EOL;
737 *rvarloc = SCM_EOL;
738 *initloc = SCM_EOL;
739
740 SCM_ASSYNT (scm_ilength (bindings) >= 1, scm_s_bindings, what);
0f2d19dd 741
0f2d19dd
JB
742 do
743 {
302c12b4
DH
744 SCM binding = SCM_CAR (bindings);
745 SCM_ASSYNT (scm_ilength (binding) == 2, scm_s_bindings, what);
746 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (binding)), scm_s_variable, what);
747 if (scm_c_improper_memq (SCM_CAR (binding), rvars))
db4b4ca6 748 scm_misc_error (what, scm_s_duplicate_bindings, SCM_EOL);
302c12b4
DH
749 rvars = scm_cons (SCM_CAR (binding), rvars);
750 *initloc = scm_list_1 (SCM_CADR (binding));
a23afe53 751 initloc = SCM_CDRLOC (*initloc);
302c12b4 752 bindings = SCM_CDR (bindings);
0f2d19dd 753 }
302c12b4 754 while (!SCM_NULLP (bindings));
26d5b9b4 755
302c12b4 756 *rvarloc = rvars;
0f2d19dd
JB
757}
758
302c12b4 759
b8229a3b 760SCM_SYNTAX(s_let, "let", scm_makmmacro, scm_m_let);
2f0d1375 761SCM_GLOBAL_SYMBOL(scm_sym_let, s_let);
b8229a3b 762
302c12b4 763SCM
6e8d25a6 764scm_m_let (SCM xorig, SCM env)
0f2d19dd 765{
302c12b4
DH
766 SCM x = SCM_CDR (xorig);
767 SCM temp;
768
769 SCM_ASSYNT (SCM_CONSP (x), scm_s_bindings, s_let);
770 temp = SCM_CAR (x);
771 if (SCM_NULLP (temp)
772 || (scm_ilength (temp) == 1 && SCM_CONSP (SCM_CAR (temp))))
26d5b9b4
MD
773 {
774 /* null or single binding, let* is faster */
3096b33f 775 SCM bindings = temp;
302c12b4 776 SCM body = scm_m_body (SCM_IM_LET, SCM_CDR (x), s_let);
3096b33f 777 return scm_m_letstar (scm_cons2 (SCM_CAR (xorig), bindings, body), env);
26d5b9b4 778 }
302c12b4 779 else if (SCM_CONSP (temp))
26d5b9b4 780 {
3096b33f
DH
781 /* plain let */
782 SCM bindings = temp;
302c12b4 783 SCM rvars, inits, body;
3096b33f 784 transform_bindings (bindings, &rvars, &inits, "let");
302c12b4
DH
785 body = scm_m_body (SCM_IM_LET, SCM_CDR (x), "let");
786 return scm_cons2 (SCM_IM_LET, rvars, scm_cons (inits, body));
26d5b9b4 787 }
302c12b4
DH
788 else
789 {
790 /* named let: Transform (let name ((var init) ...) body ...) into
791 * ((letrec ((name (lambda (var ...) body ...))) name) init ...) */
26d5b9b4 792
302c12b4
DH
793 SCM name = temp;
794 SCM vars = SCM_EOL;
795 SCM *varloc = &vars;
796 SCM inits = SCM_EOL;
797 SCM *initloc = &inits;
798 SCM bindings;
799
800 SCM_ASSYNT (SCM_SYMBOLP (name), scm_s_bindings, s_let);
801 x = SCM_CDR (x);
802 SCM_ASSYNT (SCM_CONSP (x), scm_s_bindings, s_let);
803 bindings = SCM_CAR (x);
804 SCM_ASSYNT (scm_ilength (bindings) >= 0, scm_s_bindings, s_let);
805 while (!SCM_NULLP (bindings))
806 { /* vars and inits both in order */
807 SCM binding = SCM_CAR (bindings);
808 SCM_ASSYNT (scm_ilength (binding) == 2, scm_s_bindings, s_let);
809 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (binding)), scm_s_variable, s_let);
810 *varloc = scm_list_1 (SCM_CAR (binding));
811 varloc = SCM_CDRLOC (*varloc);
812 *initloc = scm_list_1 (SCM_CADR (binding));
813 initloc = SCM_CDRLOC (*initloc);
814 bindings = SCM_CDR (bindings);
815 }
26d5b9b4 816
302c12b4
DH
817 {
818 SCM lambda_body = scm_m_body (SCM_IM_LET, SCM_CDR (x), "let");
819 SCM lambda_form = scm_cons2 (scm_sym_lambda, vars, lambda_body);
820 SCM rvar = scm_list_1 (name);
821 SCM init = scm_list_1 (lambda_form);
822 SCM body = scm_m_body (SCM_IM_LET, scm_list_1 (name), "let");
823 SCM letrec = scm_cons2 (SCM_IM_LETREC, rvar, scm_cons (init, body));
824 return scm_cons (letrec, inits);
825 }
826 }
0f2d19dd
JB
827}
828
829
9fbee57e
DH
830SCM_SYNTAX (s_letstar, "let*", scm_makmmacro, scm_m_letstar);
831SCM_GLOBAL_SYMBOL (scm_sym_letstar, s_letstar);
1cc91f1b 832
9fbee57e
DH
833/* (let* ((v1 i1) (v2 i2) ...) body) with variables v1 .. vk and initializers
834 * i1 .. ik is transformed into the form (#@let* (v1 i1 v2 i2 ...) body*). */
835SCM
836scm_m_letstar (SCM xorig, SCM env SCM_UNUSED)
0f2d19dd 837{
9fbee57e
DH
838 SCM bindings;
839 SCM x = SCM_CDR (xorig);
840 SCM vars = SCM_EOL;
841 SCM *varloc = &vars;
0f2d19dd 842
9fbee57e
DH
843 SCM_ASSYNT (SCM_CONSP (x), scm_s_bindings, s_letstar);
844
845 bindings = SCM_CAR (x);
846 SCM_ASSYNT (scm_ilength (bindings) >= 0, scm_s_bindings, s_letstar);
847 while (!SCM_NULLP (bindings))
848 {
849 SCM binding = SCM_CAR (bindings);
850 SCM_ASSYNT (scm_ilength (binding) == 2, scm_s_bindings, s_letstar);
851 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (binding)), scm_s_variable, s_letstar);
852 *varloc = scm_list_2 (SCM_CAR (binding), SCM_CADR (binding));
853 varloc = SCM_CDRLOC (SCM_CDR (*varloc));
854 bindings = SCM_CDR (bindings);
855 }
856
857 return scm_cons2 (SCM_IM_LETSTAR, vars,
858 scm_m_body (SCM_IM_LETSTAR, SCM_CDR (x), s_letstar));
859}
b8229a3b 860
0f2d19dd 861
9fbee57e
DH
862SCM_SYNTAX(s_letrec, "letrec", scm_makmmacro, scm_m_letrec);
863SCM_GLOBAL_SYMBOL(scm_sym_letrec, s_letrec);
1cc91f1b 864
0f2d19dd 865SCM
9fbee57e 866scm_m_letrec (SCM xorig, SCM env)
0f2d19dd 867{
9fbee57e
DH
868 SCM x = SCM_CDR (xorig);
869 SCM_ASSYNT (SCM_CONSP (x), scm_s_bindings, s_letrec);
870
871 if (SCM_NULLP (SCM_CAR (x)))
872 {
873 /* null binding, let* faster */
874 SCM body = scm_m_body (SCM_IM_LETREC, SCM_CDR (x), s_letrec);
875 return scm_m_letstar (scm_cons2 (SCM_CAR (xorig), SCM_EOL, body), env);
876 }
877 else
878 {
879 SCM rvars, inits, body;
880 transform_bindings (SCM_CAR (x), &rvars, &inits, "letrec");
881 body = scm_m_body (SCM_IM_LETREC, SCM_CDR (x), "letrec");
882 return scm_cons2 (SCM_IM_LETREC, rvars, scm_cons (inits, body));
883 }
0f2d19dd
JB
884}
885
73b64342 886
9fbee57e
DH
887SCM_SYNTAX (s_or, "or", scm_makmmacro, scm_m_or);
888SCM_GLOBAL_SYMBOL (scm_sym_or, s_or);
73b64342
MD
889
890SCM
9fbee57e 891scm_m_or (SCM xorig, SCM env SCM_UNUSED)
73b64342 892{
c014a02e 893 long len = scm_ilength (SCM_CDR (xorig));
9fbee57e
DH
894 SCM_ASSYNT (len >= 0, scm_s_test, s_or);
895 if (len >= 1)
896 return scm_cons (SCM_IM_OR, SCM_CDR (xorig));
897 else
898 return SCM_BOOL_F;
73b64342
MD
899}
900
73b64342 901
9fbee57e
DH
902SCM_SYNTAX (s_quasiquote, "quasiquote", scm_makacro, scm_m_quasiquote);
903SCM_GLOBAL_SYMBOL (scm_sym_quasiquote, s_quasiquote);
904
905/* Internal function to handle a quasiquotation: 'form' is the parameter in
906 * the call (quasiquotation form), 'env' is the environment where unquoted
907 * expressions will be evaluated, and 'depth' is the current quasiquotation
908 * nesting level and is known to be greater than zero. */
909static SCM
910iqq (SCM form, SCM env, unsigned long int depth)
73b64342 911{
9fbee57e 912 if (SCM_CONSP (form))
c96d76b8 913 {
9fbee57e
DH
914 SCM tmp = SCM_CAR (form);
915 if (SCM_EQ_P (tmp, scm_sym_quasiquote))
916 {
917 SCM args = SCM_CDR (form);
918 SCM_ASSYNT (scm_ilength (args) == 1, scm_s_expression, s_quasiquote);
919 return scm_list_2 (tmp, iqq (SCM_CAR (args), env, depth + 1));
920 }
921 else if (SCM_EQ_P (tmp, scm_sym_unquote))
922 {
923 SCM args = SCM_CDR (form);
924 SCM_ASSYNT (scm_ilength (args) == 1, scm_s_expression, s_quasiquote);
925 if (depth - 1 == 0)
926 return scm_eval_car (args, env);
927 else
928 return scm_list_2 (tmp, iqq (SCM_CAR (args), env, depth - 1));
929 }
930 else if (SCM_CONSP (tmp)
931 && SCM_EQ_P (SCM_CAR (tmp), scm_sym_uq_splicing))
932 {
933 SCM args = SCM_CDR (tmp);
934 SCM_ASSYNT (scm_ilength (args) == 1, scm_s_expression, s_quasiquote);
935 if (depth - 1 == 0)
936 {
937 SCM list = scm_eval_car (args, env);
938 SCM rest = SCM_CDR (form);
939 SCM_ASSYNT (scm_ilength (list) >= 0, s_splicing, s_quasiquote);
940 return scm_append (scm_list_2 (list, iqq (rest, env, depth)));
941 }
942 else
943 return scm_cons (iqq (SCM_CAR (form), env, depth - 1),
944 iqq (SCM_CDR (form), env, depth));
945 }
946 else
947 return scm_cons (iqq (SCM_CAR (form), env, depth),
948 iqq (SCM_CDR (form), env, depth));
949 }
950 else if (SCM_VECTORP (form))
c96d76b8 951 {
9fbee57e
DH
952 size_t i = SCM_VECTOR_LENGTH (form);
953 SCM const *const data = SCM_VELTS (form);
954 SCM tmp = SCM_EOL;
955 while (i != 0)
956 tmp = scm_cons (data[--i], tmp);
957 scm_remember_upto_here_1 (form);
958 return scm_vector (iqq (tmp, env, depth));
c96d76b8 959 }
9fbee57e
DH
960 else
961 return form;
962}
963
964SCM
965scm_m_quasiquote (SCM xorig, SCM env)
966{
967 SCM x = SCM_CDR (xorig);
968 SCM_ASSYNT (scm_ilength (x) == 1, scm_s_expression, s_quasiquote);
969 return iqq (SCM_CAR (x), env, 1);
970}
971
972
973SCM_SYNTAX (s_quote, "quote", scm_makmmacro, scm_m_quote);
974SCM_GLOBAL_SYMBOL (scm_sym_quote, s_quote);
975
976SCM
977scm_m_quote (SCM xorig, SCM env SCM_UNUSED)
978{
979 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1, scm_s_expression, s_quote);
980 return scm_cons (SCM_IM_QUOTE, SCM_CDR (xorig));
981}
982
983
984/* Will go into the RnRS module when Guile is factorized.
985SCM_SYNTAX (s_set_x, "set!", scm_makmmacro, scm_m_set_x); */
986static const char s_set_x[] = "set!";
987SCM_GLOBAL_SYMBOL (scm_sym_set_x, s_set_x);
988
989SCM
990scm_m_set_x (SCM xorig, SCM env SCM_UNUSED)
991{
992 SCM x = SCM_CDR (xorig);
993 SCM_ASSYNT (scm_ilength (x) == 2, scm_s_expression, s_set_x);
994 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (x)), scm_s_variable, s_set_x);
995 return scm_cons (SCM_IM_SET_X, x);
996}
997
998
999/* Start of the memoizers for non-R5RS builtin macros. */
1000
1001
1002SCM_SYNTAX (s_atapply, "@apply", scm_makmmacro, scm_m_apply);
1003SCM_GLOBAL_SYMBOL (scm_sym_atapply, s_atapply);
1004SCM_GLOBAL_SYMBOL (scm_sym_apply, s_atapply + 1);
1005
1006SCM
1007scm_m_apply (SCM xorig, SCM env SCM_UNUSED)
1008{
1009 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 2, scm_s_expression, s_atapply);
1010 return scm_cons (SCM_IM_APPLY, SCM_CDR (xorig));
73b64342
MD
1011}
1012
c96d76b8 1013
2e171178
MV
1014/* (@bind ((var exp) ...) body ...)
1015
1016 This will assign the values of the `exp's to the global variables
1017 named by `var's (symbols, not evaluated), creating them if they
1018 don't exist, executes body, and then restores the previous values of
1019 the `var's. Additionally, whenever control leaves body, the values
1020 of the `var's are saved and restored when control returns. It is an
1021 error when a symbol appears more than once among the `var's.
1022 All `exp's are evaluated before any `var' is set.
1023
c96d76b8 1024 Think of this as `let' for dynamic scope.
2e171178
MV
1025
1026 It is memoized into (#@bind ((var ...) . (reversed-val ...)) body ...).
1027
1028 XXX - also implement `@bind*'.
1029*/
1030
73b64342
MD
1031SCM_SYNTAX (s_atbind, "@bind", scm_makmmacro, scm_m_atbind);
1032
1033SCM
1034scm_m_atbind (SCM xorig, SCM env)
1035{
1036 SCM x = SCM_CDR (xorig);
2e171178 1037 SCM top_level = scm_env_top_level (env);
311f6782 1038 SCM vars = SCM_EOL, var;
2e171178
MV
1039 SCM exps = SCM_EOL;
1040
1041 SCM_ASSYNT (scm_ilength (x) > 1, scm_s_expression, s_atbind);
73b64342 1042
73b64342
MD
1043 x = SCM_CAR (x);
1044 while (SCM_NIMP (x))
1045 {
2e171178
MV
1046 SCM rest;
1047 SCM sym_exp = SCM_CAR (x);
1048 SCM_ASSYNT (scm_ilength (sym_exp) == 2, scm_s_bindings, s_atbind);
1049 SCM_ASSYNT (SCM_SYMBOLP (SCM_CAR (sym_exp)), scm_s_bindings, s_atbind);
73b64342 1050 x = SCM_CDR (x);
2e171178 1051 for (rest = x; SCM_NIMP (rest); rest = SCM_CDR (rest))
8ea46249 1052 if (SCM_EQ_P (SCM_CAR (sym_exp), SCM_CAAR (rest)))
2e171178 1053 scm_misc_error (s_atbind, scm_s_duplicate_bindings, SCM_EOL);
311f6782
MV
1054 /* The first call to scm_sym2var will look beyond the current
1055 module, while the second call wont. */
1056 var = scm_sym2var (SCM_CAR (sym_exp), top_level, SCM_BOOL_F);
1057 if (SCM_FALSEP (var))
1058 var = scm_sym2var (SCM_CAR (sym_exp), top_level, SCM_BOOL_T);
1059 vars = scm_cons (var, vars);
2e171178 1060 exps = scm_cons (SCM_CADR (sym_exp), exps);
73b64342 1061 }
2e171178
MV
1062 return scm_cons (SCM_IM_BIND,
1063 scm_cons (scm_cons (scm_reverse_x (vars, SCM_EOL), exps),
1064 SCM_CDDR (xorig)));
73b64342 1065}
73b64342 1066
b0c5d67b 1067
9fbee57e
DH
1068SCM_SYNTAX(s_atcall_cc, "@call-with-current-continuation", scm_makmmacro, scm_m_cont);
1069SCM_GLOBAL_SYMBOL(scm_sym_atcall_cc, s_atcall_cc);
1070
1071
1072SCM
1073scm_m_cont (SCM xorig, SCM env SCM_UNUSED)
b0c5d67b 1074{
9fbee57e
DH
1075 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 1,
1076 scm_s_expression, s_atcall_cc);
1077 return scm_cons (SCM_IM_CONT, SCM_CDR (xorig));
b0c5d67b 1078}
b0c5d67b
DH
1079
1080
9fbee57e
DH
1081SCM_SYNTAX (s_at_call_with_values, "@call-with-values", scm_makmmacro, scm_m_at_call_with_values);
1082SCM_GLOBAL_SYMBOL(scm_sym_at_call_with_values, s_at_call_with_values);
b0c5d67b
DH
1083
1084SCM
9fbee57e 1085scm_m_at_call_with_values (SCM xorig, SCM env SCM_UNUSED)
b0c5d67b 1086{
9fbee57e
DH
1087 SCM_ASSYNT (scm_ilength (SCM_CDR (xorig)) == 2,
1088 scm_s_expression, s_at_call_with_values);
1089 return scm_cons (SCM_IM_CALL_WITH_VALUES, SCM_CDR (xorig));
b0c5d67b 1090}
b0c5d67b
DH
1091
1092
9fbee57e
DH
1093SCM_SYNTAX (s_future, "future", scm_makmmacro, scm_m_future);
1094SCM_GLOBAL_SYMBOL (scm_sym_future, s_future);
a513ead3 1095
9fbee57e
DH
1096/* Like promises, futures are implemented as closures with an empty
1097 * parameter list. Thus, (future <expression>) is transformed into
1098 * (#@future '() <expression>), where the empty list represents the
1099 * empty parameter list. This representation allows for easy creation
1100 * of the closure during evaluation. */
a513ead3 1101SCM
9fbee57e 1102scm_m_future (SCM xorig, SCM env SCM_UNUSED)
a513ead3 1103{
9fbee57e
DH
1104 SCM_ASSYNT (scm_ilength (xorig) == 2, scm_s_expression, s_future);
1105 return scm_cons2 (SCM_IM_FUTURE, SCM_EOL, SCM_CDR (xorig));
a513ead3
MV
1106}
1107
9fbee57e
DH
1108
1109SCM_SYNTAX (s_gset_x, "set!", scm_makmmacro, scm_m_generalized_set_x);
1110SCM_SYMBOL (scm_sym_setter, "setter");
1111
1112SCM
1113scm_m_generalized_set_x (SCM xorig, SCM env SCM_UNUSED)
1114{
1115 SCM x = SCM_CDR (xorig);
1116 SCM_ASSYNT (2 == scm_ilength (x), scm_s_expression, s_set_x);
1117 if (SCM_SYMBOLP (SCM_CAR (x)))
1118 return scm_cons (SCM_IM_SET_X, x);
1119 else if (SCM_CONSP (SCM_CAR (x)))
1120 return scm_cons (scm_list_2 (scm_sym_setter, SCM_CAAR (x)),
1121 scm_append (scm_list_2 (SCM_CDAR (x), SCM_CDR (x))));
1122 else
1123 scm_misc_error (s_set_x, scm_s_variable, SCM_EOL);
1124}
1125
1126
a4aa2134 1127static const char* s_atslot_ref = "@slot-ref";
9fbee57e 1128
a4aa2134
DH
1129/* @slot-ref is bound privately in the (oop goops) module from goops.c. As
1130 * soon as the module system allows us to more freely create bindings in
1131 * arbitrary modules during the startup phase, the code from goops.c should be
1132 * moved here. */
9fbee57e
DH
1133SCM
1134scm_m_atslot_ref (SCM xorig, SCM env SCM_UNUSED)
1135#define FUNC_NAME s_atslot_ref
1136{
1137 SCM x = SCM_CDR (xorig);
1138 SCM_ASSYNT (scm_ilength (x) == 2, scm_s_expression, FUNC_NAME);
1139 SCM_VALIDATE_INUM (SCM_ARG2, SCM_CADR (x));
1140 return scm_cons (SCM_IM_SLOT_REF, x);
1141}
1142#undef FUNC_NAME
1143
1144
a4aa2134 1145static const char* s_atslot_set_x = "@slot-set!";
9fbee57e 1146
a4aa2134
DH
1147/* @slot-set! is bound privately in the (oop goops) module from goops.c. As
1148 * soon as the module system allows us to more freely create bindings in
1149 * arbitrary modules during the startup phase, the code from goops.c should be
1150 * moved here. */
9fbee57e
DH
1151SCM
1152scm_m_atslot_set_x (SCM xorig, SCM env SCM_UNUSED)
1153#define FUNC_NAME s_atslot_set_x
1154{
1155 SCM x = SCM_CDR (xorig);
1156 SCM_ASSYNT (scm_ilength (x) == 3, scm_s_expression, FUNC_NAME);
1157 SCM_VALIDATE_INUM (SCM_ARG2, SCM_CADR (x));
1158 return scm_cons (SCM_IM_SLOT_SET_X, x);
1159}
1160#undef FUNC_NAME
1161
1162
1163#if SCM_ENABLE_ELISP
1164
1165SCM_SYNTAX (s_nil_cond, "nil-cond", scm_makmmacro, scm_m_nil_cond);
1166
1167SCM
1168scm_m_nil_cond (SCM xorig, SCM env SCM_UNUSED)
1169{
1170 long len = scm_ilength (SCM_CDR (xorig));
1171 SCM_ASSYNT (len >= 1 && (len & 1) == 1, scm_s_expression, "nil-cond");
1172 return scm_cons (SCM_IM_NIL_COND, SCM_CDR (xorig));
1173}
1174
1175
1176SCM_SYNTAX (s_atfop, "@fop", scm_makmmacro, scm_m_atfop);
1177
1178SCM
1179scm_m_atfop (SCM xorig, SCM env SCM_UNUSED)
1180{
1181 SCM x = SCM_CDR (xorig), var;
1182 SCM_ASSYNT (scm_ilength (x) >= 1, scm_s_expression, "@fop");
1183 var = scm_symbol_fref (SCM_CAR (x));
1184 /* Passing the symbol name as the `subr' arg here isn't really
1185 right, but without it it can be very difficult to work out from
1186 the error message which function definition was missing. In any
1187 case, we shouldn't really use SCM_ASSYNT here at all, but instead
1188 something equivalent to (signal void-function (list SYM)) in
1189 Elisp. */
1190 SCM_ASSYNT (SCM_VARIABLEP (var),
1191 "Symbol's function definition is void",
1192 SCM_SYMBOL_CHARS (SCM_CAR (x)));
1193 /* Support `defalias'. */
1194 while (SCM_SYMBOLP (SCM_VARIABLE_REF (var)))
1195 {
1196 var = scm_symbol_fref (SCM_VARIABLE_REF (var));
1197 SCM_ASSYNT (SCM_VARIABLEP (var),
1198 "Symbol's function definition is void",
1199 SCM_SYMBOL_CHARS (SCM_CAR (x)));
1200 }
1201 /* Use `var' here rather than `SCM_VARIABLE_REF (var)' because the
1202 former allows for automatically picking up redefinitions of the
1203 corresponding symbol. */
1204 SCM_SETCAR (x, var);
1205 /* If the variable contains a procedure, leave the
1206 `transformer-macro' in place so that the procedure's arguments
1207 get properly transformed, and change the initial @fop to
1208 SCM_IM_APPLY. */
1209 if (!SCM_MACROP (SCM_VARIABLE_REF (var)))
1210 {
1211 SCM_SETCAR (xorig, SCM_IM_APPLY);
1212 return xorig;
1213 }
1214 /* Otherwise (the variable contains a macro), the arguments should
1215 not be transformed, so cut the `transformer-macro' out and return
1216 the resulting expression starting with the variable. */
1217 SCM_SETCDR (x, SCM_CDADR (x));
1218 return x;
1219}
1220
1221#endif /* SCM_ENABLE_ELISP */
1222
1223
26d5b9b4
MD
1224SCM
1225scm_m_expand_body (SCM xorig, SCM env)
1226{
22a52da1 1227 SCM x = SCM_CDR (xorig), defs = SCM_EOL;
26d5b9b4
MD
1228 char *what = SCM_ISYMCHARS (SCM_CAR (xorig)) + 2;
1229
1230 while (SCM_NIMP (x))
1231 {
22a52da1
DH
1232 SCM form = SCM_CAR (x);
1233 if (!SCM_CONSP (form))
26d5b9b4
MD
1234 break;
1235 if (!SCM_SYMBOLP (SCM_CAR (form)))
1236 break;
22a52da1 1237
3a3111a8
MD
1238 form = scm_macroexp (scm_cons_source (form,
1239 SCM_CAR (form),
1240 SCM_CDR (form)),
1241 env);
26d5b9b4 1242
cf498326 1243 if (SCM_EQ_P (SCM_IM_DEFINE, SCM_CAR (form)))
26d5b9b4
MD
1244 {
1245 defs = scm_cons (SCM_CDR (form), defs);
22a52da1 1246 x = SCM_CDR (x);
26d5b9b4 1247 }
22a52da1 1248 else if (!SCM_IMP (defs))
26d5b9b4
MD
1249 {
1250 break;
1251 }
cf498326 1252 else if (SCM_EQ_P (SCM_IM_BEGIN, SCM_CAR (form)))
26d5b9b4 1253 {
8ea46249 1254 x = scm_append (scm_list_2 (SCM_CDR (form), SCM_CDR (x)));
26d5b9b4
MD
1255 }
1256 else
1257 {
22a52da1 1258 x = scm_cons (form, SCM_CDR (x));
26d5b9b4
MD
1259 break;
1260 }
1261 }
1262
302c12b4 1263 if (!SCM_NULLP (defs))
26d5b9b4 1264 {
302c12b4
DH
1265 SCM rvars, inits, body, letrec;
1266 transform_bindings (defs, &rvars, &inits, what);
1267 body = scm_m_body (SCM_IM_DEFINE, x, what);
1268 letrec = scm_cons2 (SCM_IM_LETREC, rvars, scm_cons (inits, body));
1269 SCM_SETCAR (xorig, letrec);
1270 SCM_SETCDR (xorig, SCM_EOL);
1271 }
1272 else
1273 {
1274 SCM_ASSYNT (SCM_CONSP (x), scm_s_body, what);
1275 SCM_SETCAR (xorig, SCM_CAR (x));
1276 SCM_SETCDR (xorig, SCM_CDR (x));
26d5b9b4 1277 }
26d5b9b4
MD
1278
1279 return xorig;
1280}
1281
1282SCM
1283scm_macroexp (SCM x, SCM env)
1284{
86d31dfe 1285 SCM res, proc, orig_sym;
26d5b9b4
MD
1286
1287 /* Don't bother to produce error messages here. We get them when we
1288 eventually execute the code for real. */
1289
1290 macro_tail:
86d31dfe
MV
1291 orig_sym = SCM_CAR (x);
1292 if (!SCM_SYMBOLP (orig_sym))
26d5b9b4
MD
1293 return x;
1294
26d5b9b4
MD
1295 {
1296 SCM *proc_ptr = scm_lookupcar1 (x, env, 0);
1297 if (proc_ptr == NULL)
1298 {
1299 /* We have lost the race. */
1300 goto macro_tail;
1301 }
1302 proc = *proc_ptr;
1303 }
26d5b9b4
MD
1304
1305 /* Only handle memoizing macros. `Acros' and `macros' are really
1306 special forms and should not be evaluated here. */
1307
22a52da1 1308 if (!SCM_MACROP (proc) || SCM_MACRO_TYPE (proc) != 2)
26d5b9b4
MD
1309 return x;
1310
86d31dfe 1311 SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of lookupcar */
fdc28395 1312 res = scm_call_2 (SCM_MACRO_CODE (proc), x, env);
26d5b9b4
MD
1313
1314 if (scm_ilength (res) <= 0)
8ea46249 1315 res = scm_list_2 (SCM_IM_BEGIN, res);
26d5b9b4 1316
26d5b9b4
MD
1317 SCM_DEFER_INTS;
1318 SCM_SETCAR (x, SCM_CAR (res));
1319 SCM_SETCDR (x, SCM_CDR (res));
1320 SCM_ALLOW_INTS;
1321
1322 goto macro_tail;
1323}
73b64342 1324
a44a9715
DH
1325#define SCM_BIT7(x) (127 & SCM_UNPACK (x))
1326
1327/* A function object to implement "apply" for non-closure functions. */
1328static SCM f_apply;
1329/* An endless list consisting of #<undefined> objects: */
1330static SCM undefineds;
1331
6dbd0af5
MD
1332/* scm_unmemocopy takes a memoized expression together with its
1333 * environment and rewrites it to its original form. Thus, it is the
1334 * inversion of the rewrite rules above. The procedure is not
1335 * optimized for speed. It's used in scm_iprin1 when printing the
220ff1eb
MD
1336 * code of a closure, in scm_procedure_source, in display_frame when
1337 * generating the source for a stackframe in a backtrace, and in
1338 * display_expression.
86d31dfe 1339 *
c96d76b8 1340 * Unmemoizing is not a reliable process. You cannot in general
86d31dfe
MV
1341 * expect to get the original source back.
1342 *
1343 * However, GOOPS currently relies on this for method compilation.
1344 * This ought to change.
26d5b9b4
MD
1345 */
1346
8ea46249
DH
1347static SCM
1348build_binding_list (SCM names, SCM inits)
1349{
1350 SCM bindings = SCM_EOL;
1351 while (!SCM_NULLP (names))
1352 {
1353 SCM binding = scm_list_2 (SCM_CAR (names), SCM_CAR (inits));
1354 bindings = scm_cons (binding, bindings);
1355 names = SCM_CDR (names);
1356 inits = SCM_CDR (inits);
1357 }
1358 return bindings;
1359}
1360
6dbd0af5 1361static SCM
1bbd0b84 1362unmemocopy (SCM x, SCM env)
6dbd0af5
MD
1363{
1364 SCM ls, z;
6dbd0af5 1365 SCM p;
8c494e99 1366 if (!SCM_CONSP (x))
6dbd0af5 1367 return x;
6dbd0af5 1368 p = scm_whash_lookup (scm_source_whash, x);
8ea46249 1369 switch (SCM_ITAG7 (SCM_CAR (x)))
6dbd0af5 1370 {
1b43d24c 1371 case SCM_BIT7 (SCM_IM_AND):
2f0d1375 1372 ls = z = scm_cons (scm_sym_and, SCM_UNSPECIFIED);
6dbd0af5 1373 break;
1b43d24c 1374 case SCM_BIT7 (SCM_IM_BEGIN):
2f0d1375 1375 ls = z = scm_cons (scm_sym_begin, SCM_UNSPECIFIED);
6dbd0af5 1376 break;
1b43d24c 1377 case SCM_BIT7 (SCM_IM_CASE):
2f0d1375 1378 ls = z = scm_cons (scm_sym_case, SCM_UNSPECIFIED);
6dbd0af5 1379 break;
1b43d24c 1380 case SCM_BIT7 (SCM_IM_COND):
2f0d1375 1381 ls = z = scm_cons (scm_sym_cond, SCM_UNSPECIFIED);
6dbd0af5 1382 break;
1b43d24c 1383 case SCM_BIT7 (SCM_IM_DO):
6dbd0af5 1384 {
8ea46249
DH
1385 /* format: (#@do (nk nk-1 ...) (i1 ... ik) (test) (body) s1 ... sk),
1386 * where nx is the name of a local variable, ix is an initializer for
1387 * the local variable, test is the test clause of the do loop, body is
1388 * the body of the do loop and sx are the step clauses for the local
1389 * variables. */
1390 SCM names, inits, test, memoized_body, steps, bindings;
1391
1392 x = SCM_CDR (x);
1393 names = SCM_CAR (x);
6dbd0af5 1394 x = SCM_CDR (x);
8ea46249 1395 inits = scm_reverse (unmemocopy (SCM_CAR (x), env));
821f18a4 1396 env = SCM_EXTEND_ENV (names, SCM_EOL, env);
6dbd0af5 1397 x = SCM_CDR (x);
8ea46249
DH
1398 test = unmemocopy (SCM_CAR (x), env);
1399 x = SCM_CDR (x);
1400 memoized_body = SCM_CAR (x);
1401 x = SCM_CDR (x);
1402 steps = scm_reverse (unmemocopy (x, env));
1403
26d5b9b4 1404 /* build transformed binding list */
8ea46249
DH
1405 bindings = SCM_EOL;
1406 while (!SCM_NULLP (names))
6dbd0af5 1407 {
8ea46249
DH
1408 SCM name = SCM_CAR (names);
1409 SCM init = SCM_CAR (inits);
1410 SCM step = SCM_CAR (steps);
1411 step = SCM_EQ_P (step, name) ? SCM_EOL : scm_list_1 (step);
1412
1413 bindings = scm_cons (scm_cons2 (name, init, step), bindings);
1414
1415 names = SCM_CDR (names);
1416 inits = SCM_CDR (inits);
1417 steps = SCM_CDR (steps);
6dbd0af5 1418 }
8ea46249
DH
1419 z = scm_cons (test, SCM_UNSPECIFIED);
1420 ls = scm_cons2 (scm_sym_do, bindings, z);
1421
1422 x = scm_cons (SCM_BOOL_F, memoized_body);
1423 break;
1424 }
1b43d24c 1425 case SCM_BIT7 (SCM_IM_IF):
8ea46249
DH
1426 ls = z = scm_cons (scm_sym_if, SCM_UNSPECIFIED);
1427 break;
1b43d24c 1428 case SCM_BIT7 (SCM_IM_LET):
8ea46249
DH
1429 {
1430 /* format: (#@let (nk nk-1 ...) (i1 ... ik) b1 ...),
1431 * where nx is the name of a local variable, ix is an initializer for
1432 * the local variable and by are the body clauses. */
1433 SCM names, inits, bindings;
1434
1435 x = SCM_CDR (x);
1436 names = SCM_CAR (x);
1437 x = SCM_CDR (x);
1438 inits = scm_reverse (unmemocopy (SCM_CAR (x), env));
821f18a4 1439 env = SCM_EXTEND_ENV (names, SCM_EOL, env);
8ea46249
DH
1440
1441 bindings = build_binding_list (names, inits);
1442 z = scm_cons (bindings, SCM_UNSPECIFIED);
1443 ls = scm_cons (scm_sym_let, z);
1444 break;
1445 }
1b43d24c 1446 case SCM_BIT7 (SCM_IM_LETREC):
8ea46249
DH
1447 {
1448 /* format: (#@letrec (nk nk-1 ...) (i1 ... ik) b1 ...),
1449 * where nx is the name of a local variable, ix is an initializer for
1450 * the local variable and by are the body clauses. */
1451 SCM names, inits, bindings;
1452
1453 x = SCM_CDR (x);
1454 names = SCM_CAR (x);
821f18a4 1455 env = SCM_EXTEND_ENV (names, SCM_EOL, env);
8ea46249
DH
1456 x = SCM_CDR (x);
1457 inits = scm_reverse (unmemocopy (SCM_CAR (x), env));
1458
1459 bindings = build_binding_list (names, inits);
1460 z = scm_cons (bindings, SCM_UNSPECIFIED);
1461 ls = scm_cons (scm_sym_letrec, z);
6dbd0af5
MD
1462 break;
1463 }
1b43d24c 1464 case SCM_BIT7 (SCM_IM_LETSTAR):
6dbd0af5
MD
1465 {
1466 SCM b, y;
1467 x = SCM_CDR (x);
1468 b = SCM_CAR (x);
1469 y = SCM_EOL;
1470 if SCM_IMP (b)
1471 {
821f18a4 1472 env = SCM_EXTEND_ENV (SCM_EOL, SCM_EOL, env);
6dbd0af5
MD
1473 goto letstar;
1474 }
1475 y = z = scm_acons (SCM_CAR (b),
1476 unmemocar (
8ea46249 1477 scm_cons (unmemocopy (SCM_CADR (b), env), SCM_EOL), env),
6dbd0af5 1478 SCM_UNSPECIFIED);
821f18a4 1479 env = SCM_EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
8ea46249 1480 b = SCM_CDDR (b);
6dbd0af5
MD
1481 if (SCM_IMP (b))
1482 {
1483 SCM_SETCDR (y, SCM_EOL);
05b15362
DH
1484 z = scm_cons (y, SCM_UNSPECIFIED);
1485 ls = scm_cons (scm_sym_let, z);
6dbd0af5
MD
1486 break;
1487 }
1488 do
1489 {
a23afe53
MD
1490 SCM_SETCDR (z, scm_acons (SCM_CAR (b),
1491 unmemocar (
8ea46249 1492 scm_list_1 (unmemocopy (SCM_CADR (b), env)), env),
a23afe53
MD
1493 SCM_UNSPECIFIED));
1494 z = SCM_CDR (z);
821f18a4 1495 env = SCM_EXTEND_ENV (SCM_CAR (b), SCM_BOOL_F, env);
8ea46249 1496 b = SCM_CDDR (b);
6dbd0af5 1497 }
ff467021 1498 while (SCM_NIMP (b));
a23afe53 1499 SCM_SETCDR (z, SCM_EOL);
6dbd0af5 1500 letstar:
05b15362
DH
1501 z = scm_cons (y, SCM_UNSPECIFIED);
1502 ls = scm_cons (scm_sym_letstar, z);
6dbd0af5
MD
1503 break;
1504 }
1b43d24c 1505 case SCM_BIT7 (SCM_IM_OR):
2f0d1375 1506 ls = z = scm_cons (scm_sym_or, SCM_UNSPECIFIED);
6dbd0af5 1507 break;
1b43d24c 1508 case SCM_BIT7 (SCM_IM_LAMBDA):
6dbd0af5 1509 x = SCM_CDR (x);
8ea46249
DH
1510 z = scm_cons (SCM_CAR (x), SCM_UNSPECIFIED);
1511 ls = scm_cons (scm_sym_lambda, z);
821f18a4 1512 env = SCM_EXTEND_ENV (SCM_CAR (x), SCM_EOL, env);
6dbd0af5 1513 break;
1b43d24c 1514 case SCM_BIT7 (SCM_IM_QUOTE):
2f0d1375 1515 ls = z = scm_cons (scm_sym_quote, SCM_UNSPECIFIED);
6dbd0af5 1516 break;
1b43d24c 1517 case SCM_BIT7 (SCM_IM_SET_X):
89efbff4 1518 ls = z = scm_cons (scm_sym_set_x, SCM_UNSPECIFIED);
6dbd0af5 1519 break;
1b43d24c 1520 case SCM_BIT7 (SCM_IM_DEFINE):
6dbd0af5
MD
1521 {
1522 SCM n;
1523 x = SCM_CDR (x);
8ea46249
DH
1524 n = SCM_CAR (x);
1525 z = scm_cons (n, SCM_UNSPECIFIED);
1526 ls = scm_cons (scm_sym_define, z);
01f11e02 1527 if (!SCM_NULLP (env))
4c5f8e8f
NJ
1528 env = scm_cons (scm_cons (scm_cons (n, SCM_CAAR (env)),
1529 SCM_CDAR (env)),
1530 SCM_CDR (env));
6dbd0af5
MD
1531 break;
1532 }
1b43d24c 1533 case SCM_BIT7 (SCM_MAKISYM (0)):
6dbd0af5
MD
1534 z = SCM_CAR (x);
1535 if (!SCM_ISYMP (z))
1536 goto unmemo;
ff467021 1537 switch (SCM_ISYMNUM (z))
6dbd0af5
MD
1538 {
1539 case (SCM_ISYMNUM (SCM_IM_APPLY)):
2f0d1375 1540 ls = z = scm_cons (scm_sym_atapply, SCM_UNSPECIFIED);
6dbd0af5
MD
1541 goto loop;
1542 case (SCM_ISYMNUM (SCM_IM_CONT)):
2f0d1375 1543 ls = z = scm_cons (scm_sym_atcall_cc, SCM_UNSPECIFIED);
6dbd0af5 1544 goto loop;
a570e93a
MD
1545 case (SCM_ISYMNUM (SCM_IM_DELAY)):
1546 ls = z = scm_cons (scm_sym_delay, SCM_UNSPECIFIED);
1547 x = SCM_CDR (x);
1548 goto loop;
28d52ebb 1549 case (SCM_ISYMNUM (SCM_IM_FUTURE)):
ebf9b47c 1550 ls = z = scm_cons (scm_sym_future, SCM_UNSPECIFIED);
28d52ebb
MD
1551 x = SCM_CDR (x);
1552 goto loop;
a513ead3
MV
1553 case (SCM_ISYMNUM (SCM_IM_CALL_WITH_VALUES)):
1554 ls = z = scm_cons (scm_sym_at_call_with_values, SCM_UNSPECIFIED);
1555 goto loop;
6dbd0af5 1556 default:
fa888178 1557 /* appease the Sun compiler god: */ ;
6dbd0af5
MD
1558 }
1559 unmemo:
1560 default:
1561 ls = z = unmemocar (scm_cons (unmemocopy (SCM_CAR (x), env),
1562 SCM_UNSPECIFIED),
1563 env);
1564 }
1565loop:
8c494e99
DH
1566 x = SCM_CDR (x);
1567 while (SCM_CONSP (x))
a23afe53 1568 {
8c494e99
DH
1569 SCM form = SCM_CAR (x);
1570 if (!SCM_ISYMP (form))
1571 {
1572 SCM copy = scm_cons (unmemocopy (form, env), SCM_UNSPECIFIED);
1573 SCM_SETCDR (z, unmemocar (copy, env));
1574 z = SCM_CDR (z);
1575 }
1576 x = SCM_CDR (x);
a23afe53
MD
1577 }
1578 SCM_SETCDR (z, x);
01f11e02 1579 if (!SCM_FALSEP (p))
6dbd0af5 1580 scm_whash_insert (scm_source_whash, ls, p);
6dbd0af5
MD
1581 return ls;
1582}
1583
1cc91f1b 1584
6dbd0af5 1585SCM
6e8d25a6 1586scm_unmemocopy (SCM x, SCM env)
6dbd0af5 1587{
01f11e02 1588 if (!SCM_NULLP (env))
6dbd0af5
MD
1589 /* Make a copy of the lowest frame to protect it from
1590 modifications by SCM_IM_DEFINE */
1591 return unmemocopy (x, scm_cons (SCM_CAR (env), SCM_CDR (env)));
1592 else
1593 return unmemocopy (x, env);
1594}
1595
1cc91f1b 1596
0f2d19dd 1597int
6e8d25a6 1598scm_badargsp (SCM formals, SCM args)
0f2d19dd 1599{
6a0f6ff3 1600 while (!SCM_NULLP (formals))
0f2d19dd 1601 {
01f11e02 1602 if (!SCM_CONSP (formals))
ff467021 1603 return 0;
6a0f6ff3 1604 if (SCM_NULLP (args))
ff467021 1605 return 1;
0f2d19dd
JB
1606 formals = SCM_CDR (formals);
1607 args = SCM_CDR (args);
1608 }
01f11e02 1609 return !SCM_NULLP (args) ? 1 : 0;
0f2d19dd 1610}
a392ee15 1611
0f2d19dd 1612
002f1a5d
MD
1613static int
1614scm_badformalsp (SCM closure, int n)
1615{
726d810a
DH
1616 SCM formals = SCM_CLOSURE_FORMALS (closure);
1617 while (!SCM_NULLP (formals))
002f1a5d 1618 {
726d810a 1619 if (!SCM_CONSP (formals))
002f1a5d
MD
1620 return 0;
1621 if (n == 0)
1622 return 1;
1623 --n;
1624 formals = SCM_CDR (formals);
1625 }
1626 return n;
1627}
0f2d19dd
JB
1628
1629\f
6dbd0af5 1630SCM
6e8d25a6 1631scm_eval_args (SCM l, SCM env, SCM proc)
6dbd0af5 1632{
680ed4a8 1633 SCM results = SCM_EOL, *lloc = &results, res;
904a077d 1634 while (SCM_CONSP (l))
6dbd0af5 1635 {
680ed4a8 1636 res = EVALCAR (l, env);
904a077d 1637
8ea46249 1638 *lloc = scm_list_1 (res);
a23afe53 1639 lloc = SCM_CDRLOC (*lloc);
6dbd0af5
MD
1640 l = SCM_CDR (l);
1641 }
22a52da1 1642 if (!SCM_NULLP (l))
904a077d 1643 scm_wrong_num_args (proc);
680ed4a8 1644 return results;
6dbd0af5 1645}
c4ac4d88 1646
d0b07b5d 1647
9de33deb
MD
1648SCM
1649scm_eval_body (SCM code, SCM env)
1650{
1651 SCM next;
1652 again:
01f11e02
DH
1653 next = SCM_CDR (code);
1654 while (!SCM_NULLP (next))
9de33deb
MD
1655 {
1656 if (SCM_IMP (SCM_CAR (code)))
1657 {
1658 if (SCM_ISYMP (SCM_CAR (code)))
1659 {
28d52ebb 1660 scm_rec_mutex_lock (&source_mutex);
9bc4701c
MD
1661 /* check for race condition */
1662 if (SCM_ISYMP (SCM_CAR (code)))
1663 code = scm_m_expand_body (code, env);
28d52ebb 1664 scm_rec_mutex_unlock (&source_mutex);
9de33deb
MD
1665 goto again;
1666 }
1667 }
1668 else
1669 SCM_XEVAL (SCM_CAR (code), env);
1670 code = next;
01f11e02 1671 next = SCM_CDR (code);
9de33deb
MD
1672 }
1673 return SCM_XEVALCAR (code, env);
1674}
1675
0f2d19dd
JB
1676#endif /* !DEVAL */
1677
6dbd0af5
MD
1678
1679/* SECTION: This code is specific for the debugging support. One
1680 * branch is read when DEVAL isn't defined, the other when DEVAL is
1681 * defined.
1682 */
1683
1684#ifndef DEVAL
1685
1686#define SCM_APPLY scm_apply
1687#define PREP_APPLY(proc, args)
1688#define ENTER_APPLY
ddea3325 1689#define RETURN(x) do { return x; } while (0)
b7ff98dd
MD
1690#ifdef STACK_CHECKING
1691#ifndef NO_CEVAL_STACK_CHECKING
1692#define EVAL_STACK_CHECKING
1693#endif
6dbd0af5
MD
1694#endif
1695
1696#else /* !DEVAL */
1697
0f2d19dd
JB
1698#undef SCM_CEVAL
1699#define SCM_CEVAL scm_deval /* Substitute all uses of scm_ceval */
1700#undef SCM_APPLY
1701#define SCM_APPLY scm_dapply
6dbd0af5
MD
1702#undef PREP_APPLY
1703#define PREP_APPLY(p, l) \
1704{ ++debug.info; debug.info->a.proc = p; debug.info->a.args = l; }
1705#undef ENTER_APPLY
1706#define ENTER_APPLY \
d3a6bc94 1707do { \
b7ff98dd 1708 SCM_SET_ARGSREADY (debug);\
5132eef0 1709 if (scm_check_apply_p && SCM_TRAPS_P)\
b7ff98dd 1710 if (SCM_APPLY_FRAME_P || (SCM_TRACE_P && PROCTRACEP (proc)))\
6dbd0af5 1711 {\
156dcb09 1712 SCM tmp, tail = SCM_BOOL(SCM_TRACED_FRAME_P (debug)); \
c6a4fbce 1713 SCM_SET_TRACED_FRAME (debug); \
d95c0b76 1714 SCM_TRAPS_P = 0;\
b7ff98dd 1715 if (SCM_CHEAPTRAPS_P)\
6dbd0af5 1716 {\
c0ab1b8d 1717 tmp = scm_make_debugobj (&debug);\
d95c0b76 1718 scm_call_3 (SCM_APPLY_FRAME_HDLR, scm_sym_apply_frame, tmp, tail);\
b6d75948 1719 }\
6dbd0af5
MD
1720 else\
1721 {\
5f144b10
GH
1722 int first;\
1723 tmp = scm_make_continuation (&first);\
1724 if (first)\
d95c0b76 1725 scm_call_3 (SCM_APPLY_FRAME_HDLR, scm_sym_apply_frame, tmp, tail);\
6dbd0af5 1726 }\
d95c0b76 1727 SCM_TRAPS_P = 1;\
6dbd0af5 1728 }\
d3a6bc94 1729} while (0)
0f2d19dd 1730#undef RETURN
ddea3325 1731#define RETURN(e) do { proc = (e); goto exit; } while (0)
b7ff98dd
MD
1732#ifdef STACK_CHECKING
1733#ifndef EVAL_STACK_CHECKING
1734#define EVAL_STACK_CHECKING
1735#endif
6dbd0af5
MD
1736#endif
1737
1738/* scm_ceval_ptr points to the currently selected evaluator.
1739 * *fixme*: Although efficiency is important here, this state variable
1740 * should probably not be a global. It should be related to the
1741 * current repl.
1742 */
1743
1cc91f1b 1744
1bbd0b84 1745SCM (*scm_ceval_ptr) (SCM x, SCM env);
0f2d19dd 1746
1646d37b 1747/* scm_last_debug_frame contains a pointer to the last debugging
6dbd0af5
MD
1748 * information stack frame. It is accessed very often from the
1749 * debugging evaluator, so it should probably not be indirectly
1750 * addressed. Better to save and restore it from the current root at
1751 * any stack swaps.
1752 */
1753
6dbd0af5
MD
1754/* scm_debug_eframe_size is the number of slots available for pseudo
1755 * stack frames at each real stack frame.
1756 */
1757
c014a02e 1758long scm_debug_eframe_size;
6dbd0af5 1759
b7ff98dd 1760int scm_debug_mode, scm_check_entry_p, scm_check_apply_p, scm_check_exit_p;
6dbd0af5 1761
c014a02e 1762long scm_eval_stack;
a74145b8 1763
92c2555f 1764scm_t_option scm_eval_opts[] = {
a74145b8 1765 { SCM_OPTION_INTEGER, "stack", 22000, "Size of thread stacks (in machine words)." }
33b97402
MD
1766};
1767
92c2555f 1768scm_t_option scm_debug_opts[] = {
b7ff98dd
MD
1769 { SCM_OPTION_BOOLEAN, "cheap", 1,
1770 "*Flyweight representation of the stack at traps." },
1771 { SCM_OPTION_BOOLEAN, "breakpoints", 0, "*Check for breakpoints." },
1772 { SCM_OPTION_BOOLEAN, "trace", 0, "*Trace mode." },
1773 { SCM_OPTION_BOOLEAN, "procnames", 1,
1774 "Record procedure names at definition." },
1775 { SCM_OPTION_BOOLEAN, "backwards", 0,
1776 "Display backtrace in anti-chronological order." },
274dc5fd 1777 { SCM_OPTION_INTEGER, "width", 79, "Maximal width of backtrace." },
4e646a03
MD
1778 { SCM_OPTION_INTEGER, "indent", 10, "Maximal indentation in backtrace." },
1779 { SCM_OPTION_INTEGER, "frames", 3,
b7ff98dd 1780 "Maximum number of tail-recursive frames in backtrace." },
4e646a03
MD
1781 { SCM_OPTION_INTEGER, "maxdepth", 1000,
1782 "Maximal number of stored backtrace frames." },
1783 { SCM_OPTION_INTEGER, "depth", 20, "Maximal length of printed backtrace." },
11f77bfc
MD
1784 { SCM_OPTION_BOOLEAN, "backtrace", 0, "Show backtrace on error." },
1785 { SCM_OPTION_BOOLEAN, "debug", 0, "Use the debugging evaluator." },
863e833b 1786 { SCM_OPTION_INTEGER, "stack", 20000, "Stack size limit (measured in words; 0 = no check)." },
d95c0b76 1787 { SCM_OPTION_SCM, "show-file-name", (unsigned long)SCM_BOOL_T, "Show file names and line numbers in backtraces when not `#f'. A value of `base' displays only base names, while `#t' displays full names."}
6dbd0af5
MD
1788};
1789
92c2555f 1790scm_t_option scm_evaluator_trap_table[] = {
b6d75948 1791 { SCM_OPTION_BOOLEAN, "traps", 0, "Enable evaluator traps." },
b7ff98dd
MD
1792 { SCM_OPTION_BOOLEAN, "enter-frame", 0, "Trap when eval enters new frame." },
1793 { SCM_OPTION_BOOLEAN, "apply-frame", 0, "Trap when entering apply." },
d95c0b76
NJ
1794 { SCM_OPTION_BOOLEAN, "exit-frame", 0, "Trap when exiting eval or apply." },
1795 { SCM_OPTION_SCM, "enter-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for enter-frame traps." },
1796 { SCM_OPTION_SCM, "apply-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for apply-frame traps." },
1797 { SCM_OPTION_SCM, "exit-frame-handler", (unsigned long)SCM_BOOL_F, "Handler for exit-frame traps." }
6dbd0af5
MD
1798};
1799
a1ec6916 1800SCM_DEFINE (scm_eval_options_interface, "eval-options-interface", 0, 1, 0,
1bbd0b84 1801 (SCM setting),
b3f26b14
MG
1802 "Option interface for the evaluation options. Instead of using\n"
1803 "this procedure directly, use the procedures @code{eval-enable},\n"
3939e9df 1804 "@code{eval-disable}, @code{eval-set!} and @code{eval-options}.")
1bbd0b84 1805#define FUNC_NAME s_scm_eval_options_interface
33b97402
MD
1806{
1807 SCM ans;
1808 SCM_DEFER_INTS;
1809 ans = scm_options (setting,
1810 scm_eval_opts,
1811 SCM_N_EVAL_OPTIONS,
1bbd0b84 1812 FUNC_NAME);
a74145b8 1813 scm_eval_stack = SCM_EVAL_STACK * sizeof (void *);
33b97402
MD
1814 SCM_ALLOW_INTS;
1815 return ans;
1816}
1bbd0b84 1817#undef FUNC_NAME
33b97402 1818
d0b07b5d 1819
a1ec6916 1820SCM_DEFINE (scm_evaluator_traps, "evaluator-traps-interface", 0, 1, 0,
1bbd0b84 1821 (SCM setting),
b3f26b14 1822 "Option interface for the evaluator trap options.")
1bbd0b84 1823#define FUNC_NAME s_scm_evaluator_traps
33b97402
MD
1824{
1825 SCM ans;
1826 SCM_DEFER_INTS;
1827 ans = scm_options (setting,
1828 scm_evaluator_trap_table,
1829 SCM_N_EVALUATOR_TRAPS,
1bbd0b84 1830 FUNC_NAME);
33b97402 1831 SCM_RESET_DEBUG_MODE;
bfc69694 1832 SCM_ALLOW_INTS;
33b97402
MD
1833 return ans;
1834}
1bbd0b84 1835#undef FUNC_NAME
33b97402 1836
d0b07b5d 1837
24933780 1838static SCM
a392ee15 1839deval_args (SCM l, SCM env, SCM proc, SCM *lloc)
0f2d19dd 1840{
680ed4a8 1841 SCM *results = lloc, res;
904a077d 1842 while (SCM_CONSP (l))
0f2d19dd 1843 {
680ed4a8 1844 res = EVALCAR (l, env);
904a077d 1845
8ea46249 1846 *lloc = scm_list_1 (res);
a23afe53 1847 lloc = SCM_CDRLOC (*lloc);
0f2d19dd
JB
1848 l = SCM_CDR (l);
1849 }
22a52da1 1850 if (!SCM_NULLP (l))
904a077d 1851 scm_wrong_num_args (proc);
680ed4a8 1852 return *results;
0f2d19dd
JB
1853}
1854
6dbd0af5
MD
1855#endif /* !DEVAL */
1856
1857
a392ee15 1858/* SECTION: This code is compiled twice.
6dbd0af5
MD
1859 */
1860
a392ee15 1861
d9d39d76 1862/* Update the toplevel environment frame ENV so that it refers to the
a392ee15 1863 * current module. */
d9d39d76
MV
1864#define UPDATE_TOPLEVEL_ENV(env) \
1865 do { \
1866 SCM p = scm_current_module_lookup_closure (); \
d0b07b5d 1867 if (p != SCM_CAR (env)) \
d9d39d76
MV
1868 env = scm_top_level_env (p); \
1869 } while (0)
1870
6dbd0af5 1871
a392ee15
DH
1872/* This is the evaluator. Like any real monster, it has three heads:
1873 *
1874 * scm_ceval is the non-debugging evaluator, scm_deval is the debugging
1875 * version. Both are implemented using a common code base, using the
1876 * following mechanism: SCM_CEVAL is a macro, which is either defined to
1877 * scm_ceval or scm_deval. Thus, there is no function SCM_CEVAL, but the code
1878 * for SCM_CEVAL actually compiles to either scm_ceval or scm_deval. When
1879 * SCM_CEVAL is defined to scm_ceval, it is known that the macro DEVAL is not
1880 * defined. When SCM_CEVAL is defined to scm_deval, then the macro DEVAL is
1881 * known to be defined. Thus, in SCM_CEVAL parts for the debugging evaluator
1882 * are enclosed within #ifdef DEVAL ... #endif.
1883 *
1884 * All three (scm_ceval, scm_deval and their common implementation SCM_CEVAL)
1885 * take two input parameters, x and env: x is a single expression to be
1886 * evalutated. env is the environment in which bindings are searched.
1887 *
1888 * x is known to be a cell (i. e. a pair or any other non-immediate). Since x
1889 * is a single expression, it is necessarily in a tail position. If x is just
1890 * a call to another function like in the expression (foo exp1 exp2 ...), the
1891 * realization of that call therefore _must_not_ increase stack usage (the
1892 * evaluation of exp1, exp2 etc., however, may do so). This is realized by
1893 * making extensive use of 'goto' statements within the evaluator: The gotos
1894 * replace recursive calls to SCM_CEVAL, thus re-using the same stack frame
1895 * that SCM_CEVAL was already using. If, however, x represents some form that
1896 * requires to evaluate a sequence of expressions like (begin exp1 exp2 ...),
1897 * then recursive calls to SCM_CEVAL are performed for all but the last
1898 * expression of that sequence. */
6dbd0af5 1899
0f2d19dd 1900#if 0
0f2d19dd 1901SCM
1bbd0b84 1902scm_ceval (SCM x, SCM env)
0f2d19dd
JB
1903{}
1904#endif
1cc91f1b 1905
a392ee15 1906#if 0
0f2d19dd 1907SCM
1bbd0b84 1908scm_deval (SCM x, SCM env)
0f2d19dd
JB
1909{}
1910#endif
1911
6dbd0af5 1912SCM
1bbd0b84 1913SCM_CEVAL (SCM x, SCM env)
0f2d19dd 1914{
42030fb2 1915 SCM proc, arg1;
6dbd0af5 1916#ifdef DEVAL
92c2555f
MV
1917 scm_t_debug_frame debug;
1918 scm_t_debug_info *debug_info_end;
1646d37b 1919 debug.prev = scm_last_debug_frame;
020c890c 1920 debug.status = 0;
04b6c081 1921 /*
92c2555f 1922 * The debug.vect contains twice as much scm_t_debug_info frames as the
04b6c081
MD
1923 * user has specified with (debug-set! frames <n>).
1924 *
1925 * Even frames are eval frames, odd frames are apply frames.
1926 */
92c2555f 1927 debug.vect = (scm_t_debug_info *) alloca (scm_debug_eframe_size
a392ee15 1928 * sizeof (scm_t_debug_info));
c0ab1b8d
JB
1929 debug.info = debug.vect;
1930 debug_info_end = debug.vect + scm_debug_eframe_size;
1931 scm_last_debug_frame = &debug;
6dbd0af5 1932#endif
b7ff98dd 1933#ifdef EVAL_STACK_CHECKING
6f13f9cb
MD
1934 if (scm_stack_checking_enabled_p
1935 && SCM_STACK_OVERFLOW_P ((SCM_STACKITEM *) &proc))
6dbd0af5 1936 {
b7ff98dd 1937#ifdef DEVAL
6dbd0af5
MD
1938 debug.info->e.exp = x;
1939 debug.info->e.env = env;
b7ff98dd 1940#endif
6dbd0af5
MD
1941 scm_report_stack_overflow ();
1942 }
1943#endif
6a0f6ff3 1944
6dbd0af5
MD
1945#ifdef DEVAL
1946 goto start;
1947#endif
6a0f6ff3 1948
6dbd0af5
MD
1949loop:
1950#ifdef DEVAL
b7ff98dd
MD
1951 SCM_CLEAR_ARGSREADY (debug);
1952 if (SCM_OVERFLOWP (debug))
6dbd0af5 1953 --debug.info;
04b6c081
MD
1954 /*
1955 * In theory, this should be the only place where it is necessary to
1956 * check for space in debug.vect since both eval frames and
1957 * available space are even.
1958 *
1959 * For this to be the case, however, it is necessary that primitive
1960 * special forms which jump back to `loop', `begin' or some similar
680516ba 1961 * label call PREP_APPLY.
04b6c081 1962 */
c0ab1b8d 1963 else if (++debug.info >= debug_info_end)
6dbd0af5 1964 {
b7ff98dd 1965 SCM_SET_OVERFLOW (debug);
6dbd0af5
MD
1966 debug.info -= 2;
1967 }
6a0f6ff3 1968
6dbd0af5
MD
1969start:
1970 debug.info->e.exp = x;
1971 debug.info->e.env = env;
5132eef0
DH
1972 if (scm_check_entry_p && SCM_TRAPS_P)
1973 {
bc76d628
DH
1974 if (SCM_ENTER_FRAME_P
1975 || (SCM_BREAKPOINTS_P && scm_c_source_property_breakpoint_p (x)))
5132eef0 1976 {
bc76d628
DH
1977 SCM stackrep;
1978 SCM tail = SCM_BOOL (SCM_TAILRECP (debug));
5132eef0
DH
1979 SCM_SET_TAILREC (debug);
1980 if (SCM_CHEAPTRAPS_P)
bc76d628 1981 stackrep = scm_make_debugobj (&debug);
5132eef0
DH
1982 else
1983 {
1984 int first;
1985 SCM val = scm_make_continuation (&first);
1986
1987 if (first)
bc76d628 1988 stackrep = val;
5132eef0
DH
1989 else
1990 {
1991 x = val;
1992 if (SCM_IMP (x))
1993 RETURN (x);
1994 else
1995 /* This gives the possibility for the debugger to
1996 modify the source expression before evaluation. */
1997 goto dispatch;
1998 }
1999 }
2000 SCM_TRAPS_P = 0;
2001 scm_call_4 (SCM_ENTER_FRAME_HDLR,
2002 scm_sym_enter_frame,
bc76d628 2003 stackrep,
5132eef0
DH
2004 tail,
2005 scm_unmemocopy (x, env));
2006 SCM_TRAPS_P = 1;
2007 }
2008 }
6dbd0af5 2009#endif
f8769b1d 2010dispatch:
9cb5124f 2011 SCM_TICK;
0f2d19dd
JB
2012 switch (SCM_TYP7 (x))
2013 {
28b06554 2014 case scm_tc7_symbol:
a392ee15 2015 /* Only happens when called at top level. */
0f2d19dd 2016 x = scm_cons (x, SCM_UNDEFINED);
ddea3325 2017 RETURN (*scm_lookupcar (x, env, 1));
0f2d19dd 2018
1b43d24c 2019 case SCM_BIT7 (SCM_IM_AND):
0f2d19dd 2020 x = SCM_CDR (x);
302c12b4
DH
2021 while (!SCM_NULLP (SCM_CDR (x)))
2022 {
38ace99e
DH
2023 SCM test_result = EVALCAR (x, env);
2024 if (SCM_FALSEP (test_result) || SCM_NILP (test_result))
0f2d19dd 2025 RETURN (SCM_BOOL_F);
302c12b4
DH
2026 else
2027 x = SCM_CDR (x);
2028 }
6dbd0af5 2029 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2030 goto carloop;
2031
1b43d24c 2032 case SCM_BIT7 (SCM_IM_BEGIN):
e050d4f8
DH
2033 x = SCM_CDR (x);
2034 if (SCM_NULLP (x))
b8113bc8
MV
2035 RETURN (SCM_UNSPECIFIED);
2036
6dbd0af5 2037 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2038
2039 begin:
4163eb72
MV
2040 /* If we are on toplevel with a lookup closure, we need to sync
2041 with the current module. */
22a52da1 2042 if (SCM_CONSP (env) && !SCM_CONSP (SCM_CAR (env)))
4163eb72 2043 {
d9d39d76 2044 UPDATE_TOPLEVEL_ENV (env);
302c12b4 2045 while (!SCM_NULLP (SCM_CDR (x)))
4163eb72 2046 {
5280aaca 2047 EVALCAR (x, env);
d9d39d76 2048 UPDATE_TOPLEVEL_ENV (env);
302c12b4 2049 x = SCM_CDR (x);
4163eb72 2050 }
5280aaca 2051 goto carloop;
4163eb72
MV
2052 }
2053 else
5280aaca
MV
2054 goto nontoplevel_begin;
2055
5280aaca 2056 nontoplevel_begin:
302c12b4 2057 while (!SCM_NULLP (SCM_CDR (x)))
0f2d19dd 2058 {
6a0f6ff3
DH
2059 SCM form = SCM_CAR (x);
2060 if (SCM_IMP (form))
26d5b9b4 2061 {
6a0f6ff3 2062 if (SCM_ISYMP (form))
26d5b9b4 2063 {
28d52ebb 2064 scm_rec_mutex_lock (&source_mutex);
9bc4701c
MD
2065 /* check for race condition */
2066 if (SCM_ISYMP (SCM_CAR (x)))
2067 x = scm_m_expand_body (x, env);
28d52ebb 2068 scm_rec_mutex_unlock (&source_mutex);
5280aaca 2069 goto nontoplevel_begin;
26d5b9b4 2070 }
4163eb72 2071 else
6a0f6ff3 2072 SCM_VALIDATE_NON_EMPTY_COMBINATION (form);
26d5b9b4 2073 }
5280aaca 2074 else
6a0f6ff3 2075 SCM_CEVAL (form, env);
302c12b4 2076 x = SCM_CDR (x);
0f2d19dd 2077 }
5280aaca 2078
6a0f6ff3
DH
2079 carloop:
2080 {
2081 /* scm_eval last form in list */
2082 SCM last_form = SCM_CAR (x);
0f2d19dd 2083
6a0f6ff3
DH
2084 if (SCM_CONSP (last_form))
2085 {
2086 /* This is by far the most frequent case. */
2087 x = last_form;
2088 goto loop; /* tail recurse */
2089 }
2090 else if (SCM_IMP (last_form))
2091 RETURN (SCM_EVALIM (last_form, env));
2092 else if (SCM_VARIABLEP (last_form))
2093 RETURN (SCM_VARIABLE_REF (last_form));
2094 else if (SCM_SYMBOLP (last_form))
2095 RETURN (*scm_lookupcar (x, env, 1));
2096 else
2097 RETURN (last_form);
2098 }
0f2d19dd
JB
2099
2100
1b43d24c 2101 case SCM_BIT7 (SCM_IM_CASE):
0f2d19dd 2102 x = SCM_CDR (x);
6a0f6ff3
DH
2103 {
2104 SCM key = EVALCAR (x, env);
2105 x = SCM_CDR (x);
2106 while (!SCM_NULLP (x))
2107 {
2108 SCM clause = SCM_CAR (x);
2109 SCM labels = SCM_CAR (clause);
2110 if (SCM_EQ_P (labels, scm_sym_else))
2111 {
2112 x = SCM_CDR (clause);
2113 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2114 goto begin;
2115 }
2116 while (!SCM_NULLP (labels))
2117 {
2118 SCM label = SCM_CAR (labels);
2119 if (SCM_EQ_P (label, key) || !SCM_FALSEP (scm_eqv_p (label, key)))
2120 {
2121 x = SCM_CDR (clause);
2122 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2123 goto begin;
2124 }
2125 labels = SCM_CDR (labels);
2126 }
2127 x = SCM_CDR (x);
2128 }
2129 }
ddea3325 2130 RETURN (SCM_UNSPECIFIED);
0f2d19dd
JB
2131
2132
1b43d24c 2133 case SCM_BIT7 (SCM_IM_COND):
8ea46249
DH
2134 x = SCM_CDR (x);
2135 while (!SCM_NULLP (x))
0f2d19dd 2136 {
e5cb71a0
DH
2137 SCM clause = SCM_CAR (x);
2138 if (SCM_EQ_P (SCM_CAR (clause), scm_sym_else))
8ea46249 2139 {
e5cb71a0 2140 x = SCM_CDR (clause);
8ea46249
DH
2141 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2142 goto begin;
2143 }
e5cb71a0 2144 else
0f2d19dd 2145 {
dff98306
DH
2146 arg1 = EVALCAR (clause, env);
2147 if (!SCM_FALSEP (arg1) && !SCM_NILP (arg1))
6dbd0af5 2148 {
e5cb71a0
DH
2149 x = SCM_CDR (clause);
2150 if (SCM_NULLP (x))
dff98306 2151 RETURN (arg1);
e5cb71a0
DH
2152 else if (!SCM_EQ_P (SCM_CAR (x), scm_sym_arrow))
2153 {
2154 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2155 goto begin;
2156 }
2157 else
2158 {
2159 proc = SCM_CDR (x);
2160 proc = EVALCAR (proc, env);
2161 SCM_ASRTGO (!SCM_IMP (proc), badfun);
dff98306 2162 PREP_APPLY (proc, scm_list_1 (arg1));
e5cb71a0
DH
2163 ENTER_APPLY;
2164 if (SCM_CLOSUREP(proc) && scm_badformalsp (proc, 1))
2165 goto umwrongnumargs;
2166 else
2167 goto evap1;
2168 }
6dbd0af5 2169 }
e5cb71a0 2170 x = SCM_CDR (x);
0f2d19dd
JB
2171 }
2172 }
ddea3325 2173 RETURN (SCM_UNSPECIFIED);
0f2d19dd
JB
2174
2175
1b43d24c 2176 case SCM_BIT7 (SCM_IM_DO):
0f2d19dd 2177 x = SCM_CDR (x);
e5cb71a0
DH
2178 {
2179 /* Compute the initialization values and the initial environment. */
2180 SCM init_forms = SCM_CADR (x);
2181 SCM init_values = SCM_EOL;
2182 while (!SCM_NULLP (init_forms))
2183 {
2184 init_values = scm_cons (EVALCAR (init_forms, env), init_values);
2185 init_forms = SCM_CDR (init_forms);
2186 }
821f18a4 2187 env = SCM_EXTEND_ENV (SCM_CAR (x), init_values, env);
e5cb71a0 2188 }
8ea46249 2189 x = SCM_CDDR (x);
e5cb71a0
DH
2190 {
2191 SCM test_form = SCM_CAR (x);
2192 SCM body_forms = SCM_CADR (x);
2193 SCM step_forms = SCM_CDDR (x);
2194
2195 SCM test_result = EVALCAR (test_form, env);
2196
2197 while (SCM_FALSEP (test_result) || SCM_NILP (test_result))
2198 {
0f2d19dd 2199 {
e5cb71a0
DH
2200 /* Evaluate body forms. */
2201 SCM temp_forms;
2202 for (temp_forms = body_forms;
2203 !SCM_NULLP (temp_forms);
2204 temp_forms = SCM_CDR (temp_forms))
2205 {
2206 SCM form = SCM_CAR (temp_forms);
2207 /* Dirk:FIXME: We only need to eval forms, that may have a
2208 * side effect here. This is only true for forms that start
2209 * with a pair. All others are just constants. However,
2210 * since in the common case there is no constant expression
2211 * in a body of a do form, we just check for immediates here
2212 * and have SCM_CEVAL take care of other cases. In the long
2213 * run it would make sense to get rid of this test and have
2214 * the macro transformer of 'do' eliminate all forms that
2215 * have no sideeffect. */
2216 if (!SCM_IMP (form))
2217 SCM_CEVAL (form, env);
2218 }
0f2d19dd 2219 }
e5cb71a0
DH
2220
2221 {
2222 /* Evaluate the step expressions. */
2223 SCM temp_forms;
2224 SCM step_values = SCM_EOL;
2225 for (temp_forms = step_forms;
2226 !SCM_NULLP (temp_forms);
2227 temp_forms = SCM_CDR (temp_forms))
2228 {
2229 SCM value = EVALCAR (temp_forms, env);
2230 step_values = scm_cons (value, step_values);
2231 }
821f18a4
DH
2232 env = SCM_EXTEND_ENV (SCM_CAAR (env),
2233 step_values,
2234 SCM_CDR (env));
e5cb71a0
DH
2235 }
2236
2237 test_result = EVALCAR (test_form, env);
2238 }
2239 }
2240 x = SCM_CDAR (x);
0f2d19dd 2241 if (SCM_NULLP (x))
6dbd0af5
MD
2242 RETURN (SCM_UNSPECIFIED);
2243 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
5280aaca 2244 goto nontoplevel_begin;
0f2d19dd
JB
2245
2246
1b43d24c 2247 case SCM_BIT7 (SCM_IM_IF):
0f2d19dd 2248 x = SCM_CDR (x);
38ace99e
DH
2249 {
2250 SCM test_result = EVALCAR (x, env);
2251 if (!SCM_FALSEP (test_result) && !SCM_NILP (test_result))
2252 x = SCM_CDR (x);
2253 else
2254 {
2255 x = SCM_CDDR (x);
2256 if (SCM_NULLP (x))
2257 RETURN (SCM_UNSPECIFIED);
2258 }
2259 }
6dbd0af5 2260 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2261 goto carloop;
2262
2263
1b43d24c 2264 case SCM_BIT7 (SCM_IM_LET):
0f2d19dd 2265 x = SCM_CDR (x);
38ace99e
DH
2266 {
2267 SCM init_forms = SCM_CADR (x);
2268 SCM init_values = SCM_EOL;
2269 do
2270 {
2271 init_values = scm_cons (EVALCAR (init_forms, env), init_values);
2272 init_forms = SCM_CDR (init_forms);
2273 }
2274 while (!SCM_NULLP (init_forms));
821f18a4 2275 env = SCM_EXTEND_ENV (SCM_CAR (x), init_values, env);
38ace99e 2276 }
e050d4f8
DH
2277 x = SCM_CDDR (x);
2278 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2279 goto nontoplevel_begin;
0f2d19dd
JB
2280
2281
1b43d24c 2282 case SCM_BIT7 (SCM_IM_LETREC):
0f2d19dd 2283 x = SCM_CDR (x);
821f18a4 2284 env = SCM_EXTEND_ENV (SCM_CAR (x), undefineds, env);
0f2d19dd 2285 x = SCM_CDR (x);
38ace99e
DH
2286 {
2287 SCM init_forms = SCM_CAR (x);
2288 SCM init_values = SCM_EOL;
2289 do
2290 {
2291 init_values = scm_cons (EVALCAR (init_forms, env), init_values);
2292 init_forms = SCM_CDR (init_forms);
2293 }
2294 while (!SCM_NULLP (init_forms));
2295 SCM_SETCDR (SCM_CAR (env), init_values);
2296 }
e050d4f8
DH
2297 x = SCM_CDR (x);
2298 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2299 goto nontoplevel_begin;
0f2d19dd
JB
2300
2301
1b43d24c 2302 case SCM_BIT7 (SCM_IM_LETSTAR):
0f2d19dd 2303 x = SCM_CDR (x);
302c12b4
DH
2304 {
2305 SCM bindings = SCM_CAR (x);
2306 if (SCM_NULLP (bindings))
821f18a4 2307 env = SCM_EXTEND_ENV (SCM_EOL, SCM_EOL, env);
302c12b4
DH
2308 else
2309 {
2310 do
2311 {
2312 SCM name = SCM_CAR (bindings);
2313 SCM init = SCM_CDR (bindings);
821f18a4 2314 env = SCM_EXTEND_ENV (name, EVALCAR (init, env), env);
302c12b4
DH
2315 bindings = SCM_CDR (init);
2316 }
2317 while (!SCM_NULLP (bindings));
2318 }
2319 }
e050d4f8
DH
2320 x = SCM_CDR (x);
2321 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2322 goto nontoplevel_begin;
0f2d19dd 2323
302c12b4 2324
1b43d24c 2325 case SCM_BIT7 (SCM_IM_OR):
0f2d19dd 2326 x = SCM_CDR (x);
302c12b4 2327 while (!SCM_NULLP (SCM_CDR (x)))
0f2d19dd 2328 {
302c12b4 2329 SCM val = EVALCAR (x, env);
c96d76b8 2330 if (!SCM_FALSEP (val) && !SCM_NILP (val))
302c12b4
DH
2331 RETURN (val);
2332 else
2333 x = SCM_CDR (x);
0f2d19dd 2334 }
6dbd0af5 2335 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
0f2d19dd
JB
2336 goto carloop;
2337
2338
1b43d24c 2339 case SCM_BIT7 (SCM_IM_LAMBDA):
0f2d19dd
JB
2340 RETURN (scm_closure (SCM_CDR (x), env));
2341
2342
1b43d24c 2343 case SCM_BIT7 (SCM_IM_QUOTE):
8ea46249 2344 RETURN (SCM_CADR (x));
0f2d19dd
JB
2345
2346
1b43d24c 2347 case SCM_BIT7 (SCM_IM_SET_X):
0f2d19dd 2348 x = SCM_CDR (x);
38ace99e
DH
2349 {
2350 SCM *location;
2351 SCM variable = SCM_CAR (x);
e050d4f8 2352 if (SCM_ILOCP (variable))
38ace99e 2353 location = scm_ilookup (variable, env);
3063e30a 2354 else if (SCM_VARIABLEP (variable))
e050d4f8 2355 location = SCM_VARIABLE_LOC (variable);
38ace99e
DH
2356 else /* (SCM_SYMBOLP (variable)) is known to be true */
2357 location = scm_lookupcar (x, env, 1);
2358 x = SCM_CDR (x);
2359 *location = EVALCAR (x, env);
2360 }
0f2d19dd 2361 RETURN (SCM_UNSPECIFIED);
0f2d19dd
JB
2362
2363
1b43d24c 2364 case SCM_BIT7 (SCM_IM_DEFINE): /* only for internal defines */
26d5b9b4
MD
2365 scm_misc_error (NULL, "Bad define placement", SCM_EOL);
2366
38ace99e 2367
0f2d19dd 2368 /* new syntactic forms go here. */
1b43d24c 2369 case SCM_BIT7 (SCM_MAKISYM (0)):
0f2d19dd
JB
2370 proc = SCM_CAR (x);
2371 SCM_ASRTGO (SCM_ISYMP (proc), badfun);
a392ee15 2372 switch (SCM_ISYMNUM (proc))
0f2d19dd 2373 {
3f04400d
DH
2374
2375
0f2d19dd
JB
2376 case (SCM_ISYMNUM (SCM_IM_APPLY)):
2377 proc = SCM_CDR (x);
2378 proc = EVALCAR (proc, env);
3f04400d 2379 SCM_ASRTGO (!SCM_IMP (proc), badfun);
0f2d19dd
JB
2380 if (SCM_CLOSUREP (proc))
2381 {
6dbd0af5 2382 PREP_APPLY (proc, SCM_EOL);
dff98306
DH
2383 arg1 = SCM_CDDR (x);
2384 arg1 = EVALCAR (arg1, env);
a513ead3
MV
2385 apply_closure:
2386 /* Go here to tail-call a closure. PROC is the closure
dff98306
DH
2387 and ARG1 is the list of arguments. Do not forget to
2388 call PREP_APPLY. */
3f04400d
DH
2389 {
2390 SCM formals = SCM_CLOSURE_FORMALS (proc);
6dbd0af5 2391#ifdef DEVAL
dff98306 2392 debug.info->a.args = arg1;
6dbd0af5 2393#endif
dff98306 2394 if (scm_badargsp (formals, arg1))
ab1f1094 2395 scm_wrong_num_args (proc);
3f04400d
DH
2396 ENTER_APPLY;
2397 /* Copy argument list */
dff98306 2398 if (SCM_NULL_OR_NIL_P (arg1))
821f18a4 2399 env = SCM_EXTEND_ENV (formals, SCM_EOL, SCM_ENV (proc));
3f04400d
DH
2400 else
2401 {
dff98306 2402 SCM args = scm_list_1 (SCM_CAR (arg1));
3f04400d 2403 SCM tail = args;
dff98306
DH
2404 arg1 = SCM_CDR (arg1);
2405 while (!SCM_NULL_OR_NIL_P (arg1))
3f04400d 2406 {
dff98306 2407 SCM new_tail = scm_list_1 (SCM_CAR (arg1));
3f04400d
DH
2408 SCM_SETCDR (tail, new_tail);
2409 tail = new_tail;
dff98306 2410 arg1 = SCM_CDR (arg1);
3f04400d 2411 }
821f18a4 2412 env = SCM_EXTEND_ENV (formals, args, SCM_ENV (proc));
3f04400d 2413 }
1609038c 2414
3f04400d
DH
2415 x = SCM_CLOSURE_BODY (proc);
2416 goto nontoplevel_begin;
2417 }
0f2d19dd 2418 }
3f04400d
DH
2419 else
2420 {
a44a9715 2421 proc = f_apply;
3f04400d
DH
2422 goto evapply;
2423 }
2424
0f2d19dd
JB
2425
2426 case (SCM_ISYMNUM (SCM_IM_CONT)):
5f144b10
GH
2427 {
2428 int first;
2429 SCM val = scm_make_continuation (&first);
2430
e050d4f8 2431 if (!first)
5f144b10 2432 RETURN (val);
e050d4f8
DH
2433 else
2434 {
2435 arg1 = val;
2436 proc = SCM_CDR (x);
2437 proc = scm_eval_car (proc, env);
2438 SCM_ASRTGO (SCM_NIMP (proc), badfun);
2439 PREP_APPLY (proc, scm_list_1 (arg1));
2440 ENTER_APPLY;
2441 if (SCM_CLOSUREP(proc) && scm_badformalsp (proc, 1))
2442 goto umwrongnumargs;
2443 goto evap1;
2444 }
5f144b10 2445 }
e050d4f8 2446
0f2d19dd 2447
a570e93a 2448 case (SCM_ISYMNUM (SCM_IM_DELAY)):
ddea3325 2449 RETURN (scm_makprom (scm_closure (SCM_CDR (x), env)));
a570e93a 2450
e050d4f8 2451
28d52ebb
MD
2452 case (SCM_ISYMNUM (SCM_IM_FUTURE)):
2453 RETURN (scm_i_make_future (scm_closure (SCM_CDR (x), env)));
2454
2455
c8e1d354
MD
2456 /* PLACEHOLDER for case (SCM_ISYMNUM (SCM_IM_DISPATCH)): The
2457 following code (type_dispatch) is intended to be the tail
2458 of the case clause for the internal macro
2459 SCM_IM_DISPATCH. Please don't remove it from this
2460 location without discussing it with Mikael
2461 <djurfeldt@nada.kth.se> */
2462
f12745b6
DH
2463 /* The type dispatch code is duplicated below
2464 * (c.f. objects.c:scm_mcache_compute_cmethod) since that
2465 * cuts down execution time for type dispatch to 50%. */
dff98306 2466 type_dispatch: /* inputs: x, arg1 */
f12745b6
DH
2467 /* Type dispatch means to determine from the types of the function
2468 * arguments (i. e. the 'signature' of the call), which method from
2469 * a generic function is to be called. This process of selecting
2470 * the right method takes some time. To speed it up, guile uses
2471 * caching: Together with the macro call to dispatch the signatures
2472 * of some previous calls to that generic function from the same
2473 * place are stored (in the code!) in a cache that we call the
2474 * 'method cache'. This is done since it is likely, that
2475 * consecutive calls to dispatch from that position in the code will
2476 * have the same signature. Thus, the type dispatch works as
2477 * follows: First, determine a hash value from the signature of the
2478 * actual arguments. Second, use this hash value as an index to
2479 * find that same signature in the method cache stored at this
2480 * position in the code. If found, you have also found the
2481 * corresponding method that belongs to that signature. If the
2482 * signature is not found in the method cache, you have to perform a
2483 * full search over all signatures stored with the generic
2484 * function. */
2485 {
2486 unsigned long int specializers;
2487 unsigned long int hash_value;
2488 unsigned long int cache_end_pos;
2489 unsigned long int mask;
2490 SCM method_cache;
2491
2492 {
2493 SCM z = SCM_CDDR (x);
2494 SCM tmp = SCM_CADR (z);
2495 specializers = SCM_INUM (SCM_CAR (z));
2496
2497 /* Compute a hash value for searching the method cache. There
2498 * are two variants for computing the hash value, a (rather)
2499 * complicated one, and a simple one. For the complicated one
2500 * explained below, tmp holds a number that is used in the
2501 * computation. */
2502 if (SCM_INUMP (tmp))
2503 {
2504 /* Use the signature of the actual arguments to determine
2505 * the hash value. This is done as follows: Each class has
2506 * an array of random numbers, that are determined when the
2507 * class is created. The integer 'hashset' is an index into
2508 * that array of random numbers. Now, from all classes that
2509 * are part of the signature of the actual arguments, the
2510 * random numbers at index 'hashset' are taken and summed
2511 * up, giving the hash value. The value of 'hashset' is
2512 * stored at the call to dispatch. This allows to have
2513 * different 'formulas' for calculating the hash value at
2514 * different places where dispatch is called. This allows
2515 * to optimize the hash formula at every individual place
2516 * where dispatch is called, such that hopefully the hash
2517 * value that is computed will directly point to the right
2518 * method in the method cache. */
2519 unsigned long int hashset = SCM_INUM (tmp);
2520 unsigned long int counter = specializers + 1;
dff98306 2521 SCM tmp_arg = arg1;
f12745b6
DH
2522 hash_value = 0;
2523 while (!SCM_NULLP (tmp_arg) && counter != 0)
61364ba6 2524 {
f12745b6
DH
2525 SCM class = scm_class_of (SCM_CAR (tmp_arg));
2526 hash_value += SCM_INSTANCE_HASH (class, hashset);
2527 tmp_arg = SCM_CDR (tmp_arg);
2528 counter--;
61364ba6 2529 }
f12745b6
DH
2530 z = SCM_CDDR (z);
2531 method_cache = SCM_CADR (z);
2532 mask = SCM_INUM (SCM_CAR (z));
2533 hash_value &= mask;
2534 cache_end_pos = hash_value;
2535 }
2536 else
2537 {
2538 /* This method of determining the hash value is much
2539 * simpler: Set the hash value to zero and just perform a
2540 * linear search through the method cache. */
2541 method_cache = tmp;
2542 mask = (unsigned long int) ((long) -1);
2543 hash_value = 0;
2544 cache_end_pos = SCM_VECTOR_LENGTH (method_cache);
2545 }
2546 }
61364ba6 2547
f12745b6
DH
2548 {
2549 /* Search the method cache for a method with a matching
2550 * signature. Start the search at position 'hash_value'. The
2551 * hashing implementation uses linear probing for conflict
2552 * resolution, that is, if the signature in question is not
2553 * found at the starting index in the hash table, the next table
2554 * entry is tried, and so on, until in the worst case the whole
2555 * cache has been searched, but still the signature has not been
2556 * found. */
2557 SCM z;
2558 do
2559 {
dff98306 2560 SCM args = arg1; /* list of arguments */
f12745b6
DH
2561 z = SCM_VELTS (method_cache)[hash_value];
2562 while (!SCM_NULLP (args))
61364ba6
MD
2563 {
2564 /* More arguments than specifiers => CLASS != ENV */
f12745b6
DH
2565 SCM class_of_arg = scm_class_of (SCM_CAR (args));
2566 if (!SCM_EQ_P (class_of_arg, SCM_CAR (z)))
61364ba6 2567 goto next_method;
f12745b6 2568 args = SCM_CDR (args);
61364ba6
MD
2569 z = SCM_CDR (z);
2570 }
f12745b6
DH
2571 /* Fewer arguments than specifiers => CAR != ENV */
2572 if (SCM_NULLP (SCM_CAR (z)) || SCM_CONSP (SCM_CAR (z)))
2573 goto apply_cmethod;
2574 next_method:
2575 hash_value = (hash_value + 1) & mask;
2576 } while (hash_value != cache_end_pos);
2577
2578 /* No appropriate method was found in the cache. */
dff98306 2579 z = scm_memoize_method (x, arg1);
f12745b6 2580
dff98306 2581 apply_cmethod: /* inputs: z, arg1 */
f12745b6
DH
2582 {
2583 SCM formals = SCM_CMETHOD_FORMALS (z);
821f18a4 2584 env = SCM_EXTEND_ENV (formals, arg1, SCM_CMETHOD_ENV (z));
f12745b6
DH
2585 x = SCM_CMETHOD_BODY (z);
2586 goto nontoplevel_begin;
2587 }
2588 }
61364ba6 2589 }
73b64342 2590
1d15ecd3 2591
ca4be6ea
MD
2592 case (SCM_ISYMNUM (SCM_IM_SLOT_REF)):
2593 x = SCM_CDR (x);
1d15ecd3
DH
2594 {
2595 SCM instance = EVALCAR (x, env);
2596 unsigned long int slot = SCM_INUM (SCM_CADR (x));
2597 RETURN (SCM_PACK (SCM_STRUCT_DATA (instance) [slot]));
2598 }
2599
2600
ca4be6ea
MD
2601 case (SCM_ISYMNUM (SCM_IM_SLOT_SET_X)):
2602 x = SCM_CDR (x);
1d15ecd3
DH
2603 {
2604 SCM instance = EVALCAR (x, env);
2605 unsigned long int slot = SCM_INUM (SCM_CADR (x));
2606 SCM value = EVALCAR (SCM_CDDR (x), env);
2607 SCM_STRUCT_DATA (instance) [slot] = SCM_UNPACK (value);
2608 RETURN (SCM_UNSPECIFIED);
2609 }
2610
c96d76b8 2611
22721140 2612#if SCM_ENABLE_ELISP
ca4be6ea 2613
73b64342 2614 case (SCM_ISYMNUM (SCM_IM_NIL_COND)):
1d15ecd3
DH
2615 {
2616 SCM test_form = SCM_CDR (x);
2617 x = SCM_CDR (test_form);
2618 while (!SCM_NULL_OR_NIL_P (x))
2619 {
2620 SCM test_result = EVALCAR (test_form, env);
2621 if (!(SCM_FALSEP (test_result)
2622 || SCM_NULL_OR_NIL_P (test_result)))
2623 {
2624 if (SCM_EQ_P (SCM_CAR (x), SCM_UNSPECIFIED))
2625 RETURN (test_result);
2626 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2627 goto carloop;
2628 }
2629 else
2630 {
2631 test_form = SCM_CDR (x);
2632 x = SCM_CDR (test_form);
2633 }
2634 }
2635 x = test_form;
2636 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2637 goto carloop;
2638 }
73b64342 2639
c96d76b8 2640#endif /* SCM_ENABLE_ELISP */
73b64342
MD
2641
2642 case (SCM_ISYMNUM (SCM_IM_BIND)):
2e171178
MV
2643 {
2644 SCM vars, exps, vals;
73b64342 2645
2e171178
MV
2646 x = SCM_CDR (x);
2647 vars = SCM_CAAR (x);
2648 exps = SCM_CDAR (x);
2649
2650 vals = SCM_EOL;
2651
2652 while (SCM_NIMP (exps))
2653 {
2654 vals = scm_cons (EVALCAR (exps, env), vals);
2655 exps = SCM_CDR (exps);
2656 }
2657
2658 scm_swap_bindings (vars, vals);
2659 scm_dynwinds = scm_acons (vars, vals, scm_dynwinds);
1d15ecd3
DH
2660
2661 /* Ignore all but the last evaluation result. */
2662 for (x = SCM_CDR (x); !SCM_NULLP (SCM_CDR (x)); x = SCM_CDR (x))
2e171178 2663 {
1d15ecd3
DH
2664 if (SCM_CONSP (SCM_CAR (x)))
2665 SCM_CEVAL (SCM_CAR (x), env);
2e171178
MV
2666 }
2667 proc = EVALCAR (x, env);
73b64342 2668
2e171178
MV
2669 scm_dynwinds = SCM_CDR (scm_dynwinds);
2670 scm_swap_bindings (vars, vals);
73b64342 2671
ddea3325 2672 RETURN (proc);
2e171178 2673 }
c96d76b8 2674
1d15ecd3 2675
a513ead3
MV
2676 case (SCM_ISYMNUM (SCM_IM_CALL_WITH_VALUES)):
2677 {
2678 proc = SCM_CDR (x);
2679 x = EVALCAR (proc, env);
2680 proc = SCM_CDR (proc);
2681 proc = EVALCAR (proc, env);
dff98306
DH
2682 arg1 = SCM_APPLY (x, SCM_EOL, SCM_EOL);
2683 if (SCM_VALUESP (arg1))
2684 arg1 = scm_struct_ref (arg1, SCM_INUM0);
a513ead3 2685 else
dff98306 2686 arg1 = scm_list_1 (arg1);
a513ead3
MV
2687 if (SCM_CLOSUREP (proc))
2688 {
dff98306 2689 PREP_APPLY (proc, arg1);
a513ead3
MV
2690 goto apply_closure;
2691 }
dff98306 2692 return SCM_APPLY (proc, arg1, SCM_EOL);
a513ead3
MV
2693 }
2694
b7798e10 2695
0f2d19dd
JB
2696 default:
2697 goto badfun;
2698 }
2699
2700 default:
2701 proc = x;
2702 badfun:
1afff620 2703 scm_misc_error (NULL, "Wrong type to apply: ~S", scm_list_1 (proc));
0f2d19dd
JB
2704 case scm_tc7_vector:
2705 case scm_tc7_wvect:
22721140 2706#if SCM_HAVE_ARRAYS
0f2d19dd
JB
2707 case scm_tc7_bvect:
2708 case scm_tc7_byvect:
2709 case scm_tc7_svect:
2710 case scm_tc7_ivect:
2711 case scm_tc7_uvect:
2712 case scm_tc7_fvect:
2713 case scm_tc7_dvect:
2714 case scm_tc7_cvect:
3d05f2e0 2715#if SCM_SIZEOF_LONG_LONG != 0
0f2d19dd 2716 case scm_tc7_llvect:
afe5177e 2717#endif
0f2d19dd
JB
2718#endif
2719 case scm_tc7_string:
0f2d19dd
JB
2720 case scm_tc7_smob:
2721 case scm_tcs_closures:
224822be 2722 case scm_tc7_cclo:
89efbff4 2723 case scm_tc7_pws:
0f2d19dd 2724 case scm_tcs_subrs:
904a077d 2725 case scm_tcs_struct:
0f2d19dd
JB
2726 RETURN (x);
2727
d22a0ea1 2728 case scm_tc7_variable:
a130e982 2729 RETURN (SCM_VARIABLE_REF(x));
d22a0ea1 2730
1b43d24c 2731 case SCM_BIT7 (SCM_ILOC00):
0f2d19dd
JB
2732 proc = *scm_ilookup (SCM_CAR (x), env);
2733 SCM_ASRTGO (SCM_NIMP (proc), badfun);
0f2d19dd 2734 goto checkargs;
b7798e10 2735
0f2d19dd 2736 case scm_tcs_cons_nimcar:
e050d4f8 2737 if (SCM_SYMBOLP (SCM_CAR (x)))
0f2d19dd 2738 {
e050d4f8 2739 SCM orig_sym = SCM_CAR (x);
b7798e10
DH
2740 {
2741 SCM *location = scm_lookupcar1 (x, env, 1);
2742 if (location == NULL)
2743 {
2744 /* we have lost the race, start again. */
2745 goto dispatch;
2746 }
2747 proc = *location;
2748 }
f8769b1d 2749
0f2d19dd
JB
2750 if (SCM_IMP (proc))
2751 {
86d31dfe
MV
2752 SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of
2753 lookupcar */
0f2d19dd
JB
2754 goto badfun;
2755 }
22a52da1 2756 if (SCM_MACROP (proc))
0f2d19dd 2757 {
86d31dfe
MV
2758 SCM_SETCAR (x, orig_sym); /* Undo memoizing effect of
2759 lookupcar */
e050d4f8 2760 handle_a_macro: /* inputs: x, env, proc */
368bf056 2761#ifdef DEVAL
7c354052
MD
2762 /* Set a flag during macro expansion so that macro
2763 application frames can be deleted from the backtrace. */
2764 SCM_SET_MACROEXP (debug);
368bf056 2765#endif
dff98306 2766 arg1 = SCM_APPLY (SCM_MACRO_CODE (proc), x,
f8769b1d
MV
2767 scm_cons (env, scm_listofnull));
2768
7c354052
MD
2769#ifdef DEVAL
2770 SCM_CLEAR_MACROEXP (debug);
2771#endif
22a52da1 2772 switch (SCM_MACRO_TYPE (proc))
0f2d19dd
JB
2773 {
2774 case 2:
dff98306
DH
2775 if (scm_ilength (arg1) <= 0)
2776 arg1 = scm_list_2 (SCM_IM_BEGIN, arg1);
6dbd0af5 2777#ifdef DEVAL
22a52da1 2778 if (!SCM_CLOSUREP (SCM_MACRO_CODE (proc)))
6dbd0af5 2779 {
6dbd0af5 2780 SCM_DEFER_INTS;
dff98306
DH
2781 SCM_SETCAR (x, SCM_CAR (arg1));
2782 SCM_SETCDR (x, SCM_CDR (arg1));
6dbd0af5
MD
2783 SCM_ALLOW_INTS;
2784 goto dispatch;
2785 }
2786 /* Prevent memoizing of debug info expression. */
6203706f
MD
2787 debug.info->e.exp = scm_cons_source (debug.info->e.exp,
2788 SCM_CAR (x),
2789 SCM_CDR (x));
6dbd0af5 2790#endif
0f2d19dd 2791 SCM_DEFER_INTS;
dff98306
DH
2792 SCM_SETCAR (x, SCM_CAR (arg1));
2793 SCM_SETCDR (x, SCM_CDR (arg1));
0f2d19dd 2794 SCM_ALLOW_INTS;
680516ba
DH
2795 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2796 goto loop;
3063e30a 2797#if SCM_ENABLE_DEPRECATED == 1
0f2d19dd 2798 case 1:
680516ba
DH
2799 x = arg1;
2800 if (SCM_NIMP (x))
2801 {
2802 PREP_APPLY (SCM_UNDEFINED, SCM_EOL);
2803 goto loop;
2804 }
2805 else
2806 RETURN (arg1);
3063e30a 2807#endif
0f2d19dd 2808 case 0:
dff98306 2809 RETURN (arg1);
0f2d19dd
JB
2810 }
2811 }
2812 }
2813 else
2814 proc = SCM_CEVAL (SCM_CAR (x), env);
22a52da1 2815 SCM_ASRTGO (!SCM_IMP (proc), badfun);
bd987b8e 2816
0f2d19dd 2817 checkargs:
0f2d19dd
JB
2818 if (SCM_CLOSUREP (proc))
2819 {
e050d4f8
DH
2820 SCM formals = SCM_CLOSURE_FORMALS (proc);
2821 SCM args = SCM_CDR (x);
2822 while (!SCM_NULLP (formals))
0f2d19dd 2823 {
e050d4f8 2824 if (!SCM_CONSP (formals))
0f2d19dd 2825 goto evapply;
e050d4f8 2826 if (SCM_IMP (args))
0f2d19dd 2827 goto umwrongnumargs;
e050d4f8
DH
2828 formals = SCM_CDR (formals);
2829 args = SCM_CDR (args);
0f2d19dd 2830 }
e050d4f8 2831 if (!SCM_NULLP (args))
0f2d19dd
JB
2832 goto umwrongnumargs;
2833 }
22a52da1 2834 else if (SCM_MACROP (proc))
0f2d19dd 2835 goto handle_a_macro;
0f2d19dd
JB
2836 }
2837
2838
e050d4f8 2839evapply: /* inputs: x, proc */
6dbd0af5
MD
2840 PREP_APPLY (proc, SCM_EOL);
2841 if (SCM_NULLP (SCM_CDR (x))) {
2842 ENTER_APPLY;
89efbff4 2843 evap0:
0f2d19dd
JB
2844 switch (SCM_TYP7 (proc))
2845 { /* no arguments given */
2846 case scm_tc7_subr_0:
2847 RETURN (SCM_SUBRF (proc) ());
2848 case scm_tc7_subr_1o:
2849 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED));
2850 case scm_tc7_lsubr:
2851 RETURN (SCM_SUBRF (proc) (SCM_EOL));
2852 case scm_tc7_rpsubr:
2853 RETURN (SCM_BOOL_T);
2854 case scm_tc7_asubr:
2855 RETURN (SCM_SUBRF (proc) (SCM_UNDEFINED, SCM_UNDEFINED));
0717dfd8 2856 case scm_tc7_smob:
68b06924 2857 if (!SCM_SMOB_APPLICABLE_P (proc))
0717dfd8 2858 goto badfun;
68b06924 2859 RETURN (SCM_SMOB_APPLY_0 (proc));
0f2d19dd 2860 case scm_tc7_cclo:
dff98306 2861 arg1 = proc;
0f2d19dd 2862 proc = SCM_CCLO_SUBR (proc);
6dbd0af5
MD
2863#ifdef DEVAL
2864 debug.info->a.proc = proc;
dff98306 2865 debug.info->a.args = scm_list_1 (arg1);
6dbd0af5 2866#endif
0f2d19dd 2867 goto evap1;
89efbff4
MD
2868 case scm_tc7_pws:
2869 proc = SCM_PROCEDURE (proc);
2870#ifdef DEVAL
2871 debug.info->a.proc = proc;
2872#endif
002f1a5d
MD
2873 if (!SCM_CLOSUREP (proc))
2874 goto evap0;
2875 if (scm_badformalsp (proc, 0))
2876 goto umwrongnumargs;
0f2d19dd 2877 case scm_tcs_closures:
f9450cdb 2878 x = SCM_CLOSURE_BODY (proc);
821f18a4
DH
2879 env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
2880 SCM_EOL,
2881 SCM_ENV (proc));
f9450cdb 2882 goto nontoplevel_begin;
904a077d 2883 case scm_tcs_struct:
195847fa
MD
2884 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
2885 {
2886 x = SCM_ENTITY_PROCEDURE (proc);
dff98306 2887 arg1 = SCM_EOL;
195847fa
MD
2888 goto type_dispatch;
2889 }
2890 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
2891 goto badfun;
2892 else
da7f71d7 2893 {
dff98306 2894 arg1 = proc;
195847fa
MD
2895 proc = (SCM_I_ENTITYP (proc)
2896 ? SCM_ENTITY_PROCEDURE (proc)
2897 : SCM_OPERATOR_PROCEDURE (proc));
da7f71d7 2898#ifdef DEVAL
195847fa 2899 debug.info->a.proc = proc;
dff98306 2900 debug.info->a.args = scm_list_1 (arg1);
da7f71d7 2901#endif
195847fa
MD
2902 if (SCM_NIMP (proc))
2903 goto evap1;
2904 else
2905 goto badfun;
da7f71d7 2906 }
0f2d19dd
JB
2907 case scm_tc7_subr_1:
2908 case scm_tc7_subr_2:
2909 case scm_tc7_subr_2o:
2910 case scm_tc7_cxr:
2911 case scm_tc7_subr_3:
2912 case scm_tc7_lsubr_2:
2913 umwrongnumargs:
2914 unmemocar (x, env);
f5bf2977 2915 scm_wrong_num_args (proc);
0f2d19dd
JB
2916 default:
2917 /* handle macros here */
2918 goto badfun;
2919 }
6dbd0af5 2920 }
0f2d19dd
JB
2921
2922 /* must handle macros by here */
2923 x = SCM_CDR (x);
dff98306
DH
2924 if (SCM_CONSP (x))
2925 arg1 = EVALCAR (x, env);
680ed4a8 2926 else
ab1f1094 2927 scm_wrong_num_args (proc);
6dbd0af5 2928#ifdef DEVAL
dff98306 2929 debug.info->a.args = scm_list_1 (arg1);
6dbd0af5 2930#endif
0f2d19dd 2931 x = SCM_CDR (x);
42030fb2
DH
2932 {
2933 SCM arg2;
2934 if (SCM_NULLP (x))
2935 {
2936 ENTER_APPLY;
2937 evap1: /* inputs: proc, arg1 */
2938 switch (SCM_TYP7 (proc))
2939 { /* have one argument in arg1 */
2940 case scm_tc7_subr_2o:
2941 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED));
2942 case scm_tc7_subr_1:
2943 case scm_tc7_subr_1o:
2944 RETURN (SCM_SUBRF (proc) (arg1));
2945 case scm_tc7_cxr:
2946 if (SCM_SUBRF (proc))
2947 {
2948 if (SCM_INUMP (arg1))
2949 {
2950 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
2951 }
2952 else if (SCM_REALP (arg1))
2953 {
2954 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
2955 }
42030fb2
DH
2956 else if (SCM_BIGP (arg1))
2957 {
2958 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_i_big2dbl (arg1))));
2959 }
42030fb2
DH
2960 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
2961 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
2962 }
2963 proc = SCM_SNAME (proc);
2964 {
2965 char *chrs = SCM_SYMBOL_CHARS (proc) + SCM_SYMBOL_LENGTH (proc) - 1;
2966 while ('c' != *--chrs)
0f2d19dd 2967 {
42030fb2
DH
2968 SCM_ASSERT (SCM_CONSP (arg1),
2969 arg1, SCM_ARG1, SCM_SYMBOL_CHARS (proc));
2970 arg1 = ('a' == *chrs) ? SCM_CAR (arg1) : SCM_CDR (arg1);
0f2d19dd 2971 }
42030fb2 2972 RETURN (arg1);
0f2d19dd 2973 }
42030fb2
DH
2974 case scm_tc7_rpsubr:
2975 RETURN (SCM_BOOL_T);
2976 case scm_tc7_asubr:
2977 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED));
2978 case scm_tc7_lsubr:
0f2d19dd 2979#ifdef DEVAL
42030fb2 2980 RETURN (SCM_SUBRF (proc) (debug.info->a.args));
0f2d19dd 2981#else
42030fb2 2982 RETURN (SCM_SUBRF (proc) (scm_list_1 (arg1)));
0f2d19dd 2983#endif
42030fb2
DH
2984 case scm_tc7_smob:
2985 if (!SCM_SMOB_APPLICABLE_P (proc))
2986 goto badfun;
2987 RETURN (SCM_SMOB_APPLY_1 (proc, arg1));
2988 case scm_tc7_cclo:
2989 arg2 = arg1;
2990 arg1 = proc;
2991 proc = SCM_CCLO_SUBR (proc);
6dbd0af5 2992#ifdef DEVAL
42030fb2
DH
2993 debug.info->a.args = scm_cons (arg1, debug.info->a.args);
2994 debug.info->a.proc = proc;
6dbd0af5 2995#endif
42030fb2
DH
2996 goto evap2;
2997 case scm_tc7_pws:
2998 proc = SCM_PROCEDURE (proc);
89efbff4 2999#ifdef DEVAL
42030fb2 3000 debug.info->a.proc = proc;
89efbff4 3001#endif
42030fb2
DH
3002 if (!SCM_CLOSUREP (proc))
3003 goto evap1;
3004 if (scm_badformalsp (proc, 1))
3005 goto umwrongnumargs;
3006 case scm_tcs_closures:
3007 /* clos1: */
3008 x = SCM_CLOSURE_BODY (proc);
0f2d19dd 3009#ifdef DEVAL
821f18a4
DH
3010 env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3011 debug.info->a.args,
3012 SCM_ENV (proc));
0f2d19dd 3013#else
821f18a4
DH
3014 env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3015 scm_list_1 (arg1),
3016 SCM_ENV (proc));
0f2d19dd 3017#endif
42030fb2
DH
3018 goto nontoplevel_begin;
3019 case scm_tcs_struct:
3020 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3021 {
3022 x = SCM_ENTITY_PROCEDURE (proc);
f3d2630a 3023#ifdef DEVAL
42030fb2 3024 arg1 = debug.info->a.args;
f3d2630a 3025#else
42030fb2 3026 arg1 = scm_list_1 (arg1);
f3d2630a 3027#endif
42030fb2
DH
3028 goto type_dispatch;
3029 }
3030 else if (!SCM_I_OPERATORP (proc))
3031 goto badfun;
3032 else
3033 {
3034 arg2 = arg1;
3035 arg1 = proc;
3036 proc = (SCM_I_ENTITYP (proc)
3037 ? SCM_ENTITY_PROCEDURE (proc)
3038 : SCM_OPERATOR_PROCEDURE (proc));
0c32d76c 3039#ifdef DEVAL
42030fb2
DH
3040 debug.info->a.args = scm_cons (arg1, debug.info->a.args);
3041 debug.info->a.proc = proc;
0c32d76c 3042#endif
42030fb2
DH
3043 if (SCM_NIMP (proc))
3044 goto evap2;
3045 else
3046 goto badfun;
3047 }
3048 case scm_tc7_subr_2:
3049 case scm_tc7_subr_0:
3050 case scm_tc7_subr_3:
3051 case scm_tc7_lsubr_2:
ab1f1094 3052 scm_wrong_num_args (proc);
42030fb2
DH
3053 default:
3054 goto badfun;
3055 }
3056 }
42030fb2
DH
3057 if (SCM_CONSP (x))
3058 arg2 = EVALCAR (x, env);
3059 else
ab1f1094 3060 scm_wrong_num_args (proc);
bd987b8e 3061
42030fb2 3062 { /* have two or more arguments */
6dbd0af5 3063#ifdef DEVAL
42030fb2 3064 debug.info->a.args = scm_list_2 (arg1, arg2);
6dbd0af5 3065#endif
42030fb2
DH
3066 x = SCM_CDR (x);
3067 if (SCM_NULLP (x)) {
3068 ENTER_APPLY;
3069 evap2:
3070 switch (SCM_TYP7 (proc))
3071 { /* have two arguments */
3072 case scm_tc7_subr_2:
3073 case scm_tc7_subr_2o:
3074 RETURN (SCM_SUBRF (proc) (arg1, arg2));
3075 case scm_tc7_lsubr:
0f2d19dd 3076#ifdef DEVAL
42030fb2 3077 RETURN (SCM_SUBRF (proc) (debug.info->a.args));
6dbd0af5 3078#else
42030fb2
DH
3079 RETURN (SCM_SUBRF (proc) (scm_list_2 (arg1, arg2)));
3080#endif
3081 case scm_tc7_lsubr_2:
3082 RETURN (SCM_SUBRF (proc) (arg1, arg2, SCM_EOL));
3083 case scm_tc7_rpsubr:
3084 case scm_tc7_asubr:
3085 RETURN (SCM_SUBRF (proc) (arg1, arg2));
3086 case scm_tc7_smob:
3087 if (!SCM_SMOB_APPLICABLE_P (proc))
3088 goto badfun;
3089 RETURN (SCM_SMOB_APPLY_2 (proc, arg1, arg2));
3090 cclon:
3091 case scm_tc7_cclo:
0f2d19dd 3092#ifdef DEVAL
42030fb2
DH
3093 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
3094 scm_cons (proc, debug.info->a.args),
3095 SCM_EOL));
0f2d19dd 3096#else
42030fb2
DH
3097 RETURN (SCM_APPLY (SCM_CCLO_SUBR (proc),
3098 scm_cons2 (proc, arg1,
3099 scm_cons (arg2,
3100 scm_eval_args (x,
3101 env,
3102 proc))),
3103 SCM_EOL));
3104#endif
3105 case scm_tcs_struct:
3106 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3107 {
3108 x = SCM_ENTITY_PROCEDURE (proc);
3109#ifdef DEVAL
3110 arg1 = debug.info->a.args;
3111#else
3112 arg1 = scm_list_2 (arg1, arg2);
6dbd0af5 3113#endif
42030fb2
DH
3114 goto type_dispatch;
3115 }
3116 else if (!SCM_I_OPERATORP (proc))
3117 goto badfun;
3118 else
3119 {
3120 operatorn:
f3d2630a 3121#ifdef DEVAL
42030fb2
DH
3122 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
3123 ? SCM_ENTITY_PROCEDURE (proc)
3124 : SCM_OPERATOR_PROCEDURE (proc),
3125 scm_cons (proc, debug.info->a.args),
3126 SCM_EOL));
f3d2630a 3127#else
42030fb2
DH
3128 RETURN (SCM_APPLY (SCM_I_ENTITYP (proc)
3129 ? SCM_ENTITY_PROCEDURE (proc)
3130 : SCM_OPERATOR_PROCEDURE (proc),
3131 scm_cons2 (proc, arg1,
3132 scm_cons (arg2,
3133 scm_eval_args (x,
3134 env,
3135 proc))),
3136 SCM_EOL));
f3d2630a 3137#endif
42030fb2
DH
3138 }
3139 case scm_tc7_subr_0:
3140 case scm_tc7_cxr:
3141 case scm_tc7_subr_1o:
3142 case scm_tc7_subr_1:
3143 case scm_tc7_subr_3:
ab1f1094 3144 scm_wrong_num_args (proc);
42030fb2 3145 default:
9b07e212 3146 goto badfun;
42030fb2
DH
3147 case scm_tc7_pws:
3148 proc = SCM_PROCEDURE (proc);
3149#ifdef DEVAL
3150 debug.info->a.proc = proc;
3151#endif
3152 if (!SCM_CLOSUREP (proc))
3153 goto evap2;
3154 if (scm_badformalsp (proc, 2))
3155 goto umwrongnumargs;
3156 case scm_tcs_closures:
3157 /* clos2: */
0c32d76c 3158#ifdef DEVAL
821f18a4
DH
3159 env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3160 debug.info->a.args,
3161 SCM_ENV (proc));
195847fa 3162#else
821f18a4
DH
3163 env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3164 scm_list_2 (arg1, arg2),
3165 SCM_ENV (proc));
195847fa 3166#endif
42030fb2
DH
3167 x = SCM_CLOSURE_BODY (proc);
3168 goto nontoplevel_begin;
3169 }
3170 }
42030fb2 3171 if (!SCM_CONSP (x))
ab1f1094 3172 scm_wrong_num_args (proc);
42030fb2
DH
3173#ifdef DEVAL
3174 debug.info->a.args = scm_cons2 (arg1, arg2,
3175 deval_args (x, env, proc,
3176 SCM_CDRLOC (SCM_CDR (debug.info->a.args))));
3177#endif
3178 ENTER_APPLY;
3179 evap3:
3180 switch (SCM_TYP7 (proc))
3181 { /* have 3 or more arguments */
3182#ifdef DEVAL
6dbd0af5 3183 case scm_tc7_subr_3:
ab1f1094
DH
3184 if (!SCM_NULLP (SCM_CDR (x)))
3185 scm_wrong_num_args (proc);
3186 else
3187 RETURN (SCM_SUBRF (proc) (arg1, arg2,
3188 SCM_CADDR (debug.info->a.args)));
42030fb2
DH
3189 case scm_tc7_asubr:
3190 arg1 = SCM_SUBRF(proc)(arg1, arg2);
3191 arg2 = SCM_CDDR (debug.info->a.args);
3192 do
3193 {
3194 arg1 = SCM_SUBRF(proc)(arg1, SCM_CAR (arg2));
3195 arg2 = SCM_CDR (arg2);
3196 }
3197 while (SCM_NIMP (arg2));
3198 RETURN (arg1);
3199 case scm_tc7_rpsubr:
3200 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, arg2)))
3201 RETURN (SCM_BOOL_F);
3202 arg1 = SCM_CDDR (debug.info->a.args);
3203 do
3204 {
3205 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, SCM_CAR (arg1))))
3206 RETURN (SCM_BOOL_F);
3207 arg2 = SCM_CAR (arg1);
3208 arg1 = SCM_CDR (arg1);
3209 }
3210 while (SCM_NIMP (arg1));
3211 RETURN (SCM_BOOL_T);
3212 case scm_tc7_lsubr_2:
3213 RETURN (SCM_SUBRF (proc) (arg1, arg2,
3214 SCM_CDDR (debug.info->a.args)));
3215 case scm_tc7_lsubr:
3216 RETURN (SCM_SUBRF (proc) (debug.info->a.args));
3217 case scm_tc7_smob:
3218 if (!SCM_SMOB_APPLICABLE_P (proc))
3219 goto badfun;
3220 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, arg2,
3221 SCM_CDDR (debug.info->a.args)));
3222 case scm_tc7_cclo:
3223 goto cclon;
002f1a5d
MD
3224 case scm_tc7_pws:
3225 proc = SCM_PROCEDURE (proc);
002f1a5d 3226 debug.info->a.proc = proc;
002f1a5d 3227 if (!SCM_CLOSUREP (proc))
42030fb2
DH
3228 goto evap3;
3229 if (scm_badargsp (SCM_CLOSURE_FORMALS (proc), debug.info->a.args))
002f1a5d 3230 goto umwrongnumargs;
6dbd0af5 3231 case scm_tcs_closures:
42030fb2 3232 SCM_SET_ARGSREADY (debug);
821f18a4
DH
3233 env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3234 debug.info->a.args,
3235 SCM_ENV (proc));
f9450cdb
DH
3236 x = SCM_CLOSURE_BODY (proc);
3237 goto nontoplevel_begin;
6dbd0af5 3238#else /* DEVAL */
42030fb2 3239 case scm_tc7_subr_3:
ab1f1094
DH
3240 if (!SCM_NULLP (SCM_CDR (x)))
3241 scm_wrong_num_args (proc);
3242 else
3243 RETURN (SCM_SUBRF (proc) (arg1, arg2, EVALCAR (x, env)));
42030fb2
DH
3244 case scm_tc7_asubr:
3245 arg1 = SCM_SUBRF (proc) (arg1, arg2);
3246 do
3247 {
3248 arg1 = SCM_SUBRF(proc)(arg1, EVALCAR(x, env));
3249 x = SCM_CDR(x);
3250 }
3251 while (SCM_NIMP (x));
3252 RETURN (arg1);
3253 case scm_tc7_rpsubr:
3254 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, arg2)))
3255 RETURN (SCM_BOOL_F);
3256 do
3257 {
3258 arg1 = EVALCAR (x, env);
3259 if (SCM_FALSEP (SCM_SUBRF (proc) (arg2, arg1)))
3260 RETURN (SCM_BOOL_F);
3261 arg2 = arg1;
3262 x = SCM_CDR (x);
3263 }
3264 while (SCM_NIMP (x));
3265 RETURN (SCM_BOOL_T);
3266 case scm_tc7_lsubr_2:
3267 RETURN (SCM_SUBRF (proc) (arg1, arg2, scm_eval_args (x, env, proc)));
3268 case scm_tc7_lsubr:
3269 RETURN (SCM_SUBRF (proc) (scm_cons2 (arg1,
3270 arg2,
3271 scm_eval_args (x, env, proc))));
3272 case scm_tc7_smob:
3273 if (!SCM_SMOB_APPLICABLE_P (proc))
3274 goto badfun;
3275 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, arg2,
3276 scm_eval_args (x, env, proc)));
3277 case scm_tc7_cclo:
3278 goto cclon;
3279 case scm_tc7_pws:
3280 proc = SCM_PROCEDURE (proc);
3281 if (!SCM_CLOSUREP (proc))
3282 goto evap3;
da7f71d7 3283 {
42030fb2
DH
3284 SCM formals = SCM_CLOSURE_FORMALS (proc);
3285 if (SCM_NULLP (formals)
3286 || (SCM_CONSP (formals)
3287 && (SCM_NULLP (SCM_CDR (formals))
3288 || (SCM_CONSP (SCM_CDR (formals))
3289 && scm_badargsp (SCM_CDDR (formals), x)))))
3290 goto umwrongnumargs;
da7f71d7 3291 }
42030fb2 3292 case scm_tcs_closures:
6dbd0af5 3293#ifdef DEVAL
42030fb2 3294 SCM_SET_ARGSREADY (debug);
6dbd0af5 3295#endif
821f18a4
DH
3296 env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3297 scm_cons2 (arg1,
3298 arg2,
3299 scm_eval_args (x, env, proc)),
3300 SCM_ENV (proc));
42030fb2
DH
3301 x = SCM_CLOSURE_BODY (proc);
3302 goto nontoplevel_begin;
0f2d19dd 3303#endif /* DEVAL */
42030fb2
DH
3304 case scm_tcs_struct:
3305 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3306 {
f3d2630a 3307#ifdef DEVAL
42030fb2 3308 arg1 = debug.info->a.args;
f3d2630a 3309#else
42030fb2 3310 arg1 = scm_cons2 (arg1, arg2, scm_eval_args (x, env, proc));
f3d2630a 3311#endif
42030fb2
DH
3312 x = SCM_ENTITY_PROCEDURE (proc);
3313 goto type_dispatch;
3314 }
3315 else if (!SCM_I_OPERATORP (proc))
3316 goto badfun;
3317 else
3318 goto operatorn;
3319 case scm_tc7_subr_2:
3320 case scm_tc7_subr_1o:
3321 case scm_tc7_subr_2o:
3322 case scm_tc7_subr_0:
3323 case scm_tc7_cxr:
3324 case scm_tc7_subr_1:
ab1f1094 3325 scm_wrong_num_args (proc);
42030fb2 3326 default:
9b07e212 3327 goto badfun;
42030fb2
DH
3328 }
3329 }
0f2d19dd
JB
3330 }
3331#ifdef DEVAL
6dbd0af5 3332exit:
5132eef0 3333 if (scm_check_exit_p && SCM_TRAPS_P)
b7ff98dd 3334 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 3335 {
b7ff98dd
MD
3336 SCM_CLEAR_TRACED_FRAME (debug);
3337 if (SCM_CHEAPTRAPS_P)
dff98306 3338 arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
3339 else
3340 {
5f144b10
GH
3341 int first;
3342 SCM val = scm_make_continuation (&first);
e050d4f8 3343
5f144b10 3344 if (first)
dff98306 3345 arg1 = val;
5f144b10 3346 else
6dbd0af5 3347 {
5f144b10 3348 proc = val;
6dbd0af5
MD
3349 goto ret;
3350 }
3351 }
d95c0b76 3352 SCM_TRAPS_P = 0;
dff98306 3353 scm_call_3 (SCM_EXIT_FRAME_HDLR, scm_sym_exit_frame, arg1, proc);
d95c0b76 3354 SCM_TRAPS_P = 1;
6dbd0af5
MD
3355 }
3356ret:
1646d37b 3357 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
3358 return proc;
3359#endif
3360}
3361
6dbd0af5
MD
3362
3363/* SECTION: This code is compiled once.
3364 */
3365
0f2d19dd
JB
3366#ifndef DEVAL
3367
fdc28395 3368\f
d0b07b5d 3369
fdc28395
KN
3370/* Simple procedure calls
3371 */
3372
3373SCM
3374scm_call_0 (SCM proc)
3375{
3376 return scm_apply (proc, SCM_EOL, SCM_EOL);
3377}
3378
3379SCM
3380scm_call_1 (SCM proc, SCM arg1)
3381{
3382 return scm_apply (proc, arg1, scm_listofnull);
3383}
3384
3385SCM
3386scm_call_2 (SCM proc, SCM arg1, SCM arg2)
3387{
3388 return scm_apply (proc, arg1, scm_cons (arg2, scm_listofnull));
3389}
3390
3391SCM
3392scm_call_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)
3393{
3394 return scm_apply (proc, arg1, scm_cons2 (arg2, arg3, scm_listofnull));
3395}
3396
d95c0b76
NJ
3397SCM
3398scm_call_4 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4)
3399{
3400 return scm_apply (proc, arg1, scm_cons2 (arg2, arg3,
3401 scm_cons (arg4, scm_listofnull)));
3402}
3403
fdc28395
KN
3404/* Simple procedure applies
3405 */
3406
3407SCM
3408scm_apply_0 (SCM proc, SCM args)
3409{
3410 return scm_apply (proc, args, SCM_EOL);
3411}
3412
3413SCM
3414scm_apply_1 (SCM proc, SCM arg1, SCM args)
3415{
3416 return scm_apply (proc, scm_cons (arg1, args), SCM_EOL);
3417}
3418
3419SCM
3420scm_apply_2 (SCM proc, SCM arg1, SCM arg2, SCM args)
3421{
3422 return scm_apply (proc, scm_cons2 (arg1, arg2, args), SCM_EOL);
3423}
3424
3425SCM
3426scm_apply_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM args)
3427{
3428 return scm_apply (proc, scm_cons (arg1, scm_cons2 (arg2, arg3, args)),
3429 SCM_EOL);
3430}
3431
82a2622a 3432/* This code processes the arguments to apply:
b145c172
JB
3433
3434 (apply PROC ARG1 ... ARGS)
3435
82a2622a
JB
3436 Given a list (ARG1 ... ARGS), this function conses the ARG1
3437 ... arguments onto the front of ARGS, and returns the resulting
3438 list. Note that ARGS is a list; thus, the argument to this
3439 function is a list whose last element is a list.
3440
3441 Apply calls this function, and applies PROC to the elements of the
b145c172
JB
3442 result. apply:nconc2last takes care of building the list of
3443 arguments, given (ARG1 ... ARGS).
3444
82a2622a
JB
3445 Rather than do new consing, apply:nconc2last destroys its argument.
3446 On that topic, this code came into my care with the following
3447 beautifully cryptic comment on that topic: "This will only screw
3448 you if you do (scm_apply scm_apply '( ... ))" If you know what
3449 they're referring to, send me a patch to this comment. */
b145c172 3450
3b3b36dd 3451SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
b3f26b14
MG
3452 (SCM lst),
3453 "Given a list (@var{arg1} @dots{} @var{args}), this function\n"
3454 "conses the @var{arg1} @dots{} arguments onto the front of\n"
3455 "@var{args}, and returns the resulting list. Note that\n"
3456 "@var{args} is a list; thus, the argument to this function is\n"
3457 "a list whose last element is a list.\n"
3458 "Note: Rather than do new consing, @code{apply:nconc2last}\n"
3459 "destroys its argument, so use with care.")
1bbd0b84 3460#define FUNC_NAME s_scm_nconc2last
0f2d19dd
JB
3461{
3462 SCM *lloc;
34d19ef6 3463 SCM_VALIDATE_NONEMPTYLIST (1, lst);
0f2d19dd 3464 lloc = &lst;
c96d76b8
NJ
3465 while (!SCM_NULLP (SCM_CDR (*lloc))) /* Perhaps should be
3466 SCM_NULL_OR_NIL_P, but not
3467 needed in 99.99% of cases,
3468 and it could seriously hurt
3469 performance. - Neil */
a23afe53 3470 lloc = SCM_CDRLOC (*lloc);
1bbd0b84 3471 SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
0f2d19dd
JB
3472 *lloc = SCM_CAR (*lloc);
3473 return lst;
3474}
1bbd0b84 3475#undef FUNC_NAME
0f2d19dd
JB
3476
3477#endif /* !DEVAL */
3478
6dbd0af5
MD
3479
3480/* SECTION: When DEVAL is defined this code yields scm_dapply.
3481 * It is compiled twice.
3482 */
3483
0f2d19dd 3484#if 0
0f2d19dd 3485SCM
6e8d25a6 3486scm_apply (SCM proc, SCM arg1, SCM args)
0f2d19dd
JB
3487{}
3488#endif
3489
3490#if 0
0f2d19dd 3491SCM
6e8d25a6 3492scm_dapply (SCM proc, SCM arg1, SCM args)
d0b07b5d 3493{}
0f2d19dd
JB
3494#endif
3495
1cc91f1b 3496
82a2622a
JB
3497/* Apply a function to a list of arguments.
3498
3499 This function is exported to the Scheme level as taking two
3500 required arguments and a tail argument, as if it were:
3501 (lambda (proc arg1 . args) ...)
3502 Thus, if you just have a list of arguments to pass to a procedure,
3503 pass the list as ARG1, and '() for ARGS. If you have some fixed
3504 args, pass the first as ARG1, then cons any remaining fixed args
3505 onto the front of your argument list, and pass that as ARGS. */
3506
0f2d19dd 3507SCM
1bbd0b84 3508SCM_APPLY (SCM proc, SCM arg1, SCM args)
0f2d19dd 3509{
0f2d19dd 3510#ifdef DEVAL
92c2555f
MV
3511 scm_t_debug_frame debug;
3512 scm_t_debug_info debug_vect_body;
1646d37b 3513 debug.prev = scm_last_debug_frame;
b7ff98dd 3514 debug.status = SCM_APPLYFRAME;
c0ab1b8d 3515 debug.vect = &debug_vect_body;
6dbd0af5
MD
3516 debug.vect[0].a.proc = proc;
3517 debug.vect[0].a.args = SCM_EOL;
1646d37b 3518 scm_last_debug_frame = &debug;
0f2d19dd 3519#else
b7ff98dd 3520 if (SCM_DEBUGGINGP)
0f2d19dd 3521 return scm_dapply (proc, arg1, args);
0f2d19dd
JB
3522#endif
3523
3524 SCM_ASRTGO (SCM_NIMP (proc), badproc);
82a2622a
JB
3525
3526 /* If ARGS is the empty list, then we're calling apply with only two
3527 arguments --- ARG1 is the list of arguments for PROC. Whatever
3528 the case, futz with things so that ARG1 is the first argument to
3529 give to PROC (or SCM_UNDEFINED if no args), and ARGS contains the
30000774
JB
3530 rest.
3531
3532 Setting the debug apply frame args this way is pretty messy.
3533 Perhaps we should store arg1 and args directly in the frame as
3534 received, and let scm_frame_arguments unpack them, because that's
3535 a relatively rare operation. This works for now; if the Guile
3536 developer archives are still around, see Mikael's post of
3537 11-Apr-97. */
0f2d19dd
JB
3538 if (SCM_NULLP (args))
3539 {
3540 if (SCM_NULLP (arg1))
30000774
JB
3541 {
3542 arg1 = SCM_UNDEFINED;
3543#ifdef DEVAL
3544 debug.vect[0].a.args = SCM_EOL;
3545#endif
3546 }
0f2d19dd
JB
3547 else
3548 {
30000774
JB
3549#ifdef DEVAL
3550 debug.vect[0].a.args = arg1;
3551#endif
0f2d19dd
JB
3552 args = SCM_CDR (arg1);
3553 arg1 = SCM_CAR (arg1);
3554 }
3555 }
3556 else
3557 {
0f2d19dd 3558 args = scm_nconc2last (args);
30000774
JB
3559#ifdef DEVAL
3560 debug.vect[0].a.args = scm_cons (arg1, args);
3561#endif
0f2d19dd 3562 }
0f2d19dd 3563#ifdef DEVAL
b6d75948 3564 if (SCM_ENTER_FRAME_P && SCM_TRAPS_P)
6dbd0af5
MD
3565 {
3566 SCM tmp;
b7ff98dd 3567 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 3568 tmp = scm_make_debugobj (&debug);
6dbd0af5
MD
3569 else
3570 {
5f144b10
GH
3571 int first;
3572
3573 tmp = scm_make_continuation (&first);
3574 if (!first)
6dbd0af5
MD
3575 goto entap;
3576 }
d95c0b76
NJ
3577 SCM_TRAPS_P = 0;
3578 scm_call_2 (SCM_ENTER_FRAME_HDLR, scm_sym_enter_frame, tmp);
3579 SCM_TRAPS_P = 1;
6dbd0af5
MD
3580 }
3581entap:
3582 ENTER_APPLY;
3583#endif
6dbd0af5 3584tail:
0f2d19dd
JB
3585 switch (SCM_TYP7 (proc))
3586 {
3587 case scm_tc7_subr_2o:
3588 args = SCM_NULLP (args) ? SCM_UNDEFINED : SCM_CAR (args);
ddea3325 3589 RETURN (SCM_SUBRF (proc) (arg1, args));
0f2d19dd 3590 case scm_tc7_subr_2:
ab1f1094
DH
3591 if (SCM_NULLP (args) || !SCM_NULLP (SCM_CDR (args)))
3592 scm_wrong_num_args (proc);
0f2d19dd 3593 args = SCM_CAR (args);
ddea3325 3594 RETURN (SCM_SUBRF (proc) (arg1, args));
0f2d19dd 3595 case scm_tc7_subr_0:
ab1f1094
DH
3596 if (!SCM_UNBNDP (arg1))
3597 scm_wrong_num_args (proc);
3598 else
3599 RETURN (SCM_SUBRF (proc) ());
0f2d19dd 3600 case scm_tc7_subr_1:
ab1f1094
DH
3601 if (SCM_UNBNDP (arg1))
3602 scm_wrong_num_args (proc);
0f2d19dd 3603 case scm_tc7_subr_1o:
ab1f1094
DH
3604 if (!SCM_NULLP (args))
3605 scm_wrong_num_args (proc);
3606 else
3607 RETURN (SCM_SUBRF (proc) (arg1));
0f2d19dd 3608 case scm_tc7_cxr:
ab1f1094
DH
3609 if (SCM_UNBNDP (arg1) || !SCM_NULLP (args))
3610 scm_wrong_num_args (proc);
0f2d19dd
JB
3611 if (SCM_SUBRF (proc))
3612 {
6dbd0af5
MD
3613 if (SCM_INUMP (arg1))
3614 {
f8de44c1 3615 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
6dbd0af5 3616 }
01f11e02 3617 else if (SCM_REALP (arg1))
6dbd0af5 3618 {
eb42e2f0 3619 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
6dbd0af5 3620 }
01f11e02 3621 else if (SCM_BIGP (arg1))
ddea3325 3622 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_i_big2dbl (arg1))));
9de33deb 3623 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
3db4adfc 3624 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
0f2d19dd 3625 }
3201d763 3626 proc = SCM_SNAME (proc);
0f2d19dd 3627 {
b5c2579a 3628 char *chrs = SCM_SYMBOL_CHARS (proc) + SCM_SYMBOL_LENGTH (proc) - 1;
0f2d19dd
JB
3629 while ('c' != *--chrs)
3630 {
0c95b57d 3631 SCM_ASSERT (SCM_CONSP (arg1),
3db4adfc 3632 arg1, SCM_ARG1, SCM_SYMBOL_CHARS (proc));
0f2d19dd
JB
3633 arg1 = ('a' == *chrs) ? SCM_CAR (arg1) : SCM_CDR (arg1);
3634 }
ddea3325 3635 RETURN (arg1);
0f2d19dd
JB
3636 }
3637 case scm_tc7_subr_3:
ab1f1094
DH
3638 if (SCM_NULLP (args)
3639 || SCM_NULLP (SCM_CDR (args))
3640 || !SCM_NULLP (SCM_CDDR (args)))
3641 scm_wrong_num_args (proc);
3642 else
3643 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CADR (args)));
0f2d19dd
JB
3644 case scm_tc7_lsubr:
3645#ifdef DEVAL
ddea3325 3646 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args));
0f2d19dd 3647#else
ddea3325 3648 RETURN (SCM_SUBRF (proc) (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args)));
0f2d19dd
JB
3649#endif
3650 case scm_tc7_lsubr_2:
ab1f1094
DH
3651 if (!SCM_CONSP (args))
3652 scm_wrong_num_args (proc);
3653 else
3654 RETURN (SCM_SUBRF (proc) (arg1, SCM_CAR (args), SCM_CDR (args)));
0f2d19dd
JB
3655 case scm_tc7_asubr:
3656 if (SCM_NULLP (args))
ddea3325 3657 RETURN (SCM_SUBRF (proc) (arg1, SCM_UNDEFINED));
0f2d19dd
JB
3658 while (SCM_NIMP (args))
3659 {
3660 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3661 arg1 = SCM_SUBRF (proc) (arg1, SCM_CAR (args));
3662 args = SCM_CDR (args);
3663 }
3664 RETURN (arg1);
3665 case scm_tc7_rpsubr:
3666 if (SCM_NULLP (args))
3667 RETURN (SCM_BOOL_T);
3668 while (SCM_NIMP (args))
3669 {
3670 SCM_ASSERT (SCM_CONSP (args), args, SCM_ARG2, "apply");
3671 if (SCM_FALSEP (SCM_SUBRF (proc) (arg1, SCM_CAR (args))))
3672 RETURN (SCM_BOOL_F);
3673 arg1 = SCM_CAR (args);
3674 args = SCM_CDR (args);
3675 }
3676 RETURN (SCM_BOOL_T);
3677 case scm_tcs_closures:
3678#ifdef DEVAL
6dbd0af5 3679 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : debug.vect[0].a.args);
0f2d19dd
JB
3680#else
3681 arg1 = (SCM_UNBNDP (arg1) ? SCM_EOL : scm_cons (arg1, args));
3682#endif
726d810a 3683 if (scm_badargsp (SCM_CLOSURE_FORMALS (proc), arg1))
ab1f1094 3684 scm_wrong_num_args (proc);
1609038c
MD
3685
3686 /* Copy argument list */
3687 if (SCM_IMP (arg1))
3688 args = arg1;
3689 else
3690 {
3691 SCM tl = args = scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED);
05b15362 3692 for (arg1 = SCM_CDR (arg1); SCM_CONSP (arg1); arg1 = SCM_CDR (arg1))
1609038c 3693 {
05b15362 3694 SCM_SETCDR (tl, scm_cons (SCM_CAR (arg1), SCM_UNSPECIFIED));
1609038c
MD
3695 tl = SCM_CDR (tl);
3696 }
3697 SCM_SETCDR (tl, arg1);
3698 }
3699
821f18a4
DH
3700 args = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3701 args,
3702 SCM_ENV (proc));
f9450cdb 3703 proc = SCM_CLOSURE_BODY (proc);
e791c18f 3704 again:
05b15362
DH
3705 arg1 = SCM_CDR (proc);
3706 while (!SCM_NULLP (arg1))
2ddb0920
MD
3707 {
3708 if (SCM_IMP (SCM_CAR (proc)))
3709 {
3710 if (SCM_ISYMP (SCM_CAR (proc)))
3711 {
28d52ebb 3712 scm_rec_mutex_lock (&source_mutex);
9bc4701c
MD
3713 /* check for race condition */
3714 if (SCM_ISYMP (SCM_CAR (proc)))
3715 proc = scm_m_expand_body (proc, args);
28d52ebb 3716 scm_rec_mutex_unlock (&source_mutex);
e791c18f 3717 goto again;
2ddb0920 3718 }
5280aaca 3719 else
17fa3fcf 3720 SCM_VALIDATE_NON_EMPTY_COMBINATION (SCM_CAR (proc));
2ddb0920
MD
3721 }
3722 else
e791c18f
MD
3723 SCM_CEVAL (SCM_CAR (proc), args);
3724 proc = arg1;
05b15362 3725 arg1 = SCM_CDR (proc);
2ddb0920 3726 }
e791c18f 3727 RETURN (EVALCAR (proc, args));
0717dfd8 3728 case scm_tc7_smob:
68b06924 3729 if (!SCM_SMOB_APPLICABLE_P (proc))
0717dfd8 3730 goto badproc;
afa38f6e 3731 if (SCM_UNBNDP (arg1))
ddea3325 3732 RETURN (SCM_SMOB_APPLY_0 (proc));
afa38f6e 3733 else if (SCM_NULLP (args))
ddea3325 3734 RETURN (SCM_SMOB_APPLY_1 (proc, arg1));
0717dfd8 3735 else if (SCM_NULLP (SCM_CDR (args)))
ddea3325 3736 RETURN (SCM_SMOB_APPLY_2 (proc, arg1, SCM_CAR (args)));
0717dfd8 3737 else
68b06924 3738 RETURN (SCM_SMOB_APPLY_3 (proc, arg1, SCM_CAR (args), SCM_CDR (args)));
0f2d19dd
JB
3739 case scm_tc7_cclo:
3740#ifdef DEVAL
6dbd0af5
MD
3741 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3742 arg1 = proc;
3743 proc = SCM_CCLO_SUBR (proc);
3744 debug.vect[0].a.proc = proc;
3745 debug.vect[0].a.args = scm_cons (arg1, args);
0f2d19dd
JB
3746#else
3747 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
0f2d19dd
JB
3748 arg1 = proc;
3749 proc = SCM_CCLO_SUBR (proc);
6dbd0af5 3750#endif
0f2d19dd 3751 goto tail;
89efbff4
MD
3752 case scm_tc7_pws:
3753 proc = SCM_PROCEDURE (proc);
3754#ifdef DEVAL
3755 debug.vect[0].a.proc = proc;
3756#endif
3757 goto tail;
904a077d 3758 case scm_tcs_struct:
f3d2630a
MD
3759 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3760 {
3761#ifdef DEVAL
3762 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3763#else
3764 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3765#endif
195847fa 3766 RETURN (scm_apply_generic (proc, args));
f3d2630a
MD
3767 }
3768 else if (!SCM_I_OPERATORP (proc))
9b07e212
MD
3769 goto badproc;
3770 else
da7f71d7 3771 {
504d99c5 3772 /* operator */
da7f71d7
MD
3773#ifdef DEVAL
3774 args = (SCM_UNBNDP(arg1) ? SCM_EOL : debug.vect[0].a.args);
3775#else
3776 args = (SCM_UNBNDP(arg1) ? SCM_EOL : scm_cons (arg1, args));
3777#endif
3778 arg1 = proc;
195847fa
MD
3779 proc = (SCM_I_ENTITYP (proc)
3780 ? SCM_ENTITY_PROCEDURE (proc)
3781 : SCM_OPERATOR_PROCEDURE (proc));
da7f71d7
MD
3782#ifdef DEVAL
3783 debug.vect[0].a.proc = proc;
3784 debug.vect[0].a.args = scm_cons (arg1, args);
3785#endif
195847fa
MD
3786 if (SCM_NIMP (proc))
3787 goto tail;
3788 else
3789 goto badproc;
da7f71d7 3790 }
0f2d19dd
JB
3791 default:
3792 badproc:
db4b4ca6 3793 scm_wrong_type_arg ("apply", SCM_ARG1, proc);
0f2d19dd
JB
3794 }
3795#ifdef DEVAL
6dbd0af5 3796exit:
5132eef0 3797 if (scm_check_exit_p && SCM_TRAPS_P)
b7ff98dd 3798 if (SCM_EXIT_FRAME_P || (SCM_TRACE_P && SCM_TRACED_FRAME_P (debug)))
6dbd0af5 3799 {
b7ff98dd
MD
3800 SCM_CLEAR_TRACED_FRAME (debug);
3801 if (SCM_CHEAPTRAPS_P)
c0ab1b8d 3802 arg1 = scm_make_debugobj (&debug);
6dbd0af5
MD
3803 else
3804 {
5f144b10
GH
3805 int first;
3806 SCM val = scm_make_continuation (&first);
3807
3808 if (first)
3809 arg1 = val;
3810 else
6dbd0af5 3811 {
5f144b10 3812 proc = val;
6dbd0af5
MD
3813 goto ret;
3814 }
3815 }
d95c0b76
NJ
3816 SCM_TRAPS_P = 0;
3817 scm_call_3 (SCM_EXIT_FRAME_HDLR, scm_sym_exit_frame, arg1, proc);
3818 SCM_TRAPS_P = 1;
6dbd0af5
MD
3819 }
3820ret:
1646d37b 3821 scm_last_debug_frame = debug.prev;
0f2d19dd
JB
3822 return proc;
3823#endif
3824}
3825
6dbd0af5
MD
3826
3827/* SECTION: The rest of this file is only read once.
3828 */
3829
0f2d19dd
JB
3830#ifndef DEVAL
3831
504d99c5
MD
3832/* Trampolines
3833 *
3834 * Trampolines make it possible to move procedure application dispatch
3835 * outside inner loops. The motivation was clean implementation of
3836 * efficient replacements of R5RS primitives in SRFI-1.
3837 *
3838 * The semantics is clear: scm_trampoline_N returns an optimized
3839 * version of scm_call_N (or NULL if the procedure isn't applicable
3840 * on N args).
3841 *
3842 * Applying the optimization to map and for-each increased efficiency
3843 * noticeably. For example, (map abs ls) is now 8 times faster than
3844 * before.
3845 */
3846
756414cf
MD
3847static SCM
3848call_subr0_0 (SCM proc)
3849{
3850 return SCM_SUBRF (proc) ();
3851}
3852
3853static SCM
3854call_subr1o_0 (SCM proc)
3855{
3856 return SCM_SUBRF (proc) (SCM_UNDEFINED);
3857}
3858
3859static SCM
3860call_lsubr_0 (SCM proc)
3861{
3862 return SCM_SUBRF (proc) (SCM_EOL);
3863}
3864
3865SCM
3866scm_i_call_closure_0 (SCM proc)
3867{
6a3f13f0
DH
3868 const SCM env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3869 SCM_EOL,
3870 SCM_ENV (proc));
3871 const SCM result = scm_eval_body (SCM_CLOSURE_BODY (proc), env);
d0b07b5d 3872 return result;
756414cf
MD
3873}
3874
3875scm_t_trampoline_0
3876scm_trampoline_0 (SCM proc)
3877{
3878 if (SCM_IMP (proc))
d0b07b5d 3879 return NULL;
756414cf
MD
3880 if (SCM_DEBUGGINGP)
3881 return scm_call_0;
3882 switch (SCM_TYP7 (proc))
3883 {
3884 case scm_tc7_subr_0:
3885 return call_subr0_0;
3886 case scm_tc7_subr_1o:
3887 return call_subr1o_0;
3888 case scm_tc7_lsubr:
3889 return call_lsubr_0;
3890 case scm_tcs_closures:
3891 {
3892 SCM formals = SCM_CLOSURE_FORMALS (proc);
4b612c5b 3893 if (SCM_NULLP (formals) || !SCM_CONSP (formals))
756414cf
MD
3894 return scm_i_call_closure_0;
3895 else
d0b07b5d 3896 return NULL;
756414cf
MD
3897 }
3898 case scm_tcs_struct:
3899 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
3900 return scm_call_generic_0;
3901 else if (!SCM_I_OPERATORP (proc))
d0b07b5d 3902 return NULL;
756414cf
MD
3903 return scm_call_0;
3904 case scm_tc7_smob:
3905 if (SCM_SMOB_APPLICABLE_P (proc))
3906 return SCM_SMOB_DESCRIPTOR (proc).apply_0;
3907 else
d0b07b5d 3908 return NULL;
756414cf
MD
3909 case scm_tc7_asubr:
3910 case scm_tc7_rpsubr:
3911 case scm_tc7_cclo:
3912 case scm_tc7_pws:
3913 return scm_call_0;
3914 default:
d0b07b5d 3915 return NULL; /* not applicable on one arg */
756414cf
MD
3916 }
3917}
3918
504d99c5
MD
3919static SCM
3920call_subr1_1 (SCM proc, SCM arg1)
3921{
3922 return SCM_SUBRF (proc) (arg1);
3923}
3924
9ed24633
MD
3925static SCM
3926call_subr2o_1 (SCM proc, SCM arg1)
3927{
3928 return SCM_SUBRF (proc) (arg1, SCM_UNDEFINED);
3929}
3930
504d99c5
MD
3931static SCM
3932call_lsubr_1 (SCM proc, SCM arg1)
3933{
3934 return SCM_SUBRF (proc) (scm_list_1 (arg1));
3935}
3936
3937static SCM
3938call_dsubr_1 (SCM proc, SCM arg1)
3939{
3940 if (SCM_INUMP (arg1))
3941 {
3942 RETURN (scm_make_real (SCM_DSUBRF (proc) ((double) SCM_INUM (arg1))));
3943 }
3944 else if (SCM_REALP (arg1))
3945 {
3946 RETURN (scm_make_real (SCM_DSUBRF (proc) (SCM_REAL_VALUE (arg1))));
3947 }
504d99c5
MD
3948 else if (SCM_BIGP (arg1))
3949 RETURN (scm_make_real (SCM_DSUBRF (proc) (scm_i_big2dbl (arg1))));
504d99c5
MD
3950 SCM_WTA_DISPATCH_1 (*SCM_SUBR_GENERIC (proc), arg1,
3951 SCM_ARG1, SCM_SYMBOL_CHARS (SCM_SNAME (proc)));
3952}
3953
3954static SCM
3955call_cxr_1 (SCM proc, SCM arg1)
3956{
3957 proc = SCM_SNAME (proc);
3958 {
3959 char *chrs = SCM_SYMBOL_CHARS (proc) + SCM_SYMBOL_LENGTH (proc) - 1;
3960 while ('c' != *--chrs)
3961 {
3962 SCM_ASSERT (SCM_CONSP (arg1),
3963 arg1, SCM_ARG1, SCM_SYMBOL_CHARS (proc));
3964 arg1 = ('a' == *chrs) ? SCM_CAR (arg1) : SCM_CDR (arg1);
3965 }
3966 return (arg1);
3967 }
3968}
3969
3970static SCM
3971call_closure_1 (SCM proc, SCM arg1)
3972{
6a3f13f0
DH
3973 const SCM env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
3974 scm_list_1 (arg1),
3975 SCM_ENV (proc));
3976 const SCM result = scm_eval_body (SCM_CLOSURE_BODY (proc), env);
d0b07b5d 3977 return result;
504d99c5
MD
3978}
3979
3980scm_t_trampoline_1
3981scm_trampoline_1 (SCM proc)
3982{
3983 if (SCM_IMP (proc))
d0b07b5d 3984 return NULL;
504d99c5
MD
3985 if (SCM_DEBUGGINGP)
3986 return scm_call_1;
3987 switch (SCM_TYP7 (proc))
3988 {
3989 case scm_tc7_subr_1:
3990 case scm_tc7_subr_1o:
3991 return call_subr1_1;
9ed24633
MD
3992 case scm_tc7_subr_2o:
3993 return call_subr2o_1;
504d99c5
MD
3994 case scm_tc7_lsubr:
3995 return call_lsubr_1;
3996 case scm_tc7_cxr:
3997 if (SCM_SUBRF (proc))
3998 return call_dsubr_1;
3999 else
4000 return call_cxr_1;
4001 case scm_tcs_closures:
4002 {
4003 SCM formals = SCM_CLOSURE_FORMALS (proc);
4b612c5b
MD
4004 if (!SCM_NULLP (formals)
4005 && (!SCM_CONSP (formals) || !SCM_CONSP (SCM_CDR (formals))))
504d99c5
MD
4006 return call_closure_1;
4007 else
d0b07b5d 4008 return NULL;
504d99c5
MD
4009 }
4010 case scm_tcs_struct:
4011 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
4012 return scm_call_generic_1;
4013 else if (!SCM_I_OPERATORP (proc))
d0b07b5d 4014 return NULL;
504d99c5
MD
4015 return scm_call_1;
4016 case scm_tc7_smob:
4017 if (SCM_SMOB_APPLICABLE_P (proc))
4018 return SCM_SMOB_DESCRIPTOR (proc).apply_1;
4019 else
d0b07b5d 4020 return NULL;
504d99c5
MD
4021 case scm_tc7_asubr:
4022 case scm_tc7_rpsubr:
4023 case scm_tc7_cclo:
4024 case scm_tc7_pws:
4025 return scm_call_1;
4026 default:
d0b07b5d 4027 return NULL; /* not applicable on one arg */
504d99c5
MD
4028 }
4029}
4030
4031static SCM
4032call_subr2_2 (SCM proc, SCM arg1, SCM arg2)
4033{
4034 return SCM_SUBRF (proc) (arg1, arg2);
4035}
4036
9ed24633
MD
4037static SCM
4038call_lsubr2_2 (SCM proc, SCM arg1, SCM arg2)
4039{
4040 return SCM_SUBRF (proc) (arg1, arg2, SCM_EOL);
4041}
4042
504d99c5
MD
4043static SCM
4044call_lsubr_2 (SCM proc, SCM arg1, SCM arg2)
4045{
4046 return SCM_SUBRF (proc) (scm_list_2 (arg1, arg2));
4047}
4048
4049static SCM
4050call_closure_2 (SCM proc, SCM arg1, SCM arg2)
4051{
6a3f13f0
DH
4052 const SCM env = SCM_EXTEND_ENV (SCM_CLOSURE_FORMALS (proc),
4053 scm_list_2 (arg1, arg2),
4054 SCM_ENV (proc));
4055 const SCM result = scm_eval_body (SCM_CLOSURE_BODY (proc), env);
d0b07b5d 4056 return result;
504d99c5
MD
4057}
4058
4059scm_t_trampoline_2
4060scm_trampoline_2 (SCM proc)
4061{
4062 if (SCM_IMP (proc))
d0b07b5d 4063 return NULL;
504d99c5
MD
4064 if (SCM_DEBUGGINGP)
4065 return scm_call_2;
4066 switch (SCM_TYP7 (proc))
4067 {
4068 case scm_tc7_subr_2:
4069 case scm_tc7_subr_2o:
4070 case scm_tc7_rpsubr:
4071 case scm_tc7_asubr:
4072 return call_subr2_2;
9ed24633
MD
4073 case scm_tc7_lsubr_2:
4074 return call_lsubr2_2;
504d99c5
MD
4075 case scm_tc7_lsubr:
4076 return call_lsubr_2;
4077 case scm_tcs_closures:
4078 {
4079 SCM formals = SCM_CLOSURE_FORMALS (proc);
4b612c5b
MD
4080 if (!SCM_NULLP (formals)
4081 && (!SCM_CONSP (formals)
4082 || (!SCM_NULLP (SCM_CDR (formals))
4083 && (!SCM_CONSP (SCM_CDR (formals))
4084 || !SCM_CONSP (SCM_CDDR (formals))))))
504d99c5
MD
4085 return call_closure_2;
4086 else
d0b07b5d 4087 return NULL;
504d99c5
MD
4088 }
4089 case scm_tcs_struct:
4090 if (SCM_OBJ_CLASS_FLAGS (proc) & SCM_CLASSF_PURE_GENERIC)
4091 return scm_call_generic_2;
4092 else if (!SCM_I_OPERATORP (proc))
d0b07b5d 4093 return NULL;
504d99c5
MD
4094 return scm_call_2;
4095 case scm_tc7_smob:
4096 if (SCM_SMOB_APPLICABLE_P (proc))
4097 return SCM_SMOB_DESCRIPTOR (proc).apply_2;
4098 else
d0b07b5d 4099 return NULL;
504d99c5
MD
4100 case scm_tc7_cclo:
4101 case scm_tc7_pws:
4102 return scm_call_2;
4103 default:
d0b07b5d 4104 return NULL; /* not applicable on two args */
504d99c5
MD
4105 }
4106}
4107
d9c393f5
JB
4108/* Typechecking for multi-argument MAP and FOR-EACH.
4109
47c3f06d 4110 Verify that each element of the vector ARGV, except for the first,
d9c393f5 4111 is a proper list whose length is LEN. Attribute errors to WHO,
47c3f06d 4112 and claim that the i'th element of ARGV is WHO's i+2'th argument. */
d9c393f5 4113static inline void
47c3f06d 4114check_map_args (SCM argv,
c014a02e 4115 long len,
47c3f06d
MD
4116 SCM gf,
4117 SCM proc,
4118 SCM args,
4119 const char *who)
d9c393f5 4120{
34d19ef6 4121 SCM const *ve = SCM_VELTS (argv);
c014a02e 4122 long i;
d9c393f5 4123
b5c2579a 4124 for (i = SCM_VECTOR_LENGTH (argv) - 1; i >= 1; i--)
d9c393f5 4125 {
c014a02e 4126 long elt_len = scm_ilength (ve[i]);
d9c393f5
JB
4127
4128 if (elt_len < 0)
47c3f06d
MD
4129 {
4130 if (gf)
4131 scm_apply_generic (gf, scm_cons (proc, args));
4132 else
4133 scm_wrong_type_arg (who, i + 2, ve[i]);
4134 }
d9c393f5
JB
4135
4136 if (elt_len != len)
504d99c5 4137 scm_out_of_range_pos (who, ve[i], SCM_MAKINUM (i + 2));
d9c393f5
JB
4138 }
4139
5d2b97cd 4140 scm_remember_upto_here_1 (argv);
d9c393f5
JB
4141}
4142
4143
47c3f06d 4144SCM_GPROC (s_map, "map", 2, 0, 1, scm_map, g_map);
1cc91f1b 4145
368bf056
MD
4146/* Note: Currently, scm_map applies PROC to the argument list(s)
4147 sequentially, starting with the first element(s). This is used in
8878f040 4148 evalext.c where the Scheme procedure `map-in-order', which guarantees
368bf056 4149 sequential behaviour, is implemented using scm_map. If the
8878f040 4150 behaviour changes, we need to update `map-in-order'.
368bf056
MD
4151*/
4152
0f2d19dd 4153SCM
1bbd0b84 4154scm_map (SCM proc, SCM arg1, SCM args)
af45e3b0 4155#define FUNC_NAME s_map
0f2d19dd 4156{
c014a02e 4157 long i, len;
0f2d19dd
JB
4158 SCM res = SCM_EOL;
4159 SCM *pres = &res;
34d19ef6 4160 SCM const *ve = &args; /* Keep args from being optimized away. */
0f2d19dd 4161
d9c393f5 4162 len = scm_ilength (arg1);
47c3f06d
MD
4163 SCM_GASSERTn (len >= 0,
4164 g_map, scm_cons2 (proc, arg1, args), SCM_ARG2, s_map);
af45e3b0 4165 SCM_VALIDATE_REST_ARGUMENT (args);
0f2d19dd
JB
4166 if (SCM_NULLP (args))
4167 {
504d99c5
MD
4168 scm_t_trampoline_1 call = scm_trampoline_1 (proc);
4169 SCM_GASSERT2 (call, g_map, proc, arg1, SCM_ARG1, s_map);
4170 while (SCM_NIMP (arg1))
4171 {
4172 *pres = scm_list_1 (call (proc, SCM_CAR (arg1)));
4173 pres = SCM_CDRLOC (*pres);
4174 arg1 = SCM_CDR (arg1);
4175 }
4176 return res;
4177 }
4178 if (SCM_NULLP (SCM_CDR (args)))
4179 {
4180 SCM arg2 = SCM_CAR (args);
4181 int len2 = scm_ilength (arg2);
4182 scm_t_trampoline_2 call = scm_trampoline_2 (proc);
4183 SCM_GASSERTn (call,
4184 g_map, scm_cons2 (proc, arg1, args), SCM_ARG1, s_map);
4185 SCM_GASSERTn (len2 >= 0,
4186 g_map, scm_cons2 (proc, arg1, args), SCM_ARG3, s_map);
4187 if (len2 != len)
4188 SCM_OUT_OF_RANGE (3, arg2);
0f2d19dd
JB
4189 while (SCM_NIMP (arg1))
4190 {
504d99c5 4191 *pres = scm_list_1 (call (proc, SCM_CAR (arg1), SCM_CAR (arg2)));
a23afe53 4192 pres = SCM_CDRLOC (*pres);
0f2d19dd 4193 arg1 = SCM_CDR (arg1);
504d99c5 4194 arg2 = SCM_CDR (arg2);
0f2d19dd
JB
4195 }
4196 return res;
4197 }
05b15362
DH
4198 arg1 = scm_cons (arg1, args);
4199 args = scm_vector (arg1);
0f2d19dd 4200 ve = SCM_VELTS (args);
47c3f06d 4201 check_map_args (args, len, g_map, proc, arg1, s_map);
0f2d19dd
JB
4202 while (1)
4203 {
4204 arg1 = SCM_EOL;
b5c2579a 4205 for (i = SCM_VECTOR_LENGTH (args) - 1; i >= 0; i--)
0f2d19dd 4206 {
d9c393f5
JB
4207 if (SCM_IMP (ve[i]))
4208 return res;
0f2d19dd 4209 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
34d19ef6 4210 SCM_VECTOR_SET (args, i, SCM_CDR (ve[i]));
0f2d19dd 4211 }
8ea46249 4212 *pres = scm_list_1 (scm_apply (proc, arg1, SCM_EOL));
a23afe53 4213 pres = SCM_CDRLOC (*pres);
0f2d19dd
JB
4214 }
4215}
af45e3b0 4216#undef FUNC_NAME
0f2d19dd
JB
4217
4218
47c3f06d 4219SCM_GPROC (s_for_each, "for-each", 2, 0, 1, scm_for_each, g_for_each);
1cc91f1b 4220
0f2d19dd 4221SCM
1bbd0b84 4222scm_for_each (SCM proc, SCM arg1, SCM args)
af45e3b0 4223#define FUNC_NAME s_for_each
0f2d19dd 4224{
34d19ef6 4225 SCM const *ve = &args; /* Keep args from being optimized away. */
c014a02e 4226 long i, len;
d9c393f5 4227 len = scm_ilength (arg1);
47c3f06d
MD
4228 SCM_GASSERTn (len >= 0, g_for_each, scm_cons2 (proc, arg1, args),
4229 SCM_ARG2, s_for_each);
af45e3b0 4230 SCM_VALIDATE_REST_ARGUMENT (args);
c96d76b8 4231 if (SCM_NULLP (args))
0f2d19dd 4232 {
504d99c5
MD
4233 scm_t_trampoline_1 call = scm_trampoline_1 (proc);
4234 SCM_GASSERT2 (call, g_for_each, proc, arg1, SCM_ARG1, s_for_each);
4235 while (SCM_NIMP (arg1))
4236 {
4237 call (proc, SCM_CAR (arg1));
4238 arg1 = SCM_CDR (arg1);
4239 }
4240 return SCM_UNSPECIFIED;
4241 }
4242 if (SCM_NULLP (SCM_CDR (args)))
4243 {
4244 SCM arg2 = SCM_CAR (args);
4245 int len2 = scm_ilength (arg2);
4246 scm_t_trampoline_2 call = scm_trampoline_2 (proc);
4247 SCM_GASSERTn (call, g_for_each,
4248 scm_cons2 (proc, arg1, args), SCM_ARG1, s_for_each);
4249 SCM_GASSERTn (len2 >= 0, g_for_each,
4250 scm_cons2 (proc, arg1, args), SCM_ARG3, s_for_each);
4251 if (len2 != len)
4252 SCM_OUT_OF_RANGE (3, arg2);
c96d76b8 4253 while (SCM_NIMP (arg1))
0f2d19dd 4254 {
504d99c5 4255 call (proc, SCM_CAR (arg1), SCM_CAR (arg2));
0f2d19dd 4256 arg1 = SCM_CDR (arg1);
504d99c5 4257 arg2 = SCM_CDR (arg2);
0f2d19dd
JB
4258 }
4259 return SCM_UNSPECIFIED;
4260 }
05b15362
DH
4261 arg1 = scm_cons (arg1, args);
4262 args = scm_vector (arg1);
0f2d19dd 4263 ve = SCM_VELTS (args);
47c3f06d 4264 check_map_args (args, len, g_for_each, proc, arg1, s_for_each);
0f2d19dd
JB
4265 while (1)
4266 {
4267 arg1 = SCM_EOL;
b5c2579a 4268 for (i = SCM_VECTOR_LENGTH (args) - 1; i >= 0; i--)
0f2d19dd 4269 {
c96d76b8
NJ
4270 if (SCM_IMP (ve[i]))
4271 return SCM_UNSPECIFIED;
0f2d19dd 4272 arg1 = scm_cons (SCM_CAR (ve[i]), arg1);
34d19ef6 4273 SCM_VECTOR_SET (args, i, SCM_CDR (ve[i]));
0f2d19dd
JB
4274 }
4275 scm_apply (proc, arg1, SCM_EOL);
4276 }
4277}
af45e3b0 4278#undef FUNC_NAME
0f2d19dd 4279
1cc91f1b 4280
0f2d19dd 4281SCM
6e8d25a6 4282scm_closure (SCM code, SCM env)
0f2d19dd 4283{
16d4699b
MV
4284 SCM z;
4285 SCM closcar = scm_cons (code, SCM_EOL);
228a24ef 4286 z = scm_cell (SCM_UNPACK (closcar) + scm_tc3_closure, (scm_t_bits) env);
16d4699b 4287 scm_remember_upto_here (closcar);
0f2d19dd
JB
4288 return z;
4289}
4290
4291
92c2555f 4292scm_t_bits scm_tc16_promise;
1cc91f1b 4293
0f2d19dd 4294SCM
6e8d25a6 4295scm_makprom (SCM code)
0f2d19dd 4296{
28d52ebb
MD
4297 SCM_RETURN_NEWSMOB2 (scm_tc16_promise,
4298 SCM_UNPACK (code),
4299 scm_make_rec_mutex ());
0f2d19dd
JB
4300}
4301
28d52ebb
MD
4302static size_t
4303promise_free (SCM promise)
4304{
4305 scm_rec_mutex_free (SCM_PROMISE_MUTEX (promise));
4306 return 0;
4307}
1cc91f1b 4308
0f2d19dd 4309static int
e841c3e0 4310promise_print (SCM exp, SCM port, scm_print_state *pstate)
0f2d19dd 4311{
19402679 4312 int writingp = SCM_WRITINGP (pstate);
b7f3516f 4313 scm_puts ("#<promise ", port);
19402679 4314 SCM_SET_WRITINGP (pstate, 1);
28d52ebb 4315 scm_iprin1 (SCM_PROMISE_DATA (exp), port, pstate);
19402679 4316 SCM_SET_WRITINGP (pstate, writingp);
b7f3516f 4317 scm_putc ('>', port);
0f2d19dd
JB
4318 return !0;
4319}
4320
3b3b36dd 4321SCM_DEFINE (scm_force, "force", 1, 0, 0,
28d52ebb 4322 (SCM promise),
67e8151b
MG
4323 "If the promise @var{x} has not been computed yet, compute and\n"
4324 "return @var{x}, otherwise just return the previously computed\n"
4325 "value.")
1bbd0b84 4326#define FUNC_NAME s_scm_force
0f2d19dd 4327{
28d52ebb
MD
4328 SCM_VALIDATE_SMOB (1, promise, promise);
4329 scm_rec_mutex_lock (SCM_PROMISE_MUTEX (promise));
4330 if (!SCM_PROMISE_COMPUTED_P (promise))
0f2d19dd 4331 {
28d52ebb
MD
4332 SCM ans = scm_call_0 (SCM_PROMISE_DATA (promise));
4333 if (!SCM_PROMISE_COMPUTED_P (promise))
0f2d19dd 4334 {
28d52ebb
MD
4335 SCM_SET_PROMISE_DATA (promise, ans);
4336 SCM_SET_PROMISE_COMPUTED (promise);
0f2d19dd
JB
4337 }
4338 }
28d52ebb
MD
4339 scm_rec_mutex_unlock (SCM_PROMISE_MUTEX (promise));
4340 return SCM_PROMISE_DATA (promise);
0f2d19dd 4341}
1bbd0b84 4342#undef FUNC_NAME
0f2d19dd 4343
445f675c 4344
a1ec6916 4345SCM_DEFINE (scm_promise_p, "promise?", 1, 0, 0,
67e8151b 4346 (SCM obj),
b380b885 4347 "Return true if @var{obj} is a promise, i.e. a delayed computation\n"
7a095584 4348 "(@pxref{Delayed evaluation,,,r5rs.info,The Revised^5 Report on Scheme}).")
1bbd0b84 4349#define FUNC_NAME s_scm_promise_p
0f2d19dd 4350{
67e8151b 4351 return SCM_BOOL (SCM_TYP16_PREDICATE (scm_tc16_promise, obj));
0f2d19dd 4352}
1bbd0b84 4353#undef FUNC_NAME
0f2d19dd 4354
445f675c 4355
a1ec6916 4356SCM_DEFINE (scm_cons_source, "cons-source", 3, 0, 0,
1bbd0b84 4357 (SCM xorig, SCM x, SCM y),
11768c04
NJ
4358 "Create and return a new pair whose car and cdr are @var{x} and @var{y}.\n"
4359 "Any source properties associated with @var{xorig} are also associated\n"
4360 "with the new pair.")
1bbd0b84 4361#define FUNC_NAME s_scm_cons_source
26d5b9b4
MD
4362{
4363 SCM p, z;
16d4699b 4364 z = scm_cons (x, y);
26d5b9b4
MD
4365 /* Copy source properties possibly associated with xorig. */
4366 p = scm_whash_lookup (scm_source_whash, xorig);
445f675c 4367 if (!SCM_IMP (p))
26d5b9b4
MD
4368 scm_whash_insert (scm_source_whash, z, p);
4369 return z;
4370}
1bbd0b84 4371#undef FUNC_NAME
26d5b9b4 4372
445f675c 4373
a1ec6916 4374SCM_DEFINE (scm_copy_tree, "copy-tree", 1, 0, 0,
1bbd0b84 4375 (SCM obj),
b380b885
MD
4376 "Recursively copy the data tree that is bound to @var{obj}, and return a\n"
4377 "pointer to the new data structure. @code{copy-tree} recurses down the\n"
4378 "contents of both pairs and vectors (since both cons cells and vector\n"
4379 "cells may point to arbitrary objects), and stops recursing when it hits\n"
4380 "any other object.")
1bbd0b84 4381#define FUNC_NAME s_scm_copy_tree
0f2d19dd
JB
4382{
4383 SCM ans, tl;
26d5b9b4 4384 if (SCM_IMP (obj))
ff467021 4385 return obj;
3910272e
MD
4386 if (SCM_VECTORP (obj))
4387 {
c014a02e 4388 unsigned long i = SCM_VECTOR_LENGTH (obj);
00ffa0e7 4389 ans = scm_c_make_vector (i, SCM_UNSPECIFIED);
3910272e 4390 while (i--)
34d19ef6 4391 SCM_VECTOR_SET (ans, i, scm_copy_tree (SCM_VELTS (obj)[i]));
3910272e
MD
4392 return ans;
4393 }
01f11e02 4394 if (!SCM_CONSP (obj))
0f2d19dd 4395 return obj;
26d5b9b4
MD
4396 ans = tl = scm_cons_source (obj,
4397 scm_copy_tree (SCM_CAR (obj)),
4398 SCM_UNSPECIFIED);
05b15362 4399 for (obj = SCM_CDR (obj); SCM_CONSP (obj); obj = SCM_CDR (obj))
a23afe53
MD
4400 {
4401 SCM_SETCDR (tl, scm_cons (scm_copy_tree (SCM_CAR (obj)),
4402 SCM_UNSPECIFIED));
4403 tl = SCM_CDR (tl);
4404 }
4405 SCM_SETCDR (tl, obj);
0f2d19dd
JB
4406 return ans;
4407}
1bbd0b84 4408#undef FUNC_NAME
0f2d19dd 4409
1cc91f1b 4410
4163eb72
MV
4411/* We have three levels of EVAL here:
4412
4413 - scm_i_eval (exp, env)
4414
4415 evaluates EXP in environment ENV. ENV is a lexical environment
4416 structure as used by the actual tree code evaluator. When ENV is
4417 a top-level environment, then changes to the current module are
a513ead3 4418 tracked by updating ENV so that it continues to be in sync with
4163eb72
MV
4419 the current module.
4420
4421 - scm_primitive_eval (exp)
4422
4423 evaluates EXP in the top-level environment as determined by the
4424 current module. This is done by constructing a suitable
4425 environment and calling scm_i_eval. Thus, changes to the
4426 top-level module are tracked normally.
4427
4428 - scm_eval (exp, mod)
4429
a513ead3 4430 evaluates EXP while MOD is the current module. This is done by
4163eb72
MV
4431 setting the current module to MOD, invoking scm_primitive_eval on
4432 EXP, and then restoring the current module to the value it had
4433 previously. That is, while EXP is evaluated, changes to the
4434 current module are tracked, but these changes do not persist when
4435 scm_eval returns.
4436
4437 For each level of evals, there are two variants, distinguished by a
4438 _x suffix: the ordinary variant does not modify EXP while the _x
4439 variant can destructively modify EXP into something completely
4440 unintelligible. A Scheme data structure passed as EXP to one of the
4441 _x variants should not ever be used again for anything. So when in
4442 doubt, use the ordinary variant.
4443
4444*/
4445
0f2d19dd 4446SCM
68d8be66 4447scm_i_eval_x (SCM exp, SCM env)
0f2d19dd 4448{
68d8be66 4449 return SCM_XEVAL (exp, env);
0f2d19dd
JB
4450}
4451
68d8be66
MD
4452SCM
4453scm_i_eval (SCM exp, SCM env)
4454{
26fb6390 4455 exp = scm_copy_tree (exp);
e37a4fba 4456 return SCM_XEVAL (exp, env);
68d8be66
MD
4457}
4458
4459SCM
4163eb72 4460scm_primitive_eval_x (SCM exp)
0f2d19dd 4461{
a513ead3 4462 SCM env;
bcdab802 4463 SCM transformer = scm_current_module_transformer ();
a513ead3 4464 if (SCM_NIMP (transformer))
fdc28395 4465 exp = scm_call_1 (transformer, exp);
a513ead3 4466 env = scm_top_level_env (scm_current_module_lookup_closure ());
4163eb72 4467 return scm_i_eval_x (exp, env);
0f2d19dd
JB
4468}
4469
4163eb72
MV
4470SCM_DEFINE (scm_primitive_eval, "primitive-eval", 1, 0, 0,
4471 (SCM exp),
2069af38 4472 "Evaluate @var{exp} in the top-level environment specified by\n"
4163eb72
MV
4473 "the current module.")
4474#define FUNC_NAME s_scm_primitive_eval
4475{
a513ead3 4476 SCM env;
bcdab802 4477 SCM transformer = scm_current_module_transformer ();
a513ead3 4478 if (SCM_NIMP (transformer))
fdc28395 4479 exp = scm_call_1 (transformer, exp);
a513ead3 4480 env = scm_top_level_env (scm_current_module_lookup_closure ());
4163eb72
MV
4481 return scm_i_eval (exp, env);
4482}
4483#undef FUNC_NAME
4484
68d8be66
MD
4485/* Eval does not take the second arg optionally. This is intentional
4486 * in order to be R5RS compatible, and to prepare for the new module
4487 * system, where we would like to make the choice of evaluation
4163eb72 4488 * environment explicit. */
549e6ec6 4489
09074dbf
DH
4490static void
4491change_environment (void *data)
4492{
4493 SCM pair = SCM_PACK (data);
4494 SCM new_module = SCM_CAR (pair);
aa767bc5 4495 SCM old_module = scm_current_module ();
09074dbf 4496 SCM_SETCDR (pair, old_module);
aa767bc5 4497 scm_set_current_module (new_module);
09074dbf
DH
4498}
4499
4500
09074dbf
DH
4501static void
4502restore_environment (void *data)
4503{
4504 SCM pair = SCM_PACK (data);
4505 SCM old_module = SCM_CDR (pair);
aa767bc5 4506 SCM new_module = scm_current_module ();
2e9c835d 4507 SCM_SETCAR (pair, new_module);
aa767bc5 4508 scm_set_current_module (old_module);
09074dbf
DH
4509}
4510
4163eb72
MV
4511static SCM
4512inner_eval_x (void *data)
4513{
4514 return scm_primitive_eval_x (SCM_PACK(data));
4515}
4516
4517SCM
4518scm_eval_x (SCM exp, SCM module)
4519#define FUNC_NAME "eval!"
4520{
4521 SCM_VALIDATE_MODULE (2, module);
4522
4523 return scm_internal_dynamic_wind
4524 (change_environment, inner_eval_x, restore_environment,
4525 (void *) SCM_UNPACK (exp),
4526 (void *) SCM_UNPACK (scm_cons (module, SCM_BOOL_F)));
4527}
4528#undef FUNC_NAME
4529
4530static SCM
4531inner_eval (void *data)
4532{
4533 return scm_primitive_eval (SCM_PACK(data));
4534}
09074dbf 4535
68d8be66 4536SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
4163eb72
MV
4537 (SCM exp, SCM module),
4538 "Evaluate @var{exp}, a list representing a Scheme expression,\n"
4539 "in the top-level environment specified by @var{module}.\n"
8f85c0c6 4540 "While @var{exp} is evaluated (using @code{primitive-eval}),\n"
4163eb72
MV
4541 "@var{module} is made the current module. The current module\n"
4542 "is reset to its previous value when @var{eval} returns.")
1bbd0b84 4543#define FUNC_NAME s_scm_eval
0f2d19dd 4544{
4163eb72 4545 SCM_VALIDATE_MODULE (2, module);
09074dbf
DH
4546
4547 return scm_internal_dynamic_wind
4548 (change_environment, inner_eval, restore_environment,
4163eb72
MV
4549 (void *) SCM_UNPACK (exp),
4550 (void *) SCM_UNPACK (scm_cons (module, SCM_BOOL_F)));
0f2d19dd 4551}
1bbd0b84 4552#undef FUNC_NAME
0f2d19dd 4553
6dbd0af5
MD
4554
4555/* At this point, scm_deval and scm_dapply are generated.
4556 */
4557
a44a9715
DH
4558#define DEVAL
4559#include "eval.c"
0f2d19dd 4560
1cc91f1b 4561
0f2d19dd
JB
4562void
4563scm_init_eval ()
0f2d19dd 4564{
33b97402
MD
4565 scm_init_opts (scm_evaluator_traps,
4566 scm_evaluator_trap_table,
4567 SCM_N_EVALUATOR_TRAPS);
4568 scm_init_opts (scm_eval_options_interface,
4569 scm_eval_opts,
4570 SCM_N_EVAL_OPTIONS);
4571
f99c9c28
MD
4572 scm_tc16_promise = scm_make_smob_type ("promise", 0);
4573 scm_set_smob_mark (scm_tc16_promise, scm_markcdr);
28d52ebb 4574 scm_set_smob_free (scm_tc16_promise, promise_free);
e841c3e0 4575 scm_set_smob_print (scm_tc16_promise, promise_print);
b8229a3b 4576
a44a9715
DH
4577 undefineds = scm_list_1 (SCM_UNDEFINED);
4578 SCM_SETCDR (undefineds, undefineds);
4579 scm_permanent_object (undefineds);
7c33806a 4580
a44a9715 4581 scm_listofnull = scm_list_1 (SCM_EOL);
0f2d19dd 4582
a44a9715
DH
4583 f_apply = scm_c_define_subr ("apply", scm_tc7_lsubr_2, scm_apply);
4584 scm_permanent_object (f_apply);
86d31dfe 4585
a0599745 4586#include "libguile/eval.x"
86d31dfe 4587
25eaf21a 4588 scm_add_feature ("delay");
0f2d19dd 4589}
0f2d19dd 4590
6dbd0af5 4591#endif /* !DEVAL */
89e00824
ML
4592
4593/*
4594 Local Variables:
4595 c-file-style: "gnu"
4596 End:
4597*/