pas3.red 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. %
  3. % PASCAL BASED MINI-LISP
  4. %
  5. % File: PAS3.RED - Basic LISP Functions
  6. % ChangeDate: 10:48pm Wednesday, 15 July 1981
  7. % By: M. L. Griss
  8. % Change to add Features for Schlumberger Demo
  9. %
  10. % All RIGHTS RESERVED
  11. % COPYRIGHT (C) - 1981 - M. L. GRISS
  12. % Computer Science Department
  13. % University of Utah
  14. %
  15. % Do Not distribute with out written consent of M. L. Griss
  16. %
  17. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  18. %. Tagged TCATCH and TTHROW In terms of CATCH and THROW
  19. SYMBOLIC PROCEDURE TCATCH(TG,FORM);
  20. BEGIN SCALAR VAL;
  21. THROWING!* := NIL;
  22. VAL:=CATCH(FORM);
  23. IF NULL TG OR NULL THROWING!* THEN RETURN VAL; % CatchALL
  24. IF THROWTAG!* EQ TG THEN RETURN VAL;
  25. THROW VAL;
  26. END;
  27. SYMBOLIC PROCEDURE TTHROW(TG,VAL);
  28. <<THROWING!* := 'T;
  29. THROWTAG!* := TG;
  30. THROW VAL>>;
  31. SYMBOLIC PROCEDURE GETD NAM; %. Return (type.code) if func
  32. BEGIN SCALAR TY,V;
  33. IF NOT IDP NAM THEN RETURN NIL;
  34. TY:=GET(NAM,'TYPE);
  35. V:=FUNCELL NAM;
  36. IF NULL TY AND V THEN TY:='EXPR;
  37. IF V THEN RETURN (TY . V) ELSE RETURN NIL;
  38. END;
  39. SYMBOLIC PROCEDURE PUTD(NAM,TY,BOD); %. Make function entry
  40. IF FLAGP(NAM, 'LOSE) THEN
  41. << ERRPRT LIST(NAM,'not,'flagged,'LOSE); NAM >>
  42. ELSE BEGIN
  43. IF GETD(NAM) THEN MSGPRT LIST('Function,NAM,'redefined);
  44. IF (CODEP BOD OR EQCAR(BOD,'LAMBDA)
  45. AND TY MEMQ '(EXPR FEXPR NEXPR MACRO) )
  46. THEN <<IF TY EQ 'EXPR THEN TY:=NIL;
  47. PUT(NAM,'TYPE,TY);
  48. SETFUNCELL(NAM,BOD)>>
  49. ELSE RETURN ERROR(99,LIST(NAM,'Cant,'be,'defined));
  50. RETURN NAM;
  51. END;
  52. SYMBOLIC PROCEDURE REMD NAM; %. Remove function defn
  53. BEGIN SCALAR PR;
  54. IF (PR:=GETD NAM) THEN <<SETFUNCELL(NAM,NIL);
  55. REMPROP(NAM,'TYPE)>>;
  56. RETURN PR;
  57. END;
  58. %. Convenient definitions
  59. SYMBOLIC PROCEDURE PUTL(L,IND,VAL);
  60. IF NOT PAIRP L THEN NIL
  61. ELSE <<PUT(CAR L,IND,VAL);
  62. PUTL(CDR L,IND,VAL)>>;
  63. SYMBOLIC FEXPR PROCEDURE DE L;
  64. PUTD(CAR L,'EXPR,'LAMBDA . CDR L);
  65. SYMBOLIC FEXPR PROCEDURE DF L;
  66. PUTD(CAR L,'FEXPR,'LAMBDA . CDR L);
  67. SYMBOLIC FEXPR PROCEDURE DN L;
  68. PUTD(CAR L,'NEXPR,'LAMBDA . CDR L);
  69. SYMBOLIC FEXPR PROCEDURE DM L;
  70. PUTD(CAR L,'MACRO,'LAMBDA . CDR L);
  71. %. d) Improved EVAL, with LAMBDA, FEXPR, etc
  72. SYMBOLIC PROCEDURE EVAL(X);
  73. BEGIN SCALAR FN,A,TY;
  74. L:IF IDP(X) THEN RETURN VALUE(X)
  75. ELSE IF NOT PAIRP(X) OR (FN := CAR X) EQ 'LAMBDA THEN
  76. RETURN X;
  77. A := CDR X; % Arguments
  78. IF FN EQ 'QUOTE THEN %Important special Fexprs
  79. RETURN CAR(A);
  80. IF FN EQ 'SETQ THEN RETURN SET(CAR A,EVAL CADR A);
  81. IF IDP FN AND (TY := GET(FN, 'TYPE)) THEN
  82. <<IF TY EQ 'FEXPR THEN
  83. RETURN APPLY1(FN,A); % No Spread, No EVAL
  84. IF TY EQ 'NEXPR THEN
  85. RETURN APPLY1(FN,EVLIS A); % No Spread, EVAL
  86. IF TY EQ 'MACRO % Reval full form
  87. THEN <<X := APPLY1(FN,X); GOTO L >> >>;
  88. A := EVLIS A;
  89. IF FN EQ 'LIST THEN RETURN A;
  90. RETURN APPLY(FN,A);
  91. END;
  92. SYMBOLIC PROCEDURE APPLY1(FN,A);
  93. APPLY(FN, A . NIL);
  94. SYMBOLIC PROCEDURE APPLY(FN,A);
  95. BEGIN SCALAR EFN;
  96. EFN := FUNCELL FN;
  97. IF CODEP EFN THEN RETURN XAPPLY(EFN,A); % Spread args and EXECUTE
  98. RETURN EVLAM(EFN,A);
  99. END;
  100. SYMBOLIC PROCEDURE EVLIS(L);
  101. IF NOT PAIRP L THEN EVAL L
  102. ELSE EVAL(CAR L) . EVLIS(CDR L);
  103. %. Some standard FEXPRS and MACROS
  104. SYMBOLIC FEXPR PROCEDURE PROGN ARGS; %. Evaluate a LIST
  105. P!.N ARGS;
  106. SYMBOLIC PROCEDURE PROG2(A,B); B;
  107. SYMBOLIC PROCEDURE P!.N ARGS; %. EVALS elems of list and returns last
  108. BEGIN SCALAR ANS;
  109. WHILE PAIRP ARGS DO <<ANS := EVAL CAR ARGS; ARGS:=CDR ARGS>>;
  110. RETURN ANS
  111. END;
  112. %.===== Section 3.7 ===== Program Feature functions
  113. % All this stuff should be rewritten to use the same binding mechanism as
  114. % compiled code, and obey the same constraints on placement of GO/RETURN
  115. % as compiled code.
  116. SYMBOLIC FEXPR PROCEDURE RETURN E; %. Return From Current PROG
  117. << P!.P := NIL;
  118. TTHROW('!$PROG!$,P!.N E) >>;
  119. SYMBOLIC FEXPR PROCEDURE GO E; %. Go to label in Current PROG
  120. BEGIN SCALAR L;
  121. E := CAR E;
  122. REPEAT <<
  123. WHILE NOT IDP E DO
  124. ERROR(1100,LIST(E,'Not,'Label));
  125. L := ATSOC(E,P!.G);
  126. IF ATOM L THEN
  127. ERROR(1101,LIST(E,'Not,'a,'label))>>
  128. UNTIL PAIRP L;
  129. P!.P := CDR L;
  130. TTHROW('!$PROG!$,NIL)
  131. END;
  132. SYMBOLIC FEXPR PROCEDURE PROG E; %. Program feature interpreter
  133. % P!.P is Next SEXPR to EVAL
  134. BEGIN SCALAR TG,X,V,NVALS,SAVEP,SAVEG;
  135. SAVEP:=P!.P;
  136. SAVEG:=P!.G; % Note FLUIDS not yet working compiled
  137. NVALS :=LENGTH CAR E;
  138. PBINDN CAR E; % Bind each to NIL, putting old value on BSTACK
  139. P!.P := CDR E;
  140. % The code body
  141. X := P!.P;
  142. P!.G := NIL;
  143. FOR EACH U ON P!.P DO
  144. IF IDP CAR U THEN
  145. P!.G := U . P!.G;
  146. THROWING!* := NIL;
  147. TG := '!$PROG!$;
  148. WHILE P!.P AND TG EQ '!$PROG!$ DO <<
  149. X := CAR P!.P;
  150. P!.P := CDR P!.P;
  151. IF NOT IDP X THEN <<
  152. X := TCATCH(NIL,X);
  153. IF THROWING!* THEN
  154. <<TG := THROWTAG!*; V:=X>> >> >>;
  155. % UNBIND Even if thrown through
  156. UNBINDN NVALS;
  157. P!.P := SAVEP;
  158. P!.G := SAVEG;
  159. IF NOT(TG EQ '!$PROG!$) THEN
  160. TTHROW(TG,V)
  161. ELSE
  162. RETURN V
  163. END;
  164. SYMBOLIC FEXPR PROCEDURE WHILE ARGS; %. Simple WHILE LOOP
  165. % Will do (WHILE bool s1 .. sn)
  166. BEGIN SCALAR BOOL;
  167. IF NOT PAIRP ARGS THEN RETURN NIL;
  168. BOOL:=CAR ARGS;
  169. L1: IF NULL EVAL BOOL THEN RETURN NIL;
  170. P!.N CDR ARGS;
  171. GOTO L1
  172. END;
  173. SYMBOLIC FEXPR PROCEDURE AND(X); %. Xis list of actions
  174. BEGIN
  175. IF NOT PAIRP X THEN RETURN(T);
  176. L: IF NULL CDR(X) THEN RETURN(EVAL(CAR X))
  177. ELSE IF NULL EVAL(CAR X) THEN RETURN(NIL)
  178. ELSE << X:=CDR X; GOTO L >>
  179. END;
  180. %/// Add also IF ?
  181. SYMBOLIC FEXPR PROCEDURE COND(E); %. Conditional eval
  182. BEGIN SCALAR PR,Y;
  183. L: IF NOT PAIRP E THEN RETURN NIL;
  184. PR:=CAR E; E:=CDR E;
  185. IF PAIRP PR THEN Y:=CAR PR ELSE Y:=PR;
  186. IF NULL (Y:=EVAL(Y)) THEN GOTO L;
  187. IF NULL PAIRP PR OR NULL CDR PR THEN RETURN(Y);
  188. RETURN P!.N(CDR PR)
  189. END;
  190. SYMBOLIC FEXPR PROCEDURE OR(X); %. Or of action list
  191. BEGIN SCALAR Y;
  192. L: IF NOT PAIRP X THEN RETURN(NIL)
  193. ELSE IF(Y:=EVAL(CAR X)) THEN RETURN(Y)
  194. ELSE << X:=CDR X;GOTO L >>
  195. END;
  196. %.===== Section 3.12 ===== MAP composite functions
  197. SYMBOLIC PROCEDURE MAP(X,FN); %. Apply FN to each cdr x
  198. WHILE X DO <<APPLY1(FN,X); X := CDR X>>;
  199. SYMBOLIC PROCEDURE MAPC(X,FN); %. Apply FN to each car x
  200. WHILE X DO <<APPLY1(FN,CAR X); X := CDR X>>;
  201. SYMBOLIC PROCEDURE MAPCAN(X,FN); %. Append FN car x
  202. IF ATOM X THEN NIL ELSE NCONC(APPLY1(FN,CAR X),MAPCAN(CDR X,FN));
  203. SYMBOLIC PROCEDURE MAPCAR(X,FN); %. Collect FN car x
  204. IF ATOM X THEN NIL ELSE APPLY1(FN,CAR X) . MAPCAR(CDR X,FN);
  205. SYMBOLIC PROCEDURE MAPCON(X,FN); %. Append FN cdr x
  206. IF ATOM X THEN NIL ELSE NCONC(APPLY1(FN,X),MAPCON(CDR X,FN));
  207. SYMBOLIC PROCEDURE MAPLIST(X,FN); %. Collect FN cdr x
  208. IF ATOM X THEN NIL ELSE APPLY1(FN,X) . MAPLIST(CDR X,FN);
  209. SYMBOLIC PROCEDURE NCONC(U,V); %. Tack V onto end U
  210. BEGIN SCALAR W;
  211. IF ATOM U THEN RETURN V;
  212. W := U;
  213. WHILE PAIRP CDR W DO W := CDR W;
  214. RPLACD(W,V);
  215. RETURN U
  216. END;
  217. %... This procedure drives a simple read/eval/print top loop.
  218. SYMBOLIC PROCEDURE PUTC(X,Y,Z);
  219. PUT(X,Y,Z);
  220. SYMBOLIC PROCEDURE FLUID L;
  221. L;
  222. SYMBOLIC PROCEDURE PRIN2TL L;
  223. IF NOT PAIRP L THEN TERPRI()
  224. ELSE <<PRIN2 CAR L; PRIN2 '! ; PRIN2TL CDR L>>;
  225. % ... Missing functions to complete Standard LISP set
  226. % ... some dummies developed for PERQ, modified to better use PASLSP
  227. SYMBOLIC PROCEDURE FLOATP X; NIL;
  228. SYMBOLIC PROCEDURE STRINGP X; IDP X;
  229. SYMBOLIC PROCEDURE VECTORP X; NIL;
  230. SYMBOLIC PROCEDURE FLUIDP X; NIL;
  231. SYMBOLIC PROCEDURE INTERN X; X;
  232. SYMBOLIC PROCEDURE REMOB X; NIL;
  233. SYMBOLIC PROCEDURE GLOBAL X;
  234. WHILE X DO <<FLAG(X,'GLOBAL); X := CDR X>>;
  235. SYMBOLIC PROCEDURE GLOBALP X;
  236. FLAGP(X,'GLOBAL);
  237. SYMBOLIC PROCEDURE UNFLUID X;
  238. NIL;
  239. % No vectors yet
  240. SYMBOLIC PROCEDURE GETV(A,B); NIL;
  241. SYMBOLIC PROCEDURE MKVECT X; NIL;
  242. SYMBOLIC PROCEDURE PUTV(A,B,C); NIL;
  243. SYMBOLIC PROCEDURE UPBV X; NIL;
  244. SYMBOLIC PROCEDURE DIGIT X; NIL;
  245. SYMBOLIC PROCEDURE LITER X; NIL;
  246. SYMBOLIC PROCEDURE READCH X; NIL; %/ Needs Interp Mod
  247. SYMBOLIC PROCEDURE RDEVPR;
  248. WHILE T DO PRINT EVAL READ();
  249. SYMBOLIC PROCEDURE DSKIN(FILE);
  250. BEGIN SCALAR TMP;
  251. TMP := RDS OPEN(FILE, 'INPUT);
  252. WHILE NULL EOFP PRINT EVAL READ() DO NIL; %Use RDEVPR ?
  253. CLOSE RDS TMP;
  254. END;
  255. SYMBOLIC PROCEDURE !*FIRST!-PROCEDURE;
  256. BEGIN SCALAR X, EOFFLG, OUT;
  257. PRIN2TL '(Pascal LISP V2 !- 15 Feb 1982);
  258. PRIN2TL '(Copyright (c) 1981 U UTAH);
  259. PRIN2TL '(All Rights Reserved);
  260. NEXPRS:='(LIST);
  261. PUTL(NEXPRS,'TYPE,'NEXPR);
  262. PROCS:='(EXPR FEXPR NEXPR MACRO);
  263. EOFFLG := NIL;
  264. % Continue reading Init-File on channel 1;
  265. WHILE NOT EOFFLG DO
  266. << X := READ();
  267. EOFFLG := EOFP(X);
  268. IF NOT EOFFLG THEN
  269. EVAL X
  270. >>;
  271. RDS(2); % Switch to USER input, THE TTY
  272. EOFFLG := NIL;
  273. WHILE NOT EOFFLG DO
  274. <<OUT := WRS 3; PRIN2 '!>; WRS OUT; % Prompt, OUT holds channel #
  275. X := READ();
  276. IF EQCAR(X,'QUIT) THEN EOFFLG := 'T ELSE EOFFLG := EOFP(X);
  277. IF NOT EOFFLG THEN
  278. PRIN2T(CATCH X)
  279. >>;
  280. PRIN2T LIST('EXITING,'Top,'Loop);
  281. END;
  282. END;