dosrend.red 13 KB

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