rend.red 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. module rend; % PSL REDUCE "back-end".
  2. % Authors: Martin L. Griss and Anthony C. Hearn.
  3. % Except where noted, this works with both PSL 3.2 and PSL 3.4.
  4. create!-package('(rend),'(build));
  5. fluid '(!*break
  6. !*echo
  7. !*eolinstringok
  8. !*fastcar
  9. !*fulltrace
  10. !*gc
  11. !*int
  12. !*mode
  13. !*pgwd
  14. !*plap
  15. !*pwrds
  16. !*usermode
  17. !*verboseload
  18. currentreadmacroindicator!*
  19. currentscantable!*
  20. % current!-modulus
  21. errout!*
  22. lispscantable!*
  23. promptstring!*
  24. rlispscantable!*);
  25. global '(!$eol!$
  26. !*extraecho
  27. !*loadversion
  28. !*raise
  29. cr!*
  30. crchar!*
  31. date!*
  32. esc!*
  33. ff!*
  34. ifl!*
  35. ipl!*
  36. largest!-small!-modulus
  37. ofl!*
  38. spare!*
  39. statcounter
  40. tab!*
  41. version!*);
  42. switch break,gc,usermode,verboseload;
  43. switch plap,pgwd,pwrds;
  44. !*fastcar := t; % Since REDUCE doesn't use car and cdr on atoms.
  45. % Constants used in scanner.
  46. flag('(define!-constant),'eval);
  47. define!-constant(cr!*,intern int2id 13); % carriage return (^M).
  48. define!-constant(ff!*,intern int2id 12); % form feed (^L).
  49. define!-constant(tab!*,intern int2id 9); % tab key (^I)
  50. deflist('((!$eol!$ t) (!$eof!$ t)),'constant!?);
  51. % One inessential reference to REVERSIP in this module (left unchanged).
  52. % This file defines the system dependent code necessary to run REDUCE
  53. % under PSL.
  54. Comment The following functions, which are referenced in the basic
  55. REDUCE source (RLISP, ALG1, ALG2, MATR and PHYS) should be defined to
  56. complete the definition of REDUCE:
  57. BYE
  58. EVLOAD
  59. ERROR1
  60. FILETYPE
  61. MKFIL
  62. ORDERP
  63. QUIT
  64. SEPRP
  65. SETPCHAR.
  66. Prototypical descriptions of these functions are as follows;
  67. remprop('bye,'stat);
  68. symbolic procedure bye;
  69. %Returns control to the computer's operating system command level.
  70. %The current REDUCE job cannot be restarted;
  71. <<close!-output!-files(); exitlisp()>>;
  72. deflist('((bye endstat)),'stat);
  73. symbolic procedure seprp u;
  74. % Returns true if U is a blank, end-of-line, tab, carriage return or
  75. % form feed. This definition replaces the one in the BOOT file.
  76. u eq '! or u eq tab!* or u eq !$eol!$ or u eq ff!* or u eq cr!*;
  77. symbolic procedure error1;
  78. %This is the simplest error return, without a message printed. It can
  79. %be defined as ERROR(99,NIL) if necessary;
  80. throw('!$error!$,99);
  81. symbolic procedure filetype u;
  82. % Determines if string U has a specific file type.
  83. begin scalar v,w;
  84. v := cdr explode u;
  85. while v and not(car v eq '!.) do
  86. <<if car v eq '!< then while not(car v eq '!>) do v := cdr v;
  87. v := cdr v>>;
  88. if null v then return nil;
  89. v := cdr v;
  90. while v and not(car v eq '!") do <<w := car v . w; v := cdr v>>;
  91. % The following allows for extensions like 1E that the PSL
  92. % token scanner does not like.
  93. v := nil;
  94. while w do <<v := '!! . car w . v; w := cdr w>>;
  95. return intern compress v
  96. end;
  97. symbolic procedure mkfil u;
  98. % Converts file descriptor U into valid system filename.
  99. if stringp u then u
  100. else if not idp u then typerr(u,"file name")
  101. else string!-downcase u;
  102. % The following three functions are only used as part of mkfil.
  103. symbolic procedure string!-downcase u;
  104. begin scalar z;
  105. if not stringp u then u := '!" . append(explode2 u,'(!"))
  106. else u := explode u;
  107. for each x in u do
  108. if uppercasep x then z := red!-char!-downcase x . z
  109. else z := x . z;
  110. return compress reverse z
  111. end;
  112. symbolic procedure red!-char!-downcase u;
  113. begin scalar x;
  114. if (x := atsoc(u,
  115. '((A . !a) (B . !b) (C . !c) (D . !d) (E . !e) (F . !f)
  116. (G . !g) (H . !h) (I . !i) (J . !j) (K . !k) (L . !l)
  117. (M . !m) (N . !n) (O . !o) (P . !p) (Q . !q) (R . !r)
  118. (S . !s) (T . !t) (U . !u) (V . !v) (W . !w) (X . !x)
  119. (Y . !y) (Z . !z))))
  120. then return cdr x
  121. else rederr list(u,"not upper case character")
  122. end;
  123. symbolic procedure uppercasep u;
  124. u memq '(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z);
  125. symbolic procedure orderp(u,v);
  126. % U, v are non-numeric atoms (but can be vectors).
  127. % Returns true if U has same or higher order than id V by some
  128. % consistent convention (eg unique position in memory).
  129. wleq(inf u,inf v); % PSL 3.4 form.
  130. % id2int u <= id2int v; % PSL 3.2 form.
  131. procedure setpchar c;
  132. % Set prompt, return old one.
  133. begin scalar oldprompt;
  134. oldprompt := promptstring!*;
  135. promptstring!* := if stringp c then c
  136. else if idp c then copystring id2string c
  137. else bldmsg("%W", c);
  138. return oldprompt
  139. end;
  140. Comment The following functions are only referenced if various flags are
  141. set, or the functions are actually defined. They are defined in another
  142. module, which is not needed to build the basic system. The name of the
  143. flag follows the function name, enclosed in parentheses:
  144. CEDIT (?)
  145. COMPD (COMP)
  146. EDIT1 This function provides a link to an editor. However, a
  147. definition is not necessary, since REDUCE checks to see
  148. if it has a function value.
  149. EMBFN (?)
  150. EZGCDF (EZGCD)
  151. PRETTYPRINT (DEFN --- also called by DFPRINT)
  152. This function is used in particular for output of RLISP
  153. expressions in LISP syntax. If that feature is needed,
  154. and the prettyprint module is not available, then it
  155. should be defined as PRINT
  156. RPRINT (PRET)
  157. TIME (TIME) returns elapsed time from some arbitrary initial
  158. point in milliseconds;
  159. Comment The FACTOR module also requires a definition for GCTIME. Since
  160. this is currently undefined in PSL, we provide the following definition;
  161. symbolic procedure gctime; gctime!*;
  162. Comment The following operator is used to save a REDUCE session as a
  163. file for later use;
  164. symbolic procedure savesession u;
  165. savesystem("Saved session",u,nil);
  166. flag('(savesession),'opfn);
  167. flag('(savesession),'noval);
  168. Comment make "system" available as an operator;
  169. flag('(system),'opfn);
  170. flag('(system),'noval);
  171. Comment to make "faslend" an endstat;
  172. put('faslend,'stat,'endstat);
  173. Comment The current REDUCE model allows for the availability of fast
  174. arithmetical operations on small integers (called "inums"). All modern
  175. LISPs provide such support. However, the program will still run without
  176. these constructs. The relevant functions that should be defined for
  177. this purpose are as follows;
  178. remflag('(iplus itimes),'lose);
  179. remprop('iplus,'infix); % to allow for redefinition.
  180. remprop('itimes,'infix);
  181. symbolic macro procedure iplus u; expand(cdr u,'iplus2);
  182. symbolic macro procedure itimes u; expand(cdr u,'itimes2);
  183. flag('(iplus itimes iplus2 itimes2 iadd1 isub1 iminus iminusp
  184. idifference iquotient iremainder ilessp igreaterp), 'lose);
  185. Comment There are also a number of system constants required for each
  186. implementation. In systems that don't support inums, the equivalent
  187. single precision integers should be used;
  188. % LARGEST!-SMALL!-MODULUS is the largest power of two that can
  189. % fit in the fast arithmetic (inum) range of the implementation.
  190. % This is constant for the life of the system and could be
  191. % compiled in-line if the compiler permits it.
  192. largest!-small!-modulus := 2**23;
  193. % If the (small) modular arithmetic is always limited to LARGEST-SMALL-
  194. % MODULUS, it all fits in the inum range of the machine, with the
  195. % exception of modular-times, that needs to use generic arithmetic for
  196. % the multiplication. However, on some machines (e.g., the VAX), it is
  197. % possible to 'borrow' the extra precision needed, so that the following
  198. % definition works. This will not work of course for non-inums.
  199. % remflag('(modular!-times),'lose);
  200. % smacro procedure modular!-times(u,v);
  201. % iremainder(itimes2(u,v),current!-modulus);
  202. % flag('(modular!-times),'lose);
  203. % The following two definitions are commented out as they lead to
  204. % unchecked vector ranges;
  205. % symbolic smacro procedure getv(a,b); igetv(a,b);
  206. % symbolic smacro procedure putv(a,b,c); iputv(a,b,c);
  207. % flag('(intersection),'lose);
  208. Comment PSL Specific patches;
  209. Comment We need to define a function BEGIN, which acts as the top-level
  210. call to REDUCE, and sets the appropriate variables;
  211. % global '(startuproutine!* toploopread!* toploopeval!* toploopprint!*
  212. % toploopname!*);
  213. remflag('(begin),'go);
  214. symbolic procedure begin;
  215. begin
  216. !*echo := not !*int;
  217. !*extraecho := t;
  218. ifl!* := ipl!* := ofl!* := nil;
  219. if null date!* then go to a;
  220. if !*loadversion then errorset!*('(load entry),nil);
  221. !*gc := nil;
  222. !*usermode := nil;
  223. linelength 80;
  224. prin2 version!*;
  225. prin2 ", ";
  226. prin2 date!*;
  227. prin2t " ...";
  228. !*mode := if getd 'addsq then 'algebraic else 'symbolic;
  229. if !*mode eq 'algebraic then !*break := nil;
  230. %since most REDUCE users won't use LISP
  231. date!* := nil;
  232. a: % crchar!* := '! ;
  233. if errorp errorset!*('(begin1),nil) then go to a;
  234. %until PSL fixed
  235. prin2t "Entering LISP ... "
  236. end;
  237. flag('(begin),'go);
  238. Comment Initial setups for REDUCE;
  239. spare!* := 11; % We need this for bootstrapping.
  240. version!* := "REDUCE 3.4";
  241. symbolic procedure initreduce; initrlisp(); % For compatibility.
  242. symbolic procedure initrlisp;
  243. % Initial declarations for REDUCE
  244. <<statcounter := 0;
  245. spare!* := 11;
  246. !*int := t;
  247. !*eolinstringok := t; % we don't want the "string continued" msg.
  248. remd 'main;
  249. copyd('main,'rlispmain);
  250. date!* := date()>>;
  251. symbolic procedure rlispmain;
  252. begin scalar l;
  253. rlispscantable!* := mkvect 128;
  254. l := '(17 11 11 11 11 11 11 11 11 17 17 11 17 17 11 11 11 11 11 11
  255. 11 11 11 11 11 11 11 11 11 11 11 11 17 14 15 11 11 12 11 11
  256. 11 11 13 11 11 11 20 11 00 01 02 03 04 05 06 07 08 09 13 11
  257. 13 11 13 11 11 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
  258. 10 10 10 10 10 10 10 10 10 10 10 11 16 11 11 10 11 10 10 10
  259. 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10 10
  260. 10 10 10 11 11 11 11 11 rlispdipthong);
  261. for i:=0:128 do <<putv(rlispscantable!*,i,car l); l := cdr l>>;
  262. currentreadmacroindicator!* := 'rlispreadmacro;
  263. currentscantable!* := rlispscantable!*;
  264. errout!* := 1; % Errors to standard output, not special stream;
  265. lispeval '(begin);
  266. currentscantable!* := lispscantable!*; % But Slisp should use same
  267. % syntax as RLISP?
  268. standardlisp()
  269. end;
  270. flag('(dskin savesystem reclaim),'opfn);
  271. flag('(dskin savesystem),'noval);
  272. flag('(load reload),'noform);
  273. deflist('((load rlis) (reload rlis)),'stat);
  274. flag('(tr trst untr untrst),'noform);
  275. deflist('((tr rlis) (trst rlis) (untr rlis) (untrst rlis)),'stat);
  276. % Allow for direct calls to some UNIX and PSL functions.
  277. flag('(pwd cd setenv getenv set!-heap!-size set!-bndstk!-size
  278. set_heap_size set_bndstk_size),'opfn);
  279. if getd 'set!-heap!-size then copyd('set_heap_size,'set!-heap!-size);
  280. if getd 'set!-bndstk!-size
  281. then copyd('set_bndstk_size,'set!-bndstk!-size);
  282. % The following is PSL 3.4 specific.
  283. switch fulltrace; % Prevents node renaming in trace output.
  284. !*fulltrace := t; % Since we usually want it this way.
  285. Comment The global variable ESC* is used by the interactive string
  286. editor (defined in CEDIT) as a terminator for input strings. In PSL
  287. we use the escape character;
  288. esc!* := '!;
  289. % The following are compiler switches.
  290. fluid '(!*pgwd !*plap !*pwrds);
  291. flag('(pgwd plap pwrds),'switch);
  292. Comment The following declarations are needed to build various modules;
  293. flag('(fl2int),'lose); % Used in MATH.
  294. % flag('(nth pnth spaces subla),'lose); % Used in ALG1.
  295. flag('(explode2 explode21),'lose); % Used in RPRINT.
  296. flag('(flag1 remflag1),'lose); % Used in RCREF.
  297. flag('(vector2list),'lose); % Used in HILBERTS.
  298. deflist('((imports rlis)),'stat); % Needed for ~imports to work.
  299. Comment The following are only needed for PSL 3.2;
  300. % symbolic fexpr procedure definebop u; u;
  301. % symbolic fexpr procedure definerop u; u;
  302. endmodule;
  303. end;