rcref.red 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743
  1. COMMENT Cross reference program module;
  2. COMMENT Requires REDIO.RED file to define I/O primitives and sorting
  3. functions;
  4. SYMBOLIC;
  5. DEFLIST('((ANLFN PROCSTAT) (CRFLAPO PROCSTAT)),'STAT);
  6. FLAG('(ANLFN CRFLAPO),'COMPILE);
  7. GLOBAL '(UNDEFG!* GSEEN!* BTIME!*
  8. EXPAND!* HAVEARGS!* NOTUSE!*
  9. NOLIST!* DCLGLB!*
  10. ENTPTS!* UNDEFNS!* SEEN!* TSEEN!*
  11. OP!*!*
  12. CLOC!* PFILES!*
  13. CURLIN!* PRETITL!* !*CREFTIME
  14. !*SAVEPROPS DFPRINT!* MAXARG!* !*CREFSUMMARY
  15. !*RLISP !*CREF !*DEFN !*MODE
  16. !*GLOBALS !*ALGEBRAICS
  17. );
  18. FLUID '(GLOBS!* CALLS!* LOCLS!* TOPLV!* CURFUN!*
  19. );
  20. !*ALGEBRAICS:='T; % Default is normal parse of algebraic;
  21. !*GLOBALS:='T; % Do analyze globals;
  22. !*RLISP:=NIL; % REDUCE as default;
  23. !*SAVEPROPS:=NIL;
  24. MAXARG!*:=15; % Maximum args in Standard Lisp;
  25. COMMENT EXPAND flag on these forces expansion of MACROS;
  26. EXPAND!*:='(
  27. );
  28. SYMBOLIC PROCEDURE STANDARDFUNCTIONS L;
  29. NOLIST!* := NCONC(DEFLIST(L,'ARGCOUNT),NOLIST!*);
  30. STANDARDFUNCTIONS '( (LAMBDA 2)
  31. (ABS 1) (ADD1 1) (APPEND 2) (APPLY 2) (ASSOC 2) (ATOM 1)
  32. (CAR 1) (CDR 1) (CAAR 1) (CADR 1) (CDAR 1) (CDDR 1)
  33. (CAAAR 1) (CAADR 1) (CADAR 1) (CADDR 1) (CDAAR 1) (CDADR 1)
  34. (CDDAR 1) (CDDDR 1)
  35. (CAAAAR 1) (CAAADR 1) (CAADAR 1) (CAADDR 1)
  36. (CADAAR 1) (CADADR 1) (CADDAR 1) (CADDDR 1)
  37. (CDAAAR 1) (CDAADR 1) (CDADAR 1) (CDADDR 1)
  38. (CDDAAR 1) (CDDADR 1) (CDDDAR 1) (CDDDDR 1)
  39. (CLOSE 1) (CODEP 1) (COMPRESS 1) (CONS 2) (CONSTANTP 1)
  40. (DE 3) (DEFLIST 2) (DELETE 2) (DF 3) (DIFFERENCE 2) (DIGIT 1)
  41. (DIVIDE 2) (DM 3)
  42. (EJECT 0) (EQ 2) (EQN 2) (EQUAL 2) (ERROR 2) (ERRORSET 3)
  43. (EVAL 1) (EVLIS 1) (EXPAND 2) (EXPLODE 1) (EXPT 2)
  44. (FIX 1) (FIXP 1) (FLAG 2) (FLAGP 2) (FLOAT 1) (FLOATP 1)
  45. (FLUID 1) (FLUIDP 1) (FUNCTION 1)
  46. (GENSYM 0) (GET 2) (GETD 1) (GETV 2) (GLOBAL 1)
  47. (GLOBALP 1) (GO 1) (GREATERP 2)
  48. (IDP 1) (INTERN 1) (LENGTH 1) (LESSP 2) (LINELENGTH 1)
  49. (LITER 1) (LPOSN 0)
  50. (MAP 2) (MAPC 2) (MAPCAN 2) (MAPCAR 2) (MAPCON 2)
  51. (MAPLIST 2) (MAX2 2) (MEMBER 2) (MEMQ 2)
  52. (MINUS 1) (MINUSP 1) (MIN2 2) (MKVECT 1) (NCONC 2) (NOT 1) (NULL 1)
  53. (NUMBERP 1) (ONEP 1) (OPEN 2)
  54. (PAGELENGTH 1) (PAIR 2) (PAIRP 1) (PLUS2 2) (POSN 0)
  55. (PRIN2 1) (PRINT 1) (PRIN1 1) (PRIN2 1) (PROG2 2)
  56. (PUT 3) (PUTD 3) (PUTV 3) (QUOTE 1) (QUOTIENT 2)
  57. (RDS 1) (READ 0) (READCH 0) (REMAINDER 2) (REMD 1)
  58. (REMFLAG 2) (REMOB 1) (REMPROP 2) (RETURN 1)
  59. (REVERSE 1) (RPLACA 2) (RPLACD 2) (SASSOC 3) (SET 2) (SETQ 2)
  60. (STRINGP 1) (SUBLIS 2) (SUBST 3) (SUB1 1)
  61. (TERPRI 0) (TIMES2 2) (UNFLUID 1) (UPBV 1) (VECTORP 1) (WRS 1)
  62. (ZEROP 1)
  63. );
  64. NOLIST!*:=APPEND('(AND COND LIST MAX MIN OR PLUS PROG PROG2
  65. PROGN TIMES),NOLIST!*);
  66. FLAG ('(PLUS TIMES AND OR PROGN MAX MIN COND PROG
  67. CASE LIST),
  68. 'NARYARGS);
  69. DCLGLB!*:='(!*COMP EMSG!* !*RAISE);
  70. IF NOT GETD 'BEGIN THEN
  71. FLAG('(RDS DEFLIST FLAG FLUID GLOBAL REMPROP REMFLAG UNFLUID
  72. SETQ CREFOFF),'EVAL);
  73. SYMBOLIC PROCEDURE CREFON;
  74. BEGIN SCALAR A,OCRFIL,CRFIL;
  75. BTIME!*:=TIME();
  76. DFPRINT!* := 'REFPRINT;
  77. !*DEFN := T;
  78. IF NOT !*ALGEBRAICS THEN PUT('ALGEBRAIC,'NEWNAM,'SYMBOLIC);
  79. FLAG(NOLIST!*,'NOLIST);
  80. FLAG(EXPAND!*,'EXPAND);
  81. FLAG(DCLGLB!*,'DCLGLB);
  82. % Global lists;
  83. ENTPTS!*:=NIL; % Entry points to package;
  84. UNDEFNS!*:=NIL; % Functions undefined in package;
  85. SEEN!*:=NIL; % List of all encountered functions;
  86. TSEEN!*:=NIL; % List of all encountered types not flagged
  87. % FUNCTION;
  88. GSEEN!*:=NIL; % All encountered globals;
  89. PFILES!*:=NIL; % Processed files;
  90. UNDEFG!*:=NIL; % Undeclared globals encountered;
  91. CURLIN!*:=NIL; % Position in file(s) of current command ;
  92. PRETITL!*:=NIL; % T if error or questionables found ;
  93. % Usages in specific function under analysis;
  94. GLOBS!*:=NIL; % Globals refered to in this ;
  95. CALLS!*:=NIL; % Functions called by this;
  96. LOCLS!*:=NIL; % Defined local variables in this ;
  97. TOPLV!*:=T; % NIL if inside function body ;
  98. CURFUN!*:=NIL; % Current function beeing analysed;
  99. OP!*!*:=NIL; % Current op. in LAP code;
  100. SETPAGE(" Errors or questionables",NIL);
  101. IF GETD 'BEGIN THEN RETURN NIL; % In REDUCE;
  102. % The following loop is used when running in bare LISP;
  103. NDF: IF NOT (A EQ !$EOF!$) THEN GO LOP;
  104. CRFIL:=NIL;
  105. IF NULL OCRFIL THEN GO LOP;
  106. CRFIL:=CAAR OCRFIL;
  107. RDS CDAR OCRFIL;
  108. OCRFIL:=CDR OCRFIL;
  109. LOP: A:=ERRORSET('(!%NEXTTYI),T,!*BAKGAG);
  110. IF ATOM A THEN GO NDF;
  111. CLOC!*:=IF CRFIL THEN CRFIL . PGLINE() ELSE NIL;
  112. A:=ERRORSET('(READ),T,!*BAKGAG);
  113. IF ATOM A THEN GO NDF;
  114. A:=CAR A;
  115. IF NOT PAIRP A THEN GO LOP;
  116. IF CAR A EQ 'DSKIN THEN
  117. <<OCRFIL:=(CRFIL.RDS OPEN(CDR A,'INPUT)).OCRFIL;
  118. CRFIL:=CDR A; GO LOP>>;
  119. ERRORSET(LIST('REFPRINT,MKQUOTE A),T,!*BAKGAG);
  120. IF FLAGP(CAR A,'EVAL) AND
  121. (CAR A NEQ 'SETQ OR CADDR A MEMQ '(T NIL) OR
  122. CONSTANTP CADDR A OR EQCAR(CADDR A,'QUOTE))
  123. THEN ERRORSET(A,T,!*BAKGAG);
  124. IF !*DEFN THEN GO LOP
  125. END;
  126. SYMBOLIC PROCEDURE UNDEFDCHK FN;
  127. IF NOT FLAGP(FN,'DEFD) THEN UNDEFNS!* := FN . UNDEFNS!*;
  128. SYMBOLIC PROCEDURE PRIN2NG U;
  129. PRIN2N GETES U;
  130. SYMBOLIC SMACRO PROCEDURE MSORT LST;
  131. % Build tree then collapse;
  132. TREE2LST(TREESORT(LST),NIL);
  133. SYMBOLIC PROCEDURE CREFOFF;
  134. % main call, sets up, alphabetizes and prints;
  135. BEGIN SCALAR TIM,X;
  136. DFPRINT!* := NIL;
  137. !*DEFN:=NIL;
  138. IF NOT !*ALGEBRAICS
  139. THEN REMPROP('ALGEBRAIC,'NEWNAM); %back to normal;
  140. TIM:=TIME()-BTIME!*;
  141. FOR EACH FN IN SEEN!* DO
  142. <<IF NULL GET(FN,'CALLEDBY) THEN ENTPTS!*:=FN . ENTPTS!*;
  143. UNDEFDCHK FN>>;
  144. TSEEN!*:=FOR EACH Z IN MSORT TSEEN!* COLLECT
  145. <<REMPROP(Z,'TSEEN);
  146. FOR EACH FN IN (X:=GET(Z,'FUNS)) DO
  147. <<UNDEFDCHK FN; REMPROP(FN,'RCCNAM)>>;
  148. Z.X>>;
  149. FOR EACH Z IN GSEEN!* DO
  150. IF GET(Z,'USEDUNBY) THEN UNDEFG!*:=Z . UNDEFG!*;
  151. SETPAGE(" Summary",NIL);
  152. NEWPAGE();
  153. PFILES!*:=PUNUSED("Crossreference listing for files:",
  154. FOR EACH Z IN PFILES!* COLLECT CDR Z);
  155. ENTPTS!*:=PUNUSED("Entry Points:",ENTPTS!*);
  156. UNDEFNS!*:=PUNUSED("Undefined Functions:",UNDEFNS!*);
  157. UNDEFG!*:=PUNUSED("Undeclared Global Variables:",UNDEFG!*);
  158. GSEEN!*:=PUNUSED("Global variables:",GSEEN!*);
  159. SEEN!*:=PUNUSED("Functions:",SEEN!*);
  160. FOR EACH Z IN TSEEN!* DO
  161. <<RPLACD(Z,PUNUSED(LIST(CAR Z," procedures:"),CDR Z));
  162. X:='!( . NCONC(EXPLODE CAR Z,LIST '!));
  163. FOR EACH FN IN CDR Z DO
  164. <<FN:=GETES FN; RPLACD(FN,APPEND(X,CDR FN));
  165. RPLACA(FN,LENGTH CDR FN)>> >>;
  166. IF !*CREFSUMMARY THEN GOTO XY;
  167. IF !*GLOBALS AND GSEEN!* THEN
  168. <<SETPAGE(" Global Variable Usage",1);
  169. NEWPAGE();
  170. FOR EACH Z IN GSEEN!* DO CREF6 Z>>;
  171. IF SEEN!* THEN CREF52(" Function Usage",SEEN!*);
  172. FOR EACH Z IN TSEEN!* DO
  173. CREF52(LIST(" ",CAR Z," procedures"),CDR Z);
  174. SETPAGE(" Toplevel calls:",NIL);
  175. X:=T;
  176. FOR EACH Z IN PFILES!* DO
  177. IF GET(Z,'CALLS) OR GET(Z,'GLOBS) THEN
  178. <<IF X THEN <<NEWPAGE(); X:=NIL>>;
  179. NEWLINE 0; NEWLINE 0; PRIN2NG Z;
  180. SPACES2 15; UNDERLINE2 (LINELENGTH(NIL)-10);
  181. CREF51(Z,'CALLS,"Calls:");
  182. IF !*GLOBALS THEN CREF51(Z,'GLOBS,"Globals:")>>;
  183. XY: IF !*SAVEPROPS THEN GOTO XX;
  184. REMPROPSS(SEEN!*,'(GALL CALLS GLOBS CALLEDBY ALSOIS SAMEAS));
  185. REMFLAGSS(SEEN!*,'(SEEN CINTHIS DEFD));
  186. REMPROPSS(GSEEN!*,'(USEDBY USEDUNBY BOUNDBY SETBY));
  187. REMFLAGSS(GSEEN!*,'(DCLGLB GSEEN GLB2RF GLB2BD GLB2ST));
  188. FOR EACH Z IN TSEEN!* DO REMPROP(CAR Z,'FUNS);
  189. FOR EACH Z IN HAVEARGS!* DO REMPROP(Z,'ARGCOUNT);
  190. HAVEARGS!* := NIL;
  191. XX: NEWLINE 2;
  192. IF NOT !*CREFTIME THEN RETURN;
  193. BTIME!*:=TIME()-BTIME!*;
  194. SETPAGE(" Timing Information",NIL);
  195. NEWPAGE(); NEWLINE 0;
  196. PRTATM " Total Time="; PRTNUM BTIME!*;
  197. PRTATM " (ms)";
  198. NEWLINE 0;
  199. PRTATM " Analysis Time="; PRTNUM TIM;
  200. NEWLINE 0;
  201. PRTATM " Sorting Time="; PRTNUM (BTIME!*-TIM);
  202. NEWLINE 0; NEWLINE 0
  203. END;
  204. SYMBOLIC PROCEDURE PUNUSED(X,Y);
  205. IF Y THEN
  206. <<NEWLINE 2; PRTLST X; NEWLINE 0;
  207. LPRINT(Y := MSORT Y,8); NEWLINE 0; Y>>;
  208. SYMBOLIC PROCEDURE CREF52(X,Y);
  209. <<SETPAGE(X,1); NEWPAGE(); FOR EACH Z IN Y DO CREF5 Z>>;
  210. SYMBOLIC PROCEDURE CREF5 FN;
  211. % Print single entry;
  212. BEGIN SCALAR X,Y;
  213. NEWLINE 0; NEWLINE 0;
  214. PRIN1 FN; SPACES2 15;
  215. Y:=GET(FN,'GALL);
  216. IF Y THEN <<PRIN1 CDR Y; X:=CAR Y>>
  217. ELSE PRIN2 "Undefined";
  218. SPACES2 25;
  219. IF FLAGP(FN,'NARYARGS) THEN PRIN2 " Nary Args "
  220. ELSE IF (Y:=GET(FN,'ARGCOUNT)) THEN
  221. <<PRIN2 " "; PRIN2 Y; PRIN2 " Args ">>;
  222. UNDERLINE2 (LINELENGTH(NIL)-10);
  223. IF X THEN
  224. <<NEWLINE 15; PRTATM '!Line!:; SPACES2 27;
  225. PRTNUM CDDR X; PRTATM '!/; PRTNUM CADR X;
  226. PRTATM " in "; PRTATM CAR X>>;
  227. CREF51(FN,'CALLEDBY,"Called by:");
  228. CREF51(FN,'CALLS,"Calls:");
  229. CREF51(FN,'ALSOIS,"Is also:");
  230. CREF51(FN,'SAMEAS,"Same as:");
  231. IF !*GLOBALS THEN CREF51(FN,'GLOBS,"Globals:")
  232. END;
  233. SYMBOLIC PROCEDURE CREF51(X,Y,Z);
  234. IF (X:=GET(X,Y)) THEN <<NEWLINE 15; PRTATM Z; LPRINT(MSORT X,27)>>;
  235. SYMBOLIC PROCEDURE CREF6 GLB;
  236. % print single global usage entry;
  237. <<NEWLINE 0; PRIN1 GLB; SPACES2 15;
  238. NOTUSE!*:=T;
  239. CREF61(GLB,'USEDBY,"Global in:");
  240. CREF61(GLB,'USEDUNBY,"Undeclared:");
  241. CREF61(GLB,'BOUNDBY,"Bound in:");
  242. CREF61(GLB,'SETBY,"Set by:");
  243. IF NOTUSE!* THEN PRTATM "*** Not Used ***">>;
  244. SYMBOLIC PROCEDURE CREF61(X,Y,Z);
  245. IF (X:=GET(X,Y)) THEN
  246. <<IF NOT NOTUSE!* THEN NEWLINE 15 ELSE NOTUSE!*:=NIL;
  247. PRTATM Z; LPRINT(MSORT X,27)>>;
  248. % Analyse bodies of LISP functions for
  249. % functions called, and globals used, undefined
  250. %;
  251. SYMBOLIC SMACRO PROCEDURE FLAG1(U,V); FLAG(LIST U,V);
  252. SYMBOLIC SMACRO PROCEDURE REMFLAG1(U,V); REMFLAG(LIST U,V);
  253. SYMBOLIC SMACRO PROCEDURE ISGLOB U;
  254. FLAGP(U,'DCLGLB);
  255. SYMBOLIC SMACRO PROCEDURE CHKSEEN S;
  256. % Has this name been encountered already?;
  257. IF NOT FLAGP(S,'SEEN) THEN
  258. <<FLAG1(S,'SEEN); SEEN!*:=S . SEEN!*>>;
  259. SYMBOLIC SMACRO PROCEDURE GLOBREF U;
  260. IF NOT FLAGP(U,'GLB2RF)
  261. THEN <<FLAG1(U,'GLB2RF); GLOBS!*:=U . GLOBS!*>>;
  262. SYMBOLIC SMACRO PROCEDURE ANATOM U;
  263. % Global seen before local..ie detect extended from this;
  264. IF !*GLOBALS AND U AND NOT(U EQ 'T)
  265. AND IDP U AND NOT ASSOC(U,LOCLS!*)
  266. THEN GLOBREF U;
  267. SYMBOLIC SMACRO PROCEDURE CHKGSEEN G;
  268. IF NOT FLAGP(G,'GSEEN) THEN <<GSEEN!*:=G . GSEEN!*;
  269. FLAG1(G,'GSEEN)>>;
  270. SYMBOLIC PROCEDURE DO!-GLOBAL L;
  271. % Catch global defns;
  272. % Distinguish FLUID from GLOBAL later;
  273. IF PAIRP(L:=QCRF CAR L) AND !*GLOBALS AND TOPLV!* THEN
  274. <<FOR EACH V IN L DO CHKGSEEN V; FLAG(L,'DCLGLB)>>;
  275. PUT('GLOBAL,'ANLFN,'DO!-GLOBAL);
  276. PUT('FLUID,'ANLFN,'DO!-GLOBAL);
  277. SYMBOLIC ANLFN PROCEDURE UNFLUID L;
  278. IF PAIRP(L:=QCRF CAR L) AND !*GLOBALS AND TOPLV!* THEN
  279. <<FOR EACH V IN L DO CHKGSEEN V; REMFLAG(L,'DCLGLB)>>;
  280. SYMBOLIC PROCEDURE ADD2LOCS LL;
  281. BEGIN SCALAR OLDLOC;
  282. IF !*GLOBALS THEN FOR EACH GG IN LL DO
  283. <<OLDLOC:=ASSOC(GG,LOCLS!*);
  284. IF NOT NULL OLDLOC THEN <<
  285. QERLINE 0;
  286. PRIN2 "*** Variable ";
  287. PRIN1 GG;
  288. PRIN2 " nested declaration in ";
  289. PRIN2NG CURFUN!*;
  290. NEWLINE 0;
  291. RPLACD(OLDLOC,NIL.OLDLOC)>>
  292. ELSE LOCLS!*:=(GG . LIST NIL) . LOCLS!*;
  293. IF ISGLOB(GG) OR FLAGP(GG,'GLB2RF) THEN GLOBIND GG;
  294. IF FLAGP(GG,'SEEN) THEN
  295. <<QERLINE 0;
  296. PRIN2 "*** Function ";
  297. PRIN2NG GG;
  298. PRIN2 " used as variable in ";
  299. PRIN2NG CURFUN!*;
  300. NEWLINE 0>> >>
  301. END;
  302. SYMBOLIC PROCEDURE GLOBIND GG;
  303. <<FLAG1(GG,'GLB2BD); GLOBREF GG>>;
  304. SYMBOLIC PROCEDURE REMLOCS LLN;
  305. BEGIN SCALAR OLDLOC;
  306. IF !*GLOBALS THEN FOR EACH LL IN LLN DO
  307. <<OLDLOC:=ASSOC(LL,LOCLS!*);
  308. IF NULL OLDLOC THEN
  309. IF GETD 'BEGIN THEN REDERR LIST(" Lvar confused",LL)
  310. ELSE ERROR(0,LIST(" Lvar confused",LL));
  311. IF CDDR OLDLOC THEN RPLACD(OLDLOC,CDDR OLDLOC)
  312. ELSE LOCLS!*:=EFFACE1(OLDLOC,LOCLS!*)>>
  313. END;
  314. SYMBOLIC PROCEDURE ADD2CALLS FN;
  315. % Update local CALLS!*;
  316. IF NOT(FLAGP(FN,'NOLIST) OR FLAGP(FN,'CINTHIS))
  317. THEN <<CALLS!*:=FN . CALLS!*; FLAG1(FN,'CINTHIS)>>;
  318. SYMBOLIC PROCEDURE ANFORM U;
  319. IF ATOM U THEN ANATOM U
  320. ELSE ANFORM1 U;
  321. SYMBOLIC PROCEDURE ANFORML L;
  322. BEGIN
  323. WHILE NOT ATOM L DO <<ANFORM CAR L; L:=CDR L>>;
  324. IF L THEN ANATOM L
  325. END;
  326. SYMBOLIC PROCEDURE ANFORM1 U;
  327. BEGIN SCALAR FN,X;
  328. FN:=CAR U; U:=CDR U;
  329. IF NOT ATOM FN THEN RETURN <<ANFORM1 FN; ANFORML U>>;
  330. IF NOT IDP FN THEN RETURN NIL
  331. ELSE IF ISGLOB FN THEN <<GLOBREF FN; RETURN ANFORML U>>
  332. ELSE IF ASSOC(FN,LOCLS!*) THEN RETURN ANFORML U;
  333. ADD2CALLS FN;
  334. CHECKARGCOUNT(FN,LENGTH U);
  335. IF FLAGP(FN,'NOANL) THEN NIL
  336. ELSE IF X:=GET(FN,'ANLFN) THEN APPLY(X,LIST U)
  337. ELSE ANFORML U
  338. END;
  339. SYMBOLIC ANLFN PROCEDURE LAMBDA U;
  340. <<ADD2LOCS CAR U; ANFORML CDR U; REMLOCS CAR U>>;
  341. SYMBOLIC PROCEDURE ANLSETQ U;
  342. <<ANFORML U;
  343. IF !*GLOBALS AND FLAGP(U:=CAR U,'GLB2RF) THEN FLAG1(U,'GLB2ST)>>;
  344. PUT('SETQ,'ANLFN,'ANLSETQ);
  345. SYMBOLIC ANLFN PROCEDURE COND U;
  346. FOR EACH X IN U DO ANFORML X;
  347. SYMBOLIC ANLFN PROCEDURE PROG U;
  348. <<ADD2LOCS CAR U;
  349. FOR EACH X IN CDR U DO
  350. IF NOT ATOM X THEN ANFORM1 X;
  351. REMLOCS CAR U>>;
  352. SYMBOLIC ANLFN PROCEDURE FOREACH U;
  353. <<ANFORM CADDR U;
  354. ADD2LOCS LIST CAR U;
  355. ANFORM CADR CDDDR U;
  356. REMLOCS LIST CAR U >>;
  357. SYMBOLIC ANLFN PROCEDURE FOR U;
  358. <<ANFORML CADR U;
  359. ADD2LOCS LIST CAR U;
  360. ANFORM CADDDR U;
  361. REMLOCS LIST CAR U>>;
  362. SYMBOLIC ANLFN PROCEDURE FUNCTION U;
  363. IF PAIRP(U:=CAR U) THEN ANFORM1 U
  364. ELSE IF ISGLOB U THEN GLOBREF U
  365. ELSE IF NULL ASSOC(U,LOCLS!*) THEN ADD2CALLS U;
  366. FLAG('(QUOTE GO),'NOANL);
  367. SYMBOLIC ANLFN PROCEDURE ERRORSET U;
  368. BEGIN SCALAR FN,X;
  369. ANFORML CDR U;
  370. IF EQCAR(U:=CAR U,'QUOTE) THEN RETURN ERSANFORM CADR U
  371. ELSE IF NOT((EQCAR(U,'CONS) OR (X:=EQCAR(U,'LIST)))
  372. AND QUOTP(FN:=CADR U))
  373. THEN RETURN ANFORM U;
  374. ANFORML CDDR U;
  375. IF PAIRP(FN:=CADR FN) THEN ANFORM1 FN
  376. ELSE IF FLAGP(FN,'GLB2RF) THEN NIL
  377. ELSE IF ISGLOB FN THEN GLOBREF FN
  378. ELSE <<ADD2CALLS FN; IF X THEN CHECKARGCOUNT(FN,LENGTH CDDR U)>>
  379. END;
  380. SYMBOLIC PROCEDURE ERSANFORM U;
  381. BEGIN SCALAR LOCLS!*;
  382. RETURN ANFORM U
  383. END;
  384. SYMBOLIC PROCEDURE ANLMAP U;
  385. <<ANFORML CDR U;
  386. IF QUOTP(U:=CADDR U) AND IDP(U:=CADR U)
  387. AND NOT ISGLOBL U AND NOT ASSOC(U,LOCLS!*)
  388. THEN CHECKARGCOUNT(U,1)>>;
  389. FOR EACH X IN '(MAP MAPC MAPLIST MAPCAR MAPCON MAPCAN) DO
  390. PUT(X,'ANLFN,'ANLMAP);
  391. SYMBOLIC ANLFN PROCEDURE APPLY U;
  392. BEGIN SCALAR FN;
  393. ANFORML CDR U;
  394. IF QUOTP(FN:=CADR U) AND IDP(FN:=CADR FN) AND EQCAR(U:=CADDR U,'LIST)
  395. THEN CHECKARGCOUNT(FN,LENGTH CDR U)
  396. END;
  397. SYMBOLIC PROCEDURE QUOTP U; EQCAR(U,'QUOTE) OR EQCAR(U,'FUNCTION);
  398. PUT('CREF ,'SIMPFG ,'((T (CREFON)) (NIL (CREFOFF))));
  399. SYMBOLIC PROCEDURE OUTREF(S,VARLIS,BODY,TYPE);
  400. BEGIN SCALAR CURFUN!*,CALLS!*,GLOBS!*,LOCLS!*,TOPLV!*,A;
  401. A:=IF VARLIS MEMQ '(ANP!!ATOM ANP!!IDB ANP!!EQ ANP!!UNKNOWN)
  402. THEN NIL
  403. ELSE LENGTH VARLIS;
  404. S := OUTRDEFUN(S,TYPE,IF A THEN A ELSE GET(BODY,'ARGCOUNT));
  405. IF A THEN <<ADD2LOCS VARLIS; ANFORM(BODY); REMLOCS VARLIS>>
  406. ELSE IF NULL BODY OR NOT IDP BODY THEN NIL
  407. ELSE IF VARLIS EQ 'ANP!!EQ
  408. THEN <<PUT(S,'SAMEAS,LIST BODY); TRAPUT(BODY,'ALSOIS,S)>>
  409. ELSE ADD2CALLS BODY;
  410. OUTREFEND S
  411. END;
  412. SYMBOLIC PROCEDURE TRAPUT(U,V,W);
  413. BEGIN SCALAR A;
  414. IF A:=GET(U,V) THEN
  415. (IF NOT(TOPLV!* OR W MEMQ A) THEN RPLACD(A,W . CDR A))
  416. ELSE PUT(U,V,LIST W)
  417. END;
  418. SYMBOLIC SMACRO PROCEDURE TOPUT(U,V,W);
  419. IF W THEN PUT(U,V,IF TOPLV!* THEN UNION(W,GET(U,V)) ELSE W);
  420. SYMBOLIC PROCEDURE OUTREFEND S;
  421. <<TOPUT(S,'CALLS,CALLS!*);
  422. FOR EACH X IN CALLS!* DO
  423. <<REMFLAG1(X,'CINTHIS);
  424. IF NOT X EQ S THEN <<CHKSEEN X; TRAPUT(X,'CALLEDBY,S)>> >>;
  425. TOPUT(S,'GLOBS,GLOBS!*);
  426. FOR EACH X IN GLOBS!* DO
  427. <<TRAPUT(X,IF ISGLOB X THEN 'USEDBY
  428. ELSE <<CHKGSEEN X; 'USEDUNBY>>,S);
  429. REMFLAG1(X,'GLB2RF);
  430. IF FLAGP(X,'GLB2BD)
  431. THEN <<REMFLAG1(X,'GLB2BD); TRAPUT(X,'BOUNDBY,S)>>;
  432. IF FLAGP(X,'GLB2ST)
  433. THEN <<REMFLAG1(X,'GLB2ST); TRAPUT(X,'SETBY,S)>> >> >>;
  434. SYMBOLIC PROCEDURE RECREF(S,TYPE);
  435. <<QERLINE 2;
  436. PRTATM "*** Redefinition to ";
  437. PRIN1 TYPE;
  438. PRTATM " procedure, of:";
  439. CREF5 S;
  440. REMPROPSS(S,'(CALLS GLOBS SAMEAS));
  441. NEWLINE 2>>;
  442. SYMBOLIC PROCEDURE OUTRDEFUN(S,TYPE,V);
  443. BEGIN
  444. S:=QTYPNM(S,TYPE);
  445. IF FLAGP(S,'DEFD) THEN RECREF(S,TYPE)
  446. ELSE FLAG1(S,'DEFD);
  447. IF FLAGP(TYPE,'FUNCTION) AND (ISGLOB S OR ASSOC(S,LOCLS!*)) THEN
  448. <<QERLINE 0;
  449. PRIN2 "**** Variable ";
  450. PRIN2NG S;
  451. PRIN2 " defined as function";
  452. NEWLINE 0>>;
  453. IF V AND NOT FLAGP(TYPE,'NARYARG) THEN DEFINEARGS(S,V);
  454. PUT(S,'GALL,CURLIN!* . TYPE);
  455. GLOBS!*:=NIL;
  456. CALLS!*:=NIL;
  457. RETURN CURFUN!*:=S
  458. END;
  459. FLAG('(MACRO FEXPR),'NARYARG);
  460. SYMBOLIC PROCEDURE QTYPNM(S,TYPE);
  461. IF FLAGP(TYPE,'FUNCTION) THEN <<CHKSEEN S; S>>
  462. ELSE BEGIN SCALAR X,Y,Z;
  463. IF (Y:=GET(TYPE,'TSEEN)) AND (X:=ATSOC(S,CDR Y))
  464. THEN RETURN CDR X;
  465. IF NULL Y THEN
  466. <<Y:=LIST ('!( . NCONC(EXPLODE TYPE,LIST '!)));
  467. PUT(TYPE,'TSEEN,Y); TSEEN!* := TYPE . TSEEN!*>>;
  468. X := COMPRESS (Z := EXPLODE S);
  469. RPLACD(Y,(S . X) . CDR Y);
  470. Y := APPEND(CAR Y,Z);
  471. PUT(X,'RCCNAM,LENGTH Y . Y);
  472. TRAPUT(TYPE,'FUNS,X);
  473. RETURN X
  474. END;
  475. SYMBOLIC PROCEDURE DEFINEARGS(NAME,N);
  476. BEGIN SCALAR CALLEDWITH,X;
  477. CALLEDWITH:=GET(NAME,'ARGCOUNT);
  478. IF NULL CALLEDWITH THEN RETURN HASARG(NAME,N);
  479. IF N=CALLEDWITH THEN RETURN NIL;
  480. IF X := GET(NAME,'CALLEDBY) THEN INSTDOF(NAME,N,CALLEDWITH,X);
  481. HASARG(NAME,N)
  482. END;
  483. SYMBOLIC PROCEDURE INSTDOF(NAME,N,M,FNLST);
  484. <<QERLINE 0;
  485. PRIN2 "***** ";
  486. PRIN1 NAME;
  487. PRIN2 " called with ";
  488. PRIN2 M;
  489. PRIN2 " instead of ";
  490. PRIN2 N;
  491. PRIN2 " arguments in:";
  492. LPRINT(MSORT FNLST,POSN()+1);
  493. NEWLINE 0>>;
  494. SYMBOLIC PROCEDURE HASARG(NAME,N);
  495. <<HAVEARGS!*:=NAME . HAVEARGS!*;
  496. IF N>MAXARG!* THEN
  497. <<QERLINE 0;
  498. PRIN2 "**** "; PRIN1 NAME;
  499. PRIN2 " has "; PRIN2 N;
  500. PRIN2 " arguments";
  501. NEWLINE 0 >>;
  502. PUT(NAME,'ARGCOUNT,N)>>;
  503. SYMBOLIC PROCEDURE CHECKARGCOUNT(NAME,N);
  504. BEGIN SCALAR CORRECTN;
  505. IF FLAGP(NAME,'NARYARGS) THEN RETURN NIL;
  506. CORRECTN:=GET(NAME,'ARGCOUNT);
  507. IF NULL CORRECTN THEN RETURN HASARG(NAME,N);
  508. IF NOT CORRECTN=N THEN INSTDOF(NAME,CORRECTN,N,LIST CURFUN!*)
  509. END;
  510. SYMBOLIC PROCEDURE REFPRINT U;
  511. BEGIN SCALAR X,Y;
  512. X:=IF CLOC!* THEN FILEMK CAR CLOC!* ELSE "*TTYINPUT*";
  513. IF (CURFUN!*:=ASSOC(X,PFILES!*)) THEN
  514. <<X:=CAR CURFUN!*; CURFUN!*:=CDR CURFUN!*>>
  515. ELSE <<PFILES!*:=(X.(CURFUN!*:=GENSYM())).PFILES!*;
  516. Y:=REVERSIP CDR REVERSIP CDR EXPLODE X;
  517. PUT(CURFUN!*,'RCCNAM,LENGTH Y . Y)>>;
  518. CURLIN!*:=IF CLOC!* THEN X.CDR CLOC!* ELSE NIL;
  519. CALLS!*:=GLOBS!*:=LOCLS!*:=NIL;
  520. ANFORM U;
  521. OUTREFEND CURFUN!*
  522. END;
  523. FLAG('(SYMBOLIC SMACRO NMACRO),'CREF);
  524. SYMBOLIC ANLFN PROCEDURE PUT U;
  525. IF TOPLV!* AND QCPUTX CADR U THEN ANPUTX U
  526. ELSE ANFORML U;
  527. PUT('PUTC,'ANLFN,GET('PUT,'ANLFN));
  528. SYMBOLIC PROCEDURE QCPUTX U;
  529. EQCAR(U,'QUOTE) AND (FLAGP(CADR U,'CREF) OR FLAGP(CADR U,'COMPILE));
  530. SYMBOLIC PROCEDURE ANPUTX U;
  531. BEGIN SCALAR NAM,TYP,BODY;
  532. NAM:=QCRF CAR U;
  533. TYP:=QCRF CADR U;
  534. U:=CADDR U;
  535. IF ATOM U THEN <<BODY:=QCRF U; U:='ANP!!ATOM>>
  536. ELSE IF CAR U MEMQ '(QUOTE FUNCTION) THEN
  537. IF EQCAR(U:=CADR U,'LAMBDA) THEN <<BODY:=CADDR U; U:=CADR U>>
  538. ELSE IF IDP U THEN <<BODY:=U; U:='ANP!!IDB>>
  539. ELSE RETURN NIL
  540. ELSE IF CAR U EQ 'CDR AND EQCAR(CADR U,'GETD) THEN
  541. <<BODY:=QCRF CADADR U; U:='ANP!!EQ>>
  542. ELSE IF CAR U EQ 'GET AND QCPUTX CADDR U THEN
  543. <<BODY:=QTYPNM(QCRF CADR U,CADR CADDR U); U:='ANP!!EQ>>
  544. ELSE IF CAR U EQ 'MKCODE THEN
  545. <<ANFORM CADR U; U:=QCRF CADDR U; BODY:=NIL>>
  546. ELSE <<BODY:=QCRF U; U:='ANP!!UNKNOWN>>;
  547. OUTREF(NAM,U,BODY,TYP)
  548. END;
  549. SYMBOLIC ANLFN PROCEDURE PUTD U;
  550. IF TOPLV!* THEN ANPUTX U ELSE ANFORML U;
  551. SYMBOLIC ANLFN PROCEDURE DE U;
  552. OUTDEFR(U,'EXPR);
  553. SYMBOLIC ANLFN PROCEDURE DF U;
  554. OUTDEFR(U,'FEXPR);
  555. SYMBOLIC ANLFN PROCEDURE DM U;
  556. OUTDEFR(U,'MACRO);
  557. SYMBOLIC PROCEDURE OUTDEFR(U,TYPE);
  558. OUTREF(CAR U,CADR U,CADDR U,TYPE);
  559. SYMBOLIC PROCEDURE QCRF U;
  560. IF NULL U OR U EQ T THEN U
  561. ELSE IF EQCAR(U,'QUOTE) THEN CADR U
  562. ELSE <<ANFORM U; COMPRESS EXPLODE '!?VALUE!?!?>>;
  563. FLAG('(EXPR FEXPR MACRO SYMBOLIC SMACRO NMACRO),'FUNCTION);
  564. SYMBOLIC ANLFN PROCEDURE LAP U;
  565. IF PAIRP(U:=QCRF CAR U) THEN
  566. BEGIN SCALAR GLOBS!*,LOCLS!*,CALLS!*,CURFUN!*,TOPLV!*,X;
  567. WHILE U DO
  568. <<IF PAIRP CAR U THEN
  569. IF X:=GET(OP!*!*:=CAAR U,'CRFLAPO) THEN APPLY(X,LIST U)
  570. ELSE IF !*GLOBALS THEN FOR EACH Y IN CDAR U DO ANLAPEV Y;
  571. U:=CDR U>>;
  572. QOUTREFE()
  573. END;
  574. SYMBOLIC CRFLAPO PROCEDURE !*ENTRY U;
  575. <<QOUTREFE(); U:=CDAR U; OUTRDEFUN(CAR U,CADR U,CADDR U)>>;
  576. SYMBOLIC PROCEDURE QOUTREFE;
  577. BEGIN
  578. IF NULL CURFUN!* THEN
  579. IF GLOBS!* OR CALLS!* THEN
  580. <<CURFUN!*:=COMPRESS EXPLODE '!?LAP!?!?; CHKSEEN CURFUN!*>>
  581. ELSE RETURN;
  582. OUTREFEND CURFUN!*
  583. END;
  584. SYMBOLIC CRFLAPO PROCEDURE !*LAMBIND U;
  585. FOR EACH X IN CADDAR U DO GLOBIND CAR X;
  586. SYMBOLIC CRFLAPO PROCEDURE !*PROGBIND U;
  587. FOR EACH X IN CADAR U DO GLOBIND CAR X;
  588. SYMBOLIC PROCEDURE LINCALL U;
  589. <<ADD2CALLS CAR (U:=CDAR U); CHECKARGCOUNT(CAR U,CADDR U)>>;
  590. PUT('!*LINK,'CRFLAPO,'LINCALL);
  591. PUT('!*LINKE,'CRFLAPO,'LINCALL);
  592. SYMBOLIC PROCEDURE ANLAPEV U;
  593. IF PAIRP U THEN
  594. IF CAR U MEMQ '(GLOBAL FLUID) THEN
  595. <<U:=CADR U; GLOBREF U;
  596. IF FLAGP(OP!*!*,'STORE) THEN PUT(U,'GLB2ST,'T)>>
  597. ELSE <<ANLAPEV CAR U; ANLAPEV CDR U>>;
  598. FLAG('(!*STORE),'STORE);
  599. SYMBOLIC PROCEDURE QERLINE U;
  600. IF PRETITL!* THEN NEWLINE U
  601. ELSE <<PRETITL!*:=T; NEWPAGE()>>;
  602. % These functions defined to be able to run in bare LISP;
  603. SYMBOLIC PROCEDURE EQCAR(U,V);
  604. PAIRP U AND CAR U EQ V;
  605. SYMBOLIC PROCEDURE MKQUOTE U; LIST('QUOTE,U);
  606. SYMBOLIC PROCEDURE EFFACE1(U,V);
  607. IF NULL V THEN NIL
  608. ELSE IF U EQ CAR V THEN CDR V
  609. ELSE RPLACD(V,EFFACE1(U,CDR V));
  610. % Systemdependent part;
  611. MAXARG!*:=14;
  612. FLAG('(POP MOVEM SETZM HRRZM),'STORE);
  613. SYMBOLIC PROCEDURE LAPCALLF U;
  614. BEGIN SCALAR FN;
  615. RETURN
  616. IF EQCAR(CADR (U:=CDAR U),'E) THEN
  617. <<ADD2CALLS(FN:=CADADR U); CHECKARGCOUNT(FN,CAR U)>>
  618. ELSE IF !*GLOBALS THEN ANLAPEV CADR U
  619. END;
  620. PUT('JCALL,'CRFLAPO,'LAPCALLF);
  621. PUT('CALLF,'CRFLAPO,'LAPCALLF);
  622. PUT('JCALLF,'CRFLAPO,'LAPCALLF);
  623. SYMBOLIC CRFLAPO PROCEDURE CALL U;
  624. IF NOT(CADDAR U = '(E !*LAMBIND!*)) THEN LAPCALLF U
  625. ELSE WHILE ((U:=CDR U) AND PAIRP CAR U AND CAAR U = 0) DO
  626. GLOBIND CADR CADDAR U;
  627. END;