clrend.red 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. module rend; % CL REDUCE "back-end".
  2. % Authors: Anthony C. Hearn, Martin L. Griss, Arthur C. Norman, et al.
  3. % Modified by FJW for Common Lisp REDUCE.
  4. % The standard version is "$reduce/packages/support/*rend.red".
  5. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6. % Redistribution and use in source and binary forms, with or without %
  7. % modification, are permitted provided that the following conditions are met: %
  8. % %
  9. % * Redistributions of source code must retain the relevant copyright %
  10. % notice, this list of conditions and the following disclaimer. %
  11. % * Redistributions in binary form must reproduce the above copyright %
  12. % notice, this list of conditions and the following disclaimer in the %
  13. % documentation and/or other materials provided with the distribution. %
  14. % %
  15. % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" %
  16. % AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE %
  17. % IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE %
  18. % ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNERS OR CONTRIBUTORS BE %
  19. % LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR %
  20. % CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF %
  21. % SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS %
  22. % INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN %
  23. % CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) %
  24. % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE %
  25. % POSSIBILITY OF SUCH DAMAGE. %
  26. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  27. create!-package('(clrend),nil);
  28. fluid '(!*echo
  29. !*int
  30. !*mode
  31. ifl!*
  32. lispsystem!*
  33. promptstring!*
  34. outputhandler!*);
  35. global '(!*extraecho
  36. !*loadversion
  37. date!*
  38. esc!*
  39. ipl!*
  40. largest!-small!-modulus
  41. ofl!*
  42. spare!*
  43. statcounter
  44. version!*
  45. seprp!*
  46. symchar!*);
  47. switch break, gc, printlower, redefmsg, debug, verboseload;
  48. % This procedure definition taken from "pslrend.red" is required for
  49. % the factor module:
  50. symbolic procedure carcheck fff;
  51. nil; % CSL function used much as setting !*fastcar in PSL.
  52. Comment The following functions, which are referenced in the basic
  53. REDUCE source (RLISP, ALG1, ALG2, MATR and PHYS) should be defined to
  54. complete the definition of REDUCE:
  55. BYE
  56. EVLOAD -- defined in "clprolo.red"
  57. ERROR1 -- defined in "sl-on-cl.lisp"
  58. MKFIL
  59. ORDERP -- defined in "sl-on-cl.lisp"
  60. QUIT
  61. SEPRP
  62. SETPCHAR.
  63. Prototypical descriptions of these functions are as follows;
  64. remprop('bye,'stat);
  65. fluid '(bye!-actions!*);
  66. % A package may put a call to some termination code on top of this list.
  67. bye!-actions!* := '((close!-output!-files) (quit));
  68. symbolic procedure bye;
  69. eval('progn . bye!-actions!*);
  70. deflist('((bye endstat)),'stat);
  71. Comment to make "bye" and "quit" equivalent, as stated by the REDUCE
  72. manual;
  73. put('quit,'newnam,'bye);
  74. symbolic procedure mkfil u;
  75. % Converts file descriptor U into valid system filename.
  76. % FJW: I define string!-downcase in "sl-on-cl.lisp".
  77. if stringp u then u
  78. else if not idp u then typerr(u,"file name")
  79. else string!-downcase u;
  80. seprp!* := {'! , '! , '! , '! , !$eol!$}; % FJW
  81. symbolic procedure seprp u;
  82. % Returns true if U is a blank or other separator (eg, tab or ff).
  83. % This definition replaces one in the BOOT file (and another in "build.red").
  84. u memq seprp!*;
  85. procedure setpchar c;
  86. % Set prompt, return old one.
  87. begin scalar oldprompt;
  88. oldprompt := promptstring!*;
  89. promptstring!* := if stringp c then c
  90. else if idp c then id2string c
  91. % FJW: I don't really want to import the CL format function just
  92. % to use it here. Is this line actually used?
  93. else error(0, "Unexpected prompt in setpchar");
  94. % else format(nil, "~a", c);
  95. return oldprompt
  96. end;
  97. % This procedure has already been defined in rlisp/superv, but must be
  98. % redefined for Common Lisp to call force-output so that the prompt
  99. % appears when it should. This is the approach taken in the SBCL
  100. % default top-level REPL.
  101. symbolic procedure printprompt u;
  102. %Prints the prompt expression for input;
  103. << ofl!* and wrs nil; prin2 u; force!-output(); ofl!* and wrs cdr ofl!* >>;
  104. Comment The following functions are only referenced if various flags are
  105. set, or the functions are actually defined. They are defined in another
  106. module, which is not needed to build the basic system. The name of the
  107. flag follows the function name, enclosed in parentheses:
  108. CEDIT (?)
  109. COMPD (COMP)
  110. EDIT1 This function provides a link to an editor. However, a
  111. definition is not necessary, since REDUCE checks to see
  112. if it has a function value.
  113. EZGCDF (EZGCD)
  114. PRETTYPRINT (DEFN --- also called by DFPRINT)
  115. This function is used in particular for output of RLISP
  116. expressions in LISP syntax. If that feature is needed,
  117. and the prettyprint module is not available, then it
  118. should be defined as PRINT
  119. RPRINT (PRET)
  120. TIME (TIME) returns elapsed time from some arbitrary initial
  121. point in milliseconds;
  122. % Operating system interface:
  123. flag('(system pwd cd getenv),'opfn);
  124. flag('(system),'noval);
  125. Comment There are a number of system constants required for each
  126. implementation. In systems that don't support inums, the equivalent
  127. single precision integers should be used;
  128. % LARGEST!-SMALL!-MODULUS is the largest power of two that can
  129. % fit in the fast arithmetic (inum) range of the implementation.
  130. % This is constant for the life of the system and could be
  131. % compiled in-line if the compiler permits it.
  132. largest!-small!-modulus := 2**23;
  133. % If the (small) modular arithmetic is always limited to LARGEST-SMALL-
  134. % MODULUS, it all fits in the inum range of the machine, with the
  135. % exception of modular-times, that needs to use generic arithmetic for
  136. % the multiplication. However, on some machines (e.g., the VAX), it is
  137. % possible to 'borrow' the extra precision needed, so that the following
  138. % definition works. This will not work of course for non-inums.
  139. Comment We need to define a function BEGIN, which acts as the top-level
  140. call to REDUCE, and sets the appropriate variables;
  141. remflag('(begin),'go);
  142. symbolic procedure begin;
  143. begin
  144. !*echo := not !*int;
  145. !*extraecho := t;
  146. ifl!* := ipl!* := ofl!* := nil;
  147. if null date!* then go to a;
  148. if !*loadversion then errorset('(load entry),nil,nil);
  149. linelength 80;
  150. prin2 version!*;
  151. prin2 ", ";
  152. prin2 date!*;
  153. prin2t " ...";
  154. !*mode := if getd 'addsq then 'algebraic else 'symbolic;
  155. if !*mode eq 'algebraic then !*break := nil;
  156. %since most REDUCE users won't use LISP
  157. date!* := nil;
  158. a: if errorp errorset('(begin1),nil,nil) then go to a;
  159. prin2t "Entering LISP ... "
  160. end;
  161. flag('(begin),'go);
  162. Comment Initial setups for REDUCE;
  163. spare!* := 0; % We need this for bootstrapping. (FJW: Maybe!)
  164. symchar!* := t; % Changed prompt when in symbolic mode.
  165. symbolic procedure initreduce;
  166. % Initial declarations for REDUCE
  167. <<
  168. statcounter := 0;
  169. spare!* := 0;
  170. !*int := t;
  171. crbuflis!* := nil; % We don't want to leave old input around.
  172. % eval '(begin);
  173. >>;
  174. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  175. % tr etc. are defined as macros in "trace.lisp".
  176. % The following two declarations are from pslrend/cslrend:
  177. flag('(tr untr trst untrst),'noform);
  178. deflist('((tr rlis) (untr rlis) (trst rlis) (untrst rlis)),'stat);
  179. %% Fix problems in the arith package
  180. %% =================================
  181. % Procedure find!!minnorm causes float overflow. Not sure why, but
  182. % circumvent it for now by using a Common Lisp
  183. % Implementation-Dependent Numeric Constant:
  184. % symbolic procedure find!!minnorm();
  185. % <<
  186. % !!minnorm := least!-positive!-normalized!-single!-float;
  187. % !!minnegnorm := -!!minnorm;
  188. % >>;
  189. % flag('(find!!minnorm), 'lose);
  190. % Some CSL compatibility, taken from support/psl{,rend}.red:
  191. symbolic inline procedure prin x; prin1 x;
  192. remflag('(printc), 'lose);
  193. % printc is defined in int/int.red to be prin2t, but this inline
  194. % definition is better and is available without loading int:
  195. symbolic inline procedure printc x; << prin2 x; terpri(); x >>;
  196. flag('(printc), 'lose);
  197. symbolic procedure ttab n; while posn() < n do prin2 " ";
  198. symbolic inline procedure explodec x; explode2 x;
  199. % Make ON DEFN load the prettyprinter if necessary and
  200. % OFF DEFN reinstate property lists saved during ON DEFN:
  201. % put('defn, 'simpfg, '((t (!require '!eslpretty))
  202. % (nil (!esl!-reinstate!-plists))));
  203. #if (memq 'sbcl lispsystem!*)
  204. % Make the COMP switch control the SBCL evaluation mode:
  205. put('comp, 'simpfg, '((t (compilation t))
  206. (nil (compilation nil))));
  207. #endif
  208. remflag('(systo_get!-resource!-directory), 'lose);
  209. % This function is called in redlog but only defined for PSL or CSL
  210. % specifically. Otherwise, it only gets an autoload definition that
  211. % causes infinite recursion when called. This stub is an attempt to
  212. % avoid this error, but nothing more. It may need attention later,
  213. % but what is the Common Lisp resource directory?
  214. symbolic procedure systo_get!-resource!-directory; "";
  215. flag('(systo_get!-resource!-directory), 'lose);
  216. % This function is called in tmprint and apparently defined in PSL.
  217. % This stub is an attempt to avoid an error, but nothing more. It
  218. % will need attention later!
  219. procedure compute!-prompt!-string(count,level); "";
  220. % The function subla is built into CSL and PSL and flagged lose. It
  221. % is also defined in "rtools/general.red" and "alg/general.red", but
  222. % is needed early in the boot process, so I have defined it in
  223. % "sl-on-cl.lisp".
  224. flag('(subla), 'lose);
  225. % Fixes for the crack suite
  226. % =========================
  227. % "crack/crinit.red" defines procedure random_init for PSL or CSL
  228. % specifically with no generic definition, so here is a CL version.
  229. % Procedure `random_new_seed' is defined in "rlisp/random.red" to take
  230. % a single argument, offset, which must be a positive integer.
  231. % Function `datestamp' is defined in "sl-on-cl" to return the number
  232. % of seconds that have elapsed since some epoch.
  233. symbolic procedure random_init(); random_new_seed datestamp();
  234. % "crack/crutil.red" defines this procedure only for PSL.
  235. % Using the CL version directly doesn't work in all cases, so I
  236. % redefine it here as in crack!
  237. symbolic procedure rename!-file(fromname, toname)$
  238. % Rename fromname to toname and return t on success.
  239. % (it is defined in csl)
  240. system bldmsg("mv %w %w", fromname, toname) = 0;
  241. % From "pslrend.red"; does this also apply to Common Lisp? Not
  242. % required to run "crack.tst"!
  243. % In the crack code it is essential that subst arranges to share some of
  244. % its output with its input. The same may be the case for sublist too?
  245. % The standard implementation of subst in PSL does not do this.
  246. %% symbolic procedure subst(a, b, c);
  247. %% if c = b then a
  248. %% else if atom c then c
  249. %% else begin
  250. %% scalar sa, sd;
  251. %% sa := subst(a, b, car c);
  252. %% sd := subst(a, b, cdr c);
  253. %% if sa eq car c and sd eq cdr c then return c
  254. %% else return sa . sd
  255. %% end;
  256. % Fixes for the lalr package
  257. % ==========================
  258. % This procedure is defined in "lalr/genparser.red". Because Common
  259. % Lisp seems to view equality of uninterned and interned symbols
  260. % differently from PSL/CSL, I need explicitly to apply intern to
  261. % identifiers but not to strings handled within this procedure until I
  262. % can think of a way to modify sl-on-cl that works.
  263. fluid '(nonterminals);
  264. remflag('(lalr_collect_terminals), 'lose);
  265. symbolic procedure lalr_collect_terminals grammar;
  266. begin
  267. scalar rhs_symbols;
  268. for each productions in grammar do
  269. for each production in cdr productions do
  270. for each symbol in car production do
  271. <<
  272. if idp symbol then symbol := intern symbol; % FJW
  273. if not (symbol member rhs_symbols) then
  274. rhs_symbols := symbol . rhs_symbols
  275. >>;
  276. return setdiff(rhs_symbols, nonterminals)
  277. end;
  278. flag('(lalr_collect_terminals), 'lose);
  279. endmodule;
  280. end;