build38.lsp 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375
  1. % "build38.lsp"
  2. %
  3. % Build a CSL REDUCE.
  4. %
  5. % Depending on how this file is used it will EITHER create a bootstrap
  6. % version of REDUCE or a full and optimised one.
  7. %
  8. % The behaviour is determined by whether the version of CSL used to
  9. % run it has a full complement of functions in the modules u01.c to u12.c.
  10. %
  11. %
  12. % slowr38 -z build38.lsp -D@srcdir=<DIR> -- log/boot38.log
  13. %
  14. % Builds a system "slowr38.img" that does not depend on any
  15. % custom C code. The main use of this slow system is for profiling
  16. % REDUCE and then compiling the hot-spots into C. Once that has been
  17. % done this image is logically unnecessary.
  18. %
  19. %
  20. % r38 -z build38.lsp -D@srcdir=<DIR> -l log/full38.log
  21. %
  22. % Here the files u01.c to u12.c and u01.lsp to u12.lsp must already
  23. % have been created, and that the r38 executable has them compiled in.
  24. % The REDUCE source files that are compiled *MUST* be the same as those used
  25. % to create this C code.
  26. % Author: Anthony C. Hearn, Stanley L. Kameny and Arthur Norman
  27. (verbos 3)
  28. (window!-heading "basic CSL")
  29. (setq !*savedef (lessp (cdr (assoc 'c!-code lispsystem!*)) 20))
  30. (make!-special '!*native_code)
  31. (setq !*native_code nil)
  32. (cond ((null !*savedef) (progn
  33. (de c!:install (name env c!-version !&optional c1)
  34. (cond
  35. (c1 (check!-c!-code name env c!-version c1))
  36. (t (progn
  37. (put name 'c!-version c!-version)
  38. (cond (env (prog (v n)
  39. (setq v (mkvect (sub1 (length env))))
  40. (setq n 0)
  41. top (cond
  42. ((null env) (progn
  43. (put name 'funarg v)
  44. (return (symbol!-set!-env name v)))))
  45. (putv v n (car env))
  46. (setq n (add1 n))
  47. (setq env (cdr env))
  48. (go top))))
  49. name))))
  50. (rdf "$srcdir/../csl-c/u01.lsp")
  51. (rdf "$srcdir/../csl-c/u02.lsp")
  52. (rdf "$srcdir/../csl-c/u03.lsp")
  53. (rdf "$srcdir/../csl-c/u04.lsp")
  54. (rdf "$srcdir/../csl-c/u05.lsp")
  55. (rdf "$srcdir/../csl-c/u06.lsp")
  56. (rdf "$srcdir/../csl-c/u07.lsp")
  57. (rdf "$srcdir/../csl-c/u08.lsp")
  58. (rdf "$srcdir/../csl-c/u09.lsp")
  59. (rdf "$srcdir/../csl-c/u10.lsp")
  60. (rdf "$srcdir/../csl-c/u11.lsp")
  61. (rdf "$srcdir/../csl-c/u12.lsp") )))
  62. (rdf "$srcdir/../util/fastgets.lsp")
  63. (rdf "$srcdir/../cslbase/compat.lsp")
  64. (rdf "$srcdir/../cslbase/extras.lsp")
  65. (rdf "$srcdir/../cslbase/compiler.lsp")
  66. % (rdf "$srcdir/../cslbase/ccomp.lsp")
  67. (compile!-all)
  68. (setq !*comp t) % It's faster if we compile the boot file.
  69. % Tidy up be deleting any modules that are left over in this image
  70. (dolist (a (library!-members)) (delete!-module a))
  71. % Build fasl files for the compatibility code and the two
  72. % versions of the compiler.
  73. (faslout 'cslcompat)
  74. (rdf "$srcdir/../util/fastgets.lsp")
  75. (rdf "$srcdir/../cslbase/compat.lsp")
  76. (rdf "$srcdir/../cslbase/extras.lsp")
  77. (faslend)
  78. (faslout 'compiler)
  79. (rdf "$srcdir/../cslbase/compiler.lsp")
  80. (faslend)
  81. %(faslout 'ccomp)
  82. %(rdf "$srcdir/../cslbase/ccomp.lsp")
  83. %(faslend)
  84. (setq !*comp t)
  85. (de concat (u v)
  86. (compress (cons '!" (append (explode2 u)
  87. (nconc (explode2 v) (list '!"))))))
  88. (global '(oldchan!*))
  89. (setq prolog_file 'cslprolo)
  90. (setq rend_file 'cslrend)
  91. (setq !*argnochk t)
  92. (setq !*int nil) % Prevents input buffer being saved.
  93. (setq !*msg nil)
  94. (window!-heading "bootstrap RLISP")
  95. (rdf "$srcdir/../../../packages/support/boot.sl")
  96. (begin2)
  97. !@reduce := concat(!@srcdir, "/../../..");
  98. rds(xxx := open("$reduce/packages/support/build.red",'input));
  99. (close xxx)
  100. (load!-package!-sources prolog_file 'support)
  101. (load!-package!-sources 'rlisp 'rlisp)
  102. (load!-package!-sources rend_file 'support)
  103. (load!-package!-sources 'poly 'poly)
  104. (load!-package!-sources 'alg 'alg)
  105. (load!-package!-sources 'arith 'arith) % Needed by roots, specfn*, (psl).
  106. (load!-package!-sources 'entry 'support)
  107. (load!-package!-sources 'remake 'support)
  108. (setq !*comp nil)
  109. (begin)
  110. symbolic;
  111. !#if (not !*savedef)
  112. faslout 'user;
  113. %
  114. % The "user" module is only useful when building a full system, since
  115. % in the bootstrap the files u01.lsp to u12.lsp will probably not exist
  116. % and it is CERTAIN that they are not useful.
  117. %
  118. symbolic procedure c!:install(name, env, c!-version, !&optional, c1);
  119. begin
  120. scalar v, n;
  121. if c1 then return check!-c!-code(name, env, c!-version, c1);
  122. put(name, 'c!-version, c!-version);
  123. if null env then return name;
  124. v := mkvect sub1 length env;
  125. n := 0;
  126. while env do <<
  127. putv(v, n, car env);
  128. n := n + 1;
  129. env := cdr env >>;
  130. % I only instate the environment if there is nothing useful there at
  131. % present. Actually this is even stronger. When a built-in function is
  132. % set up it gets NIL in its environment cell by default. Things that are
  133. % not defined at all have themselves there.
  134. if symbol!-env name = nil then symbol!-set!-env(name, v);
  135. put(name, 'funarg, v);
  136. return name;
  137. end;
  138. rdf "$srcdir/../csl-c/u01.lsp"$
  139. rdf "$srcdir/../csl-c/u02.lsp"$
  140. rdf "$srcdir/../csl-c/u03.lsp"$
  141. rdf "$srcdir/../csl-c/u04.lsp"$
  142. rdf "$srcdir/../csl-c/u05.lsp"$
  143. rdf "$srcdir/../csl-c/u06.lsp"$
  144. rdf "$srcdir/../csl-c/u07.lsp"$
  145. rdf "$srcdir/../csl-c/u08.lsp"$
  146. rdf "$srcdir/../csl-c/u09.lsp"$
  147. rdf "$srcdir/../csl-c/u10.lsp"$
  148. rdf "$srcdir/../csl-c/u11.lsp"$
  149. rdf "$srcdir/../csl-c/u12.lsp"$
  150. faslend;
  151. !#endif
  152. faslout 'remake;
  153. !#if (not !*savedef)
  154. load!-module "user";
  155. !#endif
  156. !@reduce := concat(!@srcdir, "/../../..");
  157. in "$reduce/packages/support/remake.red"$
  158. global '(r38_base_modules r38_extra_modules r38_test_cases);
  159. % Master configuration data is stored in two DOS batch files.
  160. % This function extracts the information and puts it where I want it!
  161. symbolic procedure make_conf_file();
  162. begin
  163. scalar a, p1, p2, p3, w;
  164. % upackage.bat may look like
  165. % set upackages=(support rlisp alg poly polydiv arith ...)
  166. % set upackages2=(odesolve pf cvit noncom2 physop crack liepde ...)
  167. % set upackages3=(specfn2 specfaux specbess sfgamma tps limits ...)
  168. % where the first list is of CORE packages needed for bootstrapping and all
  169. % subsequent ones are independent of each other (at least ideally).
  170. %
  171. % Well as I understand it at present in the development tree this file is
  172. % called vpackage.bat...
  173. if filep "$srcdir/../../../getred.pl" then
  174. a := open("$srcdir/../../../vpackage.bat", 'input)
  175. else a := open("$srcdir/../../../upackage.bat", 'input);
  176. p1 := nil;
  177. while atom p1 and p1 neq !$eof!$ do <<
  178. a := rds a; p1 := read(); a := rds a >>;
  179. p2 := w := nil;
  180. while w neq !$eof!$ do <<
  181. w := nil;
  182. while atom w and w neq !$eof!$ do <<
  183. a := rds a; w := read(); a := rds a >>;
  184. if not atom w then p2 := append(p2, w) >>;
  185. close a;
  186. % xpackage.bat must be a list of test scripts, similar to this:
  187. % set xpackages=(alg poly polydiv arith factor int matrix solve ...)
  188. % set xpackages2=(odesolve pf cvit physop crack liepde applysym ...)
  189. % set xpackages3=(tps limits defint fps trigint ratint mathml ...)
  190. a := open("$srcdir/../../../xpackage.bat", 'input);
  191. p3 := w := nil;
  192. while w neq !$eof!$ do <<
  193. w := nil;
  194. while atom w and w neq !$eof!$ do <<
  195. a := rds a; w := read(); a := rds a >>;
  196. if not atom w then p3 := append(p3, w) >>;
  197. close a;
  198. if filep "$srcdir/../../../getred.pl" then
  199. a := "$srcdir/../util/devconfig.lsp"
  200. else a := "$srcdir/../util/config.lsp";
  201. a := open(a, 'output);
  202. << a := wrs a; linelength 72;
  203. terpri();
  204. printc "% These are packages that get built into the base system that";
  205. printc "% is used to compile what follows...";
  206. terpri();
  207. prettyprint p1; terpri();
  208. terpri();
  209. printc "% The next set of modules are all built using a system that";
  210. printc "% has the above set available. The key issue here is that the";
  211. printc "% packages in this list of ""extensions"" can all be built";
  212. printc "% independently of each other.";
  213. terpri();
  214. % The v3tools module depends on the groebner code already being built, and so
  215. % it must appear late in the list. As I introduce this script the package.bat
  216. % file may not reflect that so FUDGE it here.
  217. if memq('v3tools, p2) then
  218. p2 := append(delete('v3tools, p2), '(v3tools));
  219. % rltools must occur before redlog. This is also a pretty shameless FUDGE
  220. % here.
  221. if memq('rltools, p2) then
  222. p2 := 'rltools . delete('rltools, p2);
  223. prettyprint p2; terpri();
  224. terpri();
  225. printc "% Finally we have a list of all the test scripts that REDUCE";
  226. printc "% is shipped with.";
  227. % As a special HACK I will remove gnuplot (if present) since at least as
  228. % of the time of working on this its level of interactivity causes the
  229. % profiling job to fail.
  230. r3 := delete('gnuplot, p3);
  231. terpri();
  232. prettyprint p3; terpri();
  233. terpri();
  234. printc "% End of configuration file";
  235. close wrs a >>
  236. end;
  237. symbolic procedure get_configuration_data full_version;
  238. % Read data from a configuration file that lists the modules that must
  239. % be processed. NOTE that this and the next few funtions will ONLY
  240. % work properly if REDUCE had been started up with the correct
  241. % working directory. This is (just about) acceptable because these are
  242. % system maintainance functions rather than generally flexible things
  243. % for arbitrary use.
  244. begin
  245. scalar i, j;
  246. % Configuration information is held in a file called something like
  247. % "config.lsp", but the exact details differ in a number of cases. For
  248. % the Development Version (not for general public use) this file will
  249. % be $srcdir/../util/devconfig.lsp. For a personal version it will be
  250. % util/config.lsp and in the case of a "professional" package it is
  251. % $srcdir/../util/config.lsp. The code here tries to detect which case
  252. % applies. If a file "$srcdir/../../../getred.pl" exists it will believe
  253. % it is the development tree!
  254. if filep "$srcdir/../../../getred.pl" then
  255. << i := "$srcdir/../util/devconfig.lsp";
  256. j := "$srcdir/../../../vpackage.bat" >>
  257. else if full_version then <<
  258. i := "$srcdir/../util/config.lsp";
  259. j := "$srcdir/../../../vpackage.bat" >>
  260. else i := "util/config.lsp";
  261. % I now try to ensure that the configuration file exists and is up to date.
  262. % Note that this is only done on a full build of Reduce. The [dev]config.lsp
  263. % is updated if either upackage.bat or xpackage.bat is newer than it...
  264. if not filep i or
  265. (j and filep j and
  266. datelessp(filedate i, filedate j)) or
  267. (filep "$srcdir/../../../xpackage.bat" and
  268. datelessp(filedate i, filedate "$srcdir/../../../xpackage.bat")) then
  269. make_conf_file();
  270. i := open(i, 'input);
  271. i := rds i;
  272. r38_base_modules := read();
  273. r38_extra_modules := read();
  274. r38_test_cases := read();
  275. i := rds i;
  276. close i
  277. end;
  278. symbolic procedure build_reduce_modules names;
  279. begin
  280. scalar w;
  281. !#if !*savedef
  282. !*savedef := t;
  283. !#else
  284. !*savedef := nil;
  285. !#endif
  286. make!-special '!*native_code;
  287. !*native_code := nil;
  288. load!-latest!-patches();
  289. !@reduce := concat(!@srcdir, "/../../..");
  290. in "$reduce/package.red"$
  291. window!-heading list!-to!-string explodec car names;
  292. !#if !*savedef
  293. % When building the bootstrap version I want to record what switches
  294. % get declared...
  295. if not getd 'original!-switch then <<
  296. w := getd 'switch;
  297. putd('original!-switch, car w, cdr w);
  298. putd('switch, 'expr,
  299. '(lambda (x)
  300. (dolist (y x) (princ "+++ Declaring a switch: ") (print y))
  301. (original!-switch x))) >>;
  302. !#endif
  303. package!-remake car names;
  304. if null (names := cdr names) then printc "Recompilation complete";
  305. !#if !*savedef
  306. if null names then restart!-csl 'begin
  307. !#else
  308. if null names then restart!-csl '(user begin)
  309. !#endif
  310. else restart!-csl('(remake build_reduce_modules), names)
  311. end;
  312. symbolic procedure test_a_package names;
  313. begin
  314. scalar packge, logname, logtmp, logfile, start_time, start_gctime, gt;
  315. scalar redef, quitfn, oll;
  316. princ "TESTING: "; print car names;
  317. window!-heading list!-to!-string explodec car names;
  318. !*backtrace := nil;
  319. !*errcont := t;
  320. !*extraecho := t; % Ensure standard environment for the test...
  321. !*int := nil; % ... so that results are predictable.
  322. packge := car names;
  323. verbos nil;
  324. load!-latest!-patches();
  325. if boundp '!@log and stringp symbol!-value '!@log then
  326. logname := symbol!-value '!@log
  327. else logname := "log";
  328. logname := concat("$srcdir/../../../", concat(logname, "/"));
  329. logtmp := concat(logname, concat(car names, ".tmp"));
  330. logname := concat(logname, concat(car names,".rlg"));
  331. logfile := open(logtmp, 'output);
  332. in_list1("$srcdir/../../../package.red", nil);
  333. begin
  334. scalar !*terminal!-io!*, !*standard!-output!*, !*error!-output!*,
  335. !*trace!-output!*, !*debug!-io!*, !*query!-io!*, !*errcont,
  336. outputhandler!*;
  337. !*terminal!-io!* := !*standard!-output!* := !*error!-output!* := logfile;
  338. !*trace!-output!* := !*debug!-io!* := !*query!-io!* := logfile;
  339. oll := linelength 80;
  340. princ date(); princ " run on "; printc cdr assoc('name, lispsystem!*);
  341. load!-package packge;
  342. if get(packge,'folder) then packge := get(packge,'folder);
  343. packge := concat("$srcdir/../../../packages/",
  344. concat(packge,
  345. concat("/",
  346. concat(car names,".tst"))));
  347. redef := !*redefmsg;
  348. !*redefmsg := nil;
  349. quitfn := getd 'quit;
  350. % At least at one stage at least one test file ends in "quit;" rather than
  351. % "end;" and the normal effect would be that this leads it to cancel
  352. % all execution instantly. To avoid that I will undefine the function
  353. % "quit", but restore it after the test. I reset !*redefmsg to avoid getting
  354. % messages about this. I redefined quit to something (specifically "posn")
  355. % that does not need an argument and that is "harmless".
  356. remd 'quit;
  357. putd('quit, 'expr, 'posn);
  358. start_time := time();
  359. start_gctime := gctime();
  360. !*mode := 'algebraic;
  361. !*extraecho := t; % Ensure standard environment for the test...
  362. !*int := nil; % ... so that results are predictable.
  363. !*errcont := t;
  364. in_list1(packge, t);
  365. erfg!* := nil;
  366. terpri();
  367. putd('quit, car quitfn, cdr quitfn);
  368. !*redefmsg := redef;
  369. terpri();
  370. prin2 "Time for test: ";
  371. gt := time() - start_time;
  372. % I ensure that the reported time is at least 1 millisecond.
  373. if gt = 0 then gt := 1;
  374. prin2 gt;
  375. prin2 " ms";
  376. if (gt := gctime() - start_gctime) > 0 then <<
  377. prin2 ", plus GC time: ";
  378. prin2 gt;
  379. prin2 " ms" >>;
  380. terpri();
  381. linelength oll
  382. end;
  383. close logfile;
  384. delete!-file logname;
  385. rename!-file(logtmp, logname);
  386. names := cdr names;
  387. if null names then restart!-csl t
  388. else restart!-csl('(remake test_a_package), names)
  389. end;
  390. symbolic procedure personal_test_a_package names;
  391. % This version is only used with the personal version of REDUCE and uses
  392. % different paths to access files.
  393. begin
  394. scalar packge, logname, logtmp, logfile, start_time, start_gctime, gt;
  395. scalar redef, quitfn, oll;
  396. princ "TESTING: "; print car names;
  397. window!-heading list!-to!-string explodec car names;
  398. !*backtrace := nil;
  399. !*errcont := t;
  400. !*extraecho := t; % Ensure standard environment for the test...
  401. !*int := nil; % ... so that results are predictable.
  402. packge := car names;
  403. verbos nil;
  404. load!-latest!-patches();
  405. if boundp '!@log and stringp symbol!-value '!@log then
  406. logname := symbol!-value '!@log
  407. else logname := "log";
  408. logname := concat(logname, "/");
  409. logtmp := concat(logname, concat(car names, ".tmp"));
  410. logname := concat(logname, concat(car names,".rlg"));
  411. logfile := open(logtmp, 'output);
  412. begin
  413. scalar !*terminal!-io!*, !*standard!-output!*, !*error!-output!*,
  414. !*trace!-output!*, !*debug!-io!*, !*query!-io!*, !*errcont,
  415. outputhandler!*;
  416. !*terminal!-io!* := !*standard!-output!* := !*error!-output!* := logfile;
  417. !*trace!-output!* := !*debug!-io!* := !*query!-io!* := logfile;
  418. oll := linelength 80;
  419. princ date(); princ " run on "; printc cdr assoc('name, lispsystem!*);
  420. load!-package packge;
  421. packge := concat("tests/", concat(car names,".tst"));
  422. redef := !*redefmsg;
  423. !*redefmsg := nil;
  424. quitfn := getd 'quit;
  425. % At least at one stage at least one test file ends in "quit;" rather than
  426. % "end;" and the normal effect would be that this leads it to cancel
  427. % all execution instantly. To avoid that I will undefine the function
  428. % "quit", but restore it after the test. I reset !*redefmsg to avoid getting
  429. % messages about this. I redefined quit to something (specifically "posn")
  430. % that does not need an argument and that is "harmless".
  431. remd 'quit;
  432. putd('quit, 'expr, 'posn);
  433. start_time := time();
  434. start_gctime := gctime();
  435. !*mode := 'algebraic;
  436. !*extraecho := t; % Ensure standard environment for the test...
  437. !*int := nil; % ... so that results are predictable.
  438. !*errcont := t;
  439. in_list1(packge, t);
  440. erfg!* := nil;
  441. terpri();
  442. putd('quit, car quitfn, cdr quitfn);
  443. !*redefmsg := redef;
  444. terpri();
  445. prin2 "Time for test: ";
  446. gt := time() - start_time;
  447. % I ensure that the reported time is at least 1 millisecond.
  448. if gt = 0 then gt := 1;
  449. prin2 gt;
  450. prin2 " ms";
  451. if (gt := gctime() - start_gctime) > 0 then <<
  452. prin2 ", plus GC time: ";
  453. prin2 gt;
  454. prin2 " ms" >>;
  455. terpri();
  456. linelength oll
  457. end;
  458. close logfile;
  459. delete!-file logname;
  460. rename!-file(logtmp, logname);
  461. names := cdr names;
  462. if null names then restart!-csl t
  463. else restart!-csl('(remake personal_test_a_package), names)
  464. end;
  465. symbolic procedure report_incomplete_tests names;
  466. begin
  467. % Displays information about what "complete_tests" would do
  468. scalar packge, tfile, logname;
  469. scalar date1, date2, date3;
  470. in_list1("$srcdir/../../../package.red", nil);
  471. for each packge in names do <<
  472. tfile := packge;
  473. if get(packge,'folder) then tfile := get(packge,'folder);
  474. tfile := concat("$srcdir/../../../packages/",
  475. concat(tfile,
  476. concat("/",
  477. concat(packge,".tst"))));
  478. if boundp '!@log and stringp symbol!-value '!@log then
  479. logname := symbol!-value '!@log
  480. else logname := "log";
  481. logname := concat("$srcdir/../../../", concat(logname, "/"));
  482. logname := concat(logname, concat(packge,".rlg"));
  483. date1 := filedate "r38.img";
  484. date2 := filedate tfile;
  485. date3 := filedate logname;
  486. if null date1 then date1 := date();
  487. if null date2 then date2 := date();
  488. if null date3 or
  489. datelessp(date3, date1) or datelessp(date3, date2) then <<
  490. princ "NEED TO TEST: "; print packge >> >>
  491. end;
  492. symbolic procedure complete_tests names;
  493. begin
  494. % Just like the previous testing code except that logs that are already up
  495. % to date are not re-generated.
  496. scalar packge, tfile, logname, logfile, logtmp,
  497. start_time, start_gctime, gt;
  498. scalar date1, date2, date3, oll;
  499. !*backtrace := nil;
  500. !*errcont := t;
  501. !*extraecho := t; % Ensure standard environment for the test...
  502. !*int := nil; % ... so that results are predictable.
  503. verbos nil;
  504. load!-latest!-patches();
  505. in_list1("$srcdir/../../../package.red", nil);
  506. top:
  507. tfile := packge := car names;
  508. if get(tfile,'folder) then tfile := get(tfile,'folder);
  509. tfile := concat("$srcdir/../../../packages/",
  510. concat(tfile,
  511. concat("/",
  512. concat(packge,".tst"))));
  513. if boundp '!@log and stringp symbol!-value '!@log then
  514. logname := symbol!-value '!@log
  515. else logname := "log";
  516. logname := concat("$srcdir/../../../", concat(logname, "/"));
  517. logtmp := concat(logname, concat(packge, ".tmp"));
  518. logname := concat(logname, concat(packge, ".rlg"));
  519. date1 := filedate "r38.img";
  520. date2 := filedate tfile;
  521. date3 := filedate logname;
  522. if null date1 then date1 := date();
  523. if null date2 then date2 := date();
  524. if null date3 or
  525. datelessp(date3, date1) or datelessp(date3, date2) then <<
  526. princ "TESTING: "; print packge;
  527. window!-heading list!-to!-string explodec packge;
  528. logfile := open(logtmp, 'output);
  529. start_time := time();
  530. start_gctime := gctime();
  531. begin
  532. scalar !*terminal!-io!*, !*standard!-output!*, !*error!-output!*,
  533. !*trace!-output!*, !*debug!-io!*, !*query!-io!*, !*errcont,
  534. outputhandler!*, redef, quitfn;
  535. !*terminal!-io!* := !*standard!-output!* := !*error!-output!* := logfile;
  536. !*trace!-output!* := !*debug!-io!* := !*query!-io!* := logfile;
  537. oll := linelength 80;
  538. princ date(); princ " run on ";
  539. printc cdr assoc('name, lispsystem!*);
  540. load!-package packge;
  541. !*mode := 'algebraic;
  542. !*extraecho := t; % Ensure standard environment for the test...
  543. !*int := nil; % ... so that results are predictable.
  544. redef := !*redefmsg;
  545. !*redefmsg := nil;
  546. quitfn := getd 'quit;
  547. remd 'quit;
  548. putd('quit, 'expr, 'posn);
  549. !*errcont := t;
  550. in_list1(tfile, t);
  551. erfg!* := nil;
  552. terpri();
  553. putd('quit, car quitfn, cdr quitfn);
  554. !*redefmsg := redef;
  555. terpri();
  556. prin2 "Time for test: ";
  557. gt := time() - start_time;
  558. if gt = 0 then gt := 1;
  559. prin2 gt;
  560. prin2 " ms";
  561. if (gt := gctime() - start_gctime) > 0 then <<
  562. prin2 ", plus GC time: ";
  563. prin2 gt;
  564. prin2 " ms" >>;
  565. terpri();
  566. linelength oll
  567. end;
  568. close logfile;
  569. delete!-file logname;
  570. rename!-file(logtmp, logname) >>
  571. else if cdr names then <<
  572. names := cdr names;
  573. go to top >>;
  574. names := cdr names;
  575. if null names then restart!-csl t
  576. else restart!-csl('(remake complete_tests), names)
  577. end;
  578. symbolic procedure profile_compare_fn(p, q);
  579. (float caddr p/float cadr p) < (float caddr q/float cadr q);
  580. %
  581. % This function runs a test file and sorts out what the top 350
  582. % functions in it. It appends their names to "profile.dat".
  583. %
  584. % I need to talk a little about the interaction between profiling and
  585. % patching. Well firstly I arrange that whenever I run a profiling job
  586. % I rebuild REDUCE with the latest paches. This may involve re-compiling
  587. % the patches.red source. Thus when a test is run the current patches
  588. % will be in place. Patched functions are first defined with funny names
  589. % (including a hash based on their definition) and then copied into place
  590. % when a package is loaded. However MAPSTORE and the CSL instrumentation
  591. % attributes their cost to the hash-extended name even though the
  592. % functions may have been called via the simple one. Thus in the face
  593. % of patches one can expect the profile data to refer to some names that
  594. % are long and curious looking. Throughout all this I assume that there will
  595. % never be embarassing collisions in my hash functions.
  596. symbolic procedure profile_a_package names;
  597. begin
  598. scalar packge, oll, w, w1, w2, quitfn, !*errcont;
  599. princ "PROFILING: "; print car names;
  600. !*backtrace := nil;
  601. !*errcont := t;
  602. !*int := nil;
  603. packge := car names;
  604. verbos nil;
  605. load!-latest!-patches();
  606. load!-package packge;
  607. in_list1("$srcdir/../../../package.red", nil);
  608. if get(packge,'folder) then packge := get(packge,'folder);
  609. packge := concat("$srcdir/../../../packages/",
  610. concat(packge,
  611. concat("/",
  612. concat(car names,".tst"))));
  613. oll := linelength 80;
  614. !*mode := 'algebraic;
  615. window!-heading list!-to!-string explodec car names;
  616. quitfn := getd 'quit;
  617. remd 'quit;
  618. putd('quit, 'expr, 'posn);
  619. mapstore 4; % reset counts;
  620. !*errcont := t;
  621. % I try hard to arrange that even if the test fails I can continue and that
  622. % input & output file selection is not messed up for me.
  623. w := wrs nil; w1 := rds nil;
  624. wrs w; rds w1;
  625. errorset(list('in_list1, mkquote packge, t), nil, nil);
  626. wrs w; rds w1;
  627. erfg!* := nil;
  628. terpri();
  629. putd('quit, car quitfn, cdr quitfn);
  630. w := sort(mapstore 2, function profile_compare_fn);
  631. w1 := nil;
  632. while w do <<
  633. w2 := get(caar w, '!*savedef);
  634. % if eqcar(w2, 'lambda) then <<
  635. % princ "md60: "; print (caar w . cdr w2);
  636. % princ "= "; print md60 (caar w . cdr w2) >>;
  637. if eqcar(w2, 'lambda) then w1 := (caar w . md60 (caar w . cdr w2) .
  638. cadar w . caddar w) . w1;
  639. w := cdr w >>;
  640. w := w1;
  641. % I collect the top 350 functions as used by each test, not because all
  642. % that many will be wanted but because I might as well record plenty
  643. % of information here and discard unwanted parts later on.
  644. for i := 1:349 do if w1 then w1 := cdr w1;
  645. if w1 then rplacd(w1, nil);
  646. % princ "MODULE "; prin car names; princ " suggests ";
  647. % print for each z in w collect car z;
  648. w1 := open("profile.dat", 'append);
  649. w1 := wrs w1;
  650. linelength 80;
  651. princ "("; prin car names; terpri();
  652. for each n in w do <<
  653. princ " ("; prin car n; princ " ";
  654. if posn() > 30 then << terpri(); ttab 30 >>;
  655. prin cadr n;
  656. % I also display the counts just to help me debug & for interest.
  657. princ " "; prin caddr n; princ " "; princ cdddr n;
  658. printc ")" >>;
  659. printc " )";
  660. terpri();
  661. close wrs w1;
  662. linelength oll;
  663. names := cdr names;
  664. if null names then restart!-csl t
  665. else restart!-csl('(remake profile_a_package), names)
  666. end;
  667. symbolic procedure trim_prefix(a, b);
  668. begin
  669. while a and b and car a = car b do <<
  670. a := cdr a;
  671. b := cdr b >>;
  672. if null a then return b
  673. else return nil
  674. end;
  675. fluid '(time_info);
  676. symbolic procedure read_file f1;
  677. begin
  678. % I take the view that I can afford to read the whole of a file into
  679. % memory at the start of processing. This makes life easier for me
  680. % and the REDUCE log files are small compared with current main memory sizes.
  681. scalar r, w, w1, n, x;
  682. scalar p1, p2, p3, p4, p5, p6, p7;
  683. % To make comparisons between my CSL logs and some of the Hearn "reference
  684. % logs", which are created using a different script, I will discard
  685. % lines that match certain patterns! Note that if the reference logs change
  686. % the particular tests I perform here could become out of date! Also if any
  687. % legitimate test output happened to match one of the following strings
  688. % I would lose out slightly.
  689. p1 := explodec "REDUCE 3.8,";
  690. p2 := explodec "1: 1:";
  691. p3 := explodec "2: 2: 2:";
  692. p4 := explodec "3: 3: "; % a prefix to first real line of output.
  693. p5 := explodec "4: 4: 4:";
  694. p6 := explodec "5: 5:";
  695. p7 := explodec "Quittin"; % nb left so that the "g" remains!
  696. % this is so that the match is detected.
  697. r := nil;
  698. n := 0;
  699. while not ((w := readline f1) = !$eof!$) do <<
  700. w1 := explodec w;
  701. if x := trim_prefix(p4, w1) then
  702. r := ((n := n + 1) . list!-to!-string x) . r
  703. else if trim_prefix(p1, w1) or
  704. trim_prefix(p2, w1) or
  705. trim_prefix(p3, w1) or
  706. trim_prefix(p5, w1) or
  707. trim_prefix(p6, w1) or
  708. trim_prefix(p7, w1) then nil
  709. else r := ((n := n + 1) . w) . r >>;
  710. w := r;
  711. % The text scanned for here is expected to match that generated by the
  712. % test script. I locate the last match in a file, extract the numbers
  713. % and eventually write them to log/times.log
  714. n := explodec "Time for test:";
  715. while w and null (x := trim_prefix(n, explodec cdar w)) do w := cdr w;
  716. if null w then <<
  717. time_info := nil;
  718. return reversip r >>;
  719. while eqcar(x, '! ) do x := cdr x;
  720. w := n := nil;
  721. while digit car x do << w := car x . w; x := cdr x >>;
  722. while eqcar(x, '! ) do x := cdr x;
  723. if x := trim_prefix(explodec "ms, plus GC time:", x) then <<
  724. while eqcar(x, '! ) do x := cdr x;
  725. while digit car x do << n := car x . n; x := cdr x >> >>;
  726. if null w then w := '(!0);
  727. if null n then n := '(!0);
  728. time_info := compress reverse w . compress reverse n;
  729. return reversip r;
  730. end;
  731. symbolic procedure roughly_equal(a, b);
  732. begin
  733. % a and b are strings repesenting lines of text. I want to test if they
  734. % match subject to some floating point slop.
  735. scalar wa, wb, adot, bdot;
  736. if a = b then return t;
  737. a := explodec a;
  738. b := explodec b;
  739. top:
  740. % First deal with end of line matters.
  741. if null a and null b then return t
  742. else if null a or null b then return nil;
  743. % next split off any bits of a and b up to a digit
  744. wa := wb := nil;
  745. while a and not digit car a do <<
  746. wa := car a . wa;
  747. a := cdr a >>;
  748. while b and not digit car b do <<
  749. wb := car b . wb;
  750. b := cdr b >>;
  751. if not (wa = wb) then return nil;
  752. % now both a and b start with digits. I will seek a chunk of the
  753. % form nnn.mmmE+xxx where E<sign>xxx is optional...
  754. % Note that any leading sign on the float has been checked already!
  755. wa := wb := nil;
  756. adot := bdot := nil;
  757. while a and digit car a do <<
  758. wa := car a . wa;
  759. a := cdr a >>;
  760. if eqcar(a, '!.) then <<
  761. adot := t;
  762. wa := car a . wa;
  763. a := cdr a >>;
  764. while a and digit car a do <<
  765. wa := car a . wa;
  766. a := cdr a >>;
  767. if eqcar(a, '!e) or eqcar(a, '!E) then <<
  768. adot := t;
  769. wa := car a . wa;
  770. a := cdr a;
  771. if eqcar(a, '!+) or eqcar(a, '!-) then <<
  772. wa := car a . wa;
  773. a := cdr a >>;
  774. while a and digit car a do <<
  775. wa := car a . wa;
  776. a := cdr a >> >>;
  777. % Now all the same to grab a float from b
  778. while b and digit car b do <<
  779. wb := car b . wb;
  780. b := cdr b >>;
  781. if eqcar(b, '!.) then <<
  782. bdot := t;
  783. wb := car b . wb;
  784. b := cdr b >>;
  785. while b and digit car b do <<
  786. wb := car b . wb;
  787. b := cdr b >>;
  788. if eqcar(b, '!e) or eqcar(b, '!E) then <<
  789. bdot := t;
  790. wb := car b . wb;
  791. b := cdr b;
  792. if eqcar(b, '!+) or eqcar(b, '!-) then <<
  793. wb := car b . wb;
  794. b := cdr b >>;
  795. while b and digit car b do <<
  796. wb := car b . wb;
  797. b := cdr b >> >>;
  798. % Now one possibility is that I had an integer not a float,
  799. % and in that case I want an exact match
  800. if not adot or not bdot then <<
  801. if wa = wb then goto top
  802. else return nil >>;
  803. if wa = wb then goto top; % textual match on floating point values
  804. wa := compress reversip wa;
  805. wb := compress reversip wb;
  806. if fixp wa then wa := float wa;
  807. if fixp wb then wb := float wb;
  808. if not (floatp wa and floatp wb) then return nil; % messed up somehow!
  809. if wa = wb then goto top;
  810. % now the crucial approximate floating point test - note that both numbers
  811. % are positive, but that they may be extreme in range.
  812. % As a cop-out I am going to insist that if values are either very very big
  813. % or very very small that they match as text.
  814. if wa > 1.0e100 or wb > 1.0e100 then return nil;
  815. if wa < 1.0e-100 or wb < 1.0e-100 then return nil;
  816. wa := (wa - wb)/(wa + wb);
  817. if wa < 0 then wa := -wa;
  818. if wa > 0.0001 then return nil; % pretty crude!
  819. goto top
  820. end;
  821. symbolic procedure in_sync(d1, n1, d2, n2);
  822. begin
  823. for i := 1:n1 do if d1 then << % skip n1 lines from d1
  824. d1 := cdr d1 >>;
  825. for i := 1:n2 do if d2 then << % skip n2 lines from d2
  826. d2 := cdr d2 >>;
  827. % If one is ended but the other is not then we do not have a match. If
  828. % both are ended we do have one.
  829. if null d1 then return null d2
  830. else if null d2 then return nil;
  831. % Here I insist on 3 lines that agree before I count a match as
  832. % having been re-established.
  833. if not roughly_equal(cdar d1, cdar d2) then return nil;
  834. d1 := cdr d1; d2 := cdr d2;
  835. if null d1 then return null d2
  836. else if null d2 then return nil;
  837. if not roughly_equal(cdar d1, cdar d2) then return nil;
  838. d1 := cdr d1; d2 := cdr d2;
  839. if null d1 then return null d2
  840. else if null d2 then return nil;
  841. if not roughly_equal(cdar d1, cdar d2) then return nil;
  842. d1 := cdr d1; d2 := cdr d2;
  843. if null d1 then return null d2
  844. else if null d2 then return nil
  845. else return t
  846. end;
  847. fluid '(time_data time_ratio gc_time_ratio log_count);
  848. symbolic procedure file_compare(f1, f2, name);
  849. begin
  850. scalar i, j, d1, d2, t1, gt1, t2, gt2, time_info;
  851. d1 := read_file f1;
  852. if null time_info then t1 := gt1 := 0
  853. else << t1 := car time_info; gt1 := cdr time_info >>;
  854. d2 := read_file f2;
  855. if null time_info then t2 := gt2 := 0
  856. else << t2 := car time_info; gt2 := cdr time_info >>;
  857. i := wrs time_data;
  858. j := set!-print!-precision 3;
  859. prin name;
  860. ttab 20;
  861. if zerop t1 then princ "---"
  862. else << prin t1; ttab 30; prin gt1 >>;
  863. ttab 40;
  864. if zerop t2 then princ "---"
  865. else << prin t2; ttab 50; prin gt2 >>;
  866. ttab 60;
  867. if zerop t1 or zerop t2 then princ "*** ***"
  868. else begin
  869. scalar r1, gr1;
  870. r1 := float t1 / float t2;
  871. gr1 := float (t1+gt1)/float (t2+gt2);
  872. % I will only use tests where the time taken was over 200ms in my eventual
  873. % composite summary of timings, since measurement accuracy can leave the
  874. % really short tests pretty meaningless.
  875. if t1 > 200 and t2 > 200 then <<
  876. time_ratio := time_ratio * r1;
  877. gc_time_ratio := gc_time_ratio * gr1;
  878. log_count := log_count + 1 >>;
  879. prin r1;
  880. ttab 70;
  881. prin gr1 end;
  882. terpri();
  883. set!-print!-precision j;
  884. wrs i;
  885. % The next segment of code is a version of "diff" to report ways in which
  886. % reference and recent log files match or diverge.
  887. % I can not see a neat way to get a "structured" control structure
  888. % here easily. Ah well, drop back to GOTO statements!
  889. top:
  890. if null d1 then << % end of one file
  891. if d2 then terpri();
  892. i := 0;
  893. while d2 and i < 20 do <<
  894. princ "REF "; princ caar d2; princ ":"; ttab 10; printc cdar d2;
  895. d2 := cdr d2;
  896. i := i + 1 >>;
  897. if d2 then printc "...";
  898. return >>;
  899. if null d2 then << % end of other file
  900. i := 0;
  901. while d1 and i < 20 do <<
  902. princ "NEW "; princ caar d1; princ ":"; ttab 10; printc cdar d1;
  903. d1 := cdr d1;
  904. i := i + 1 >>;
  905. if d1 then printc "...";
  906. return >>;
  907. % The test "roughly_equal" compares allowing some tolerance on floating
  908. % point values. This is because REDUCE uses platform libraries for
  909. % floating point elementary functions and printing, so small differences
  910. % are expected. This is perhaps uncomfortable, but is part of reality, and
  911. % the test here makes comparison output much more useful in that the
  912. % differences shown up are better limited towards "real" ones.
  913. if roughly_equal(cdar d1, cdar d2) then <<
  914. d1 := cdr d1;
  915. d2 := cdr d2;
  916. go to top >>;
  917. % I will first see if there are just a few blank lines inserted into
  918. % one or other file. This special case is addressed here because it
  919. % appears more common a possibility than I had expected.
  920. if cdar d1 = "" and cdr d1 and roughly_equal(cdadr d1, cdar d2) then <<
  921. princ "NEW "; princ caar d1; princ ":"; ttab 10; printc cdar d1;
  922. d1 := cdr d1;
  923. go to top >>
  924. else if cdar d1 = "" and cdr d1 and cdadr d1 = "" and cddr d1 and
  925. roughly_equal(cdaddr d1, cdar d2) then <<
  926. princ "NEW "; princ caar d1; princ ":"; ttab 10; printc cdar d1;
  927. d1 := cdr d1;
  928. princ "NEW "; princ caar d1; princ ":"; ttab 10; printc cdar d1;
  929. d1 := cdr d1;
  930. go to top >>
  931. else if cdar d2 = "" and cdr d2 and
  932. roughly_equal(cdadr d2, cdar d1) then <<
  933. princ "REF "; princ caar d2; princ ":"; ttab 10; printc cdar d2;
  934. d2 := cdr d2;
  935. go to top >>
  936. else if cdar d2 = "" and cdr d2 and cdadr d2 = "" and cddr d2 and
  937. roughly_equal(cdaddr d2, cdar d1) then <<
  938. princ "REF "; princ caar d2; princ ":"; ttab 10; printc cdar d2;
  939. d2 := cdr d2;
  940. princ "REF "; princ caar d2; princ ":"; ttab 10; printc cdar d2;
  941. d2 := cdr d2;
  942. go to top >>;
  943. i := 1;
  944. seek_rematch:
  945. j := 0;
  946. inner:
  947. if in_sync(d1, i, d2, j) then <<
  948. terpri();
  949. for k := 1:i do <<
  950. princ "NEW "; princ caar d1; princ ":"; ttab 10; printc cdar d1;
  951. d1 := cdr d1 >>;
  952. for k := 1:j do <<
  953. princ "REF "; princ caar d2; princ ":"; ttab 10; printc cdar d2;
  954. d2 := cdr d2 >>;
  955. % Should be in step again here.
  956. if null d1 then return
  957. else go to top >>;
  958. j := j + 1;
  959. i := i - 1;
  960. if i >= 0 then go to inner;
  961. i := j;
  962. % I am prepared to seek 80 lines ahead on each side before I give up.
  963. % The number 80 is pretty much arbitrary.
  964. if i < 80 then goto seek_rematch;
  965. terpri();
  966. i := 0;
  967. while d2 and i < 20 do <<
  968. princ "REF "; princ caar d2; princ ":"; ttab 10; printc cdar d2;
  969. d2 := cdr d2;
  970. i := i+1 >>;
  971. if d2 then printc "...";
  972. i := 0;
  973. while d1 and i < 20 do <<
  974. princ "NEW "; princ caar d1; princ ":"; ttab 10; printc cdar d1;
  975. d1 := cdr d1;
  976. i := i+1 >>;
  977. if d1 then printc "...";
  978. printc "Comparison failed."
  979. end;
  980. fluid '(which_module);
  981. symbolic procedure check_a_package;
  982. begin
  983. scalar oll, names, p1, logname, mylogname, mylog, reflogname, reflog,
  984. time_data, time_ratio, gc_time_ratio, log_count;
  985. get_configuration_data t;
  986. if boundp 'which_module and symbol!-value 'which_module and
  987. not (symbol!-value 'which_module = "") then <<
  988. names := compress explodec symbol!-value 'which_module;
  989. if member(names, r38_test_cases) then names := list names
  990. else error(0, list("unknown module to check", which_module)) >>
  991. else names := r38_test_cases;
  992. in_list1("$srcdir/../../../package.red", nil);
  993. % I write a summary of timing information into log/times.log
  994. time_data := open("log/times.log", 'output);
  995. p1 := wrs time_data;
  996. princ "MODULE";
  997. ttab 20; princ "Local"; ttab 30; princ "(GC)";
  998. ttab 40; princ "Reference"; ttab 50; princ "(GC)";
  999. ttab 60; princ "Ratio"; ttab 70; printc "inc GC";
  1000. wrs p1;
  1001. terpri();
  1002. oll := linelength 100;
  1003. printc "=== Comparison results ===";
  1004. time_ratio := gc_time_ratio := 1.0; log_count := 0;
  1005. for each packge in names do <<
  1006. terpri();
  1007. princ "CHECKING: "; print packge;
  1008. if boundp '!@log and stringp symbol!-value '!@log then
  1009. logname := symbol!-value '!@log
  1010. else logname := "log";
  1011. logname := concat("$srcdir/../../../", concat(logname, "/"));
  1012. mylogname := concat(logname, concat(packge, ".rlg"));
  1013. if get(packge,'folder) then p1 := get(packge,'folder)
  1014. else p1 := packge;
  1015. reflogname := concat("$srcdir/../../../packages/",
  1016. concat(p1,
  1017. concat("/",
  1018. concat(packge,".rlg"))));
  1019. mylog := errorset(list('open, mkquote mylogname, ''input), nil, nil);
  1020. reflog := errorset(list('open, mkquote reflogname, ''input), nil, nil);
  1021. if errorp mylog then <<
  1022. if not errorp reflog then close car reflog;
  1023. princ "No current log in "; print mylogname >>
  1024. else if errorp reflog then <<
  1025. close car mylog;
  1026. princ "No reference log in "; print reflogname >>
  1027. else <<
  1028. princ "LOGS: "; princ mylogname; princ " "; printc reflogname;
  1029. mylog := car mylog; reflog := car reflog;
  1030. file_compare(mylog, reflog, packge);
  1031. close mylog;
  1032. close reflog >> >>;
  1033. time_data := wrs time_data;
  1034. if not zerop log_count then <<
  1035. time_ratio := expt(time_ratio, 1.0/log_count);
  1036. gc_time_ratio := expt(gc_time_ratio, 1.0/log_count);
  1037. terpri();
  1038. p1 := set!-print!-precision 3;
  1039. princ "Over "; prin log_count; princ " tests the speed ratio was ";
  1040. print time_ratio;
  1041. princ " (or ";
  1042. prin gc_time_ratio;
  1043. printc " is garbage collection costs are included)";
  1044. set!-print!-precision p1 >>;
  1045. close wrs time_data;
  1046. linelength oll;
  1047. end;
  1048. symbolic procedure personal_check_a_package;
  1049. begin
  1050. scalar oll, names, p1, logname, mylogname, mylog, reflogname, reflog,
  1051. time_data, time_ratio, gc_time_ratio, log_count;
  1052. get_configuration_data nil;
  1053. if boundp 'which_module and symbol!-value 'which_module and
  1054. not (symbol!-value 'which_module = "") then <<
  1055. names := compress explodec symbol!-value 'which_module;
  1056. if member(names, r38_test_cases) then names := list names
  1057. else error(0, list("unknown module to check", which_module)) >>
  1058. else names := r38_test_cases;
  1059. % I write a summary of timing information into log/times.log
  1060. time_data := open("log/times.log", 'output);
  1061. p1 := wrs time_data;
  1062. princ "MODULE";
  1063. ttab 20; princ "Local"; ttab 30; princ "(GC)";
  1064. ttab 40; princ "Reference"; ttab 50; princ "(GC)";
  1065. ttab 60; princ "Ratio"; ttab 70; printc "inc GC";
  1066. wrs p1;
  1067. terpri();
  1068. oll := linelength 100;
  1069. printc "=== Comparison results ===";
  1070. time_ratio := gc_time_ratio := 1.0; log_count := 0;
  1071. for each packge in names do <<
  1072. terpri();
  1073. princ "CHECKING: "; print packge;
  1074. mylogname := concat("log/", concat(packge, ".rlg"));
  1075. reflogname := concat("tests/", concat(packge,".rlg"));
  1076. mylog := errorset(list('open, mkquote mylogname, ''input), nil, nil);
  1077. reflog := errorset(list('open, mkquote reflogname, ''input), nil, nil);
  1078. if errorp mylog then <<
  1079. if not errorp reflog then close car reflog;
  1080. princ "No current log in "; print mylogname >>
  1081. else if errorp reflog then <<
  1082. close car mylog;
  1083. princ "No reference log in "; print reflogname >>
  1084. else <<
  1085. princ "LOGS: "; princ mylogname; princ " "; printc reflogname;
  1086. mylog := car mylog; reflog := car reflog;
  1087. file_compare(mylog, reflog, packge);
  1088. close mylog;
  1089. close reflog >> >>;
  1090. time_data := wrs time_data;
  1091. if not zerop log_count then <<
  1092. time_ratio := expt(time_ratio, 1.0/log_count);
  1093. gc_time_ratio := expt(gc_time_ratio, 1.0/log_count);
  1094. terpri();
  1095. p1 := set!-print!-precision 3;
  1096. princ "Over "; prin log_count; princ " tests the speed ratio was ";
  1097. print time_ratio;
  1098. princ " (or ";
  1099. prin gc_time_ratio;
  1100. printc " is garbage collection costs are included)";
  1101. set!-print!-precision p1 >>;
  1102. close wrs time_data;
  1103. linelength oll;
  1104. end;
  1105. faslend;
  1106. % faslout 'cslhelp;
  1107. %
  1108. % module cslhelp;
  1109. %
  1110. % global '(!*force);
  1111. %
  1112. % flag('(force),'switch);
  1113. % flag('(on),'eval);
  1114. %
  1115. % on force;
  1116. %
  1117. % symbolic procedure formhelp(u,vars,mode);
  1118. % list('help, 'list . for each x in cdr u collect mkquote x);
  1119. %
  1120. % if member('help, lispsystem!*) then <<
  1121. % put('help, 'stat, 'rlis);
  1122. % flag('(help), 'go);
  1123. % put('help, 'formfn, 'formhelp) >>;
  1124. %
  1125. % off force;
  1126. % remflag('(on),'eval);
  1127. %
  1128. % endmodule;
  1129. %
  1130. % faslend;
  1131. load!-module 'remake;
  1132. << initreduce();
  1133. date!* := "Bootstrap version";
  1134. !@reduce := symbol!-value gensym();
  1135. checkpoint('begin, "REDUCE 3.8") >>;
  1136. !#if (not !*savedef)
  1137. load!-module 'user;
  1138. !#endif
  1139. !@reduce := concat(!@srcdir, "/../../..");
  1140. in "$reduce/package.red"$
  1141. package!-remake2(prolog_file,'support);
  1142. package!-remake2(rend_file,'support);
  1143. package!-remake2('entry,'support);
  1144. package!-remake2('remake,'support);
  1145. % The next lines have LOTS of hidden depth! They restart CSL repeatedly
  1146. % so that each of the modules that has to be processed gets dealt with in
  1147. % a fresh uncluttered environment. The list of modules is fetched from
  1148. % a configuration file which must have 3 s-expressions in it. The first
  1149. % is a list of basic modules that must be built to get a core version of
  1150. % REDUCE. The second list identifies modules that can be built one the core
  1151. % is ready for use, while the last list indicates which modules have
  1152. % associated test scripts.
  1153. %
  1154. % when the modules have been rebuild the system does a restart that
  1155. % kicks it back into REDUCE by calling begin(). This then continues
  1156. % reading from the stream that had been the standard input when this
  1157. % job started. Thus this script MUST be invoked as
  1158. % ./csl -oslowr38.img -z build38.lsp -l log/build38.log
  1159. % with the file build38.lsp specified on the command line in the call. It
  1160. % will not work if you start csl manually and then do a (rdf ..) [say]
  1161. % on build38.lsp. I told you that it was a little delicate.
  1162. !#if !*savedef
  1163. % Some switches may be in the utter core and not introduced via the
  1164. % "switch" declaration...
  1165. for each y in oblist() do
  1166. if flagp(y, 'switch) then <<
  1167. princ "+++ Declaring a switch: ";
  1168. print y >>;
  1169. !#endif
  1170. get_configuration_data t;
  1171. build_reduce_modules r38_base_modules;
  1172. % Now I want to do a cold-start so that I can create a sensible
  1173. % image for use in the subsequent build steps. This image should not
  1174. % contain ANYTHING extraneous.
  1175. symbolic restart!-csl nil;
  1176. (setq !*savedef (lessp (cdr (assoc 'c!-code lispsystem!*)) 20))
  1177. (make!-special '!*native_code)
  1178. (setq !*native_code nil)
  1179. (setq !*backtrace t)
  1180. (cond ((null !*savedef) (load!-module 'user)))
  1181. (load!-module 'cslcompat)
  1182. (setq !*comp nil)
  1183. (load!-module 'module) % Definition of load_package, etc.
  1184. (load!-module 'cslprolo) % CSL specific code.
  1185. (setq loaded!-packages!* '(cslcompat user cslprolo))
  1186. % NB I will re-load the "patches" module when REDUCE is started
  1187. % if there is a version newer than the one I load up here. Note that
  1188. % if there had not been a "patches.red" file I will not have a module to load
  1189. % here.
  1190. (cond
  1191. ((modulep 'patches) (load!-module 'patches)))
  1192. (load!-package 'rlisp)
  1193. (load!-package 'cslrend)
  1194. (load!-package 'poly)
  1195. (load!-package 'arith)
  1196. (load!-package 'alg)
  1197. (load!-package 'mathpr)
  1198. (cond
  1199. ((modulep 'tmprint) (load!-package 'tmprint)))
  1200. (load!-package 'entry)
  1201. % (write!-help!-module "$srcdir/../util/r38.inf" nil)
  1202. %
  1203. % (load!-module 'cslhelp)
  1204. (setq version!* "REDUCE 3.8")
  1205. (setq !*backtrace nil)
  1206. (initreduce)
  1207. (setq date!* "15-Apr-04")
  1208. (setq no_init_file nil)
  1209. (setq !@csl (setq !@reduce (symbol!-value (gensym))))
  1210. % If the user compiles a new FASL module then I will let it
  1211. % generate native code by default. I build the bulk of REDUCE
  1212. % without that since I have statically-selected hot-spot compilation
  1213. % that gives me what I believe to be a better speed/space tradeoff.
  1214. (fluid '(!*native_code))
  1215. (setq !*native_code t)
  1216. (checkpoint 'begin (bldmsg "%w, %w ..." version!* date!*))
  1217. (setq no_init_file t)
  1218. (begin)
  1219. %
  1220. % See the fairly length comments given a bit earlier about the
  1221. % delicacy of the next few lines!
  1222. %
  1223. symbolic;
  1224. load!-module 'remake;
  1225. get_configuration_data t;
  1226. build_reduce_modules r38_extra_modules;
  1227. % At this stage I have a complete workable REDUCE. If built using a
  1228. % basic CSL (I call it "slowr38" here) nothing has been compiled into C
  1229. % (everything is bytecoded), and it is big because it has retained all
  1230. % Lisp source code in the image file. If however I built using a version
  1231. % of CSL ("r38") that did have things compiled into C then these will
  1232. % be exploited and the original Lisp source will be omitted from the
  1233. % image, leaving a production version.
  1234. bye;