p-apply-lap.red 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. %
  2. % P-APPLY-LAP.RED - Inefficient, portable version of APPLY-LAP
  3. %
  4. % Author: Eric Benson and M. L. Griss
  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. % Modifications by M.L. Griss 25 October, 1982.
  12. % Added J. MacDonalds Mods of 29 January (for IBM, non neg stack index)
  13. % In CODEEVALAPLY
  14. % Functions which must be written non-portably,
  15. % "portable" versions defined in PT:TEST-FUNCTION-PRIMITIVES.RED
  16. % CodePrimitive
  17. % Takes the code pointer stored in the fluid variable CodePtr!*
  18. % and jumps to its address, without distubing any of the argument
  19. % registers. This can be flagged 'InternalFunction for compilation
  20. % before this file is compiled or done as an 'OpenCode and 'ExitOpenCode
  21. % property for the compiler.
  22. % CompiledCallingInterpreted
  23. % Called by some convention from the function cell of an ID which
  24. % has an interpreted function definition. It should store the ID
  25. % in the fluid variable CodeForm!* without disturbing the argument
  26. % registers, then finish with
  27. % (!*JCALL CompiledCallingInterpretedAux)
  28. % (CompiledCallingInterpretedAux may be flagged 'InternalFunction).
  29. % FastApply
  30. % Called with a functional form in (reg t1) and argument registers
  31. % loaded. If it is a code pointer or an ID, the function address
  32. % associated with either should be jumped to. If it is anything else
  33. % except a lambda form, an error should be signaled. If it is a lambda
  34. % form, store (reg t1) in the fluid variable CodeForm!* and
  35. % (!*JCALL FastLambdaApply)
  36. % (FastLambdaApply may be flagged 'InternalFunction).
  37. % UndefinedFunction
  38. % Called by some convention from the function cell of an ID (probably
  39. % the same as CompiledCallingInterpreted) for an undefined function.
  40. % Should call Error with the ID as part of the error message.
  41. Compiletime <<
  42. fluid '(CodePtr!* % gets code pointer used by CodePrimitive
  43. CodeForm!* % gets fn to be called from code
  44. );
  45. >>;
  46. on Syslisp;
  47. external WArray CodeArgs;
  48. syslsp procedure CodeApply(CodePtr, ArgList);
  49. begin scalar I;
  50. I := 0;
  51. LispVar CodePtr!* := CodePtr;
  52. while PairP ArgList and ILessP(I, 15) do
  53. << WPutV(CodeArgs , I, first ArgList);
  54. I := IAdd1 I;
  55. ArgList := rest ArgList >>;
  56. if IGEQ(I, 15)
  57. then return StdError List("Too many arguments to function",I,CodePtr);
  58. return case I of
  59. 0: CodePrimitive();
  60. 1: CodePrimitive WGetV(CodeArgs, 0);
  61. 2: CodePrimitive(WGetV(CodeArgs, 0), WGetV(CodeArgs, 1));
  62. 3: CodePrimitive(WGetV(CodeArgs, 0), WgetV(CodeArgs, 1),
  63. WGetV(CodeArgs, 2));
  64. 4: CodePrimitive(WGetV(CodeArgs, 0), WgetV(CodeArgs, 1),
  65. WGetV(CodeArgs, 2), WgetV(CodeArgs, 3));
  66. 5: CodePrimitive(WGetV(CodeArgs, 0), WgetV(CodeArgs, 1),
  67. WGetV(CodeArgs, 2), WgetV(CodeArgs, 3),
  68. WGetV(CodeArgs, 4));
  69. 6: CodePrimitive(WGetV(CodeArgs, 0), WgetV(CodeArgs, 1),
  70. WGetV(CodeArgs, 2), WgetV(CodeArgs, 3),
  71. WGetV(CodeArgs, 4), WgetV(CodeArgs, 5));
  72. 7: CodePrimitive(WGetV(CodeArgs, 0), WgetV(CodeArgs, 1),
  73. WgetV(CodeArgs, 2), WgetV(CodeArgs, 3),
  74. WgetV(CodeArgs, 4), WgetV(CodeArgs, 5),
  75. WgetV(CodeArgs, 6));
  76. 8: CodePrimitive(WgetV(CodeArgs, 0), WgetV(CodeArgs, 1),
  77. WgetV(CodeArgs, 2), WgetV(CodeArgs, 3),
  78. WgetV(CodeArgs, 4), WgetV(CodeArgs, 5),
  79. WgetV(CodeArgs, 6), WgetV(CodeArgs, 7));
  80. 9: CodePrimitive(WgetV(CodeArgs, 0), WgetV(CodeArgs, 1),
  81. WgetV(CodeArgs, 2), WgetV(CodeArgs, 3),
  82. WgetV(CodeArgs, 4), WgetV(CodeArgs, 5),
  83. WgetV(CodeArgs, 6), WgetV(CodeArgs, 7),
  84. WgetV(CodeArgs, 8));
  85. 10: CodePrimitive(WgetV(CodeArgs, 0), WgetV(CodeArgs, 1),
  86. WgetV(CodeArgs, 2), WgetV(CodeArgs, 3),
  87. WgetV(CodeArgs, 4), WgetV(CodeArgs, 5),
  88. WgetV(CodeArgs, 6), WgetV(CodeArgs, 7),
  89. WgetV(CodeArgs, 8), WgetV(CodeArgs, 9));
  90. 11: CodePrimitive(WgetV(CodeArgs, 0), WgetV(CodeArgs, 1),
  91. WgetV(CodeArgs, 2), WgetV(CodeArgs, 3),
  92. WgetV(CodeArgs, 4), WgetV(CodeArgs, 5),
  93. WgetV(CodeArgs, 6), WgetV(CodeArgs, 7),
  94. WgetV(CodeArgs, 8), WgetV(CodeArgs, 9),
  95. WgetV(CodeArgs, 10));
  96. 12: CodePrimitive(WgetV(CodeArgs, 0), WgetV(CodeArgs, 1),
  97. WgetV(CodeArgs, 2), WgetV(CodeArgs, 3),
  98. WgetV(CodeArgs, 4), WgetV(CodeArgs, 5),
  99. WgetV(CodeArgs, 6), WgetV(CodeArgs, 7),
  100. WgetV(CodeArgs, 8), WgetV(CodeArgs, 9),
  101. WgetV(CodeArgs, 10), WgetV(CodeArgs, 11));
  102. 13: CodePrimitive(WgetV(CodeArgs, 0), WgetV(CodeArgs, 1),
  103. WgetV(CodeArgs, 2), WgetV(CodeArgs, 3),
  104. WgetV(CodeArgs, 4), WgetV(CodeArgs, 5),
  105. WgetV(CodeArgs, 6), WgetV(CodeArgs, 7),
  106. WgetV(CodeArgs, 8), WgetV(CodeArgs, 9),
  107. WgetV(CodeArgs, 10), WgetV(CodeArgs, 11),
  108. WgetV(CodeArgs, 12));
  109. 14: CodePrimitive(WgetV(CodeArgs, 0), WgetV(CodeArgs, 1),
  110. WgetV(CodeArgs, 2), WgetV(CodeArgs, 3),
  111. WgetV(CodeArgs, 4), WgetV(CodeArgs, 5),
  112. WgetV(CodeArgs, 6), WgetV(CodeArgs, 7),
  113. WgetV(CodeArgs, 8), WgetV(CodeArgs, 9),
  114. WgetV(CodeArgs, 10), WgetV(CodeArgs, 11),
  115. WgetV(CodeArgs, 12), WgetV(CodeArgs, 13));
  116. 15: CodePrimitive(WgetV(CodeArgs, 0), WgetV(CodeArgs, 1),
  117. WgetV(CodeArgs, 2), WgetV(CodeArgs, 3),
  118. WgetV(CodeArgs, 4), WgetV(CodeArgs, 5),
  119. WgetV(CodeArgs, 6), WgetV(CodeArgs, 7),
  120. WgetV(CodeArgs, 8), WgetV(CodeArgs, 9),
  121. WgetV(CodeArgs, 10), WgetV(CodeArgs, 11),
  122. WgetV(CodeArgs, 12), WgetV(CodeArgs, 13),
  123. WgetV(CodeArgs, 14));
  124. end;
  125. end;
  126. %lisp procedure CodeEvalApply(CodePtr, ArgList);
  127. % CodeApply(CodePtr, EvLis ArgList);
  128. lap '((!*entry CodeEvalApply expr 2)
  129. (!*ALLOC 15)
  130. (!*LOC (reg 3) (frame 15)) %/jim really wrong/
  131. % (!*LOC (reg 3) (frame 1)) %/jim: for non-neg stack indices on IBM/
  132. % But must be base of a block of ascending
  133. % addresses, check cmacros
  134. (!*CALL CodeEvalApplyAux)
  135. (!*EXIT 15)
  136. );
  137. syslsp procedure CodeEvalApplyAux(CodePtr, ArgList, P);
  138. begin scalar N;
  139. N := 0;
  140. while PairP ArgList and ILessP(N, 15) do
  141. %/ << WPutV(P, ITimes2(StackDirection, N), Eval first ArgList); %/jim/
  142. << WPutV(P, N, Eval first ArgList); %/jim/
  143. ArgList := rest ArgList;
  144. N := IAdd1 N >>;
  145. if IGEQ(N, 15)
  146. then return StdError list("Too many arguments to function",N,CodePtr);
  147. LispVar CodePtr!* := CodePtr;
  148. return case N of
  149. 0: CodePrimitive();
  150. 1: CodePrimitive(WgetV(P, 0));
  151. 2: CodePrimitive(WgetV(P, 0), WgetV(P, 1));
  152. 3: CodePrimitive(WgetV(P, 0), WgetV(P, 1), WgetV(P, 2));
  153. 4: CodePrimitive(WgetV(P, 0), WgetV(P, 1), WgetV(P, 2),
  154. WgetV(P, 3));
  155. 5: CodePrimitive(WgetV(P, 0), WgetV(P, 1), WgetV(P, 2),
  156. WgetV(P, 3), WgetV(P, 4));
  157. 6: CodePrimitive(WgetV(P, 0), WgetV(P, 1), WgetV(P, 2),
  158. WgetV(P, 3), WgetV(P, 4), WgetV(P, 5));
  159. 7: CodePrimitive(WgetV(P, 0), WgetV(P, 1), WgetV(P, 2),
  160. WgetV(P, 3), WgetV(P, 4), WgetV(P, 5),
  161. WgetV(P, 6));
  162. 8: CodePrimitive(WgetV(P, 0), WgetV(P, 1), WgetV(P, 2),
  163. WgetV(P, 3), WgetV(P, 4), WgetV(P, 5),
  164. WgetV(P, 6), WgetV(P, 7));
  165. 9: CodePrimitive(WgetV(P, 0), WgetV(P, 1), WgetV(P, 2),
  166. WgetV(P, 3), WgetV(P, 4), WgetV(P, 5),
  167. WgetV(P, 6), WgetV(P, 7), WgetV(P, 8));
  168. 10: CodePrimitive(WgetV(P, 0), WgetV(P, 1), WgetV(P, 2),
  169. WgetV(P, 3), WgetV(P, 4), WgetV(P, 5),
  170. WgetV(P, 6), WgetV(P, 7), WgetV(P, 8),
  171. WgetV(P, 9));
  172. 11: CodePrimitive(WgetV(P, 0), WgetV(P, 1), WgetV(P, 2),
  173. WgetV(P, 3), WgetV(P, 4), WgetV(P, 5),
  174. WgetV(P, 6), WgetV(P, 7), WgetV(P, 8),
  175. WgetV(P, 9), WgetV(P, 10));
  176. 12: CodePrimitive(WgetV(P, 0), WgetV(P, 1), WgetV(P, 2),
  177. WgetV(P, 3), WgetV(P, 4), WgetV(P, 5),
  178. WgetV(P, 6), WgetV(P, 7), WgetV(P, 8),
  179. WgetV(P, 9), WgetV(P, 10), WgetV(P, 11));
  180. 13: CodePrimitive(WgetV(P, 0), WgetV(P, 1), WgetV(P, 2),
  181. WgetV(P, 3), WgetV(P, 4), WgetV(P, 5),
  182. WgetV(P, 6), WgetV(P, 7), WgetV(P, 8),
  183. WgetV(P, 9), WgetV(P, 10), WgetV(P, 11),
  184. WgetV(P, 12));
  185. 14: CodePrimitive(WgetV(P, 0), WgetV(P, 1), WgetV(P, 2),
  186. WgetV(P, 3), WgetV(P, 4), WgetV(P, 5),
  187. WgetV(P, 6), WgetV(P, 7), WgetV(P, 8),
  188. WgetV(P, 9), WgetV(P, 10), WgetV(P, 11),
  189. WgetV(P, 12), WgetV(P, 13));
  190. 15: CodePrimitive(WgetV(P, 0), WgetV(P, 1), WgetV(P, 2),
  191. WgetV(P, 3), WgetV(P, 4), WgetV(P, 5),
  192. WgetV(P, 6), WgetV(P, 7), WgetV(P, 8),
  193. WgetV(P, 9), WgetV(P, 10), WgetV(P, 11),
  194. WgetV(P, 12), WgetV(P, 13), WgetV(P, 14));
  195. end;
  196. end;
  197. syslsp procedure BindEval(Formals, Args);
  198. BindEvalAux(Formals, Args, 0);
  199. syslsp procedure BindEvalAux(Formals, Args, N);
  200. begin scalar F, A;
  201. return if PairP Formals then
  202. if PairP Args then
  203. << F := first Formals;
  204. A := Eval first Args;
  205. N := BindEvalAux(rest Formals, rest Args, IAdd1 N);
  206. if N = -1 then -1 else
  207. << LBind1(F, A);
  208. N >> >>
  209. else -1
  210. else if PairP Args then -1
  211. else N;
  212. end;
  213. syslsp procedure CompiledCallingInterpretedAux();
  214. << %Later Use NARGS also
  215. % Recall that ID# in CODEFORM
  216. CompiledCallingInterpretedAuxAux
  217. get(MkID(LispVar CodeForm!*), '!*LambdaLink)>>;
  218. syslsp procedure FastLambdaApply();
  219. << SaveRegisters();
  220. CompiledCallingInterpretedAuxAux LispVar CodeForm!* >>;
  221. syslsp procedure CompiledCallingInterpretedAuxAux Fn;
  222. if not (PairP Fn and car Fn = 'LAMBDA) then
  223. StdError BldMsg("Ill-formed functional expression %r for %r",
  224. Fn, LispVar CodeForm!*)
  225. else begin scalar Formals, N, Result;
  226. Formals := cadr Fn;
  227. N := 0;
  228. while PairP Formals do
  229. << LBind1(car Formals,WgetV(CodeArgs, N));
  230. Formals := cdr Formals;
  231. N := IAdd1 N >>;
  232. Result := EvProgN cddr Fn;
  233. if N neq 0 then UnBindN N;
  234. return Result;
  235. end;
  236. off Syslisp;
  237. END;