compat.lsp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. % This file defines functions and variables needed to make REDUCE
  2. % and the underlying CSL system compatible. it should
  3. % be loaded as the first file whenever REDUCE services are required.
  4. %
  5. % This code may be used and modified, and redistributed in binary
  6. % or source form, subject to the "CCL Public License", which should
  7. % accompany it. This license is a variant on the BSD license, and thus
  8. % permits use of code derived from this in either open and commercial
  9. % projects: but it does require that updates to this code be made
  10. % available back to the originators of the package.
  11. % Before merging other code in with this or linking this code
  12. % with other packages or libraries please check that the license terms
  13. % of the other material are compatible with those of this.
  14. %
  15. (setpchar "> ")
  16. (remflag '(geq leq neq logand logor logxor leftshift princ printc
  17. evenp reversip seprp atsoc eqcar flagp!*!* flagpcar get!*
  18. prin1 prin2 apply0 apply1 apply2 apply3 smemq spaces
  19. subla gcdn printprompt pair) 'lose)
  20. (symbol!-make!-fastget 32)
  21. (symbol!-make!-fastget 'noncom 0) % built into the kernel
  22. (symbol!-make!-fastget 'lose 1)
  23. (flag '(raise lower echo comp plap pgwd pwrds savedef) 'switch)
  24. (make!-special '!*echo)
  25. (setq !*echo nil)
  26. (make!-special '!*raise)
  27. (setq !*raise nil)
  28. (make!-special '!*lower)
  29. (setq !*lower t)
  30. (make!-special '!*savedef)
  31. % I only nil out !*savedef if it is not already present because of
  32. % some bootstrapping delicacies when this file is re-loaded.
  33. (if (not (boundp '!*savedef)) (setq !*savedef nil))
  34. (make!-special '!*comp)
  35. (setq !*comp nil)
  36. (make!-special '!*plap)
  37. (setq !*plap nil)
  38. (make!-special '!*pgwd)
  39. (setq !*pgwd nil)
  40. (make!-special '!*pwrds)
  41. (setq !*pwrds t)
  42. % Until the following lines have been executed the
  43. % bitwise operations listed here will not work.
  44. (progn
  45. (symbol!-set!-env 'logand 1)
  46. (symbol!-set!-env 'logxor 6)
  47. (symbol!-set!-env 'logor 7)
  48. (symbol!-set!-env 'logeqv 9))
  49. (make!-special '!!fleps1)
  50. (setq !!fleps1 1.0e-12)
  51. (symbol!-set!-env 'safe!-fp!-plus '!!fleps1)
  52. (de rplacw (a b) (progn (rplaca a (car b)) (rplacd a (cdr b))))
  53. (de expand (l fn)
  54. (cond
  55. ((null (cdr l)) (car l))
  56. (t (list fn (car l) (expand (cdr l) fn)))))
  57. (dm plus (a)
  58. (cond ((null (cdr a)) 0)
  59. (t (expand (cdr a) 'plus2))))
  60. (dm times (a)
  61. (cond ((null (cdr a)) 1)
  62. (t (expand (cdr a) 'times2))))
  63. (de mapcar (l fn)
  64. (prog (r)
  65. top (cond ((null l) (return (reversip r))))
  66. (setq r (cons (funcall fn (car l)) r))
  67. (setq l (cdr l))
  68. (go top)))
  69. (de maplist (l fn)
  70. (prog (r)
  71. top (cond ((null l) (return (reversip r))))
  72. (setq r (cons (funcall fn l) r))
  73. (setq l (cdr l))
  74. (go top)))
  75. (de mapcan (l fn)
  76. (cond ((null l) nil)
  77. (t (nconc (funcall fn (car l)) (mapcan (cdr l) fn)))))
  78. (de mapcon (l fn)
  79. (cond ((null l) nil)
  80. (t (nconc (funcall fn l) (mapcon (cdr l) fn)))))
  81. (de mapc (l fn)
  82. (prog ()
  83. top (cond ((null l) (return nil)))
  84. (funcall fn (car l))
  85. (setq l (cdr l))
  86. (go top)))
  87. (de map (l fn)
  88. (prog ()
  89. top (cond ((null l) (return nil)))
  90. (funcall fn l)
  91. (setq l (cdr l))
  92. (go top)))
  93. (de copy (a)
  94. (cond
  95. ((atom a) a)
  96. (t (cons (copy (car a)) (copy (cdr a))))))
  97. (de sassoc (a l fn)
  98. (cond
  99. ((atom l) (funcall fn))
  100. ((equal a (caar l)) (car l))
  101. (t (sassoc a (cdr l) fn))))
  102. (de rassoc (x l) % Not in Standard Lisp
  103. (prog ()
  104. loop (cond ((atom l) (return nil))
  105. ((equal x (cdar l)) (return (car l)))
  106. (t (setq l (cdr l)) (go loop))) ))
  107. (de lastcar (x) % Not in Standard Lisp
  108. (cond
  109. ((null x) nil)
  110. ((null (cdr x)) (car x))
  111. (t (lastcar (cdr x)))))
  112. % The system-coded primitive function ~OPEN opens a file, and takes a second
  113. % argument that shows what options are wanted. See "print.c" for an
  114. % explanation of the bits.
  115. (de open (a b)
  116. (cond
  117. ((eq b 'input) (!~open a (plus 1 64))) % if-does-not-exist error
  118. ((eq b 'output) (!~open a (plus 2 20 32))) % if-does-not-exist create,
  119. % if-exists new-version
  120. ((eq b 'append) (!~open a (plus 2 8 32))) % if-exists append
  121. (t (error "bad direction ~A in open" b))))
  122. (de binopen (a b)
  123. (cond
  124. ((eq b 'input) (!~open a (plus 1 64 128)))
  125. ((eq b 'output) (!~open a (plus 2 20 32 128)))
  126. ((eq b 'append) (!~open a (plus 2 8 32 128)))
  127. (t (error "bad direction ~A in binopen" b))))
  128. (de pipe!-open (c d)
  129. (cond
  130. ((eq d 'input) (!~open c (plus 1 256)))
  131. ((eq d 'output) (!~open c (plus 2 256)))
  132. (t (error "bad direction ~A in pipe-open" d))))
  133. (de putd (a type b)
  134. (progn
  135. (cond
  136. ((eqcar b 'funarg) (setq b (cons 'lambda (cddr b)))))
  137. (cond
  138. ((flagp a 'lose) (progn
  139. (terpri) (princ "+++ ") (prin a)
  140. (printc " not defined (LOSE flag)")
  141. nil))
  142. (t (progn
  143. (cond
  144. ((and !*redefmsg (getd a)) (progn
  145. (terpri) (princ "+++ ") (prin a) (printc " redefined"))))
  146. (cond
  147. ((eq type 'expr) (symbol!-set!-definition a b))
  148. ((eq type 'subr) (symbol!-set!-definition a b))
  149. ((and (eq type 'macro) (eqcar b 'lambda))
  150. (eval (list!* 'dm a (cdr b))))
  151. (t (error "Bad type ~S in putd" type)))
  152. a))))))
  153. (de putc (a b c)
  154. (put a b c))
  155. (de traceset1 (name)
  156. (prog (w !*comp)
  157. (setq w (getd name))
  158. (cond ((not (and (eqcar w 'expr) (eqcar (cdr w) 'lambda)))
  159. (princ "+++++ ") (prin name)
  160. (printc " should be interpreted for traceset to work")
  161. (return nil)))
  162. (putd name 'expr (subst 'noisy!-setq 'setq (cdr w)))
  163. (trace (list name))))
  164. (de untraceset1 (name)
  165. (prog (w !*comp)
  166. (setq w (getd name))
  167. (cond ((not (and (eqcar w 'expr) (eqcar (cdr w) 'lambda)))
  168. (princ "+++++ ") (prin name)
  169. (printc " should be interpreted for untraceset to work")
  170. (return nil)))
  171. (putd name 'expr (subst 'setq 'noisy!-setq (cdr w)))
  172. (untrace (list name))))
  173. (de traceset (l)
  174. (mapc l (function traceset1)))
  175. (de untraceset (l)
  176. (mapc l (function untraceset1)))
  177. (de deflist (a b)
  178. (prog (r)
  179. top (cond ((null a) (return (reversip r))))
  180. (put (caar a) b (cadar a))
  181. (setq r (cons (caar a) r))
  182. (setq a (cdr a))
  183. (go top)))
  184. (de global (l)
  185. (prog nil
  186. top (cond ((null l) (return nil)))
  187. (make!-global (car l))
  188. (cond ((not (boundp (car l))) (set (car l) nil)))
  189. (setq l (cdr l))
  190. (go top)))
  191. (de fluid (l)
  192. (prog nil
  193. top (cond ((null l) (return nil)))
  194. (make!-special (car l))
  195. (cond ((not (boundp (car l))) (set (car l) nil)))
  196. (setq l (cdr l))
  197. (go top)))
  198. (de unglobal (l)
  199. (prog ()
  200. top (cond ((null l) (return nil)))
  201. (unmake!-global (car l))
  202. (setq l (cdr l))
  203. (go top)))
  204. (de unfluid (l)
  205. (prog ()
  206. top (cond ((null l) (return nil)))
  207. (unmake!-special (car l))
  208. (setq l (cdr l))
  209. (go top)))
  210. (global '(ofl!*))
  211. (de printprompt (u) nil)
  212. (global '(program!* ttype!* eof!*))
  213. (global '(crbuf!*))
  214. (global '(blank !$eol!$ tab !$eof!$ esc!*))
  215. (fluid '(!*notailcall !*carcheckflag))
  216. (fluid '(!*terminal!-io!* !*standard!-input!* !*standard!-output!*
  217. !*error!-output!* !*trace!-output!* !*debug!-io!* !*query!-io!*))
  218. (setq !*notailcall nil)
  219. (setq !*carcheckflag t)
  220. (de carcheck (n)
  221. (prog (old)
  222. (cond ((zerop n) (setq n nil)))
  223. (setq old !*carcheckflag)
  224. (setq !*carcheckflag n)
  225. (return old)))
  226. (progn
  227. (setq blank (compress (list '!! (special!-char 0))))
  228. (setq !$eol!$ (compress (list '!! (special!-char 1))))
  229. (setq tab (compress (list '!! (special!-char 3))))
  230. (setq esc!* (compress (list '!! (special!-char 9))))
  231. (setq !$eof!$ (special!-char 8))
  232. nil)
  233. (setq crbuf!* (list !$eol!$)) % may not be necessary
  234. (de symerr (u v)
  235. (progn (terpri)
  236. (print (list 'symerr u v))
  237. (error 'failure)))
  238. (de s!:oblist (v r)
  239. (prog (n a)
  240. (setq n (upbv v))
  241. top (cond ((minusp n) (return r)))
  242. (setq a (getv v n))
  243. (cond
  244. ((and (idp a)
  245. % I list things that have a function value of some sort or that have
  246. % a non-empty property-list. Symbols that have been mentioned but which do
  247. % not have properties or values are missed out since they are dull and
  248. % seeing them listed is probably not very helpful. People may disagree
  249. % about that... if so it would be very easy to remove the tests here and
  250. %end up listing everything
  251. (or (symbol!-function a)
  252. (macro!-function a)
  253. (special!-form!-p a)
  254. (fluidp a)
  255. (globalp a)
  256. (not (null (plist a)))))
  257. (setq r (cons a r))))
  258. (setq n (sub1 n))
  259. (go top)))
  260. (de s!:oblist1 (v r)
  261. (cond
  262. ((null v) r)
  263. ((vectorp v) (s!:oblist v r))
  264. % This allows for segmented object-vectors
  265. (t (s!:oblist (car v) (s!:oblist1 (cdr v) r)))))
  266. (de oblist ()
  267. (sort (s!:oblist1 (getv !*package!* 1) nil)
  268. (function orderp)))
  269. % Now a few things not needed by Standard Lisp but maybe helpful
  270. % when using Lisp directly.
  271. (de s!:make!-psetq!-vars (u)
  272. (if (null u)
  273. nil
  274. (if (null (cdr u))
  275. (error "odd number of items in psetq")
  276. (cons (gensym) (s!:make!-psetq!-vars (cddr u))))))
  277. (de s!:make!-psetq!-bindings (vars u)
  278. (if (null u)
  279. nil
  280. (cons
  281. (list (car vars) (cadr u))
  282. (s!:make!-psetq!-bindings (cdr vars) (cddr u)))))
  283. (de s!:make!-psetq!-assignments (vars u)
  284. (if (null u)
  285. nil
  286. (cons
  287. (list 'setq (car u) (car vars))
  288. (s!:make!-psetq!-assignments (cdr vars) (cddr u)))))
  289. (dm psetq (x)
  290. (!~let ((vars (s!:make!-psetq!-vars (cdr x))))
  291. `(let!* ,(s!:make!-psetq!-bindings vars (cdr x))
  292. ,@(s!:make!-psetq!-assignments vars (cdr x)))))
  293. % (do ((v i s) ..)
  294. % (end result ...)
  295. % body)
  296. (de s!:do!-bindings (u)
  297. (if (null u)
  298. nil
  299. (if (atom (car u))
  300. (cons (car u) (s!:do!-bindings (cdr u)))
  301. (if (null (cdar u))
  302. (cons (list (caar u) nil) (s!:do!-bindings (cdr u)))
  303. (cons (list (caar u) (cadar u)) (s!:do!-bindings (cdr u)))))))
  304. (de s!:do!-endtest (u)
  305. (if (null u)
  306. nil
  307. (car u)))
  308. (de s!:do!-result (u)
  309. (if (null u)
  310. nil
  311. (cdr u)))
  312. (de s!:do!-updates (u)
  313. (if (null u)
  314. nil
  315. (!~let ((v (car u))
  316. (x (s!:do!-updates (cdr u))))
  317. (if (or (atom v)
  318. (null (cdr v))
  319. (null (cddr v)))
  320. x
  321. (cons (car v) (cons (caddr v) x))))))
  322. (de s!:expand!-do (u letter setter)
  323. (let!* ((bindings (s!:do!-bindings (car u)))
  324. (result (s!:do!-result (cadr u)))
  325. (updates (s!:do!-updates (car u)))
  326. (body (cddr u))
  327. (endtest (s!:do!-endtest (cadr u)))
  328. (upd (if updates (list (cons setter updates)) nil))
  329. (res (if (null result)
  330. nil
  331. (if (null (cdr result))
  332. (car result)
  333. (cons 'progn result))))
  334. (x (if (null endtest) nil
  335. `((if ,endtest (return ,res)))))
  336. (g (gensym)))
  337. (if bindings
  338. `(,letter ,bindings
  339. (prog nil
  340. ,g ,@x
  341. ,@body
  342. ,@upd
  343. (go ,g)))
  344. `(prog nil
  345. ,g ,@x
  346. ,@body
  347. ,@upd
  348. (go ,g)))))
  349. (dm do (u) (s!:expand!-do (cdr u) '!~let 'psetq))
  350. (dm do!* (u) (s!:expand!-do (cdr u) 'let!* 'setq))
  351. (de s!:expand!-dolist (vir b)
  352. (prog (l v var init res)
  353. (setq var (car vir))
  354. (setq init (car (setq vir (cdr vir))))
  355. (setq res (cdr vir))
  356. (setq v (gensym))
  357. (setq l (gensym))
  358. (return `(prog (,v ,var)
  359. (setq ,v ,init)
  360. ,l (cond ((null ,v) (return (progn ,@res))))
  361. (setq ,var (car ,v))
  362. ,@b
  363. (setq ,v (cdr ,v))
  364. (go ,l)))))
  365. (dm dolist (u) (s!:expand!-dolist (cadr u) (cddr u)))
  366. (de s!:expand!-dotimes (vnr b)
  367. (prog (l v var count res)
  368. (setq var (car vnr))
  369. (setq count (car (setq vnr (cdr vnr))))
  370. (setq res (cdr vnr))
  371. (setq v (gensym))
  372. (setq l (gensym))
  373. (return `(prog (,v ,var)
  374. (setq ,v ,count)
  375. (setq ,var 0)
  376. ,l (cond ((not (lessp ,var ,v)) (return (progn ,@res))))
  377. ,@b
  378. (setq ,var (add1 ,var))
  379. (go ,l)))))
  380. (dm dotimes (u) (s!:expand!-dotimes (cadr u) (cddr u)))
  381. (flag '(geq leq neq logand logor logxor leftshift princ printc
  382. evenp reversip seprp atsoc eqcar flagp!*!* flagpcar get!*
  383. prin1 prin2 apply0 apply1 apply2 apply3 smemq spaces
  384. subla gcdn printprompt pair) 'lose)
  385. % end of compat.lsp