eval3.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300
  1. /* eval3.c Copyright (C) 1991-96 Codemist Ltd */
  2. /*
  3. * Interpreter (part 3).
  4. * Implementations of special forms (interpreted versions).
  5. *
  6. */
  7. /* Signature: 0c8cf0ed 07-Mar-2000 */
  8. #include <stdarg.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #ifdef __WATCOMC__
  12. #include <float.h>
  13. #endif
  14. #include "machine.h"
  15. #include "tags.h"
  16. #include "cslerror.h"
  17. #include "externs.h"
  18. #include "arith.h"
  19. #include "entries.h"
  20. #ifdef TIMEOUT
  21. #include "timeout.h"
  22. #endif
  23. #ifndef COMMON
  24. static Lisp_Object plus_fn(Lisp_Object args, Lisp_Object env)
  25. {
  26. Lisp_Object nil = C_nil;
  27. Lisp_Object r;
  28. if (!consp(args)) return fixnum_of_int(0); /* (plus) => 0 */
  29. stackcheck2(0, args, env);
  30. push2(args, env);
  31. r = qcar(args);
  32. r = eval(r, env);
  33. pop2(env, args);
  34. errexit();
  35. args = qcdr(args);
  36. while (consp(args))
  37. { Lisp_Object w;
  38. push3(env, args, r);
  39. w = qcar(args);
  40. w = eval(w, env);
  41. pop(r);
  42. errexitn(2);
  43. if (is_fixnum(r) && is_fixnum(w))
  44. { int32 c = int_of_fixnum(r) + int_of_fixnum(w);
  45. int32 w1 = c & fix_mask;
  46. if (w1 == 0 || w1 == fix_mask) r = fixnum_of_int(c);
  47. else r = plus2(r, w);
  48. }
  49. else r = plus2(r, w);
  50. errexitn(2);
  51. pop2(args, env);
  52. args = qcdr(args);
  53. }
  54. return onevalue(r);
  55. }
  56. static Lisp_Object times_fn(Lisp_Object args, Lisp_Object env)
  57. {
  58. Lisp_Object nil = C_nil;
  59. Lisp_Object r;
  60. if (!consp(args)) return fixnum_of_int(1); /* (times) => 1 */
  61. stackcheck2(0, args, env);
  62. push2(args, env);
  63. r = qcar(args);
  64. r = eval(r, env);
  65. pop2(env, args);
  66. errexit();
  67. args = qcdr(args);
  68. while (consp(args))
  69. { Lisp_Object w;
  70. push3(env, args, r);
  71. w = qcar(args);
  72. w = eval(w, env);
  73. pop(r);
  74. errexitn(2);
  75. r = times2(r, w);
  76. pop2(args, env);
  77. errexit();
  78. args = qcdr(args);
  79. }
  80. return onevalue(r);
  81. }
  82. static Lisp_Object list_fn(Lisp_Object args, Lisp_Object env)
  83. {
  84. Lisp_Object nil = C_nil;
  85. Lisp_Object w1, w2, w3, r = nil;
  86. /*
  87. * I am going to write out the cases of list with 0, 1, 2 or 3
  88. * args specially here, since I expect them to be the more common ones
  89. * and I am generally jumpy about performance. It seems a bit nasty
  90. * to get to an interpreted call to list anyway.
  91. */
  92. if (!consp(args)) return onevalue(nil); /* (list) */
  93. w1 = qcar(args); args = qcdr(args);
  94. if (!consp(args)) /* (list w1) */
  95. { w1 = eval(w1, env);
  96. errexit();
  97. w1 = ncons(w1);
  98. errexit();
  99. return onevalue(w1);
  100. }
  101. w2 = qcar(args); args = qcdr(args);
  102. if (!consp(args)) /* (list w1 w2) */
  103. { push2(env, w2);
  104. w1 = eval(w1, env);
  105. errexitn(2);
  106. w2 = stack[0];
  107. stack[0] = w1;
  108. w2 = eval(w2, stack[-1]);
  109. errexitn(2);
  110. w1 = list2(stack[0], w2);
  111. popv(2);
  112. errexit();
  113. return onevalue(w1);
  114. }
  115. w3 = qcar(args); args = qcdr(args);
  116. if (!is_cons(args)) /* (list w1 w2 w3) */
  117. { push3(env, w2, w3);
  118. w1 = eval(w1, env);
  119. errexitn(3);
  120. w2 = stack[-1];
  121. stack[-1] = w1;
  122. w2 = eval(w2, stack[-2]);
  123. errexitn(3);
  124. w3 = stack[0];
  125. stack[0] = w2;
  126. w3 = eval(w3, stack[-2]);
  127. errexitn(3);
  128. w3 = ncons(w3);
  129. errexitn(3);
  130. w1 = list2star(stack[-1], stack[0], w3);
  131. popv(3);
  132. errexit();
  133. return onevalue(w1);
  134. }
  135. push4(args, env, w1, w2);
  136. w3 = eval(w3, env);
  137. errexitn(4);
  138. push(w3);
  139. w2 = eval(stack[-1], stack[-3]);
  140. errexitn(5);
  141. stack[-1] = w2;
  142. w1 = eval(stack[-2], stack[-3]);
  143. errexitn(5);
  144. r = ncons(w1);
  145. errexitn(5);
  146. pop2(w3, w2);
  147. r = list2star(w3, w2, r);
  148. errexitn(3);
  149. pop3(w1, env, args);
  150. while (consp(args))
  151. { Lisp_Object w;
  152. push3(env, args, r);
  153. w = qcar(args);
  154. w = eval(w, env);
  155. pop(r);
  156. errexitn(2);
  157. r = cons(w, r);
  158. pop2(args, env);
  159. errexit();
  160. args = qcdr(args);
  161. }
  162. return onevalue(nreverse(r));
  163. }
  164. static Lisp_Object liststar_fn(Lisp_Object args, Lisp_Object env)
  165. {
  166. Lisp_Object nil = C_nil;
  167. Lisp_Object r = nil;
  168. if (!consp(args)) return aerror("list*");
  169. do
  170. { Lisp_Object w;
  171. push3(env, args, r);
  172. w = qcar(args);
  173. w = eval(w, env);
  174. pop(r);
  175. errexitn(2);
  176. r = cons(w, r);
  177. pop2(args, env);
  178. errexit();
  179. args = qcdr(args);
  180. } while (consp(args));
  181. args = qcar(r);
  182. r = qcdr(r);
  183. while (r != nil)
  184. { Lisp_Object c = r;
  185. r = qcdr(r);
  186. qcdr(c) = args;
  187. args = c;
  188. }
  189. return onevalue(args);
  190. }
  191. #endif
  192. #define BODY_LET 0
  193. #define BODY_COMPILER_LET 1
  194. #define BODY_PROG 2
  195. #ifdef COMMON
  196. static Lisp_Object macrolet_fn(Lisp_Object args, Lisp_Object env)
  197. {
  198. Lisp_Object d, nil = C_nil;
  199. if (!consp(args)) return onevalue(nil);
  200. stackcheck2(0, args, env);
  201. d = qcar(args); /* The bunch of definitions */
  202. while (consp(d))
  203. { Lisp_Object w = qcar(d); /* w = (name bvl ...) */
  204. if (consp(w) && consp(qcdr(w)))
  205. {
  206. /*
  207. * Here I need to call (expand-definer <form> nil) to map
  208. * macro specifications with all the possible magic options into ones
  209. * which just take 2 args, a form and an environment.
  210. */
  211. push2(args, env);
  212. w = cons(expand_def_symbol, w);
  213. errexitn(2);
  214. w = Lfuncalln(nil, 3, expand_def_symbol, w, nil);
  215. errexitn(2);
  216. /*
  217. * I expect expand-definer to return either
  218. * (~~defmacro name bvl ...)
  219. * OR (progn XXX (~~defmacro name bvl ...))
  220. * where XXX is exactly one form.
  221. */
  222. if (qcar(w) == progn_symbol)
  223. w = qcar(qcdr(qcdr(w)));
  224. w = qcdr(w);
  225. w = cons(qcdr(w), qcar(w));
  226. errexitn(2);
  227. pop2(env, args);
  228. env = cons(w, env);
  229. errexit();
  230. }
  231. d = qcdr(d);
  232. }
  233. return let_fn_1(nil, qcdr(args), env, BODY_LET);
  234. }
  235. #endif
  236. #ifdef COMMON
  237. static Lisp_Object mv_prog1_fn(Lisp_Object args, Lisp_Object env)
  238. {
  239. Lisp_Object r, rl, nil = C_nil;
  240. int nargs, i;
  241. if (!consp(args)) return onevalue(nil);
  242. stackcheck2(0, args, env);
  243. push2(args, env);
  244. r = qcar(args);
  245. r = eval(r, env);
  246. pop2(env, args);
  247. errexit();
  248. rl = nil;
  249. nargs = exit_count;
  250. push(r);
  251. /*
  252. * I could use the Lisp stack to save things here, but I hope that this
  253. * function is not used much and performance will not matter.
  254. */
  255. for (i=nargs; i>=2; i--)
  256. rl = cons_no_gc((&mv_2)[i-2], rl);
  257. rl = cons_gc_test(rl);
  258. errexitn(1);
  259. push(rl);
  260. while (is_cons(args = qcdr(args)) && args!=nil)
  261. { Lisp_Object w;
  262. push2(args, env);
  263. w = qcar(args);
  264. eval(w, env);
  265. pop2(env, args);
  266. errexitn(2);
  267. }
  268. pop(rl);
  269. for (i = 2; i<=nargs; i++)
  270. { (&mv_2)[i-2] = qcar(rl);
  271. rl = qcdr(rl);
  272. }
  273. pop(r);
  274. return nvalues(r, nargs);
  275. }
  276. #endif
  277. static Lisp_Object or_fn(Lisp_Object args, Lisp_Object env)
  278. /* also needs to be a macro for Common Lisp */
  279. {
  280. Lisp_Object nil = C_nil;
  281. if (!consp(args)) return onevalue(nil);
  282. stackcheck2(0, args, env);
  283. for (;;)
  284. { Lisp_Object v = qcar(args);
  285. args = qcdr(args);
  286. if (!consp(args)) return eval(v, env);
  287. push2(args, env);
  288. v = eval(v, env);
  289. pop2(env, args);
  290. errexit();
  291. if (v != nil) return onevalue(v);
  292. }
  293. }
  294. static Lisp_Object prog_fn(Lisp_Object args, Lisp_Object env)
  295. {
  296. Lisp_Object p, nil = C_nil;
  297. if (!consp(args) || !consp(qcdr(args))) return onevalue(nil);
  298. stackcheck2(0, args, env);
  299. push3(nil, args, env);
  300. #define env stack[0]
  301. #define args stack[-1]
  302. #define my_tag stack[-2]
  303. /*
  304. * I need to augment the (lexical) environment with a null block
  305. * tag so that (return ..) will work as required. See block_fn for
  306. * further elaboration since (block ..) is the main way of introducing
  307. * new block tags.
  308. */
  309. my_tag = cons(fixnum_of_int(0), nil);
  310. errexitn(3);
  311. env = cons(my_tag, env);
  312. errexitn(3);
  313. p = let_fn_1(qcar(args), qcdr(args), env, BODY_PROG);
  314. nil = C_nil;
  315. if (exception_pending())
  316. { flip_exception(); /* Temp restore it */
  317. qcar(my_tag) = fixnum_of_int(2); /* Invalidate */
  318. if (exit_reason == UNWIND_RETURN && exit_tag == my_tag)
  319. { exit_reason = UNWIND_NULL; /* not strictly needed - but tidy */
  320. popv(3);
  321. return exit_value; /* exit_count already OK here */
  322. }
  323. if ((exit_reason & UNWIND_ERROR) != 0)
  324. { err_printf("\nEvaluating: ");
  325. loop_print_error(args);
  326. }
  327. flip_exception(); /* re-instate exit condition */
  328. popv(3);
  329. return nil;
  330. }
  331. popv(3);
  332. return onevalue(nil);
  333. #undef env
  334. #undef args
  335. #undef my_tag
  336. }
  337. #ifdef COMMON
  338. /*--
  339. *-- At one time I though I might implement PROG* in the kernel here, but
  340. *-- now it seems at least as reasonable to implement it is a Lisp-coded
  341. *-- macro that expands to BLOCK, LET* and TAGBODY, thus meaning that the
  342. *-- code that was supposed to be provided here is pretty-well irrelevant.
  343. *--
  344. *-- static Lisp_Object progstar_fn(Lisp_Object args, Lisp_Object env)
  345. *-- /*
  346. *-- * /* At present this is WRONG in that it is just a copy of prog_fn,
  347. *-- * so it awaits re-work to make the bindings happen in serial rather
  348. *-- * than parallel..
  349. *-- * /
  350. *-- {
  351. *-- Lisp_Object p, nil = C_nil;
  352. *-- if (!consp(args) || !consp(qcdr(args))) return onevalue(nil);
  353. *-- stackcheck2(0, args, env);
  354. *-- push3(nil, args, env);
  355. *-- #define env stack[0]
  356. *-- #define args stack[-1]
  357. *-- #define my_tag stack[-2]
  358. *-- /*
  359. *-- * I need to augment the (lexical) environment with a null block
  360. *-- * tag so that (return ..) will work as required. See block_fn for
  361. *-- * further elaboration since (block ..) is the main way of introducing
  362. *-- * new block tags.
  363. *-- * /
  364. *-- my_tag = cons(fixnum_of_int(0), nil);
  365. *-- errexitn(3);
  366. *-- env = cons(my_tag, env);
  367. *-- errexitn(3);
  368. *-- p = let_fn_1(qcar(args), qcdr(args), env, BODY_PROG);
  369. *-- nil = C_nil;
  370. *-- if (exception_pending())
  371. *-- { flip_exception(); /* Temp restore it * /
  372. *-- qcar(my_tag) = fixnum_of_int(2); /* Invalidate * /
  373. *-- if (exit_reason == UNWIND_RETURN && exit_tag == my_tag)
  374. *-- { exit_reason = UNWIND_NULL; /* not strictly needed - but tidy * /
  375. *-- popv(3);
  376. *-- return exit_value;
  377. *-- }
  378. *-- if ((exit_reason & UNWIND_ERROR) != 0)
  379. *-- { err_printf("\nEvaluating: ");
  380. *-- loop_print_error(qcar(args));
  381. *-- }
  382. *-- flip_exception(); /* re-instate exit condition * /
  383. *-- popv(3);
  384. *-- return nil;
  385. *-- }
  386. *-- popv(3);
  387. *-- return onevalue(nil);
  388. *-- #undef env
  389. *-- #undef args
  390. *-- #undef my_tag
  391. *-- }
  392. *--
  393. */
  394. #endif
  395. Lisp_Object progn_fn(Lisp_Object args, Lisp_Object env)
  396. {
  397. Lisp_Object f, nil = C_nil;
  398. if (!consp(args)) return onevalue(nil);
  399. stackcheck2(0, args, env);
  400. f = nil;
  401. for (;;)
  402. { f = qcar(args);
  403. args = qcdr(args);
  404. if (!consp(args)) break;
  405. push3(args, env, f);
  406. voideval(f, env);
  407. pop3(f, env, args);
  408. nil = C_nil;
  409. if (exception_pending())
  410. { flip_exception();
  411. if ((exit_reason & UNWIND_ERROR) != 0)
  412. { err_printf("\nEvaluating: ");
  413. loop_print_error(f);
  414. }
  415. flip_exception();
  416. return nil; /* premature exit */
  417. }
  418. }
  419. return eval(f, env); /* tail call on last item in the progn */
  420. }
  421. static Lisp_Object prog1_fn(Lisp_Object args, Lisp_Object env)
  422. /*
  423. * prog1 and prog2 will be implemented as macros for Common Lisp,
  424. * and are here implemented as special forms too in the expectation
  425. * that that will be good for performance.
  426. */
  427. {
  428. Lisp_Object f, nil = C_nil;
  429. if (!consp(args)) return onevalue(nil); /* (prog1) -> nil */
  430. stackcheck2(0, args, env);
  431. push2(args, env);
  432. f = qcar(args);
  433. f = eval(f, env); /* first arg */
  434. pop2(env, args);
  435. push(f);
  436. errexit();
  437. for (;;)
  438. { args = qcdr(args);
  439. if (!consp(args)) break;
  440. push2(args, env);
  441. { Lisp_Object w = qcar(args);
  442. voideval(w, env);
  443. }
  444. pop2(env, args);
  445. errexitn(1);
  446. }
  447. pop(f);
  448. return onevalue(f); /* always hands back just 1 value */
  449. }
  450. static Lisp_Object prog2_fn(Lisp_Object args, Lisp_Object env)
  451. {
  452. Lisp_Object f, nil = C_nil;
  453. if (!consp(args)) return onevalue(nil); /* (prog2) -> nil */
  454. stackcheck2(0, args, env);
  455. push2(args, env);
  456. args = qcar(args);
  457. voideval(args, env); /* discard first arg */
  458. pop2(env, args);
  459. errexit();
  460. args = qcdr(args);
  461. if (!consp(args)) return onevalue(nil); /* (prog2 x) -> nil */
  462. push2(args, env);
  463. f = qcar(args);
  464. f = eval(f, env); /* second arg */
  465. pop2(env, args);
  466. push(f);
  467. errexit();
  468. for (;;)
  469. { args = qcdr(args);
  470. if (!consp(args)) break;
  471. push2(args, env);
  472. args = qcar(args);
  473. voideval(args, env);
  474. pop2(env, args);
  475. errexitn(1);
  476. }
  477. pop(f);
  478. return onevalue(f); /* always hands back just 1 value */
  479. }
  480. #ifdef COMMON
  481. static Lisp_Object progv_fn(Lisp_Object args, Lisp_Object env)
  482. {
  483. Lisp_Object syms, vals, specenv, nil = C_nil, w;
  484. if (!consp(args)) return onevalue(nil);
  485. stackcheck2(0, args, env);
  486. syms = vals = specenv = nil;
  487. syms = qcar(args);
  488. args = qcdr(args);
  489. push5(args, env, syms, vals, specenv);
  490. #define specenv stack[0]
  491. #define vals stack[-1]
  492. #define syms stack[-2]
  493. #define env stack[-3]
  494. #define args stack[-4]
  495. syms = eval(syms, env);
  496. nil = C_nil;
  497. if (exception_pending() || !consp(args)) { popv(5); return nil; }
  498. w = qcar(args);
  499. args = qcdr(args);
  500. vals = eval(w, env);
  501. nil = C_nil;
  502. if (exception_pending() || !consp(args)) { popv(5); return nil; }
  503. while (consp(syms))
  504. { Lisp_Object v = qcar(syms);
  505. Lisp_Object w1;
  506. if (consp(vals))
  507. { w = qcar(vals);
  508. vals = qcdr(vals);
  509. }
  510. else w = unset_var;
  511. syms = qcdr(syms);
  512. if (!is_symbol(v)) continue;
  513. w1 = cons(v, qvalue(v));
  514. /*
  515. * If I were to take the error exit here then some variables would have
  516. * been set to their new values and some not. That would be a mess!
  517. */
  518. errexitn(5);
  519. qvalue(v) = w;
  520. specenv = cons(w1, specenv);
  521. errexitn(5);
  522. }
  523. args = progn_fn(args, env);
  524. nil = C_nil;
  525. if (exception_pending())
  526. { flip_exception();
  527. while (specenv != nil)
  528. { Lisp_Object p = qcar(specenv);
  529. qvalue(qcar(p)) = qcdr(p);
  530. specenv = qcdr(specenv);
  531. }
  532. flip_exception();
  533. popv(5);
  534. return nil;
  535. }
  536. while (specenv != nil)
  537. { Lisp_Object p = qcar(specenv);
  538. qvalue(qcar(p)) = qcdr(p);
  539. specenv = qcdr(specenv);
  540. }
  541. popv(4);
  542. #undef specenv
  543. #undef vals
  544. #undef syms
  545. #undef env
  546. #undef args
  547. pop(vals);
  548. return vals;
  549. }
  550. #endif
  551. Lisp_Object quote_fn(Lisp_Object args, Lisp_Object env)
  552. {
  553. Lisp_Object nil = C_nil;
  554. CSL_IGNORE(env);
  555. if (consp(args) && qcdr(args) == nil) return onevalue(qcar(args));
  556. return aerror("quote");
  557. }
  558. static Lisp_Object return_fn(Lisp_Object args, Lisp_Object env)
  559. {
  560. /*
  561. * First check that the block name (nil in this case) is lexically available
  562. */
  563. Lisp_Object p, nil = C_nil;
  564. stackcheck2(0, args, env);
  565. for(p=env; consp(p); p=qcdr(p))
  566. { Lisp_Object w = qcar(p);
  567. if (!consp(w)) continue;
  568. if (qcar(w) == fixnum_of_int(0) && qcdr(w) == nil)
  569. { p = w;
  570. goto tag_found;
  571. }
  572. }
  573. return error(1, err_block_tag, nil);
  574. tag_found:
  575. if (consp(args))
  576. {
  577. push(p);
  578. p = qcar(args);
  579. env = eval(p, env);
  580. pop(p);
  581. errexit();
  582. exit_value = env;
  583. #ifndef COMMON
  584. exit_count = 1;
  585. #else
  586. /* exit_count was left set by the call to eval */
  587. #endif
  588. }
  589. else
  590. { exit_value = nil;
  591. exit_count = 1;
  592. }
  593. exit_tag = p;
  594. exit_reason = UNWIND_RETURN;
  595. flip_exception();
  596. return nil;
  597. }
  598. #ifdef COMMON
  599. static Lisp_Object return_from_fn(Lisp_Object args, Lisp_Object env)
  600. {
  601. Lisp_Object p, tag, nil = C_nil;
  602. stackcheck2(0, args, env);
  603. if (!consp(args)) tag = nil;
  604. else
  605. { tag = qcar(args);
  606. args = qcdr(args);
  607. }
  608. for(p=env; consp(p); p=qcdr(p))
  609. { Lisp_Object w = qcar(p);
  610. if (!consp(w)) continue;
  611. if (qcar(w) == fixnum_of_int(0) && qcdr(w) == tag)
  612. { p = w;
  613. goto tag_found;
  614. }
  615. }
  616. return error(1, err_block_tag, tag);
  617. tag_found:
  618. if (consp(args))
  619. {
  620. push(p);
  621. p = qcar(args);
  622. env = eval(p, env);
  623. pop(p);
  624. errexit();
  625. exit_value = env;
  626. #ifndef COMMON
  627. exit_count = 1;
  628. #else
  629. /* exit_count left set by eval */
  630. #endif
  631. }
  632. else
  633. { exit_value = nil;
  634. exit_count = 1;
  635. }
  636. exit_tag = p;
  637. exit_reason = UNWIND_RETURN;
  638. flip_exception();
  639. return nil;
  640. }
  641. #endif
  642. static Lisp_Object setq_fn(Lisp_Object args, Lisp_Object env)
  643. {
  644. Lisp_Object nil = C_nil;
  645. Lisp_Object var, val = nil;
  646. stackcheck2(0, args, env);
  647. while (consp(args))
  648. { var = qcar(args);
  649. if (!is_symbol(var) || var == nil || var == lisp_true)
  650. return aerror("setq (bad variable)");
  651. args = qcdr(args);
  652. if (consp(args))
  653. { push3(args, env, var);
  654. val = qcar(args);
  655. val = eval(val, env);
  656. pop3(var, env, args);
  657. errexit();
  658. args = qcdr(args);
  659. }
  660. else val = nil;
  661. #ifndef COMMON
  662. qvalue(var) = val;
  663. #else
  664. if (qheader(var) & SYM_SPECIAL_VAR) qvalue(var) = val;
  665. else
  666. { Lisp_Object p = env, w;
  667. for (;;)
  668. { if (!consp(p))
  669. {
  670. #ifndef COMMON
  671. qheader(var) |= SYM_SPECIAL_VAR;
  672. push3(args, env, var);
  673. debug_printf("\n+++++ "); loop_print_debug(var);
  674. debug_printf(" proclaimed SPECIAL by SETQ\n");
  675. pop3(var, env, args);
  676. errexit();
  677. #endif
  678. qvalue(var) = val;
  679. break;
  680. }
  681. w = qcar(p);
  682. if (qcar(w) == var)
  683. {
  684. if (qcdr(w) == work_symbol) qvalue(var) = val;
  685. else qcdr(w) = val;
  686. break;
  687. }
  688. p = qcdr(p);
  689. }
  690. }
  691. #endif
  692. }
  693. return onevalue(val);
  694. }
  695. static Lisp_Object noisy_setq_fn(Lisp_Object args, Lisp_Object env)
  696. {
  697. Lisp_Object nil = C_nil;
  698. Lisp_Object var, val = nil;
  699. stackcheck2(0, args, env);
  700. while (consp(args))
  701. { var = qcar(args);
  702. if (!is_symbol(var) || var == nil || var == lisp_true)
  703. return aerror("setq (bad variable)");
  704. args = qcdr(args);
  705. if (consp(args))
  706. { push3(args, env, var);
  707. val = qcar(args);
  708. val = eval(val, env);
  709. pop3(var, env, args);
  710. errexit();
  711. args = qcdr(args);
  712. }
  713. else val = nil;
  714. push4(var, env, args, val);
  715. loop_print_trace(var);
  716. errexitn(4);
  717. trace_printf(" := ");
  718. loop_print_trace(stack[0]);
  719. errexitn(4);
  720. trace_printf("\n");
  721. pop4(val, args, env, var);
  722. #ifndef COMMON
  723. qvalue(var) = val;
  724. #else
  725. if (qheader(var) & SYM_SPECIAL_VAR) qvalue(var) = val;
  726. else
  727. { Lisp_Object p = env, w;
  728. for (;;)
  729. { if (!consp(p))
  730. {
  731. #ifndef COMMON
  732. qheader(var) |= SYM_SPECIAL_VAR;
  733. push3(args, env, var);
  734. debug_printf("\n+++++ "); loop_print_debug(var);
  735. debug_printf(" proclaimed SPECIAL by SETQ\n");
  736. pop3(var, env, args);
  737. errexit();
  738. #endif
  739. qvalue(var) = val;
  740. break;
  741. }
  742. w = qcar(p);
  743. if (qcar(w) == var)
  744. {
  745. if (qcdr(w) == work_symbol) qvalue(var) = val;
  746. else qcdr(w) = val;
  747. break;
  748. }
  749. p = qcdr(p);
  750. }
  751. }
  752. #endif
  753. }
  754. return onevalue(val);
  755. }
  756. Lisp_Object tagbody_fn(Lisp_Object args, Lisp_Object env)
  757. {
  758. Lisp_Object f, p, my_env, nil = C_nil;
  759. /*
  760. * Bind the labels that occur in this block. Note that I invalidate
  761. * these bindings if I ever exit from this block, so that nobody
  762. * even thinks that they can use (go xx) to get back in.
  763. */
  764. stackcheck2(0, args, env);
  765. f = nil;
  766. push2(env, args);
  767. for (p=args; consp(p); p=qcdr(p))
  768. { Lisp_Object w = qcar(p);
  769. if (!consp(w))
  770. { Lisp_Object w1;
  771. push3(f, p, env);
  772. w1 = cons(fixnum_of_int(1), p);
  773. pop(env);
  774. nil = C_nil;
  775. if (!exception_pending()) env = cons(w1, env);
  776. pop2(p, f);
  777. errexitn(2);
  778. }
  779. }
  780. pop(args);
  781. /*
  782. * (go xx) sets exit_tag to xx, which is then noticed next time tagbody
  783. * is about to do anything.
  784. */
  785. for (p=args;;p = qcdr(p))
  786. { nil = C_nil;
  787. if (exception_pending())
  788. { flip_exception();
  789. pop(my_env);
  790. if (exit_reason != UNWIND_GO)
  791. {
  792. while (env != my_env)
  793. { qcar(qcar(env)) = fixnum_of_int(2);
  794. env = qcdr(env);
  795. }
  796. if ((exit_reason & UNWIND_ERROR) != 0)
  797. { err_printf("\nEvaluating: ");
  798. loop_print_error(f);
  799. ignore_exception();
  800. }
  801. flip_exception();
  802. return nil; /* re-instate exit condition */
  803. }
  804. else
  805. { for (p=env;;p=qcdr(p))
  806. /*
  807. * If the target of (go xx) is not found then tagbody returns without
  808. * clearing exit_tag, thus giving an enclosing tagbody a chance to notice
  809. * the problem and look for the label.
  810. */
  811. { if (p == my_env) /* Not to a tag in this tagbody */
  812. { while (env != my_env)
  813. { qcar(qcar(env)) = fixnum_of_int(2);
  814. env = qcdr(env);
  815. }
  816. if ((exit_reason & UNWIND_ERROR) != 0)
  817. { err_printf("\nEvaluating: ");
  818. loop_print_error(f);
  819. ignore_exception();
  820. }
  821. flip_exception();
  822. return nil;
  823. }
  824. if (exit_tag == qcar(p))
  825. { p = qcdr(qcdr(exit_tag));
  826. exit_tag = nil;
  827. exit_reason = UNWIND_NULL;
  828. push(my_env);
  829. break; /* Success! */
  830. }
  831. }
  832. }
  833. }
  834. if (!consp(p))
  835. { pop(my_env);
  836. while (env != my_env)
  837. { qcar(qcar(env)) = fixnum_of_int(2);
  838. env = qcdr(env);
  839. }
  840. return onevalue(nil);
  841. }
  842. if (is_cons(f = qcar(p)) && f!=nil)
  843. { push3(p, env, f);
  844. voideval(f, env);
  845. pop3(f, env, p);
  846. }
  847. }
  848. }
  849. #ifdef COMMON
  850. static Lisp_Object the_fn(Lisp_Object args, Lisp_Object env)
  851. /*
  852. * in effect an identity function for the present
  853. */
  854. {
  855. Lisp_Object nil = C_nil;
  856. if (!consp(args)) return onevalue(nil);
  857. args = qcdr(args);
  858. if (!consp(args)) return onevalue(nil);
  859. args = qcar(args);
  860. return eval(args, env);
  861. }
  862. #endif
  863. static Lisp_Object throw_fn(Lisp_Object args, Lisp_Object env)
  864. {
  865. Lisp_Object tag, p, nil = C_nil;
  866. if (!consp(args)) return aerror("throw");
  867. stackcheck2(0, args, env);
  868. tag = qcar(args);
  869. args = qcdr(args);
  870. push2(args, env);
  871. tag = eval(tag, env);
  872. pop2(env, args);
  873. errexit();
  874. for (p = catch_tags; p!=nil; p=qcdr(p))
  875. if (tag == qcar(p)) goto tag_found;
  876. return aerror("throw: tag not found");
  877. tag_found:
  878. if (consp(args))
  879. {
  880. push(p);
  881. tag = qcar(args);
  882. tag = eval(tag, env);
  883. pop(p);
  884. errexit();
  885. exit_value = tag;
  886. #ifndef COMMON
  887. exit_count = 1;
  888. #else
  889. /* exit_count left set by eval */
  890. #endif
  891. }
  892. else
  893. { exit_value = nil;
  894. exit_count = 1;
  895. }
  896. exit_tag = p;
  897. exit_reason = UNWIND_THROW;
  898. flip_exception();
  899. return nil;
  900. }
  901. static Lisp_Object unless_fn(Lisp_Object args, Lisp_Object env)
  902. {
  903. Lisp_Object w, nil = C_nil;
  904. if (!consp(args)) return onevalue(nil);
  905. stackcheck2(0, args, env);
  906. push2(args, env);
  907. w = qcar(args);
  908. w = eval(w, env);
  909. pop2(env, args);
  910. errexit();
  911. if (w != nil) return onevalue(nil);
  912. else return progn_fn(qcdr(args), env);
  913. }
  914. static Lisp_Object unwind_protect_fn(Lisp_Object args, Lisp_Object env)
  915. {
  916. Lisp_Object nil = C_nil;
  917. Lisp_Object r = nil ,rl = nil;
  918. int nargs = 0, i;
  919. if (!consp(args)) return onevalue(nil);
  920. stackcheck2(0, args, env);
  921. push2(args, env);
  922. r = qcar(args);
  923. r = eval(r, env);
  924. pop2(env, args);
  925. nil = C_nil;
  926. if (exception_pending())
  927. { Lisp_Object xt, xv;
  928. int xc, xr;
  929. /*
  930. * Here I am in the process of exiting because of a throw, return-from,
  931. * go or error. I need to save all the internal stuff that tells me
  932. * what is going on so I can restore it after the clean-up forms have been
  933. * processed. The values involved are:
  934. * (a) exit_tag marks use of go, return-from or throw
  935. * (b) exit_value first result value (throw, return-from)
  936. * (c) exit_count number of values (throw, return-from)
  937. * (d) mv2,... as indicated by exit_count
  938. * (e) exit_reason what it says.
  939. */
  940. flip_exception();
  941. xv = exit_value;
  942. xt = exit_tag;
  943. xc = exit_count;
  944. xr = exit_reason;
  945. push2(xv, xt);
  946. for (i=xc; i>=2; i--)
  947. rl = cons_no_gc((&mv_2)[i-2], rl);
  948. rl = cons_gc_test(rl);
  949. errexitn(2);
  950. push(rl);
  951. while (is_cons(args = qcdr(args)) && args!=nil)
  952. { Lisp_Object w = qcar(args);
  953. push2(args, env);
  954. voideval(w, env);
  955. pop2(env, args);
  956. errexitn(3);
  957. }
  958. pop3(rl, xt, xv);
  959. for (i = 2; i<=xc; i++)
  960. { (&mv_2)[i-2] = qcar(rl);
  961. rl = qcdr(rl);
  962. }
  963. exit_value = xv;
  964. exit_tag = xt;
  965. exit_count = xc;
  966. exit_reason = xr;
  967. flip_exception();
  968. return nil;
  969. }
  970. /*
  971. * Now code (just like multiple-value-prog1) that evaluates the
  972. * cleanup forms in the case that the protected form exits normally.
  973. */
  974. #ifndef COMMON
  975. nargs = 1; /* Just one value returned */
  976. #else
  977. nargs = exit_count;
  978. #endif
  979. push2(args, env);
  980. for (i=nargs; i>=2; i--)
  981. rl = cons_no_gc((&mv_2)[i-2], rl);
  982. rl = cons_gc_test(rl);
  983. errexitn(2);
  984. push(rl);
  985. #define env stack[-1]
  986. #define args stack[-2]
  987. while (is_cons(args = qcdr(args)) && args!=nil)
  988. { Lisp_Object w = qcar(args);
  989. voideval(w, env);
  990. errexitn(3);
  991. }
  992. #undef env
  993. #undef args
  994. pop(rl);
  995. popv(2);
  996. for (i = 2; i<=nargs; i++)
  997. { (&mv_2)[i-2] = qcar(rl);
  998. rl = qcdr(rl);
  999. }
  1000. return nvalues(r, nargs);
  1001. }
  1002. /*
  1003. * Errorset is not defined as part of COMMON Lisp but I want it in
  1004. * any Lisp system that I use notwithstanding that.
  1005. */
  1006. #ifndef __cplusplus
  1007. jmp_buf *errorset_buffer;
  1008. #endif
  1009. char *errorset_msg;
  1010. static char signal_msg[32];
  1011. #ifdef __WATCOMC__
  1012. void low_level_signal_handler(int code)
  1013. #else
  1014. void MS_CDECL low_level_signal_handler(int code)
  1015. #endif
  1016. {
  1017. Lisp_Object nil;
  1018. #ifdef __WATCOMC__
  1019. _fpreset();
  1020. #endif
  1021. ignore_exception();
  1022. if (miscflags & HEADLINE_FLAG)
  1023. switch (code)
  1024. {
  1025. default:
  1026. sprintf(signal_msg, "Signal (code=%d)", code);
  1027. errorset_msg = signal_msg;
  1028. break;
  1029. case SIGFPE:
  1030. errorset_msg = "Floating point exception";
  1031. break;
  1032. case SIGSEGV:
  1033. errorset_msg = "Memory access violation";
  1034. break;
  1035. #ifdef SIGBUS
  1036. case SIGBUS:
  1037. errorset_msg = "Bus error";
  1038. break;
  1039. #endif
  1040. #ifdef SIGILL
  1041. case SIGILL:
  1042. errorset_msg = "Illegal instruction";
  1043. break;
  1044. #endif
  1045. }
  1046. #ifdef __cplusplus
  1047. throw "low_level_signal_handler";
  1048. #else
  1049. longjmp(*errorset_buffer, 1);
  1050. #endif
  1051. }
  1052. void unwind_stack(Lisp_Object *entry_stack, CSLbool findcatch)
  1053. {
  1054. Lisp_Object *sp = stack;
  1055. while (sp != entry_stack)
  1056. { Lisp_Object bv, w;
  1057. int32 n;
  1058. w = *sp--;
  1059. if (findcatch && w == SPID_CATCH) break;
  1060. if (w == (Lisp_Object)SPID_FBIND)
  1061. {
  1062. /*
  1063. * Here I have found some fluid binding that need to be unwound. The code
  1064. * here is similar to that for FREERSTR.
  1065. */
  1066. bv = *sp--;
  1067. n = length_of_header(vechdr(bv));
  1068. while (n>4)
  1069. { Lisp_Object v = *(Lisp_Object *)(
  1070. (int32)bv + n - (4 + TAG_VECTOR));
  1071. n -= 4;
  1072. qvalue(v) = *sp--;
  1073. }
  1074. }
  1075. else if (w == (Lisp_Object)SPID_PVBIND)
  1076. { bv = *sp--;
  1077. while (bv != C_nil)
  1078. { Lisp_Object w = qcar(bv);
  1079. qvalue(qcar(w)) = qcdr(w);
  1080. bv = qcdr(bv);
  1081. }
  1082. }
  1083. }
  1084. /*
  1085. * If "findcatch" is true this code must actually update the stack pointer -
  1086. * otherwise it must not. Ugly! The only use with findcatch set true is
  1087. * from the bytecode interpreter (bytes1.c)
  1088. */
  1089. if (findcatch) stack = sp;
  1090. }
  1091. Lisp_Object MS_CDECL Lerrorsetn(Lisp_Object env, int nargs, ...)
  1092. /*
  1093. * This is not a special form, but is put into the code here because,
  1094. * like unwind-protect, it has to re-gain control after an evaluation
  1095. * error.
  1096. */
  1097. {
  1098. Lisp_Object r, nil = C_nil, form, fg1, fg2;
  1099. va_list a;
  1100. Lisp_Object *save;
  1101. unsigned32 flags = miscflags;
  1102. #ifndef __cplusplus
  1103. jmp_buf this_level, *saved_buffer = errorset_buffer;
  1104. #endif
  1105. if (nargs < 1 || nargs > 3) return aerror("errorset");
  1106. va_start(a, nargs);
  1107. form = va_arg(a, Lisp_Object);
  1108. fg1 = fg2 = lisp_true;
  1109. if (nargs >= 2)
  1110. { fg1 = fg2 = va_arg(a, Lisp_Object);
  1111. if (nargs >= 3) fg2 = va_arg(a, Lisp_Object);
  1112. }
  1113. va_end(a);
  1114. miscflags &= ~(HEADLINE_FLAG | MESSAGES_FLAG);
  1115. if (fg1 != nil) miscflags |= HEADLINE_FLAG;
  1116. if (fg2 != nil) miscflags |= MESSAGES_FLAG;
  1117. push2(codevec, litvec);
  1118. save = stack;
  1119. stackcheck2(2, form, env);
  1120. errorset_msg = NULL;
  1121. #ifdef __cplusplus
  1122. try
  1123. #else
  1124. if (!setjmp(this_level))
  1125. #endif
  1126. {
  1127. #ifndef __cplusplus
  1128. errorset_buffer = &this_level;
  1129. #endif
  1130. r = eval(form, env);
  1131. #ifndef __cplusplus
  1132. errorset_buffer = saved_buffer;
  1133. #endif
  1134. nil = C_nil;
  1135. if (exception_pending())
  1136. { flip_exception();
  1137. pop2(litvec, codevec);
  1138. miscflags = (flags & ~GC_MSG_BITS) | (miscflags & GC_MSG_BITS);
  1139. switch (exit_reason)
  1140. {
  1141. case UNWIND_RESTART:
  1142. flip_exception();
  1143. return nil; /* Not catchable */
  1144. default:break;
  1145. }
  1146. if (consp(exit_value)) exit_value = nil;
  1147. return onevalue(exit_value);
  1148. }
  1149. pop2(litvec, codevec);
  1150. miscflags = (flags & ~GC_MSG_BITS) | (miscflags & GC_MSG_BITS);
  1151. r = ncons(r);
  1152. errexit();
  1153. return onevalue(r);
  1154. }
  1155. #ifdef __cplusplus
  1156. catch (char *)
  1157. #else
  1158. else
  1159. #endif
  1160. { if (errorset_msg != NULL)
  1161. { term_printf("\n%s detected\n", errorset_msg);
  1162. errorset_msg = NULL;
  1163. }
  1164. /*
  1165. * Worry about restoration of fluids bound before the exception
  1166. * forced unwinding. All pretty dreadful, I think. If I leave fluid
  1167. * unbind information interleaved on the stack I could cope with it
  1168. * here I think... but I have not done so yet.
  1169. */
  1170. unwind_stack(save, NO);
  1171. stack = save;
  1172. nil = C_nil;
  1173. pop2(litvec, codevec);
  1174. #ifndef __cplusplus
  1175. errorset_buffer = saved_buffer;
  1176. #endif
  1177. signal(SIGFPE, low_level_signal_handler);
  1178. #ifdef __WATCOMC__
  1179. _control87(_EM_OVERFLOW | _EM_INVALID | _EM_DENORMAL |
  1180. _EM_ZERODIVIDE | _EM_INEXACT | _EM_UNDERFLOW,
  1181. _MCW_EM);
  1182. #endif
  1183. if (segvtrap) signal(SIGSEGV, low_level_signal_handler);
  1184. #ifdef SIGBUS
  1185. if (segvtrap) signal(SIGBUS, low_level_signal_handler);
  1186. #endif
  1187. #ifdef SIGILL
  1188. if (segvtrap) signal(SIGILL, low_level_signal_handler);
  1189. #endif
  1190. return onevalue(nil);
  1191. }
  1192. }
  1193. Lisp_Object Lerrorset1(Lisp_Object nil, Lisp_Object form)
  1194. {
  1195. return Lerrorsetn(nil, 3, form, nil, nil);
  1196. }
  1197. Lisp_Object Lerrorset2(Lisp_Object nil, Lisp_Object form, Lisp_Object ffg1)
  1198. {
  1199. return Lerrorsetn(nil, 3, form, ffg1, nil);
  1200. }
  1201. static Lisp_Object when_fn(Lisp_Object args, Lisp_Object env)
  1202. {
  1203. Lisp_Object w, nil = C_nil;
  1204. if (!consp(args)) return onevalue(nil);
  1205. stackcheck2(0, args, env);
  1206. push2(args, env);
  1207. w = qcar(args);
  1208. w = eval(w, env);
  1209. pop2(env, args);
  1210. errexit();
  1211. if (w == nil) return onevalue(nil);
  1212. else return progn_fn(qcdr(args), env);
  1213. }
  1214. setup_type const eval3_setup[] =
  1215. {
  1216. {"or", or_fn, bad_special2, bad_specialn},
  1217. {"prog", prog_fn, bad_special2, bad_specialn},
  1218. {"prog1", prog1_fn, bad_special2, bad_specialn},
  1219. {"prog2", prog2_fn, bad_special2, bad_specialn},
  1220. /* {"progn", progn_fn, bad_special2, bad_specialn}, */
  1221. /* {"quote", quote_fn, bad_special2, bad_specialn}, */
  1222. {"return", return_fn, bad_special2, bad_specialn},
  1223. {"setq", setq_fn, bad_special2, bad_specialn},
  1224. {"noisy-setq", noisy_setq_fn, bad_special2, bad_specialn},
  1225. {"tagbody", tagbody_fn, bad_special2, bad_specialn},
  1226. {"throw", throw_fn, bad_special2, bad_specialn},
  1227. {"unless", unless_fn, bad_special2, bad_specialn},
  1228. {"unwind-protect", unwind_protect_fn, bad_special2, bad_specialn},
  1229. {"when", when_fn, bad_special2, bad_specialn},
  1230. #ifdef COMMON
  1231. {"macrolet", macrolet_fn, bad_special2, bad_specialn},
  1232. {"multiple-value-call", mv_call_fn, bad_special2, bad_specialn},
  1233. {"multiple-value-prog1", mv_prog1_fn, bad_special2, bad_specialn},
  1234. /*--{"prog*", progstar_fn, bad_special2, bad_specialn}, */
  1235. {"progv", progv_fn, bad_special2, bad_specialn},
  1236. {"return-from", return_from_fn, bad_special2, bad_specialn},
  1237. {"the", the_fn, bad_special2, bad_specialn},
  1238. #else
  1239. {"list", list_fn, bad_special2, bad_specialn},
  1240. {"list*", liststar_fn, bad_special2, bad_specialn},
  1241. {"plus", plus_fn, bad_special2, bad_specialn},
  1242. {"times", times_fn, bad_special2, bad_specialn},
  1243. #endif
  1244. {NULL, 0, 0, 0}};
  1245. /* end of eval3.c */