eval2.c 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331
  1. /* eval2.c Copyright (C) 1989-96 Codemist Ltd */
  2. /*
  3. * Interpreter (part 2). apply & some special forms
  4. */
  5. /* Signature: 589bce9e 17-Jan-1999 */
  6. #include <stdarg.h>
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include "machine.h"
  10. #include "tags.h"
  11. #include "cslerror.h"
  12. #include "externs.h"
  13. #include "entries.h"
  14. #ifdef TIMEOUT
  15. #include "timeout.h"
  16. #endif
  17. static Lisp_Object apply_lots(int nargs, n_args *f, Lisp_Object def)
  18. /*
  19. * Cases with 8 or more args are lifted out here into a subroutine
  20. * to make APPLY a bit shorter and because these cases should be
  21. * uncommon & not worth optimising much. The code that Microsoft C 6.00A
  22. * produced for this was utterly DREADFUL - maybe other C compilers will
  23. * make a mess of it too. Anyway I hope it will not be called very often.
  24. */
  25. {
  26. switch(nargs)
  27. {
  28. case 9:
  29. return (*f)(def, 9, stack[-9], stack[-8], stack[-7],
  30. stack[-6], stack[-5], stack[-4], stack[-3],
  31. stack[-2], stack[-1]);
  32. case 10:
  33. return (*f)(def, 10, stack[-10], stack[-9], stack[-8],
  34. stack[-7], stack[-6], stack[-5], stack[-4],
  35. stack[-3], stack[-2], stack[-1]);
  36. case 11:
  37. return (*f)(def, 11, stack[-11], stack[-10],
  38. stack[-9], stack[-8], stack[-7], stack[-6],
  39. stack[-5], stack[-4], stack[-3], stack[-2],
  40. stack[-1]);
  41. case 12:
  42. return (*f)(def, 12, stack[-12], stack[-11],
  43. stack[-10], stack[-9], stack[-8], stack[-7],
  44. stack[-6], stack[-5], stack[-4], stack[-3],
  45. stack[-2], stack[-1]);
  46. case 13:
  47. return (*f)(def, 13, stack[-13], stack[-12],
  48. stack[-11], stack[-10], stack[-9], stack[-8],
  49. stack[-7], stack[-6], stack[-5], stack[-4],
  50. stack[-3], stack[-2], stack[-1]);
  51. case 14:
  52. return (*f)(def, 14, stack[-14], stack[-13],
  53. stack[-12], stack[-11], stack[-10], stack[-9],
  54. stack[-8], stack[-7], stack[-6], stack[-5],
  55. stack[-4], stack[-3], stack[-2], stack[-1]);
  56. case 15:
  57. return (*f)(def, 15, stack[-15], stack[-14],
  58. stack[-13], stack[-12], stack[-11], stack[-10],
  59. stack[-9], stack[-8], stack[-7], stack[-6],
  60. stack[-5], stack[-4], stack[-3], stack[-2],
  61. stack[-1]);
  62. case 16:
  63. return (*f)(def, 16, stack[-16], stack[-15],
  64. stack[-14], stack[-13], stack[-12], stack[-11],
  65. stack[-10], stack[-9], stack[-8], stack[-7],
  66. stack[-6], stack[-5], stack[-4], stack[-3],
  67. stack[-2], stack[-1]);
  68. case 17:
  69. return (*f)(def, 17, stack[-17], stack[-16],
  70. stack[-15], stack[-14], stack[-13], stack[-12],
  71. stack[-11], stack[-10], stack[-9], stack[-8],
  72. stack[-7], stack[-6], stack[-5], stack[-4],
  73. stack[-3], stack[-2], stack[-1]);
  74. case 18:
  75. return (*f)(def, 18, stack[-18], stack[-17],
  76. stack[-16], stack[-15], stack[-14], stack[-13],
  77. stack[-12], stack[-11], stack[-10], stack[-9],
  78. stack[-8], stack[-7], stack[-6], stack[-5],
  79. stack[-4], stack[-3], stack[-2], stack[-1]);
  80. case 19:
  81. return (*f)(def, 19, stack[-19], stack[-18],
  82. stack[-17], stack[-16], stack[-15], stack[-14],
  83. stack[-13], stack[-12], stack[-11], stack[-10],
  84. stack[-9], stack[-8], stack[-7], stack[-6],
  85. stack[-5], stack[-4], stack[-3], stack[-2],
  86. stack[-1]);
  87. case 20:
  88. return (*f)(def, 20, stack[-20], stack[-19],
  89. stack[-18], stack[-17], stack[-16], stack[-15],
  90. stack[-14], stack[-13], stack[-12], stack[-11],
  91. stack[-10], stack[-9], stack[-8], stack[-7],
  92. stack[-6], stack[-5], stack[-4], stack[-3],
  93. stack[-2], stack[-1]);
  94. case 21:
  95. return (*f)(def, 21, stack[-21], stack[-20],
  96. stack[-19], stack[-18], stack[-17], stack[-16],
  97. stack[-15], stack[-14], stack[-13], stack[-12],
  98. stack[-11], stack[-10], stack[-9], stack[-8],
  99. stack[-7], stack[-6], stack[-5], stack[-4],
  100. stack[-3], stack[-2], stack[-1]);
  101. case 22:
  102. return (*f)(def, 22, stack[-22], stack[-21],
  103. stack[-20], stack[-19], stack[-18], stack[-17],
  104. stack[-16], stack[-15], stack[-14], stack[-13],
  105. stack[-12], stack[-11], stack[-10], stack[-9],
  106. stack[-8], stack[-7], stack[-6], stack[-5],
  107. stack[-4], stack[-3], stack[-2], stack[-1]);
  108. case 23:
  109. return (*f)(def, 23, stack[-23], stack[-22],
  110. stack[-21], stack[-20], stack[-19], stack[-18],
  111. stack[-17], stack[-16], stack[-15], stack[-14],
  112. stack[-13], stack[-12], stack[-11], stack[-10],
  113. stack[-9], stack[-8], stack[-7], stack[-6],
  114. stack[-5], stack[-4], stack[-3], stack[-2],
  115. stack[-1]);
  116. case 24:
  117. return (*f)(def, 24, stack[-24], stack[-23],
  118. stack[-22], stack[-21], stack[-20], stack[-19],
  119. stack[-18], stack[-17], stack[-16], stack[-15],
  120. stack[-14], stack[-13], stack[-12], stack[-11],
  121. stack[-10], stack[-9], stack[-8], stack[-7],
  122. stack[-6], stack[-5], stack[-4], stack[-3],
  123. stack[-2], stack[-1]);
  124. case 25:
  125. return (*f)(def, 25, stack[-25], stack[-24], stack[-23],
  126. stack[-22], stack[-21], stack[-20], stack[-19],
  127. stack[-18], stack[-17], stack[-16], stack[-15],
  128. stack[-14], stack[-13], stack[-12], stack[-11],
  129. stack[-10], stack[-9], stack[-8], stack[-7],
  130. stack[-6], stack[-5], stack[-4], stack[-3],
  131. stack[-2], stack[-1]);
  132. default:
  133. /*
  134. * If more than 25 args are going to be passed I will arrange that the
  135. * final ones are built into a list - as if the 25th arg was specified
  136. * as a "&rest" one. Why? Because passing VERY large numbers of arguments
  137. * in C is not a good idea - ANSI C compilers are only obliged to support
  138. * up to 31 args, and one some machines this limit seems to really matter.
  139. * But Common Lisp can need more args than that. I will ignore the fact that
  140. * what I do here is slow. I will HOPE that calls with 25 or more args
  141. * are very uncommon.
  142. */
  143. { int n = nargs;
  144. Lisp_Object w, *tsp = stack, nil = C_nil;
  145. #if (ARG_CUT_OFF != 25)
  146. if (ARG_CUT_OFF != 25)
  147. { fprintf(stderr, "\n+++ ARG_CUT_OFF incorrectly configured\n");
  148. my_exit(EXIT_FAILURE);
  149. }
  150. #endif
  151. w = ncons(tsp[-1]);
  152. errexit();
  153. tsp[-1] = w;
  154. while (n > ARG_CUT_OFF)
  155. { w = cons(tsp[-2], tsp[-1]);
  156. errexit();
  157. tsp[-2] = w;
  158. tsp[-1] = tsp[0];
  159. tsp--;
  160. n--;
  161. }
  162. return (*f)(def, nargs, tsp[-25], tsp[-24], tsp[-23],
  163. tsp[-22], tsp[-21], tsp[-20], tsp[-19],
  164. tsp[-18], tsp[-17], tsp[-16], tsp[-15],
  165. tsp[-14], tsp[-13], tsp[-12], tsp[-11],
  166. tsp[-10], tsp[-9], tsp[-8], tsp[-7],
  167. tsp[-6], tsp[-5], tsp[-4], tsp[-3],
  168. tsp[-2], tsp[-1]);
  169. }
  170. }
  171. }
  172. void push_args(va_list a, int nargs)
  173. /*
  174. * The unpacking here must match "apply_lots" as above. For up to
  175. * (and including) ARG_CUT_OFF (=25) args things are passed normally.
  176. * beyond that the first ARG_CUT_OFF-1 args are passed normally, and the
  177. * rest are in a list as a final actual arg. Note that this list will
  178. * have at least two elements.
  179. */
  180. {
  181. int i;
  182. if (nargs <= ARG_CUT_OFF)
  183. { for (i = 0; i<nargs; i++)
  184. { Lisp_Object w = va_arg(a, Lisp_Object);
  185. push(w);
  186. }
  187. }
  188. else
  189. { Lisp_Object x;
  190. for (i = 0; i<(ARG_CUT_OFF-1); i++)
  191. { Lisp_Object w = va_arg(a, Lisp_Object);
  192. push(w);
  193. }
  194. x = va_arg(a, Lisp_Object);
  195. /*
  196. * Internal consistency should ensure that the list passed here is long
  197. * enough for the following unpacking operation. But if (as a result of
  198. * internal system muddles it is not maybe the fact that qcar(nil) =
  199. * qcdr(nil) = nil will tend to reduce the damage?
  200. */
  201. for (; i<nargs; i++)
  202. { push(qcar(x));
  203. x = qcdr(x);
  204. }
  205. }
  206. va_end(a);
  207. }
  208. void push_args_1(va_list a, int nargs)
  209. /*
  210. * This is very much like push_args(), but is for the (rather small number
  211. * of) cases where the first argument to a function must NOT be pushed on the
  212. * stack. See, for instance, "funcall" as an example.
  213. */
  214. {
  215. int i;
  216. if (nargs <= ARG_CUT_OFF)
  217. { for (i = 1; i<nargs; i++)
  218. { Lisp_Object w = va_arg(a, Lisp_Object);
  219. push(w);
  220. }
  221. }
  222. else
  223. { Lisp_Object x;
  224. for (i = 1; i<(ARG_CUT_OFF-1); i++)
  225. { Lisp_Object w = va_arg(a, Lisp_Object);
  226. push(w);
  227. }
  228. x = va_arg(a, Lisp_Object);
  229. for (; i<nargs; i++)
  230. { push(qcar(x));
  231. x = qcdr(x);
  232. }
  233. }
  234. va_end(a);
  235. }
  236. Lisp_Object apply(Lisp_Object fn, int nargs, Lisp_Object env, Lisp_Object name)
  237. /*
  238. * There are (nargs) arguments on the Lisp stack, and apply() must use them
  239. * then pop them off. They were pushed in the order push(arg1); push(arg2),
  240. * and so on, and the stack grows upwards.
  241. * If I return with an error I will hand back the value name rather than the
  242. * junk value normally used in such cases.
  243. */
  244. {
  245. Lisp_Object def, nil = C_nil;
  246. for (;;)
  247. { if (symbolp(fn))
  248. {
  249. def = qenv(fn); /* this is passed as arg1 to the called code */
  250. /*
  251. * apply_lambda() will find arguments on the stack and is responsible for
  252. * popping them before it exits.
  253. */
  254. {
  255. /*
  256. * Because there are nargs values pushed on the (upwards growing) stack,
  257. * &stack[1-nargs] points at the first value pushed, i.e. arg-1. At one stage
  258. * I had a machine-specific bit of code (called "ncall") to do the following,
  259. * arguing that maybe in assembly code it would be possible to do much better
  260. * than the really ugly switch statement shown now. My belief now (especially
  261. * given that ncall was used in just one place - here) is that the switch will
  262. * cost no more than the procedure call did, and that in-line code will help
  263. * speed up the common and critical cases of 0, 1, 2 and 3 args. Also apply
  264. * is otherwise a reasonably short function, so if this switch is needed
  265. * anywhere here is not too bad.
  266. */
  267. push(name);
  268. switch (nargs)
  269. {
  270. /*
  271. * The Standard Lisp Report (Marti et al, Utah UUCS-78-101) only
  272. * requires support for 15 args. Common Lisp requires at least 50.
  273. * I deal with up to 8 args in-line here (I expect more than that to be
  274. * amazingly uncommon) so that this function is kept under contol.
  275. * Calls with more than 8 args go over to apply_lots, and within that
  276. * function calls with over 25 args have an even more clumsy treatment.
  277. */
  278. case 0:
  279. #ifdef DEBUG
  280. if (qfnn(fn) == NULL)
  281. { term_printf("Illegal APPLY\n");
  282. my_exit(EXIT_FAILURE);
  283. }
  284. #endif
  285. def = (*qfnn(fn))(def, 0);
  286. break;
  287. case 1:
  288. #ifdef DEBUG
  289. if (qfn1(fn) == NULL)
  290. { term_printf("Illegal APPLY\n");
  291. my_exit(EXIT_FAILURE);
  292. }
  293. #endif
  294. def = (*qfn1(fn))(def, stack[-1]);
  295. break;
  296. case 2:
  297. #ifdef DEBUG
  298. if (qfn2(fn) == NULL)
  299. { term_printf("Illegal APPLY\n");
  300. my_exit(EXIT_FAILURE);
  301. }
  302. #endif
  303. def = (*qfn2(fn))(def, stack[-2], stack[-1]);
  304. break;
  305. case 3:
  306. #ifdef DEBUG
  307. if (qfnn(fn) == NULL)
  308. { term_printf("Illegal APPLY\n");
  309. my_exit(EXIT_FAILURE);
  310. }
  311. #endif
  312. def = (*qfnn(fn))(def, 3, stack[-3], stack[-2], stack[-1]);
  313. break;
  314. case 4:
  315. #ifdef DEBUG
  316. if (qfnn(fn) == NULL)
  317. { term_printf("Illegal APPLY\n");
  318. my_exit(EXIT_FAILURE);
  319. }
  320. #endif
  321. def = (*qfnn(fn))(def, 4, stack[-4], stack[-3], stack[-2],
  322. stack[-1]);
  323. break;
  324. case 5:
  325. #ifdef DEBUG
  326. if (qfnn(fn) == NULL)
  327. { term_printf("Illegal APPLY\n");
  328. my_exit(EXIT_FAILURE);
  329. }
  330. #endif
  331. def = (*qfnn(fn))(def, 5, stack[-5], stack[-4], stack[-3],
  332. stack[-2], stack[-1]);
  333. break;
  334. case 6:
  335. #ifdef DEBUG
  336. if (qfnn(fn) == NULL)
  337. { term_printf("Illegal APPLY\n");
  338. my_exit(EXIT_FAILURE);
  339. }
  340. #endif
  341. def = (*qfnn(fn))(def, 6, stack[-6], stack[-5], stack[-4],
  342. stack[-3], stack[-2], stack[-1]);
  343. break;
  344. case 7:
  345. #ifdef DEBUG
  346. if (qfnn(fn) == NULL)
  347. { term_printf("Illegal APPLY\n");
  348. my_exit(EXIT_FAILURE);
  349. }
  350. #endif
  351. def = (*qfnn(fn))(def, 7, stack[-7], stack[-6], stack[-5],
  352. stack[-4], stack[-3], stack[-2], stack[-1]);
  353. break;
  354. case 8:
  355. #ifdef DEBUG
  356. if (qfnn(fn) == NULL)
  357. { term_printf("Illegal APPLY\n");
  358. my_exit(EXIT_FAILURE);
  359. }
  360. #endif
  361. def = (*qfnn(fn))(def, 8, stack[-8], stack[-7], stack[-6],
  362. stack[-5], stack[-4], stack[-3], stack[-2],
  363. stack[-1]);
  364. break;
  365. default:
  366. #ifdef DEBUG
  367. if (qfnn(fn) == NULL)
  368. { term_printf("Illegal APPLY\n");
  369. my_exit(EXIT_FAILURE);
  370. }
  371. #endif
  372. def = apply_lots(nargs, qfnn(fn), def);
  373. break;
  374. }
  375. /*
  376. * here I have to pop the stack by hand - note that popv does not
  377. * corrupt exit_count, which tells me how many results were being handed
  378. * back.
  379. */
  380. pop(name);
  381. popv(nargs);
  382. nil = C_nil;
  383. if (exception_pending()) return name;
  384. else return def;
  385. }
  386. }
  387. else if (!is_cons(fn))
  388. { popv(nargs);
  389. push(name);
  390. error(1, err_bad_fn, fn);
  391. pop(name);
  392. return name;
  393. }
  394. /* apply_lambda() will pop the args from the stack when it is done */
  395. if ((def = qcar(fn)) == lambda)
  396. return apply_lambda(qcdr(fn), nargs, env, name);
  397. /*
  398. * A bytecoded funarg is stored as (cfunarg <actual fn> <env>) and any call
  399. * to it behaves as if the actual function was called with the environment
  400. * passed as a forced-in first argument.
  401. */
  402. else if (def == cfunarg)
  403. { int i;
  404. push(nil);
  405. def = qcdr(fn);
  406. fn = qcar(def);
  407. for (i=0; i<nargs; i++) stack[-i] = stack[-i-1];
  408. stack[-nargs] = qcdr(def);
  409. nargs++;
  410. continue;
  411. }
  412. else if (def == funarg)
  413. { def = qcdr(fn);
  414. if (consp(def))
  415. return apply_lambda(qcdr(def), nargs, qcar(def), name);
  416. }
  417. break;
  418. }
  419. /*
  420. * Other cases are all errors.
  421. */
  422. popv(nargs);
  423. push(name);
  424. error(1, err_bad_apply, fn);
  425. pop(name);
  426. return name;
  427. }
  428. /*
  429. * Now for implementation of all the special forms...
  430. */
  431. static Lisp_Object and_fn(Lisp_Object args, Lisp_Object env)
  432. /* also needs to be a macro for Common Lisp */
  433. {
  434. Lisp_Object nil = C_nil;
  435. stackcheck2(0, args, env);
  436. if (!consp(args)) return onevalue(lisp_true);
  437. for (;;)
  438. { Lisp_Object v = qcar(args);
  439. args = qcdr(args);
  440. if (!consp(args)) return eval(v, env);
  441. push2(args, env);
  442. v = eval(v, env);
  443. pop2(env, args);
  444. errexit();
  445. if (v == nil) return onevalue(nil);
  446. }
  447. }
  448. /*
  449. * This is not used at present, but may be wanted sometime so I will
  450. * leave it here for now...
  451. *
  452. Lisp_Object append(Lisp_Object a, Lisp_Object b)
  453. {
  454. Lisp_Object nil = C_nil;
  455. if (!consp(a)) return b;
  456. else
  457. { stackcheck2(0, a, b);
  458. push(a);
  459. b = append(qcdr(a), b);
  460. pop(a);
  461. errexit();
  462. return cons(qcar(a), b);
  463. }
  464. }
  465. */
  466. static Lisp_Object block_fn(Lisp_Object args, Lisp_Object env)
  467. {
  468. Lisp_Object p, nil = C_nil;
  469. if (!consp(args)) return onevalue(nil);
  470. stackcheck2(0, args, env);
  471. push3(qcar(args), /* my_tag */
  472. qcdr(args), /* args */
  473. env);
  474. #define env stack[0]
  475. #define args stack[-1]
  476. #define my_tag stack[-2]
  477. /*
  478. * I need to augment the (lexical) environment with the name of my
  479. * tag in such a way that return-from can throw out to exactly the
  480. * correct matching level. This is done by pushing (0 . tag) onto
  481. * the environment - the 0 marks this as a block name.
  482. */
  483. my_tag = cons(fixnum_of_int(0), my_tag);
  484. errexitn(3);
  485. env = cons(my_tag, env);
  486. errexitn(3);
  487. p = nil;
  488. while (consp(args))
  489. { p = qcar(args);
  490. p = eval(p, env);
  491. /*
  492. * one of the sorts of exit that may be activated by marking nil is
  493. * a return_from. Here I need to check to see if that is what
  494. * is going on.
  495. */
  496. nil = C_nil;
  497. if (exception_pending())
  498. { flip_exception(); /* Temp restore it */
  499. qcar(my_tag) = fixnum_of_int(2); /* Invalidate */
  500. if (exit_reason == UNWIND_RETURN && exit_tag == my_tag)
  501. { exit_reason = UNWIND_NULL; /* not strictly needed - but tidy */
  502. popv(3);
  503. return nvalues(exit_value, exit_count);
  504. }
  505. if ((exit_reason & UNWIND_ERROR) != 0)
  506. { err_printf("\nEvaluating: ");
  507. loop_print_error(qcar(args));
  508. ignore_exception();
  509. }
  510. flip_exception(); /* re-instate exit condition */
  511. popv(3);
  512. return nil;
  513. }
  514. args = qcdr(args);
  515. }
  516. popv(3);
  517. return p;
  518. #undef env
  519. #undef args
  520. #undef my_tag
  521. }
  522. static Lisp_Object catch_fn(Lisp_Object args, Lisp_Object env)
  523. {
  524. Lisp_Object tag, nil = C_nil;
  525. if (!consp(args)) return onevalue(nil);
  526. stackcheck2(0, args, env);
  527. push2(args, env);
  528. tag = qcar(args);
  529. tag = eval(tag, env);
  530. errexit();
  531. tag = catch_tags = cons(tag, catch_tags);
  532. pop2(env, args);
  533. errexit();
  534. push(tag);
  535. {
  536. Lisp_Object v = progn_fn(qcdr(args), env);
  537. pop(tag);
  538. nil = C_nil;
  539. if (exception_pending())
  540. { flip_exception();
  541. catch_tags = qcdr(tag);
  542. qcar(tag) = tag;
  543. qcdr(tag) = nil; /* Invalidate the catch frame */
  544. if (exit_reason == UNWIND_THROW && exit_tag == tag)
  545. { exit_reason = UNWIND_NULL;
  546. return nvalues(exit_value, exit_count);
  547. }
  548. flip_exception();
  549. return nil;
  550. }
  551. catch_tags = qcdr(tag);
  552. qcar(tag) = tag;
  553. qcdr(tag) = nil; /* Invalidate the catch frame */
  554. return v;
  555. }
  556. }
  557. #define BODY_LET 0
  558. #define BODY_COMPILER_LET 1
  559. #define BODY_PROG 2
  560. Lisp_Object let_fn_1(Lisp_Object bvl, Lisp_Object body,
  561. Lisp_Object env, int compilerp)
  562. /*
  563. * This will have to look for (declare (special ...)).
  564. * compiler-let forces all of its bindings to be locally special. In
  565. * CSL mode I do not support local declarations, which simplifies and
  566. * speeds things up here.
  567. */
  568. {
  569. Lisp_Object nil = C_nil;
  570. stackcheck3(0, bvl, body, env);
  571. push3(bvl, body, env);
  572. nil = C_nil;
  573. push5(nil, nil, env, nil, nil);
  574. #ifdef COMMON
  575. /*
  576. * I lose the name (for security) but leave the junk stack location
  577. * (because doing otherwise seems unduly complicated.
  578. */
  579. #define local_decs stack[0]
  580. #endif
  581. #define specenv stack[-1]
  582. #define env1 stack[-2]
  583. #define p stack[-3]
  584. #define q stack[-4]
  585. #define env stack[-5]
  586. #define body stack[-6]
  587. #define bvl stack[-7]
  588. #define Return(v) { popv(8); return (v); }
  589. #ifdef COMMON
  590. /*
  591. * Find local declarations - it is necessary to macro-expand
  592. * items in the body to see if they turn into declarations.
  593. */
  594. for (;;)
  595. { if (exception_pending() || !consp(body)) break;
  596. p = macroexpand(qcar(body), env);
  597. errexitn(8);
  598. body = qcdr(body);
  599. if (!consp(p))
  600. { if (stringp(p) && consp(body)) continue;
  601. body = cons(p, body);
  602. nil = C_nil;
  603. break;
  604. }
  605. if (qcar(p) != declare_symbol)
  606. { body = cons(p, body);
  607. nil = C_nil;
  608. break;
  609. }
  610. for (p = qcdr(p); consp(p); p = qcdr(p))
  611. { q = qcar(p);
  612. if (!consp(q) || qcar(q) != special_symbol) continue;
  613. /* here q says (special ...) */
  614. for (q=qcdr(q); consp(q); q = qcdr(q))
  615. { local_decs = cons(qcar(q), local_decs);
  616. nil = C_nil;
  617. if (exception_pending()) break;
  618. }
  619. if (exception_pending()) break;
  620. }
  621. }
  622. if (exception_pending()) Return(nil);
  623. #endif
  624. for (; consp(bvl); bvl=qcdr(bvl))
  625. { Lisp_Object z;
  626. q = qcar(bvl);
  627. if (consp(q))
  628. { z = qcdr(q);
  629. q = qcar(q);
  630. if (consp(z)) z = qcar(z); else z = nil;
  631. }
  632. else z = nil;
  633. if (!is_symbol(q))
  634. { Lisp_Object qq = q;
  635. Return(error(1, err_bad_bvl, qq));
  636. }
  637. else
  638. {
  639. #ifdef COMMON
  640. Header h = qheader(q);
  641. #endif
  642. if (z != nil)
  643. { z = eval(z, env);
  644. errexitn(8);
  645. }
  646. z = cons(q, z);
  647. errexitn(8);
  648. #ifdef COMMON
  649. if (compilerp == BODY_COMPILER_LET)
  650. { specenv = cons(z, specenv);
  651. errexitn(8);
  652. q = acons(q, work_symbol, env1);
  653. errexitn(8);
  654. env1 = q; /* Locally special */
  655. }
  656. else
  657. #endif
  658. #ifndef COMMON
  659. specenv = cons(z, specenv);
  660. #else
  661. if (h & SYM_SPECIAL_VAR) specenv = cons(z, specenv);
  662. else
  663. {
  664. Lisp_Object w;
  665. for (w = local_decs; w!=nil; w = qcdr(w))
  666. { if (q != qcar(w)) continue;
  667. qcar(w) = fixnum_of_int(0);
  668. /* The next few calls to cons() maybe lose w, but that is OK! */
  669. specenv = cons(z, specenv);
  670. errexitn(8);
  671. q = acons(q, work_symbol, env1);
  672. errexitn(8);
  673. env1 = q;
  674. goto bound;
  675. }
  676. env1 = cons(z, env1);
  677. bound: ;
  678. }
  679. #endif
  680. errexitn(8);
  681. }
  682. }
  683. #ifdef COMMON
  684. while (local_decs!=nil) /* Pervasive special declarations */
  685. { Lisp_Object q1 = qcar(local_decs);
  686. local_decs=qcdr(local_decs);
  687. if (!is_symbol(q1)) continue;
  688. q1 = acons(q1, work_symbol, env1);
  689. errexitn(8);
  690. env1 = q1;
  691. }
  692. #endif
  693. if (specenv == nil)
  694. { Lisp_Object bodyx = body, env1x = env1;
  695. /*
  696. * See expansion of Return() for an explanation of why body and env1 have
  697. * been moved into new local variables before the call..
  698. */
  699. if (compilerp == BODY_PROG)
  700. { Return(tagbody_fn(bodyx, env1x));
  701. }
  702. else
  703. { Return(progn_fn(bodyx, env1x));
  704. }
  705. }
  706. /*
  707. * I instate the special bindings after all values to bind have been collected
  708. */
  709. for (p = specenv; p != nil; p = qcdr(p))
  710. { Lisp_Object w = qcar(p), v = qcar(w), z = qcdr(w);
  711. Lisp_Object old = qvalue(v);
  712. qvalue(v) = z;
  713. qcdr(w) = old;
  714. }
  715. {
  716. if (compilerp == BODY_PROG)
  717. body = tagbody_fn(body, env1);
  718. else body = progn_fn(body, env1);
  719. nil = C_nil;
  720. if (exception_pending())
  721. { flip_exception();
  722. for (p = specenv; p != nil; p = qcdr(p))
  723. { Lisp_Object w = qcar(p), v = qcar(w), z = qcdr(w);
  724. qvalue(v) = z;
  725. }
  726. flip_exception();
  727. Return(nil);
  728. }
  729. else
  730. { for (p = specenv; p != nil; p = qcdr(p))
  731. { Lisp_Object w = qcar(p), v = qcar(w), z = qcdr(w);
  732. qvalue(v) = z;
  733. }
  734. { Lisp_Object bodyx = body;
  735. Return(bodyx);
  736. }
  737. }
  738. }
  739. #ifdef COMMON
  740. #undef local_decs
  741. #endif
  742. #undef specenv
  743. #undef env1
  744. #undef p
  745. #undef q
  746. #undef env
  747. #undef body
  748. #undef bvl
  749. #undef Return
  750. }
  751. #ifdef COMMON
  752. static Lisp_Object compiler_let_fn(Lisp_Object args, Lisp_Object env)
  753. {
  754. Lisp_Object nil = C_nil;
  755. if (!consp(args)) return onevalue(nil);
  756. return let_fn_1(qcar(args), qcdr(args), env, BODY_COMPILER_LET);
  757. }
  758. #endif
  759. static Lisp_Object cond_fn(Lisp_Object args, Lisp_Object env)
  760. {
  761. Lisp_Object nil = C_nil;
  762. stackcheck2(0, args, env);
  763. while (consp(args))
  764. {
  765. Lisp_Object p = qcar(args);
  766. if (consp(p))
  767. { Lisp_Object p1;
  768. push2(args, env);
  769. p1 = qcar(p);
  770. p1 = eval(p1, env);
  771. pop2(env, args);
  772. errexit();
  773. if (p1 != nil)
  774. { args = qcdr(qcar(args));
  775. /* Here I support the case "(cond (predicate) ...)" with no consequents */
  776. if (!consp(args)) return onevalue(p1);
  777. else return progn_fn(args, env);
  778. }
  779. }
  780. args = qcdr(args);
  781. }
  782. return onevalue(nil);
  783. }
  784. #ifdef COMMON
  785. Lisp_Object declare_fn(Lisp_Object args, Lisp_Object env)
  786. /*
  787. * declarations can only properly occur at the heads of various
  788. * special forms, and so may NOT be evaluated in an ordinary manner.
  789. * Thus I am entitled (just about) to make this a no-op. It would
  790. * probably be better to arrange that (declare ...) never got evaluated
  791. * and then I could raise an error if this bit of code got activated.
  792. * Indeed (declare ...) probably does not ever get evaluated - still
  793. * a no-op here seems the safest bet.
  794. */
  795. {
  796. Lisp_Object nil = C_nil;
  797. CSL_IGNORE(env);
  798. CSL_IGNORE(args);
  799. return onevalue(nil);
  800. }
  801. #endif
  802. #define flagged_lose(v) \
  803. ((fv = qfastgets(v)) != nil && elt(fv, 1) != SPID_NOPROP)
  804. static Lisp_Object defun_fn(Lisp_Object args, Lisp_Object env)
  805. {
  806. /*
  807. * defun is eventually expected (required!) to be a macro rather than (maybe
  808. * as well as?) a special form. For bootstrap purposes it seems useful to
  809. * build it in as a special form. Also this special form is quite good enough
  810. * in CSL mode
  811. */
  812. Lisp_Object fname, nil = C_nil;
  813. CSL_IGNORE(env);
  814. if (consp(args))
  815. { fname = qcar(args);
  816. args = qcdr(args);
  817. if (is_symbol(fname))
  818. { Lisp_Object fv;
  819. if (qheader(fname) & SYM_SPECIAL_FORM)
  820. return error(1, err_redef_special, fname);
  821. if ((qheader(fname) & (SYM_C_DEF | SYM_CODEPTR)) ==
  822. (SYM_C_DEF | SYM_CODEPTR)) return onevalue(fname);
  823. if (flagged_lose(fname))
  824. { debug_printf("\n+++ ");
  825. loop_print_debug(fname);
  826. debug_printf(" not defined because of LOSE flag\n");
  827. return onevalue(nil);
  828. }
  829. qheader(fname) = qheader(fname) & ~SYM_MACRO;
  830. if ((qheader(fname) & SYM_C_DEF) != 0) lose_C_def(fname);
  831. if (qfn1(fname) != undefined1)
  832. { if (qvalue(redef_msg) != nil)
  833. { debug_printf("\n+++ ");
  834. loop_print_debug(fname);
  835. debug_printf(" redefined\n");
  836. }
  837. errexit();
  838. set_fns(fname, undefined1, undefined2, undefinedn);
  839. qenv(fname) = fname;
  840. }
  841. /*
  842. * qfn() can contain 'interpreted' for a function defined wrt the null
  843. * environment, or 'funarged' for one with an environment - in the latter
  844. * case the definition (in qenv()) is a pair (<def> . <env>)
  845. */
  846. qenv(fname) = args; /* Sort of notional lambda present */
  847. set_fns(fname, interpreted1, interpreted2, interpretedn);
  848. if (qvalue(comp_symbol) != nil &&
  849. qfn1(compiler_symbol) != undefined1)
  850. { push(fname);
  851. args = ncons(fname);
  852. nil = C_nil;
  853. if (!exception_pending())
  854. (qfn1(compiler_symbol))(qenv(compiler_symbol), args);
  855. pop(fname);
  856. }
  857. return onevalue(fname);
  858. }
  859. }
  860. return aerror("defun");
  861. }
  862. static Lisp_Object defmacro_fn(Lisp_Object args, Lisp_Object env)
  863. {
  864. /*
  865. * defmacro is eventually expected (required!) to be a macro rather than (maybe
  866. * as well as?) a special form. For bootstrap purposes it seems useful to
  867. * build it in as a special form.
  868. */
  869. Lisp_Object fname, nil = C_nil;
  870. CSL_IGNORE(env);
  871. if (consp(args))
  872. { fname = qcar(args);
  873. args = qcdr(args);
  874. if (is_symbol(fname))
  875. {
  876. if ((qheader(fname) & (SYM_C_DEF | SYM_CODEPTR)) ==
  877. (SYM_C_DEF | SYM_CODEPTR)) return onevalue(fname);
  878. qheader(fname) |= SYM_MACRO;
  879. /*
  880. * Note that a name can have a definition as a macro and as a special form,
  881. * and in that case the qfn() cell gives the special form and the qenv()
  882. * cell the macro definition. Otherwise at present I put 'undefined'
  883. * in the qfn() cell, but in due course I will want something else as better
  884. * protection against compiled code improperly attempting to call a macro.
  885. * Note also that if the symbol was a special form before I do not want
  886. * to clear the C_DEF flag, since the special form must be re-instated when
  887. * I reload the system.
  888. */
  889. if ((qheader(fname) & SYM_SPECIAL_FORM) == 0)
  890. { qheader(fname) &= ~SYM_C_DEF;
  891. if (qfn1(fname) != undefined1 &&
  892. qvalue(redef_msg) != nil)
  893. { debug_printf("\n+++ ");
  894. loop_print_debug(fname);
  895. debug_printf(" redefined as a macro\n");
  896. errexit();
  897. }
  898. set_fns(fname, undefined1, undefined2, undefinedn);
  899. }
  900. qenv(fname) = args; /* Sort of notional lambda present */
  901. if (qvalue(comp_symbol) != nil &&
  902. qfn1(compiler_symbol) != undefined1)
  903. { Lisp_Object t1, t2;
  904. push(fname);
  905. if (!(consp(args) &&
  906. consp(qcdr(args)) &&
  907. qcdr(qcdr(args)) == nil &&
  908. (t1 = qcar(args),
  909. t2 = qcdr(qcar(qcdr(args))),
  910. equal(t1, t2))))
  911. { errexitn(1);
  912. fname = stack[0];
  913. args = ncons(fname);
  914. nil = C_nil;
  915. if (!exception_pending())
  916. (qfn1(compiler_symbol))(qenv(compiler_symbol), args);
  917. }
  918. pop(fname);
  919. errexit();
  920. }
  921. return onevalue(fname);
  922. }
  923. }
  924. return aerror("defmacro");
  925. }
  926. static Lisp_Object eval_when_fn(Lisp_Object args, Lisp_Object env)
  927. /*
  928. * When interpreted, eval-when just looks for the situation EVAL.
  929. */
  930. {
  931. Lisp_Object situations, nil = C_nil;
  932. if (!consp(args)) return onevalue(nil);
  933. situations = qcar(args);
  934. args = qcdr(args);
  935. while (consp(situations))
  936. { if (qcar(situations) == eval_symbol) return progn_fn(args, env);
  937. situations = qcdr(situations);
  938. }
  939. return onevalue(nil);
  940. }
  941. #ifdef COMMON
  942. static Lisp_Object flet_fn(Lisp_Object args, Lisp_Object env)
  943. {
  944. Lisp_Object my_env, d, nil = C_nil;
  945. if (!consp(args)) return onevalue(nil);
  946. stackcheck2(0, args, env);
  947. my_env = env;
  948. d = qcar(args); /* The bunch of definitions */
  949. args = qcdr(args);
  950. nil = C_nil;
  951. while (consp(d))
  952. { Lisp_Object w = qcar(d);
  953. if (consp(w) && consp(qcdr(w)))
  954. { Lisp_Object w1;
  955. push4(args, d, env, w);
  956. w1 = list2star(funarg, my_env, qcdr(w));
  957. pop(w);
  958. nil = C_nil;
  959. if (!exception_pending()) w1 = cons(w1, qcar(w));
  960. pop(env);
  961. nil = C_nil;
  962. if (!exception_pending()) env = cons(w1, env);
  963. pop2(d, args);
  964. errexit();
  965. }
  966. d = qcdr(d);
  967. }
  968. /*
  969. * Treat body as (let nil ...) to get (declare ...) recognized.
  970. */
  971. return let_fn_1(nil, args, env, BODY_LET);
  972. }
  973. #endif
  974. Lisp_Object function_fn(Lisp_Object args, Lisp_Object env)
  975. {
  976. /*
  977. * For most things this behaves just like (quote xxx), but
  978. * (function (lambda (x) y)) gets converted to
  979. * (funarg env (x) y).
  980. */
  981. Lisp_Object nil = C_nil;
  982. if (consp(args) && qcdr(args) == nil)
  983. { args = qcar(args);
  984. if (consp(args) && qcar(args) == lambda)
  985. args = list2star(funarg, env, qcdr(args));
  986. return onevalue(args);
  987. }
  988. return aerror("function");
  989. }
  990. static Lisp_Object go_fn(Lisp_Object args, Lisp_Object env)
  991. {
  992. Lisp_Object p, tag, nil = C_nil;
  993. CSL_IGNORE(env);
  994. if (!consp(args)) return aerror("go");
  995. else tag = qcar(args);
  996. for(p=env; consp(p); p=qcdr(p))
  997. { Lisp_Object w = qcar(p), z;
  998. if (!consp(w)) continue;
  999. if (qcar(w) == fixnum_of_int(1) &&
  1000. (z = qcar(qcdr(w)), eql(z, tag)))
  1001. { p = w;
  1002. goto tag_found;
  1003. }
  1004. }
  1005. return error(1, err_go_tag, tag);
  1006. tag_found:
  1007. exit_tag = p;
  1008. exit_count = 0;
  1009. exit_reason = UNWIND_GO;
  1010. flip_exception(); /* Exceptional exit active */
  1011. return nil;
  1012. }
  1013. static Lisp_Object if_fn(Lisp_Object args, Lisp_Object env)
  1014. {
  1015. Lisp_Object nil = C_nil;
  1016. Lisp_Object p=nil, tr=nil, fs=nil;
  1017. if (!consp(args)) return aerror("if");
  1018. p = qcar(args);
  1019. args = qcdr(args);
  1020. if (!consp(args)) return aerror("if");
  1021. tr = qcar(args);
  1022. args = qcdr(args);
  1023. if (!consp(args)) fs = nil;
  1024. else
  1025. { fs = qcar(args);
  1026. args = qcdr(args);
  1027. if (args != nil) return aerror("if");
  1028. }
  1029. stackcheck4(0, p, env, tr, fs);
  1030. push3(fs, tr, env);
  1031. p = eval(p, env);
  1032. pop3(env, tr, fs);
  1033. errexit();
  1034. if (p == nil)
  1035. return eval(fs, env); /* tail call on result */
  1036. else return eval(tr, env); /* ... passing back values */
  1037. }
  1038. #ifdef COMMON
  1039. static Lisp_Object labels_fn(Lisp_Object args, Lisp_Object env)
  1040. {
  1041. Lisp_Object my_env, d, nil = C_nil;
  1042. if (!consp(args)) return onevalue(nil);
  1043. stackcheck2(0, args, env);
  1044. my_env = env;
  1045. d = qcar(args); /* The bunch of definitions */
  1046. while (consp(d))
  1047. { Lisp_Object w = qcar(d);
  1048. if (consp(w) && consp(qcdr(w)))
  1049. { Lisp_Object w1;
  1050. push4(args, d, env, w);
  1051. w1 = list2star(funarg, nil, qcdr(w));
  1052. pop(w);
  1053. nil = C_nil;
  1054. if (!exception_pending()) w1 = cons(w1, qcar(w));
  1055. pop(env);
  1056. nil = C_nil;
  1057. if (!exception_pending()) env = cons(w1, env);
  1058. pop2(d, args);
  1059. errexit();
  1060. }
  1061. d = qcdr(d);
  1062. }
  1063. /*
  1064. * Now patch up the environments stored with the local defs so as to
  1065. * permit mutual recursion between them all.
  1066. */
  1067. for (d=env; d!=my_env; d=qcdr(d))
  1068. qcar(qcdr(qcar(qcar(d)))) = env;
  1069. return let_fn_1(nil, qcdr(args), env, BODY_LET);
  1070. }
  1071. #endif
  1072. static Lisp_Object let_fn(Lisp_Object args, Lisp_Object env)
  1073. {
  1074. Lisp_Object nil = C_nil;
  1075. if (!consp(args)) return onevalue(nil);
  1076. return let_fn_1(qcar(args), qcdr(args), env, BODY_LET);
  1077. }
  1078. static Lisp_Object letstar_fn(Lisp_Object args, Lisp_Object env)
  1079. /*
  1080. * This will have to look for (declare (special ...)), unless
  1081. * I am in CSL mode.
  1082. */
  1083. {
  1084. Lisp_Object nil = C_nil;
  1085. if (!consp(args)) return onevalue(nil);
  1086. stackcheck2(0, args, env);
  1087. push3(qcar(args), qcdr(args), env);
  1088. nil = C_nil;
  1089. push5(nil, nil, /* p, q */
  1090. env, nil, nil); /* env1, specenv, local_decs */
  1091. #ifdef COMMON
  1092. #define local_decs stack[0]
  1093. #endif
  1094. #define specenv stack[-1]
  1095. #define env1 stack[-2]
  1096. #define p stack[-3]
  1097. #define q stack[-4]
  1098. #define env stack[-5]
  1099. #define body stack[-6]
  1100. #define bvl stack[-7]
  1101. #define Return(v) { popv(8); return (v); }
  1102. #ifdef COMMON
  1103. for (;;)
  1104. { if (exception_pending() || !consp(body)) break;
  1105. p = macroexpand(qcar(body), env);
  1106. errexitn(8);
  1107. body = qcdr(body);
  1108. if (!consp(p))
  1109. { if (stringp(p) && consp(body)) continue;
  1110. body = cons(p, body);
  1111. nil = C_nil;
  1112. break;
  1113. }
  1114. if (qcar(p) != declare_symbol)
  1115. { body = cons(p, body);
  1116. nil = C_nil;
  1117. break;
  1118. }
  1119. for (p = qcdr(p); consp(p); p = qcdr(p))
  1120. { q = qcar(p);
  1121. if (!consp(q) || qcar(q) != special_symbol) continue;
  1122. /* here q says (special ...) */
  1123. for (q=qcdr(q); consp(q); q = qcdr(q))
  1124. { local_decs = cons(qcar(q), local_decs);
  1125. nil = C_nil;
  1126. if (exception_pending()) break;
  1127. }
  1128. if (exception_pending()) break;
  1129. }
  1130. }
  1131. if (exception_pending()) Return(nil);
  1132. #endif
  1133. for (; consp(bvl); bvl=qcdr(bvl))
  1134. { Lisp_Object z;
  1135. q = qcar(bvl);
  1136. if (consp(q))
  1137. { z = qcdr(q);
  1138. q = qcar(q);
  1139. if (consp(z)) z = qcar(z); else z = nil;
  1140. }
  1141. else z = nil;
  1142. if (!is_symbol(q))
  1143. { error(1, err_bad_bvl, q);
  1144. goto unwind_special_bindings;
  1145. }
  1146. else
  1147. {
  1148. #ifdef COMMON
  1149. Header h = qheader(q);
  1150. #endif
  1151. if (z != nil)
  1152. { z = eval(z, env);
  1153. nil = C_nil;
  1154. if (exception_pending()) goto unwind_special_bindings;
  1155. }
  1156. #ifndef COMMON
  1157. p = z;
  1158. z = acons(q, qvalue(q), specenv);
  1159. nil = C_nil;
  1160. if (!exception_pending()) specenv = z;
  1161. qvalue(q) = p;
  1162. #else
  1163. if (h & SYM_SPECIAL_VAR)
  1164. {
  1165. p = z;
  1166. z = acons(q, qvalue(q), specenv);
  1167. nil = C_nil;
  1168. if (!exception_pending()) specenv = z;
  1169. qvalue(q) = p;
  1170. }
  1171. else
  1172. {
  1173. for (p = local_decs; p!=nil; p = qcdr(p))
  1174. { Lisp_Object w;
  1175. if (q != qcar(p)) continue;
  1176. qcar(p) = fixnum_of_int(0);
  1177. w = acons(q, qvalue(q), specenv);
  1178. nil = C_nil;
  1179. if (exception_pending()) goto unwind_special_bindings;
  1180. specenv = w;
  1181. w = acons(q, work_symbol, env);
  1182. nil = C_nil;
  1183. if (exception_pending()) goto unwind_special_bindings;
  1184. env = w;
  1185. qvalue(q) = z;
  1186. goto bound;
  1187. }
  1188. q = acons(q, z, env);
  1189. nil = C_nil;
  1190. if (exception_pending()) goto unwind_special_bindings;
  1191. env = q;
  1192. bound: ;
  1193. }
  1194. #endif
  1195. nil = C_nil;
  1196. if (exception_pending()) goto unwind_special_bindings;
  1197. }
  1198. }
  1199. #ifdef COMMON
  1200. while (local_decs!=nil) /* Pervasive special declarations */
  1201. { q = qcar(local_decs);
  1202. local_decs=qcdr(local_decs);
  1203. if (!is_symbol(q)) continue;
  1204. q = acons(q, work_symbol, env);
  1205. nil = C_nil;
  1206. if (!exception_pending()) env = q;
  1207. else goto unwind_special_bindings;
  1208. }
  1209. #endif
  1210. if (specenv == nil)
  1211. { Lisp_Object bodyx = body, envx = env;
  1212. Return(progn_fn(bodyx, envx)); /* beware Return macro! */
  1213. }
  1214. {
  1215. body = progn_fn(body, env);
  1216. nil = C_nil;
  1217. if (exception_pending()) goto unwind_special_bindings;
  1218. for (bvl = specenv; bvl != nil; bvl = qcdr(bvl))
  1219. { Lisp_Object w = qcar(bvl), v = qcar(w), z = qcdr(w);
  1220. qvalue(v) = z;
  1221. }
  1222. { Lisp_Object bodyx = body;
  1223. Return(bodyx);
  1224. }
  1225. }
  1226. unwind_special_bindings:
  1227. flip_exception();
  1228. for (bvl = specenv; bvl != nil; bvl = qcdr(bvl))
  1229. { Lisp_Object w = qcar(bvl), v = qcar(w), z = qcdr(w);
  1230. qvalue(v) = z;
  1231. }
  1232. flip_exception();
  1233. popv(8);
  1234. return nil;
  1235. #ifdef COMMON
  1236. #undef local_decs
  1237. #endif
  1238. #undef specenv
  1239. #undef env1
  1240. #undef p
  1241. #undef q
  1242. #undef env
  1243. #undef body
  1244. #undef bvl
  1245. #undef Return
  1246. }
  1247. setup_type const eval2_setup[] =
  1248. /*
  1249. * A jolly curiosity - "function" and "declare" are ALSO set up in
  1250. * restart.c (because handles are needed on the symbols). I leave
  1251. * the redundant initialisation here too since I find it clearer that
  1252. * way.
  1253. */
  1254. {
  1255. {"and", and_fn, bad_special2, bad_specialn},
  1256. {"catch", catch_fn, bad_special2, bad_specialn},
  1257. {"cond", cond_fn, bad_special2, bad_specialn},
  1258. /*
  1259. * I am not over-enthusiastic about supporting eval-when in CSL, but
  1260. * something of that sort seems needed by some bits of code that I have
  1261. * come across...
  1262. */
  1263. {"eval-when", eval_when_fn, bad_special2, bad_specialn},
  1264. {"function", function_fn, bad_special2, bad_specialn},
  1265. {"go", go_fn, bad_special2, bad_specialn},
  1266. {"if", if_fn, bad_special2, bad_specialn},
  1267. {"let*", letstar_fn, bad_special2, bad_specialn},
  1268. /* DE and DM are used as low level primitives in the Common Lisp bootstrap */
  1269. {"de", defun_fn, bad_special2, bad_specialn},
  1270. {"dm", defmacro_fn, bad_special2, bad_specialn},
  1271. #ifdef COMMON
  1272. {"block", block_fn, bad_special2, bad_specialn},
  1273. {"compiler-let", compiler_let_fn, bad_special2, bad_specialn},
  1274. {"declare", declare_fn, bad_special2, bad_specialn},
  1275. {"flet", flet_fn, bad_special2, bad_specialn},
  1276. {"labels", labels_fn, bad_special2, bad_specialn},
  1277. {"let", let_fn, bad_special2, bad_specialn},
  1278. #else
  1279. {"~block", block_fn, bad_special2, bad_specialn},
  1280. {"~let", let_fn, bad_special2, bad_specialn},
  1281. #endif
  1282. {NULL, 0, 0, 0}};
  1283. /* end of eval2.c */