p-apply-lap.red 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. %
  2. % P-APPLY-LAP.RED - Inefficient, portable version of APPLY-LAP
  3. %
  4. % Author: Eric Benson
  5. % Symbolic Computation Group
  6. % Computer Science Dept.
  7. % University of Utah
  8. % Date: 29 July 1982
  9. % Copyright (c) 1982 University of Utah
  10. %
  11. % Functions which must be written non-portably:
  12. % CodePrimitive
  13. % Takes the code pointer stored in the fluid variable CodePtr!*
  14. % and jumps to its address, without distubing any of the argument
  15. % registers. This can be flagged 'InternalFunction for compilation
  16. % before this file is compiled or done as an 'OpenCode and 'ExitOpenCode
  17. % property for the compiler.
  18. % CompiledCallingInterpreted
  19. % Called by some convention from the function cell of an ID which
  20. % has an interpreted function definition. It should store the ID
  21. % in the fluid variable CodeForm!* without disturbing the argument
  22. % registers, then finish with
  23. % (!*JCALL CompiledCallingInterpretedAux)
  24. % (CompiledCallingInterpretedAux may be flagged 'InternalFunction).
  25. % FastApply
  26. % Called with a functional form in (reg t1) and argument registers
  27. % loaded. If it is a code pointer or an ID, the function address
  28. % associated with either should be jumped to. If it is anything else
  29. % except a lambda form, an error should be signaled. If it is a lambda
  30. % form, store (reg t1) in the fluid variable CodeForm!* and
  31. % (!*JCALL FastLambdaApply)
  32. % (FastLambdaApply may be flagged 'InternalFunction).
  33. % UndefinedFunction
  34. % Called by some convention from the function cell of an ID (probably
  35. % the same as CompiledCallingInterpreted) for an undefined function.
  36. % Should call Error with the ID as part of the error message.
  37. CompileTime <<
  38. flag('(CompiledCallingInterpretedAuxAux BindEvalAux SaveRegisters),
  39. 'InternalFunction);
  40. fluid '(CodePtr!* % gets code pointer used by CodePrimitive
  41. CodeForm!* % gets fn to be called from code
  42. );
  43. >>;
  44. on Syslisp;
  45. internal WArray CodeArgs[15];
  46. syslsp procedure CodeApply(CodePtr, ArgList);
  47. begin scalar I;
  48. I := 0;
  49. LispVar CodePtr!* := CodePtr;
  50. while PairP ArgList and ILessP(I, 15) do
  51. << WPutV(CodeArgs , I, first ArgList);
  52. I := IAdd1 I;
  53. ArgList := rest ArgList >>;
  54. if IGEQ(I, 15) then return StdError "Too many arguments to function";
  55. return case I of
  56. 0:
  57. CodePrimitive();
  58. 1:
  59. CodePrimitive WGetV(CodeArgs, 0);
  60. 2:
  61. CodePrimitive(WGetV(CodeArgs, 0),
  62. WGetV(CodeArgs, 1));
  63. 3:
  64. CodePrimitive(WGetV(CodeArgs, 0),
  65. WGetV(CodeArgs, 1),
  66. WGetV(CodeArgs, 2));
  67. 4:
  68. CodePrimitive(WGetV(CodeArgs, 0),
  69. WGetV(CodeArgs, 1),
  70. WGetV(CodeArgs, 2),
  71. WGetV(CodeArgs, 3));
  72. 5:
  73. CodePrimitive(WGetV(CodeArgs, 0),
  74. WGetV(CodeArgs, 1),
  75. WGetV(CodeArgs, 2),
  76. WGetV(CodeArgs, 3),
  77. WGetV(CodeArgs, 4));
  78. 6:
  79. CodePrimitive(WGetV(CodeArgs, 0),
  80. WGetV(CodeArgs, 1),
  81. WGetV(CodeArgs, 2),
  82. WGetV(CodeArgs, 3),
  83. WGetV(CodeArgs, 4),
  84. WGetV(CodeArgs, 5));
  85. 7:
  86. CodePrimitive(WGetV(CodeArgs, 0),
  87. WGetV(CodeArgs, 1),
  88. WGetV(CodeArgs, 2),
  89. WGetV(CodeArgs, 3),
  90. WGetV(CodeArgs, 4),
  91. WGetV(CodeArgs, 5),
  92. WGetV(CodeArgs, 6));
  93. 8:
  94. CodePrimitive(WGetV(CodeArgs, 0),
  95. WGetV(CodeArgs, 1),
  96. WGetV(CodeArgs, 2),
  97. WGetV(CodeArgs, 3),
  98. WGetV(CodeArgs, 4),
  99. WGetV(CodeArgs, 5),
  100. WGetV(CodeArgs, 6),
  101. WGetV(CodeArgs, 7));
  102. 9:
  103. CodePrimitive(WGetV(CodeArgs, 0),
  104. WGetV(CodeArgs, 1),
  105. WGetV(CodeArgs, 2),
  106. WGetV(CodeArgs, 3),
  107. WGetV(CodeArgs, 4),
  108. WGetV(CodeArgs, 5),
  109. WGetV(CodeArgs, 6),
  110. WGetV(CodeArgs, 7),
  111. WGetV(CodeArgs, 8));
  112. 10:
  113. CodePrimitive(WGetV(CodeArgs, 0),
  114. WGetV(CodeArgs, 1),
  115. WGetV(CodeArgs, 2),
  116. WGetV(CodeArgs, 3),
  117. WGetV(CodeArgs, 4),
  118. WGetV(CodeArgs, 5),
  119. WGetV(CodeArgs, 6),
  120. WGetV(CodeArgs, 7),
  121. WGetV(CodeArgs, 8),
  122. WGetV(CodeArgs, 9));
  123. 11:
  124. CodePrimitive(WGetV(CodeArgs, 0),
  125. WGetV(CodeArgs, 1),
  126. WGetV(CodeArgs, 2),
  127. WGetV(CodeArgs, 3),
  128. WGetV(CodeArgs, 4),
  129. WGetV(CodeArgs, 5),
  130. WGetV(CodeArgs, 6),
  131. WGetV(CodeArgs, 7),
  132. WGetV(CodeArgs, 8),
  133. WGetV(CodeArgs, 9),
  134. WGetV(CodeArgs, 10));
  135. 12:
  136. CodePrimitive(WGetV(CodeArgs, 0),
  137. WGetV(CodeArgs, 1),
  138. WGetV(CodeArgs, 2),
  139. WGetV(CodeArgs, 3),
  140. WGetV(CodeArgs, 4),
  141. WGetV(CodeArgs, 5),
  142. WGetV(CodeArgs, 6),
  143. WGetV(CodeArgs, 7),
  144. WGetV(CodeArgs, 8),
  145. WGetV(CodeArgs, 9),
  146. WGetV(CodeArgs, 10),
  147. WGetV(CodeArgs, 11));
  148. 13:
  149. CodePrimitive(WGetV(CodeArgs, 0),
  150. WGetV(CodeArgs, 1),
  151. WGetV(CodeArgs, 2),
  152. WGetV(CodeArgs, 3),
  153. WGetV(CodeArgs, 4),
  154. WGetV(CodeArgs, 5),
  155. WGetV(CodeArgs, 6),
  156. WGetV(CodeArgs, 7),
  157. WGetV(CodeArgs, 8),
  158. WGetV(CodeArgs, 9),
  159. WGetV(CodeArgs, 10),
  160. WGetV(CodeArgs, 11),
  161. WGetV(CodeArgs, 12));
  162. 14:
  163. CodePrimitive(WGetV(CodeArgs, 0),
  164. WGetV(CodeArgs, 1),
  165. WGetV(CodeArgs, 2),
  166. WGetV(CodeArgs, 3),
  167. WGetV(CodeArgs, 4),
  168. WGetV(CodeArgs, 5),
  169. WGetV(CodeArgs, 6),
  170. WGetV(CodeArgs, 7),
  171. WGetV(CodeArgs, 8),
  172. WGetV(CodeArgs, 9),
  173. WGetV(CodeArgs, 10),
  174. WGetV(CodeArgs, 11),
  175. WGetV(CodeArgs, 12),
  176. WGetV(CodeArgs, 13));
  177. 15:
  178. CodePrimitive(WGetV(CodeArgs, 0),
  179. WGetV(CodeArgs, 1),
  180. WGetV(CodeArgs, 2),
  181. WGetV(CodeArgs, 3),
  182. WGetV(CodeArgs, 4),
  183. WGetV(CodeArgs, 5),
  184. WGetV(CodeArgs, 6),
  185. WGetV(CodeArgs, 7),
  186. WGetV(CodeArgs, 8),
  187. WGetV(CodeArgs, 9),
  188. WGetV(CodeArgs, 10),
  189. WGetV(CodeArgs, 11),
  190. WGetV(CodeArgs, 12),
  191. WGetV(CodeArgs, 13),
  192. WGetV(CodeArgs, 14));
  193. end;
  194. end;
  195. %lisp procedure CodeEvalApply(CodePtr, ArgList);
  196. % CodeApply(CodePtr, EvLis ArgList);
  197. lap '((!*entry CodeEvalApply expr 2)
  198. (!*ALLOC 15)
  199. (!*LOC (reg 3) (frame 15))
  200. (!*CALL CodeEvalApplyAux)
  201. (!*EXIT 15)
  202. );
  203. syslsp procedure CodeEvalApplyAux(CodePtr, ArgList, P);
  204. begin scalar N;
  205. N := 0;
  206. while PairP ArgList and ILessP(N, 15) do
  207. << WPutV(P, ITimes2(StackDirection, N), Eval first ArgList);
  208. ArgList := rest ArgList;
  209. N := IAdd1 N >>;
  210. if IGEQ(N, 15) then return StdError "Too many arguments to function";
  211. LispVar CodePtr!* := CodePtr;
  212. return case N of
  213. 0:
  214. CodePrimitive();
  215. 1:
  216. CodePrimitive WGetV(P, ITimes2(StackDirection, 0));
  217. 2:
  218. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  219. WGetV(P, ITimes2(StackDirection, 1)));
  220. 3:
  221. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  222. WGetV(P, ITimes2(StackDirection, 1)),
  223. WGetV(P, ITimes2(StackDirection, 2)));
  224. 4:
  225. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  226. WGetV(P, ITimes2(StackDirection, 1)),
  227. WGetV(P, ITimes2(StackDirection, 2)),
  228. WGetV(P, ITimes2(StackDirection, 3)));
  229. 5:
  230. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  231. WGetV(P, ITimes2(StackDirection, 1)),
  232. WGetV(P, ITimes2(StackDirection, 2)),
  233. WGetV(P, ITimes2(StackDirection, 3)),
  234. WGetV(P, ITimes2(StackDirection, 4)));
  235. 6:
  236. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  237. WGetV(P, ITimes2(StackDirection, 1)),
  238. WGetV(P, ITimes2(StackDirection, 2)),
  239. WGetV(P, ITimes2(StackDirection, 3)),
  240. WGetV(P, ITimes2(StackDirection, 4)),
  241. WGetV(P, ITimes2(StackDirection, 5)));
  242. 7:
  243. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  244. WGetV(P, ITimes2(StackDirection, 1)),
  245. WGetV(P, ITimes2(StackDirection, 2)),
  246. WGetV(P, ITimes2(StackDirection, 3)),
  247. WGetV(P, ITimes2(StackDirection, 4)),
  248. WGetV(P, ITimes2(StackDirection, 5)),
  249. WGetV(P, ITimes2(StackDirection, 6)));
  250. 8:
  251. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  252. WGetV(P, ITimes2(StackDirection, 1)),
  253. WGetV(P, ITimes2(StackDirection, 2)),
  254. WGetV(P, ITimes2(StackDirection, 3)),
  255. WGetV(P, ITimes2(StackDirection, 4)),
  256. WGetV(P, ITimes2(StackDirection, 5)),
  257. WGetV(P, ITimes2(StackDirection, 6)),
  258. WGetV(P, ITimes2(StackDirection, 7)));
  259. 9:
  260. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  261. WGetV(P, ITimes2(StackDirection, 1)),
  262. WGetV(P, ITimes2(StackDirection, 2)),
  263. WGetV(P, ITimes2(StackDirection, 3)),
  264. WGetV(P, ITimes2(StackDirection, 4)),
  265. WGetV(P, ITimes2(StackDirection, 5)),
  266. WGetV(P, ITimes2(StackDirection, 6)),
  267. WGetV(P, ITimes2(StackDirection, 7)),
  268. WGetV(P, ITimes2(StackDirection, 8)));
  269. 10:
  270. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  271. WGetV(P, ITimes2(StackDirection, 1)),
  272. WGetV(P, ITimes2(StackDirection, 2)),
  273. WGetV(P, ITimes2(StackDirection, 3)),
  274. WGetV(P, ITimes2(StackDirection, 4)),
  275. WGetV(P, ITimes2(StackDirection, 5)),
  276. WGetV(P, ITimes2(StackDirection, 6)),
  277. WGetV(P, ITimes2(StackDirection, 7)),
  278. WGetV(P, ITimes2(StackDirection, 8)),
  279. WGetV(P, ITimes2(StackDirection, 9)));
  280. 11:
  281. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  282. WGetV(P, ITimes2(StackDirection, 1)),
  283. WGetV(P, ITimes2(StackDirection, 2)),
  284. WGetV(P, ITimes2(StackDirection, 3)),
  285. WGetV(P, ITimes2(StackDirection, 4)),
  286. WGetV(P, ITimes2(StackDirection, 5)),
  287. WGetV(P, ITimes2(StackDirection, 6)),
  288. WGetV(P, ITimes2(StackDirection, 7)),
  289. WGetV(P, ITimes2(StackDirection, 8)),
  290. WGetV(P, ITimes2(StackDirection, 9)),
  291. WGetV(P, ITimes2(StackDirection, 10)));
  292. 12:
  293. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  294. WGetV(P, ITimes2(StackDirection, 1)),
  295. WGetV(P, ITimes2(StackDirection, 2)),
  296. WGetV(P, ITimes2(StackDirection, 3)),
  297. WGetV(P, ITimes2(StackDirection, 4)),
  298. WGetV(P, ITimes2(StackDirection, 5)),
  299. WGetV(P, ITimes2(StackDirection, 6)),
  300. WGetV(P, ITimes2(StackDirection, 7)),
  301. WGetV(P, ITimes2(StackDirection, 8)),
  302. WGetV(P, ITimes2(StackDirection, 9)),
  303. WGetV(P, ITimes2(StackDirection, 10)),
  304. WGetV(P, ITimes2(StackDirection, 11)));
  305. 13:
  306. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  307. WGetV(P, ITimes2(StackDirection, 1)),
  308. WGetV(P, ITimes2(StackDirection, 2)),
  309. WGetV(P, ITimes2(StackDirection, 3)),
  310. WGetV(P, ITimes2(StackDirection, 4)),
  311. WGetV(P, ITimes2(StackDirection, 5)),
  312. WGetV(P, ITimes2(StackDirection, 6)),
  313. WGetV(P, ITimes2(StackDirection, 7)),
  314. WGetV(P, ITimes2(StackDirection, 8)),
  315. WGetV(P, ITimes2(StackDirection, 9)),
  316. WGetV(P, ITimes2(StackDirection, 10)),
  317. WGetV(P, ITimes2(StackDirection, 11)),
  318. WGetV(P, ITimes2(StackDirection, 12)));
  319. 14:
  320. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  321. WGetV(P, ITimes2(StackDirection, 1)),
  322. WGetV(P, ITimes2(StackDirection, 2)),
  323. WGetV(P, ITimes2(StackDirection, 3)),
  324. WGetV(P, ITimes2(StackDirection, 4)),
  325. WGetV(P, ITimes2(StackDirection, 5)),
  326. WGetV(P, ITimes2(StackDirection, 6)),
  327. WGetV(P, ITimes2(StackDirection, 7)),
  328. WGetV(P, ITimes2(StackDirection, 8)),
  329. WGetV(P, ITimes2(StackDirection, 9)),
  330. WGetV(P, ITimes2(StackDirection, 10)),
  331. WGetV(P, ITimes2(StackDirection, 11)),
  332. WGetV(P, ITimes2(StackDirection, 12)),
  333. WGetV(P, ITimes2(StackDirection, 13)));
  334. 15:
  335. CodePrimitive(WGetV(P, ITimes2(StackDirection, 0)),
  336. WGetV(P, ITimes2(StackDirection, 1)),
  337. WGetV(P, ITimes2(StackDirection, 2)),
  338. WGetV(P, ITimes2(StackDirection, 3)),
  339. WGetV(P, ITimes2(StackDirection, 4)),
  340. WGetV(P, ITimes2(StackDirection, 5)),
  341. WGetV(P, ITimes2(StackDirection, 6)),
  342. WGetV(P, ITimes2(StackDirection, 7)),
  343. WGetV(P, ITimes2(StackDirection, 8)),
  344. WGetV(P, ITimes2(StackDirection, 9)),
  345. WGetV(P, ITimes2(StackDirection, 10)),
  346. WGetV(P, ITimes2(StackDirection, 11)),
  347. WGetV(P, ITimes2(StackDirection, 12)),
  348. WGetV(P, ITimes2(StackDirection, 13)),
  349. WGetV(P, ITimes2(StackDirection, 14)));
  350. end;
  351. end;
  352. off Syslisp;
  353. syslsp procedure BindEval(Formals, Args);
  354. BindEvalAux(Formals, Args, 0);
  355. syslsp procedure BindEvalAux(Formals, Args, N);
  356. begin scalar F, A;
  357. return if PairP Formals then
  358. if PairP Args then
  359. << F := first Formals;
  360. A := Eval first Args;
  361. N := BindEvalAux(rest Formals, rest Args, IAdd1 N);
  362. if N = -1 then -1 else
  363. << LBind1(F, A);
  364. N >> >>
  365. else -1
  366. else if PairP Args then -1
  367. else N;
  368. end;
  369. syslsp procedure SaveRegisters(A1, A2, A3, A4, A5,
  370. A6, A7, A8, A9, A10,
  371. A11, A12, A13, A14, A15);
  372. << CodeArgs[14] := A15;
  373. CodeArgs[13] := A14;
  374. CodeArgs[12] := A13;
  375. CodeArgs[11] := A12;
  376. CodeArgs[10] := A11;
  377. CodeArgs[9] := A10;
  378. CodeArgs[8] := A9;
  379. CodeArgs[7] := A8;
  380. CodeArgs[6] := A7;
  381. CodeArgs[5] := A6;
  382. CodeArgs[4] := A5;
  383. CodeArgs[3] := A4;
  384. CodeArgs[2] := A3;
  385. CodeArgs[1] := A2;
  386. CodeArgs[0] := A1 >>;
  387. syslsp procedure CompiledCallingInterpretedAux();
  388. << SaveRegisters();
  389. CompiledCallingInterpretedAuxAux get(LispVar CodeForm!*, '!*LambdaLink) >>;
  390. syslsp procedure FastLambdaApply();
  391. << SaveRegisters();
  392. CompiledCallingInterpretedAuxAux LispVar CodeForm!* >>;
  393. syslsp procedure CompiledCallingInterpretedAuxAux Fn;
  394. if not (PairP Fn and car Fn = 'LAMBDA) then
  395. StdError BldMsg("Ill-formed functional expression %r for %r",
  396. Fn, LispVar CodeForm!*)
  397. else begin scalar Formals, N, Result;
  398. Formals := cadr Fn;
  399. N := 0;
  400. while PairP Formals do
  401. << LBind1(car Formals, WGetV(CodeArgs, N));
  402. Formals := cdr Formals;
  403. N := IAdd1 N >>;
  404. Result := EvProgN cddr Fn;
  405. if N neq 0 then UnBindN N;
  406. return Result;
  407. end;
  408. off Syslisp;
  409. END;