eval.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955
  1. /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006,2007,2008,2009,2010,2011
  2. * Free Software Foundation, Inc.
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public License
  6. * as published by the Free Software Foundation; either version 3 of
  7. * the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful, but
  10. * WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  17. * 02110-1301 USA
  18. */
  19. #ifdef HAVE_CONFIG_H
  20. # include <config.h>
  21. #endif
  22. #include <alloca.h>
  23. #include "libguile/__scm.h"
  24. #include "libguile/_scm.h"
  25. #include "libguile/alist.h"
  26. #include "libguile/async.h"
  27. #include "libguile/continuations.h"
  28. #include "libguile/control.h"
  29. #include "libguile/debug.h"
  30. #include "libguile/deprecation.h"
  31. #include "libguile/dynwind.h"
  32. #include "libguile/eq.h"
  33. #include "libguile/expand.h"
  34. #include "libguile/feature.h"
  35. #include "libguile/fluids.h"
  36. #include "libguile/goops.h"
  37. #include "libguile/hash.h"
  38. #include "libguile/hashtab.h"
  39. #include "libguile/list.h"
  40. #include "libguile/macros.h"
  41. #include "libguile/memoize.h"
  42. #include "libguile/modules.h"
  43. #include "libguile/ports.h"
  44. #include "libguile/print.h"
  45. #include "libguile/procprop.h"
  46. #include "libguile/programs.h"
  47. #include "libguile/root.h"
  48. #include "libguile/smob.h"
  49. #include "libguile/srcprop.h"
  50. #include "libguile/stackchk.h"
  51. #include "libguile/strings.h"
  52. #include "libguile/threads.h"
  53. #include "libguile/throw.h"
  54. #include "libguile/validate.h"
  55. #include "libguile/values.h"
  56. #include "libguile/vectors.h"
  57. #include "libguile/vm.h"
  58. #include "libguile/eval.h"
  59. #include "libguile/private-options.h"
  60. /* We have three levels of EVAL here:
  61. - eval (exp, env)
  62. evaluates EXP in environment ENV. ENV is a lexical environment
  63. structure as used by the actual tree code evaluator. When ENV is
  64. a top-level environment, then changes to the current module are
  65. tracked by updating ENV so that it continues to be in sync with
  66. the current module.
  67. - scm_primitive_eval (exp)
  68. evaluates EXP in the top-level environment as determined by the
  69. current module. This is done by constructing a suitable
  70. environment and calling eval. Thus, changes to the
  71. top-level module are tracked normally.
  72. - scm_eval (exp, mod)
  73. evaluates EXP while MOD is the current module. This is done
  74. by setting the current module to MOD_OR_STATE, invoking
  75. scm_primitive_eval on EXP, and then restoring the current module
  76. to the value it had previously. That is, while EXP is evaluated,
  77. changes to the current module (or dynamic state) are tracked,
  78. but these changes do not persist when scm_eval returns.
  79. */
  80. /* Boot closures. We only see these when compiling eval.scm, because once
  81. eval.scm is in the house, closures are standard VM closures.
  82. */
  83. static scm_t_bits scm_tc16_boot_closure;
  84. #define RETURN_BOOT_CLOSURE(code, env) \
  85. SCM_RETURN_NEWSMOB2 (scm_tc16_boot_closure, SCM_UNPACK (code), SCM_UNPACK (env))
  86. #define BOOT_CLOSURE_P(obj) SCM_TYP16_PREDICATE (scm_tc16_boot_closure, (obj))
  87. #define BOOT_CLOSURE_CODE(x) SCM_SMOB_OBJECT (x)
  88. #define BOOT_CLOSURE_ENV(x) SCM_SMOB_OBJECT_2 (x)
  89. #define BOOT_CLOSURE_BODY(x) CAR (BOOT_CLOSURE_CODE (x))
  90. #define BOOT_CLOSURE_NUM_REQUIRED_ARGS(x) SCM_I_INUM (CADR (BOOT_CLOSURE_CODE (x)))
  91. #define BOOT_CLOSURE_IS_FIXED(x) scm_is_null (CDDR (BOOT_CLOSURE_CODE (x)))
  92. /* NB: One may only call the following accessors if the closure is not FIXED. */
  93. #define BOOT_CLOSURE_HAS_REST_ARGS(x) scm_is_true (CADDR (BOOT_CLOSURE_CODE (x)))
  94. #define BOOT_CLOSURE_IS_REST(x) scm_is_null (CDDDR (BOOT_CLOSURE_CODE (x)))
  95. /* NB: One may only call the following accessors if the closure is not REST. */
  96. #define BOOT_CLOSURE_IS_FULL(x) (1)
  97. #define BOOT_CLOSURE_PARSE_FULL(fu_,body,nargs,rest,nopt,kw,inits,alt) \
  98. do { SCM fu = fu_; \
  99. body = CAR (fu); fu = CDR (fu); \
  100. \
  101. rest = kw = alt = SCM_BOOL_F; \
  102. inits = SCM_EOL; \
  103. nopt = 0; \
  104. \
  105. nreq = SCM_I_INUM (CAR (fu)); fu = CDR (fu); \
  106. if (scm_is_pair (fu)) \
  107. { \
  108. rest = CAR (fu); fu = CDR (fu); \
  109. if (scm_is_pair (fu)) \
  110. { \
  111. nopt = SCM_I_INUM (CAR (fu)); fu = CDR (fu); \
  112. kw = CAR (fu); fu = CDR (fu); \
  113. inits = CAR (fu); fu = CDR (fu); \
  114. alt = CAR (fu); \
  115. } \
  116. } \
  117. } while (0)
  118. static void prepare_boot_closure_env_for_apply (SCM proc, SCM args,
  119. SCM *out_body, SCM *out_env);
  120. static void prepare_boot_closure_env_for_eval (SCM proc, unsigned int argc,
  121. SCM exps, SCM *out_body,
  122. SCM *inout_env);
  123. #define CAR(x) SCM_CAR(x)
  124. #define CDR(x) SCM_CDR(x)
  125. #define CAAR(x) SCM_CAAR(x)
  126. #define CADR(x) SCM_CADR(x)
  127. #define CDAR(x) SCM_CDAR(x)
  128. #define CDDR(x) SCM_CDDR(x)
  129. #define CADDR(x) SCM_CADDR(x)
  130. #define CDDDR(x) SCM_CDDDR(x)
  131. SCM_SYMBOL (scm_unbound_variable_key, "unbound-variable");
  132. static void error_used_before_defined (void)
  133. {
  134. scm_error (scm_unbound_variable_key, NULL,
  135. "Variable used before given a value", SCM_EOL, SCM_BOOL_F);
  136. }
  137. static void error_invalid_keyword (SCM proc)
  138. {
  139. scm_error_scm (scm_from_latin1_symbol ("keyword-argument-error"), proc,
  140. scm_from_locale_string ("Invalid keyword"), SCM_EOL,
  141. SCM_BOOL_F);
  142. }
  143. static void error_unrecognized_keyword (SCM proc)
  144. {
  145. scm_error_scm (scm_from_latin1_symbol ("keyword-argument-error"), proc,
  146. scm_from_locale_string ("Unrecognized keyword"), SCM_EOL,
  147. SCM_BOOL_F);
  148. }
  149. /* Multiple values truncation. */
  150. static SCM
  151. truncate_values (SCM x)
  152. {
  153. if (SCM_LIKELY (!SCM_VALUESP (x)))
  154. return x;
  155. else
  156. {
  157. SCM l = scm_struct_ref (x, SCM_INUM0);
  158. if (SCM_LIKELY (scm_is_pair (l)))
  159. return scm_car (l);
  160. else
  161. {
  162. scm_ithrow (scm_from_latin1_symbol ("vm-run"),
  163. scm_list_3 (scm_from_latin1_symbol ("vm-run"),
  164. scm_from_locale_string
  165. ("Too few values returned to continuation"),
  166. SCM_EOL),
  167. 1);
  168. /* Not reached. */
  169. return SCM_BOOL_F;
  170. }
  171. }
  172. }
  173. #define EVAL1(x, env) (truncate_values (eval ((x), (env))))
  174. /* the environment:
  175. (VAL ... . MOD)
  176. If MOD is #f, it means the environment was captured before modules were
  177. booted.
  178. If MOD is the literal value '(), we are evaluating at the top level, and so
  179. should track changes to the current module. You have to be careful in this
  180. case, because further lexical contours should capture the current module.
  181. */
  182. #define CAPTURE_ENV(env) \
  183. (scm_is_null (env) ? scm_current_module () : \
  184. (scm_is_false (env) ? scm_the_root_module () : env))
  185. static SCM
  186. eval (SCM x, SCM env)
  187. {
  188. SCM mx;
  189. SCM proc = SCM_UNDEFINED, args = SCM_EOL;
  190. unsigned int argc;
  191. loop:
  192. SCM_TICK;
  193. if (!SCM_MEMOIZED_P (x))
  194. abort ();
  195. mx = SCM_MEMOIZED_ARGS (x);
  196. switch (SCM_MEMOIZED_TAG (x))
  197. {
  198. case SCM_M_BEGIN:
  199. for (; !scm_is_null (CDR (mx)); mx = CDR (mx))
  200. eval (CAR (mx), env);
  201. x = CAR (mx);
  202. goto loop;
  203. case SCM_M_IF:
  204. if (scm_is_true (EVAL1 (CAR (mx), env)))
  205. x = CADR (mx);
  206. else
  207. x = CDDR (mx);
  208. goto loop;
  209. case SCM_M_LET:
  210. {
  211. SCM inits = CAR (mx);
  212. SCM new_env = CAPTURE_ENV (env);
  213. for (; scm_is_pair (inits); inits = CDR (inits))
  214. new_env = scm_cons (EVAL1 (CAR (inits), env),
  215. new_env);
  216. env = new_env;
  217. x = CDR (mx);
  218. goto loop;
  219. }
  220. case SCM_M_LAMBDA:
  221. RETURN_BOOT_CLOSURE (mx, CAPTURE_ENV (env));
  222. case SCM_M_QUOTE:
  223. return mx;
  224. case SCM_M_DEFINE:
  225. scm_define (CAR (mx), EVAL1 (CDR (mx), env));
  226. return SCM_UNSPECIFIED;
  227. case SCM_M_DYNWIND:
  228. {
  229. SCM in, out, res, old_winds;
  230. in = EVAL1 (CAR (mx), env);
  231. out = EVAL1 (CDDR (mx), env);
  232. scm_call_0 (in);
  233. old_winds = scm_i_dynwinds ();
  234. scm_i_set_dynwinds (scm_acons (in, out, old_winds));
  235. res = eval (CADR (mx), env);
  236. scm_i_set_dynwinds (old_winds);
  237. scm_call_0 (out);
  238. return res;
  239. }
  240. case SCM_M_WITH_FLUIDS:
  241. {
  242. long i, len;
  243. SCM *fluidv, *valuesv, walk, wf, res;
  244. len = scm_ilength (CAR (mx));
  245. fluidv = alloca (sizeof (SCM)*len);
  246. for (i = 0, walk = CAR (mx); i < len; i++, walk = CDR (walk))
  247. fluidv[i] = EVAL1 (CAR (walk), env);
  248. valuesv = alloca (sizeof (SCM)*len);
  249. for (i = 0, walk = CADR (mx); i < len; i++, walk = CDR (walk))
  250. valuesv[i] = EVAL1 (CAR (walk), env);
  251. wf = scm_i_make_with_fluids (len, fluidv, valuesv);
  252. scm_i_swap_with_fluids (wf, SCM_I_CURRENT_THREAD->dynamic_state);
  253. scm_i_set_dynwinds (scm_cons (wf, scm_i_dynwinds ()));
  254. res = eval (CDDR (mx), env);
  255. scm_i_swap_with_fluids (wf, SCM_I_CURRENT_THREAD->dynamic_state);
  256. scm_i_set_dynwinds (CDR (scm_i_dynwinds ()));
  257. return res;
  258. }
  259. case SCM_M_APPLY:
  260. /* Evaluate the procedure to be applied. */
  261. proc = EVAL1 (CAR (mx), env);
  262. /* Evaluate the argument holding the list of arguments */
  263. args = EVAL1 (CADR (mx), env);
  264. apply_proc:
  265. /* Go here to tail-apply a procedure. PROC is the procedure and
  266. * ARGS is the list of arguments. */
  267. if (BOOT_CLOSURE_P (proc))
  268. {
  269. prepare_boot_closure_env_for_apply (proc, args, &x, &env);
  270. goto loop;
  271. }
  272. else
  273. return scm_call_with_vm (scm_the_vm (), proc, args);
  274. case SCM_M_CALL:
  275. /* Evaluate the procedure to be applied. */
  276. proc = EVAL1 (CAR (mx), env);
  277. argc = SCM_I_INUM (CADR (mx));
  278. mx = CDDR (mx);
  279. if (BOOT_CLOSURE_P (proc))
  280. {
  281. prepare_boot_closure_env_for_eval (proc, argc, mx, &x, &env);
  282. goto loop;
  283. }
  284. else
  285. {
  286. SCM *argv;
  287. unsigned int i;
  288. argv = alloca (argc * sizeof (SCM));
  289. for (i = 0; i < argc; i++, mx = CDR (mx))
  290. argv[i] = EVAL1 (CAR (mx), env);
  291. return scm_c_vm_run (scm_the_vm (), proc, argv, argc);
  292. }
  293. case SCM_M_CONT:
  294. return scm_i_call_with_current_continuation (EVAL1 (mx, env));
  295. case SCM_M_CALL_WITH_VALUES:
  296. {
  297. SCM producer;
  298. SCM v;
  299. producer = EVAL1 (CAR (mx), env);
  300. /* `proc' is the consumer. */
  301. proc = EVAL1 (CDR (mx), env);
  302. v = scm_call_with_vm (scm_the_vm (), producer, SCM_EOL);
  303. if (SCM_VALUESP (v))
  304. args = scm_struct_ref (v, SCM_INUM0);
  305. else
  306. args = scm_list_1 (v);
  307. goto apply_proc;
  308. }
  309. case SCM_M_LEXICAL_REF:
  310. {
  311. int n;
  312. SCM ret;
  313. for (n = SCM_I_INUM (mx); n; n--)
  314. env = CDR (env);
  315. ret = CAR (env);
  316. if (SCM_UNLIKELY (SCM_UNBNDP (ret)))
  317. /* we don't know what variable, though, because we don't have its
  318. name */
  319. error_used_before_defined ();
  320. return ret;
  321. }
  322. case SCM_M_LEXICAL_SET:
  323. {
  324. int n;
  325. SCM val = EVAL1 (CDR (mx), env);
  326. for (n = SCM_I_INUM (CAR (mx)); n; n--)
  327. env = CDR (env);
  328. SCM_SETCAR (env, val);
  329. return SCM_UNSPECIFIED;
  330. }
  331. case SCM_M_TOPLEVEL_REF:
  332. if (SCM_VARIABLEP (mx))
  333. return SCM_VARIABLE_REF (mx);
  334. else
  335. {
  336. while (scm_is_pair (env))
  337. env = CDR (env);
  338. return SCM_VARIABLE_REF
  339. (scm_memoize_variable_access_x (x, CAPTURE_ENV (env)));
  340. }
  341. case SCM_M_TOPLEVEL_SET:
  342. {
  343. SCM var = CAR (mx);
  344. SCM val = EVAL1 (CDR (mx), env);
  345. if (SCM_VARIABLEP (var))
  346. {
  347. SCM_VARIABLE_SET (var, val);
  348. return SCM_UNSPECIFIED;
  349. }
  350. else
  351. {
  352. while (scm_is_pair (env))
  353. env = CDR (env);
  354. SCM_VARIABLE_SET
  355. (scm_memoize_variable_access_x (x, CAPTURE_ENV (env)),
  356. val);
  357. return SCM_UNSPECIFIED;
  358. }
  359. }
  360. case SCM_M_MODULE_REF:
  361. if (SCM_VARIABLEP (mx))
  362. return SCM_VARIABLE_REF (mx);
  363. else
  364. return SCM_VARIABLE_REF
  365. (scm_memoize_variable_access_x (x, SCM_BOOL_F));
  366. case SCM_M_MODULE_SET:
  367. if (SCM_VARIABLEP (CDR (mx)))
  368. {
  369. SCM_VARIABLE_SET (CDR (mx), EVAL1 (CAR (mx), env));
  370. return SCM_UNSPECIFIED;
  371. }
  372. else
  373. {
  374. SCM_VARIABLE_SET
  375. (scm_memoize_variable_access_x (x, SCM_BOOL_F),
  376. EVAL1 (CAR (mx), env));
  377. return SCM_UNSPECIFIED;
  378. }
  379. case SCM_M_PROMPT:
  380. {
  381. SCM vm, res;
  382. /* We need the prompt and handler values after a longjmp case,
  383. so make sure they are volatile. */
  384. volatile SCM handler, prompt;
  385. vm = scm_the_vm ();
  386. prompt = scm_c_make_prompt (EVAL1 (CAR (mx), env),
  387. SCM_VM_DATA (vm)->fp,
  388. SCM_VM_DATA (vm)->sp, SCM_VM_DATA (vm)->ip,
  389. 0, -1, scm_i_dynwinds ());
  390. handler = EVAL1 (CDDR (mx), env);
  391. scm_i_set_dynwinds (scm_cons (prompt, scm_i_dynwinds ()));
  392. if (SCM_PROMPT_SETJMP (prompt))
  393. {
  394. /* The prompt exited nonlocally. */
  395. proc = handler;
  396. args = scm_i_prompt_pop_abort_args_x (scm_the_vm ());
  397. goto apply_proc;
  398. }
  399. res = eval (CADR (mx), env);
  400. scm_i_set_dynwinds (CDR (scm_i_dynwinds ()));
  401. return res;
  402. }
  403. default:
  404. abort ();
  405. }
  406. }
  407. /* Simple procedure calls
  408. */
  409. SCM
  410. scm_call_0 (SCM proc)
  411. {
  412. return scm_c_vm_run (scm_the_vm (), proc, NULL, 0);
  413. }
  414. SCM
  415. scm_call_1 (SCM proc, SCM arg1)
  416. {
  417. return scm_c_vm_run (scm_the_vm (), proc, &arg1, 1);
  418. }
  419. SCM
  420. scm_call_2 (SCM proc, SCM arg1, SCM arg2)
  421. {
  422. SCM args[] = { arg1, arg2 };
  423. return scm_c_vm_run (scm_the_vm (), proc, args, 2);
  424. }
  425. SCM
  426. scm_call_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3)
  427. {
  428. SCM args[] = { arg1, arg2, arg3 };
  429. return scm_c_vm_run (scm_the_vm (), proc, args, 3);
  430. }
  431. SCM
  432. scm_call_4 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4)
  433. {
  434. SCM args[] = { arg1, arg2, arg3, arg4 };
  435. return scm_c_vm_run (scm_the_vm (), proc, args, 4);
  436. }
  437. SCM
  438. scm_call_5 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5)
  439. {
  440. SCM args[] = { arg1, arg2, arg3, arg4, arg5 };
  441. return scm_c_vm_run (scm_the_vm (), proc, args, 5);
  442. }
  443. SCM
  444. scm_call_6 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM arg4, SCM arg5,
  445. SCM arg6)
  446. {
  447. SCM args[] = { arg1, arg2, arg3, arg4, arg5, arg6 };
  448. return scm_c_vm_run (scm_the_vm (), proc, args, 6);
  449. }
  450. SCM
  451. scm_call_n (SCM proc, SCM *argv, size_t nargs)
  452. {
  453. return scm_c_vm_run (scm_the_vm (), proc, argv, nargs);
  454. }
  455. /* Simple procedure applies
  456. */
  457. SCM
  458. scm_apply_0 (SCM proc, SCM args)
  459. {
  460. return scm_apply (proc, args, SCM_EOL);
  461. }
  462. SCM
  463. scm_apply_1 (SCM proc, SCM arg1, SCM args)
  464. {
  465. return scm_apply (proc, scm_cons (arg1, args), SCM_EOL);
  466. }
  467. SCM
  468. scm_apply_2 (SCM proc, SCM arg1, SCM arg2, SCM args)
  469. {
  470. return scm_apply (proc, scm_cons2 (arg1, arg2, args), SCM_EOL);
  471. }
  472. SCM
  473. scm_apply_3 (SCM proc, SCM arg1, SCM arg2, SCM arg3, SCM args)
  474. {
  475. return scm_apply (proc, scm_cons (arg1, scm_cons2 (arg2, arg3, args)),
  476. SCM_EOL);
  477. }
  478. /* This code processes the arguments to apply:
  479. (apply PROC ARG1 ... ARGS)
  480. Given a list (ARG1 ... ARGS), this function conses the ARG1
  481. ... arguments onto the front of ARGS, and returns the resulting
  482. list. Note that ARGS is a list; thus, the argument to this
  483. function is a list whose last element is a list.
  484. Apply calls this function, and applies PROC to the elements of the
  485. result. apply:nconc2last takes care of building the list of
  486. arguments, given (ARG1 ... ARGS).
  487. Rather than do new consing, apply:nconc2last destroys its argument.
  488. On that topic, this code came into my care with the following
  489. beautifully cryptic comment on that topic: "This will only screw
  490. you if you do (scm_apply scm_apply '( ... ))" If you know what
  491. they're referring to, send me a patch to this comment. */
  492. SCM_DEFINE (scm_nconc2last, "apply:nconc2last", 1, 0, 0,
  493. (SCM lst),
  494. "Given a list (@var{arg1} @dots{} @var{args}), this function\n"
  495. "conses the @var{arg1} @dots{} arguments onto the front of\n"
  496. "@var{args}, and returns the resulting list. Note that\n"
  497. "@var{args} is a list; thus, the argument to this function is\n"
  498. "a list whose last element is a list.\n"
  499. "Note: Rather than do new consing, @code{apply:nconc2last}\n"
  500. "destroys its argument, so use with care.")
  501. #define FUNC_NAME s_scm_nconc2last
  502. {
  503. SCM *lloc;
  504. SCM_VALIDATE_NONEMPTYLIST (1, lst);
  505. lloc = &lst;
  506. while (!scm_is_null (SCM_CDR (*lloc)))
  507. lloc = SCM_CDRLOC (*lloc);
  508. SCM_ASSERT (scm_ilength (SCM_CAR (*lloc)) >= 0, lst, SCM_ARG1, FUNC_NAME);
  509. *lloc = SCM_CAR (*lloc);
  510. return lst;
  511. }
  512. #undef FUNC_NAME
  513. SCM
  514. scm_map (SCM proc, SCM arg1, SCM args)
  515. {
  516. static SCM var = SCM_BOOL_F;
  517. if (scm_is_false (var))
  518. var = scm_private_variable (scm_the_root_module (),
  519. scm_from_latin1_symbol ("map"));
  520. return scm_apply (scm_variable_ref (var),
  521. scm_cons (proc, scm_cons (arg1, args)), SCM_EOL);
  522. }
  523. SCM
  524. scm_for_each (SCM proc, SCM arg1, SCM args)
  525. {
  526. static SCM var = SCM_BOOL_F;
  527. if (scm_is_false (var))
  528. var = scm_private_variable (scm_the_root_module (),
  529. scm_from_latin1_symbol ("for-each"));
  530. return scm_apply (scm_variable_ref (var),
  531. scm_cons (proc, scm_cons (arg1, args)), SCM_EOL);
  532. }
  533. static SCM
  534. scm_c_primitive_eval (SCM exp)
  535. {
  536. if (!SCM_EXPANDED_P (exp))
  537. exp = scm_call_1 (scm_current_module_transformer (), exp);
  538. return eval (scm_memoize_expression (exp), SCM_EOL);
  539. }
  540. static SCM var_primitive_eval;
  541. SCM
  542. scm_primitive_eval (SCM exp)
  543. {
  544. return scm_c_vm_run (scm_the_vm (), scm_variable_ref (var_primitive_eval),
  545. &exp, 1);
  546. }
  547. /* Eval does not take the second arg optionally. This is intentional
  548. * in order to be R5RS compatible, and to prepare for the new module
  549. * system, where we would like to make the choice of evaluation
  550. * environment explicit. */
  551. SCM_DEFINE (scm_eval, "eval", 2, 0, 0,
  552. (SCM exp, SCM module_or_state),
  553. "Evaluate @var{exp}, a list representing a Scheme expression,\n"
  554. "in the top-level environment specified by\n"
  555. "@var{module_or_state}.\n"
  556. "While @var{exp} is evaluated (using @code{primitive-eval}),\n"
  557. "@var{module_or_state} is made the current module when\n"
  558. "it is a module, or the current dynamic state when it is\n"
  559. "a dynamic state."
  560. "Example: (eval '(+ 1 2) (interaction-environment))")
  561. #define FUNC_NAME s_scm_eval
  562. {
  563. SCM res;
  564. scm_dynwind_begin (SCM_F_DYNWIND_REWINDABLE);
  565. if (scm_is_dynamic_state (module_or_state))
  566. scm_dynwind_current_dynamic_state (module_or_state);
  567. else if (scm_module_system_booted_p)
  568. {
  569. SCM_VALIDATE_MODULE (2, module_or_state);
  570. scm_dynwind_current_module (module_or_state);
  571. }
  572. /* otherwise if the module system isn't booted, ignore the module arg */
  573. res = scm_primitive_eval (exp);
  574. scm_dynwind_end ();
  575. return res;
  576. }
  577. #undef FUNC_NAME
  578. static SCM f_apply;
  579. /* Apply a function to a list of arguments.
  580. This function is exported to the Scheme level as taking two
  581. required arguments and a tail argument, as if it were:
  582. (lambda (proc arg1 . args) ...)
  583. Thus, if you just have a list of arguments to pass to a procedure,
  584. pass the list as ARG1, and '() for ARGS. If you have some fixed
  585. args, pass the first as ARG1, then cons any remaining fixed args
  586. onto the front of your argument list, and pass that as ARGS. */
  587. SCM
  588. scm_apply (SCM proc, SCM arg1, SCM args)
  589. {
  590. /* Fix things up so that args contains all args. */
  591. if (scm_is_null (args))
  592. args = arg1;
  593. else
  594. args = scm_cons_star (arg1, args);
  595. return scm_call_with_vm (scm_the_vm (), proc, args);
  596. }
  597. static void
  598. prepare_boot_closure_env_for_apply (SCM proc, SCM args,
  599. SCM *out_body, SCM *out_env)
  600. {
  601. int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (proc);
  602. SCM env = BOOT_CLOSURE_ENV (proc);
  603. if (BOOT_CLOSURE_IS_FIXED (proc)
  604. || (BOOT_CLOSURE_IS_REST (proc)
  605. && !BOOT_CLOSURE_HAS_REST_ARGS (proc)))
  606. {
  607. if (SCM_UNLIKELY (scm_ilength (args) != nreq))
  608. scm_wrong_num_args (proc);
  609. for (; scm_is_pair (args); args = CDR (args))
  610. env = scm_cons (CAR (args), env);
  611. *out_body = BOOT_CLOSURE_BODY (proc);
  612. *out_env = env;
  613. }
  614. else if (BOOT_CLOSURE_IS_REST (proc))
  615. {
  616. if (SCM_UNLIKELY (scm_ilength (args) < nreq))
  617. scm_wrong_num_args (proc);
  618. for (; nreq; nreq--, args = CDR (args))
  619. env = scm_cons (CAR (args), env);
  620. env = scm_cons (args, env);
  621. *out_body = BOOT_CLOSURE_BODY (proc);
  622. *out_env = env;
  623. }
  624. else
  625. {
  626. int i, argc, nreq, nopt;
  627. SCM body, rest, kw, inits, alt;
  628. SCM mx = BOOT_CLOSURE_CODE (proc);
  629. loop:
  630. BOOT_CLOSURE_PARSE_FULL (mx, body, nargs, rest, nopt, kw, inits, alt);
  631. argc = scm_ilength (args);
  632. if (argc < nreq)
  633. {
  634. if (scm_is_true (alt))
  635. {
  636. mx = alt;
  637. goto loop;
  638. }
  639. else
  640. scm_wrong_num_args (proc);
  641. }
  642. if (scm_is_false (kw) && argc > nreq + nopt && scm_is_false (rest))
  643. {
  644. if (scm_is_true (alt))
  645. {
  646. mx = alt;
  647. goto loop;
  648. }
  649. else
  650. scm_wrong_num_args (proc);
  651. }
  652. for (i = 0; i < nreq; i++, args = CDR (args))
  653. env = scm_cons (CAR (args), env);
  654. if (scm_is_false (kw))
  655. {
  656. /* Optional args (possibly), but no keyword args. */
  657. for (; i < argc && i < nreq + nopt;
  658. i++, args = CDR (args))
  659. {
  660. env = scm_cons (CAR (args), env);
  661. inits = CDR (inits);
  662. }
  663. for (; i < nreq + nopt; i++, inits = CDR (inits))
  664. env = scm_cons (EVAL1 (CAR (inits), env), env);
  665. if (scm_is_true (rest))
  666. env = scm_cons (args, env);
  667. }
  668. else
  669. {
  670. SCM aok;
  671. aok = CAR (kw);
  672. kw = CDR (kw);
  673. /* Keyword args. As before, but stop at the first keyword. */
  674. for (; i < argc && i < nreq + nopt && !scm_is_keyword (CAR (args));
  675. i++, args = CDR (args), inits = CDR (inits))
  676. env = scm_cons (CAR (args), env);
  677. for (; i < nreq + nopt; i++, inits = CDR (inits))
  678. env = scm_cons (EVAL1 (CAR (inits), env), env);
  679. if (scm_is_true (rest))
  680. {
  681. env = scm_cons (args, env);
  682. i++;
  683. }
  684. /* Now fill in env with unbound values, limn the rest of the args for
  685. keywords, and fill in unbound values with their inits. */
  686. {
  687. int imax = i - 1;
  688. int kw_start_idx = i;
  689. SCM walk, k, v;
  690. for (walk = kw; scm_is_pair (walk); walk = CDR (walk))
  691. if (SCM_I_INUM (CDAR (walk)) > imax)
  692. imax = SCM_I_INUM (CDAR (walk));
  693. for (; i <= imax; i++)
  694. env = scm_cons (SCM_UNDEFINED, env);
  695. if (scm_is_pair (args) && scm_is_pair (CDR (args)))
  696. for (; scm_is_pair (args) && scm_is_pair (CDR (args));
  697. args = CDR (args))
  698. {
  699. k = CAR (args); v = CADR (args);
  700. if (!scm_is_keyword (k))
  701. {
  702. if (scm_is_true (rest))
  703. continue;
  704. else
  705. break;
  706. }
  707. for (walk = kw; scm_is_pair (walk); walk = CDR (walk))
  708. if (scm_is_eq (k, CAAR (walk)))
  709. {
  710. /* Well... ok, list-set! isn't the nicest interface, but
  711. hey. */
  712. int iset = imax - SCM_I_INUM (CDAR (walk));
  713. scm_list_set_x (env, SCM_I_MAKINUM (iset), v);
  714. args = CDR (args);
  715. break;
  716. }
  717. if (scm_is_null (walk) && scm_is_false (aok))
  718. error_unrecognized_keyword (proc);
  719. }
  720. if (scm_is_pair (args) && scm_is_false (rest))
  721. error_invalid_keyword (proc);
  722. /* Now fill in unbound values, evaluating init expressions in their
  723. appropriate environment. */
  724. for (i = imax - kw_start_idx; scm_is_pair (inits); i--, inits = CDR (inits))
  725. {
  726. SCM tail = scm_list_tail (env, SCM_I_MAKINUM (i));
  727. if (SCM_UNBNDP (CAR (tail)))
  728. SCM_SETCAR (tail, EVAL1 (CAR (inits), CDR (tail)));
  729. }
  730. }
  731. }
  732. *out_body = body;
  733. *out_env = env;
  734. }
  735. }
  736. static void
  737. prepare_boot_closure_env_for_eval (SCM proc, unsigned int argc,
  738. SCM exps, SCM *out_body, SCM *inout_env)
  739. {
  740. int nreq = BOOT_CLOSURE_NUM_REQUIRED_ARGS (proc);
  741. SCM new_env = BOOT_CLOSURE_ENV (proc);
  742. if (BOOT_CLOSURE_IS_FIXED (proc)
  743. || (BOOT_CLOSURE_IS_REST (proc)
  744. && !BOOT_CLOSURE_HAS_REST_ARGS (proc)))
  745. {
  746. for (; scm_is_pair (exps); exps = CDR (exps), nreq--)
  747. new_env = scm_cons (EVAL1 (CAR (exps), *inout_env),
  748. new_env);
  749. if (SCM_UNLIKELY (nreq != 0))
  750. scm_wrong_num_args (proc);
  751. *out_body = BOOT_CLOSURE_BODY (proc);
  752. *inout_env = new_env;
  753. }
  754. else if (BOOT_CLOSURE_IS_REST (proc))
  755. {
  756. if (SCM_UNLIKELY (argc < nreq))
  757. scm_wrong_num_args (proc);
  758. for (; nreq; nreq--, exps = CDR (exps))
  759. new_env = scm_cons (EVAL1 (CAR (exps), *inout_env),
  760. new_env);
  761. {
  762. SCM rest = SCM_EOL;
  763. for (; scm_is_pair (exps); exps = CDR (exps))
  764. rest = scm_cons (EVAL1 (CAR (exps), *inout_env), rest);
  765. new_env = scm_cons (scm_reverse (rest),
  766. new_env);
  767. }
  768. *out_body = BOOT_CLOSURE_BODY (proc);
  769. *inout_env = new_env;
  770. }
  771. else
  772. {
  773. SCM args = SCM_EOL;
  774. for (; scm_is_pair (exps); exps = CDR (exps))
  775. args = scm_cons (EVAL1 (CAR (exps), *inout_env), args);
  776. args = scm_reverse_x (args, SCM_UNDEFINED);
  777. prepare_boot_closure_env_for_apply (proc, args, out_body, inout_env);
  778. }
  779. }
  780. static SCM
  781. boot_closure_apply (SCM closure, SCM args)
  782. {
  783. SCM body, env;
  784. prepare_boot_closure_env_for_apply (closure, args, &body, &env);
  785. return eval (body, env);
  786. }
  787. static int
  788. boot_closure_print (SCM closure, SCM port, scm_print_state *pstate)
  789. {
  790. SCM args;
  791. scm_puts ("#<boot-closure ", port);
  792. scm_uintprint ((scm_t_bits)SCM2PTR (closure), 16, port);
  793. scm_putc (' ', port);
  794. args = scm_make_list (scm_from_int (BOOT_CLOSURE_NUM_REQUIRED_ARGS (closure)),
  795. scm_from_latin1_symbol ("_"));
  796. if (!BOOT_CLOSURE_IS_FIXED (closure) && BOOT_CLOSURE_HAS_REST_ARGS (closure))
  797. args = scm_cons_star (scm_from_latin1_symbol ("_"), args);
  798. /* FIXME: optionals and rests */
  799. scm_display (args, port);
  800. scm_putc ('>', port);
  801. return 1;
  802. }
  803. void
  804. scm_init_eval ()
  805. {
  806. SCM primitive_eval;
  807. f_apply = scm_c_define_gsubr ("apply", 2, 0, 1, scm_apply);
  808. scm_tc16_boot_closure = scm_make_smob_type ("boot-closure", 0);
  809. scm_set_smob_apply (scm_tc16_boot_closure, boot_closure_apply, 0, 0, 1);
  810. scm_set_smob_print (scm_tc16_boot_closure, boot_closure_print);
  811. primitive_eval = scm_c_make_gsubr ("primitive-eval", 1, 0, 0,
  812. scm_c_primitive_eval);
  813. var_primitive_eval = scm_define (SCM_SUBR_NAME (primitive_eval),
  814. primitive_eval);
  815. #include "libguile/eval.x"
  816. }
  817. /*
  818. Local Variables:
  819. c-file-style: "gnu"
  820. End:
  821. */