1;; Copyright (c) 1991-2002, The Numerical ALgorithms Group Ltd.
2;; All rights reserved.
3;;
4;; Redistribution and use in source and binary forms, with or without
5;; modification, are permitted provided that the following conditions are
6;; met:
7;;
8;;     - Redistributions of source code must retain the above copyright
9;;       notice, this list of conditions and the following disclaimer.
10;;
11;;     - Redistributions in binary form must reproduce the above copyright
12;;       notice, this list of conditions and the following disclaimer in
13;;       the documentation and/or other materials provided with the
14;;       distribution.
15;;
16;;     - Neither the name of The Numerical ALgorithms Group Ltd. nor the
17;;       names of its contributors may be used to endorse or promote products
18;;       derived from this software without specific prior written permission.
19;;
20;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
21;; IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22;; TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23;; PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24;; OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25;; EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26;; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27;; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28;; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32
33;      VM LISP EMULATION PACKAGE
34;      Lars Ericson, Barry Trager, Martial Schor, tim daly, LVMCL, et al
35;      IBM Thomas J. Watson Research Center
36;      Summer, 1986
37
38; This emulation package version is written for Symbolics Common Lisp.
39; Emulation commentary refers to LISP/VM, IBM Program Number 5798-DQZ,
40; as described in the LISP/VM User's Guide, document SH20-6477-1.
41; Main comment section headings refer to sections in the User's Guide.
42
43; If you are using this, you are probably in Common Lisp, yes?
44
45(in-package "BOOT")
46
47;; defuns
48
49(defun define-function (f v)
50 (setf (symbol-function f) v))
51
52(define-function '|append| #'APPEND)
53(define-function 'LASTTAIL #'last)
54
55;;; Used in constructors for evaluating conditions
56(define-function '|not| #'NOT)
57
58(define-function '|get_run_time| #'get-internal-run-time)
59
60; 9.4 Vectors and Bpis
61
62(defun FBPIP (item) (or (compiled-function-p item)
63                        (and (symbolp item) (fboundp item)
64                             (not (macro-function item))
65                             (compiled-function-p (symbol-function item)))))
66
67; 9.5 Identifiers
68
69(defun gensymp (x) (and (symbolp x) (null (symbol-package x))))
70
71(defun digitp (x)
72  (or (and (symbolp x) (digitp (symbol-name x)))
73      (and (characterp x) (digit-char-p x))
74      (and (stringp x) (= (length x) 1) (digit-char-p (char x 0)))))
75
76(defun dig2fix (x)
77  (if (symbolp x)
78    (digit-char-p (char (symbol-name x) 0))
79    (digit-char-p x)))
80
81(defun LOG2 (x) (LOG x 2.0))
82
83; 11.0 Operations on Identifiers
84
85; 11.1 Creation
86
87(defun upcase (l)
88  (cond ((stringp l) (string-upcase l))
89        ((identp l) (intern (string-upcase (symbol-name l))))
90        ((characterp l) (char-upcase l))
91        ((atom l) l)
92        (t (mapcar #'upcase l))))
93
94(defun downcase (l)
95  (cond ((stringp l) (string-downcase l))
96        ((identp l) (intern (string-downcase (symbol-name l))))
97        ((characterp l) (char-downcase L))
98        ((atom l) l)
99        (t (mapcar #'downcase l))))
100
101; 11.2 Accessing
102
103;; note it is important that PNAME returns nil not an error for non-symbols
104(defun PNAME (x)
105  (cond ((symbolp x) (symbol-name x))
106        ((characterp x) (string x))
107        (t nil)))
108
109(defun put (sym ind val) (setf (get sym ind) val))
110
111(define-function 'MAKEPROP #'put)
112
113; 12.0 Operations on Numbers
114
115; 12.1 Conversion
116
117; 12.2 Predicates
118
119; 12.3 Computation
120
121
122(defun QUOTIENT (x y)
123  (cond ((or (floatp x) (floatp y)) (BREAK))
124        (t (truncate x y))))
125
126(defun REMAINDER (x y)
127  (if (and (integerp x) (integerp y))
128      (rem x y)
129      (BREAK)))
130
131(defun DIVIDE (x y)
132  (if (and (integerp x) (integerp y))
133      (multiple-value-list (truncate x y))
134      (BREAK)))
135
136; 13.3 Updating
137
138
139(defun RPLPAIR (pair1 pair2)
140  (RPLACA pair1 (CAR pair2))
141  (RPLACD pair1 (CDR pair2)) pair1)
142
143(defun RPLNODE (pair1 ca2 cd2)
144 (RPLACA pair1 ca2)
145 (RPLACD pair1 cd2) pair1)
146
147; 14.0 Operations on Lists
148
149; 14.1 Creation
150
151;;; needed for SPAD compiler output
152(define-function '|construct| #'list)
153
154(defun VEC2LIST (vec) (coerce vec 'list))
155
156(defun |makeList| (size el) (make-list size :initial-element el) )
157
158; note default test for union, intersection and set-difference is eql
159(defun UNIONQ (l1 l2) (union l1 l2 :test #'eq))
160(defun INTERSECTIONQ (l1 l2) (intersection l1 l2 :test #'eq))
161(defun |member| (item sequence)
162   (cond ((symbolp item) (member item sequence :test #'eq))
163         ((stringp item) (member item sequence :test #'equal))
164         ((and (atom item) (not (arrayp item))) (member item sequence))
165         (T (member item sequence :test #'equalp))))
166
167(defun |remove| (list item &optional (count 1))
168  (if (integerp count)
169      (remove item list :count count :test #'equalp)
170      (remove item list :test #'equalp)))
171
172;;; moved from union.lisp
173
174(defmacro RESETQ(a b)
175 `(prog1 ,a (setq ,a ,b)))
176
177(DEFUN |intersection|  (LIST-OF-ITEMS-1 LIST-OF-ITEMS-2)
178    (PROG (I H V)
179      (SETQ V (SETQ H (CONS NIL NIL)))
180      (COND
181        ( (NOT (LISTP LIST-OF-ITEMS-1))
182          (SETQ LIST-OF-ITEMS-1 (LIST LIST-OF-ITEMS-1)) ) )
183      (COND
184        ( (NOT (LISTP LIST-OF-ITEMS-2))
185          (SETQ LIST-OF-ITEMS-2 (LIST LIST-OF-ITEMS-2)) ) )
186  LP  (COND
187        ( (NOT (PAIRP LIST-OF-ITEMS-1))
188          (RETURN (QCDR H)) )
189        ( (|member|
190            (SETQ I (QCAR (RESETQ LIST-OF-ITEMS-1 (QCDR LIST-OF-ITEMS-1))))
191            (QCDR H)) )
192        ( (|member| I LIST-OF-ITEMS-2)
193          (QRPLACD V (SETQ V (CONS I NIL))) ) )
194      (GO LP) ) )
195
196(DEFUN |union| (LIST-OF-ITEMS-1 LIST-OF-ITEMS-2)
197    (PROG (I H V)
198      (SETQ H (SETQ V (CONS NIL NIL)))
199      (COND
200        ( (NOT (LISTP LIST-OF-ITEMS-1))
201          (SETQ LIST-OF-ITEMS-1 (LIST LIST-OF-ITEMS-1)) ) )
202      (COND
203        ( (NOT (LISTP LIST-OF-ITEMS-2))
204          (SETQ LIST-OF-ITEMS-2 (LIST LIST-OF-ITEMS-2)) ) )
205  LP1 (COND
206        ( (NOT (PAIRP LIST-OF-ITEMS-1))
207          (COND
208            ( (PAIRP LIST-OF-ITEMS-2)
209              (SETF LIST-OF-ITEMS-1 LIST-OF-ITEMS-2)
210              (SETF LIST-OF-ITEMS-2 NIL) )
211            ( 'T
212              (RETURN (QCDR H)) ) ) )
213        ( (NOT
214            (|member|
215              (SETQ I (QCAR (RESETQ LIST-OF-ITEMS-1 (QCDR LIST-OF-ITEMS-1))))
216              (QCDR H)))
217          (QRPLACD V (SETQ V (CONS I NIL))) ) )
218      (GO LP1) ) )
219
220(DEFUN SETDIFFERENCE (LIST-OF-ITEMS-1 LIST-OF-ITEMS-2)
221    (PROG (I H V)
222      (SETQ H (SETQ V (CONS NIL NIL)))
223      (COND
224        ( (NOT (LISTP LIST-OF-ITEMS-1))
225          (SETQ LIST-OF-ITEMS-1 (LIST LIST-OF-ITEMS-1)) ) )
226      (COND
227        ( (NOT (LISTP LIST-OF-ITEMS-2))
228          (SETQ LIST-OF-ITEMS-2 (LIST LIST-OF-ITEMS-2)) ) )
229  LP1 (COND
230        ( (NOT (PAIRP LIST-OF-ITEMS-1))
231          (RETURN (QCDR H)) )
232        ( (|member|
233            (SETQ I (QCAR (RESETQ LIST-OF-ITEMS-1 (QCDR LIST-OF-ITEMS-1))))
234            (QCDR H)) )
235        ( (NOT (|member| I LIST-OF-ITEMS-2))
236          (QRPLACD V (SETQ V (CONS I NIL))) ) )
237      (GO LP1) ) )
238
239;;; end of moved fragment
240
241; 14.2 Accessing
242
243(defun |last| (x) (car (LASTNODE x)))
244
245; 14.3 Searching
246
247(DEFUN |assoc| (X Y)
248  "Return the pair associated with key X in association list Y."
249  ; ignores non-nil list terminators
250  ; ignores non-pair a-list entries
251  (cond ((symbolp X)
252         (PROG ()
253               A  (COND ((ATOM Y) (RETURN NIL))
254                        ((NOT (consp (CAR Y))) )
255                        ((EQ (CAAR Y) X) (RETURN (CAR Y))) )
256               (SETQ Y (CDR Y))
257               (GO A)))
258        ((or (numberp x) (characterp x))
259         (PROG ()
260               A  (COND ((ATOM Y) (RETURN NIL))
261                        ((NOT (consp (CAR Y))) )
262                        ((EQL (CAAR Y) X) (RETURN (CAR Y))) )
263               (SETQ Y (CDR Y))
264               (GO A)))
265        (t
266         (PROG ()
267               A  (COND ((ATOM Y) (RETURN NIL))
268                        ((NOT (consp (CAR Y))) )
269                        ((EQUAL (CAAR Y) X) (RETURN (CAR Y))) )
270               (SETQ Y (CDR Y))
271               (GO A)))))
272; 14.5 Updating
273
274(defun NREMOVE (list item &optional (count 1))
275  (if (integerp count)
276      (delete item list :count count :test #'equal)
277      (delete item list :test #'equal)))
278
279(defun EFFACE (item list) (delete item list :count 1 :test #'equal))
280
281(defun NCONC2 (x y) (NCONC x y)) ;NCONC with exactly two arguments
282
283; 14.6 Miscellaneous
284
285(defun SORTBY (keyfn l)
286 (declare (special sortgreaterp))
287  (nreverse (sort (copy-seq l) SORTGREATERP :key keyfn)))
288
289; 16.0 Operations on Vectors
290
291; 16.1 Creation
292
293(defun MAKE_VEC (n) (make-array n :initial-element nil))
294
295(defun GETREFV (n) (make-array n :initial-element nil))
296
297(defun |makeVector| (els type)
298 (make-array (length els) :element-type (or type t) :initial-contents els))
299
300(defun GETZEROVEC (n) (MAKE-ARRAY n :initial-element 0))
301
302#-:GCL
303(defun LIST2VEC (list) (coerce list 'vector))
304
305;;; At least in gcl 2.6.8 coerce is slow, so we roll our own version
306#+:GCL
307(defun LIST2VEC (list)
308    (if (consp list)
309        (let* ((len (length list))
310               (vec (make-array len)))
311             (dotimes (i len)
312                  (setf (aref vec i) (pop list)))
313             vec)
314        (coerce list 'vector)))
315
316
317(define-function 'LIST2REFVEC #'LIST2VEC)
318
319; 16.2 Accessing
320
321
322(defun size (l)
323  (cond ((vectorp l) (length l))
324        ((consp l)   (list-length l))
325        (t           0)))
326
327(define-function 'MOVEVEC #'replace)
328
329; 17.0 Operations on Character and Bit Vectors
330
331(defun charp (a) (or (characterp a)
332                     (and (identp a) (= (length (symbol-name a)) 1))))
333
334(defun NUM2CHAR (n) (code-char n))
335
336(defun CHAR2NUM (c) (char-code (character c)))
337
338(define-function '|isLowerCaseLetter| #'LOWER-CASE-P)
339
340#+(or :UNICODE :SB-UNICODE :OPENMCL-UNICODE-STRINGS)
341(defun NUM2USTR (n)
342    (make-string 1 :initial-element (NUM2CHAR n)))
343#-(or :UNICODE :SB-UNICODE :OPENMCL-UNICODE-STRINGS)
344(defun NUM2USTR (n)
345   (let (k n1 n2 n3 n4 (l nil))
346       (cond
347           ((< n 128)
348               (setf k 1)
349               (setf l (list n)))
350           ((< n (ash 1 11))
351               (setf k 2)
352               (setf n1 (logior 128 (logand 63 n)))
353               (setf n2 (logior 192 (logand 31 (ash n -6))))
354               (setf l (list n2 n1)))
355           ((< n (ash 1 16))
356               (setf k 3)
357               (setf n1 (logior 128 (logand 63 n)))
358               (setf n2 (logior 128 (logand 63 (ash n -6))))
359               (setf n3 (logior 224 (logand 15 (ash n -12))))
360               (setf l (list n3 n2 n1)))
361           ((< n (ash 1 21))
362               (setf k 4)
363               (setf n1 (logior 128 (logand 63 n)))
364               (setf n2 (logior 128 (logand 63 (ash n -6))))
365               (setf n3 (logior 128 (logand 63 (ash n -12))))
366               (setf n4 (logior 240 (logand 7 (ash n -18))))
367               (setf l (list n4 n3 n2 n1)))
368           (t
369               (|error| "Too large character code"))
370       )
371       (make-array k :element-type 'character
372                  :initial-contents (mapcar #'code-char l))))
373
374
375(defun UENTRIES(s)
376   (let* ((res (cons nil nil))
377         (res1 res)
378         (c 0)
379         (i 0)
380         (l (length s)))
381        (loop
382        (cond ((eql i l) (return-from UENTRIES (cdr res))))
383#+(or :UNICODE :SB-UNICODE :OPENMCL-UNICODE-STRINGS)
384        (progn
385            (setf c (char-code (aref s i)))
386            (setf i (+ i 1)))
387#-(or :UNICODE :SB-UNICODE :OPENMCL-UNICODE-STRINGS)
388        (let ((c1 (char-code (aref s i))))
389            (cond ((< c1 128)
390                   (setf c c1)
391                   (setf i (+ i 1)))
392                  ((< c1 224)
393                      (cond ((> (+ i 2) l)
394                             (|error| "Invalid UTF-8 string"))
395                            (t
396                              (setf c (logior
397                                          (logand 63
398                                                 (char-code (aref s (+ i 1))))
399                                          (ash (logand 31 c1) 6)))
400                              (setf i (+ i 2)))))
401                  ((< c1 240)
402                      (cond ((> (+ i 3) l)
403                             (|error| "Invalid UTF-8 string"))
404                            (t
405                              (setf c (logior
406                                          (logand 63
407                                                 (char-code (aref s (+ i 2))))
408                                          (ash (logand 63
409                                                 (char-code (aref s (+ i 1))))
410                                               6)
411                                          (ash (logand 15 c1) 12)))
412                              (setf i (+ i 3)))))
413                  ((< c1 248)
414                      (cond ((> (+ i 4) l)
415                             (|error| "Invalid UTF-8 string"))
416                            (t
417                              (setf c (logior
418                                          (logand 63
419                                                 (char-code (aref s (+ i 3))))
420                                          (ash (logand 63
421                                                 (char-code (aref s (+ i 2))))
422                                               6)
423                                          (ash (logand 63
424                                                 (char-code (aref s (+ i 1))))
425                                               12)
426                                          (ash (logand 7 c1) 18)))
427                              (cond ((>= c 1114112)
428                                     (|error| "Invalid UTF-8 string")))
429                              (setf i (+ i 4)))))
430                  (t (|error| "Invalid UTF-8 string"))))
431        (setf (cdr res1) (cons c nil))
432        (setf res1 (cdr res1)))))
433
434;;; Double negation to have boolean result
435(defun CGREATERP (s1 s2) (not (not (string> (string s1) (string s2)))))
436
437; 17.1 Creation
438
439
440#-AKCL
441(defun concat (a b &rest l)
442   (let ((type (cond ((bit-vector-p a) 'bit-vector) (t 'string))))
443      (cond ((eq type 'string)
444             (setq a (string a) b (string b))
445             (if l (setq l (mapcar #'string l)))))
446      (if l (apply #'concatenate type a b l)
447        (concatenate type a b))) )
448#+AKCL
449(defun concat (a b &rest l)
450  (if (bit-vector-p a)
451      (if l (apply #'concatenate 'bit-vector a b l)
452        (concatenate 'bit-vector a b))
453    (if l (apply #'system:string-concatenate a b l)
454      (system:string-concatenate a b))))
455
456(define-function 'strconc #'concat)
457
458(defun |make_full_CVEC|(sint &optional (char #\space))
459  (make-string sint :initial-element (if (integerp char)
460                                       (code-char char)
461                                       (character char))))
462
463; 17.2 Accessing
464
465(defun STRING2ID_N (cvec sint)
466  (if (< sint 1)
467      nil
468      (let ((start (position-if-not #'(lambda (x) (char= x #\Space)) cvec)))
469        (if start
470            (let ((end (or (position #\Space cvec :start start) (length cvec))))
471              (if (= sint 1)
472                  (intern (subseq cvec start end))
473                  (STRING2ID_N (subseq cvec end) (1- sint))))
474            0))))
475
476(defun substring (cvec start length)
477  (setq cvec (string cvec))
478  (if length (subseq cvec start (+ start length)) (subseq cvec start)))
479
480; 17.3 Searching
481
482(defun strpos (what in start dontcare)
483   (setq what (string what) in (string in))
484   (if dontcare (progn (setq dontcare (character dontcare))
485                       (search what in :start2 start
486                               :test #'(lambda (x y) (or (eql x dontcare)
487                                                         (eql x y)))))
488                (if (= start 0)
489                   (search what in)
490                   (search what in :start2 start))
491   ))
492
493; In the following, table should be a string:
494
495(defun strposl (table cvec sint item)
496  (setq cvec (string cvec))
497  (if (not item)
498      (position table cvec :test #'(lambda (x y) (position y x)) :start sint)
499      (position table cvec :test-not #'(lambda (x y) (position y x)) :start sint)))
500
501; 17.4 Updating operators
502
503;;-- (defun rplacstr (cvec1 start1 length1 cvec2
504;;--                        &optional (start2 0) (length2 nil)
505;;--                        &aux end1 end2)
506;;--   (setq cvec2 (string cvec2))
507;;--   (if (null start1) (setq start1 0))
508;;--   (if (null start2) (setq start2 0))
509;;--   (if (null length1) (setq length1 (- (length cvec1) start1)))
510;;--   (if (null length2) (setq length2 (- (length cvec2) start2)))
511;;--   (if (numberp length1) (setq end1 (+ start1 length1)))
512;;--   (if (numberp length2) (setq end2 (+ start2 length2)))
513;;--   (if (/= length1 length2)
514;;--       (concatenate 'string (subseq cvec1 0 start1)
515;;--                            (subseq cvec2 start2 end2)
516;;--                            (subseq cvec1 end1))
517;;--       (replace cvec1 cvec2 :start1 start1 :end1 end1
518;;--              :start2 start2 :end2 end2)))
519
520; The following version has been provided to avoid reliance on the
521; Common Lisp concatenate and replace functions. These built-in Lisp
522; functions would probably end up doing the character-by-character
523; copying shown here, but would also need to cope with generic sorts
524; of sequences and unwarranted keyword generality
525
526(defun rplacstr (cvec1 start1 length1 cvec2
527                       &optional start2 length2
528                       &aux end1 end2)
529  (setq cvec2 (string cvec2))
530  (if (null start1) (setq start1 0))
531  (if (null start2) (setq start2 0))
532  (if (null length1) (setq length1 (- (length cvec1) start1)))
533  (if (null length2) (setq length2 (- (length cvec2) start2)))
534  (setq end1 (+ start1 length1))
535  (setq end2 (+ start2 length2))
536  (if (= length1 length2)
537      (do ()
538          ((= start1 end1) cvec1)
539          (setf (aref cvec1 start1) (aref cvec2 start2))
540          (setq start1 (1+ start1))
541          (setq start2 (1+ start2)))
542      (let* ((l1 (length cvec1))
543             (r (make-string (- (+ l1 length2) length1)))
544             (i 0))
545         (do ((j 0 (1+ j)))
546             ((= j start1))
547             (setf (aref r i) (aref cvec1 j))
548             (setq i (1+ i)))
549         (do ((j start2 (1+ j)))
550             ((= j end2))
551             (setf (aref r i) (aref cvec2 j))
552             (setq i (1+ i)))
553         (do ((j end1 (1+ j)))
554             ((= j l1))
555             (setf (aref r i) (aref cvec1 j))
556             (setq i (1+ i)))
557         r)
558  ))
559
560; 19.0 Operations on Arbitrary Objects
561
562; 19.1 Creating
563
564(defun |substitute| (new old tree) (subst new old tree :test #'equal))
565
566(define-function 'MSUBSTQ #'subst) ;default test is eql
567
568(defun copy (x) (copy-tree x)) ; not right since should descend vectors
569
570(defun eqsubstlist (new old list) (sublis (mapcar #'cons old new) list))
571
572
573; 24.0 Printing
574
575;(define-function 'prin2cvec #'write-to-string)
576(define-function 'prin2cvec #'princ-to-string)
577;(define-function 'stringimage #'write-to-string)
578(define-function 'stringimage #'princ-to-string)
579
580(define-function 'printexp #'princ)
581(define-function 'prin0  #'prin1)
582
583(defun |limited_print1_stdout|(form) (|limited_print1| form *standard-output*))
584
585(defun |limited_print1|(form stream)
586    (let ((*print-level* 4) (*print-length* 4))
587       (prin1 form stream) (terpri stream)))
588
589(defun prettyprint (x &optional (stream *standard-output*))
590  (prettyprin0 x stream) (terpri stream))
591
592(defun prettyprin0 (x &optional (stream *standard-output*))
593  (let ((*print-pretty* t) (*print-array* t))
594    (prin1 x stream)))
595
596(defun tab (sint &optional (stream t))
597  (format stream "~vT" sint))
598
599; 27.0 Stream I/O
600
601
602; 27.1 Creation
603
604(defun |get_console_input| () *standard-input*)
605
606(defun MAKE_INSTREAM (filespec)
607   (cond
608         ((null filespec) (error "not handled yet"))
609         (t (open (|make_input_filename| filespec)
610                  :direction :input :if-does-not-exist nil))))
611
612(defun MAKE_OUTSTREAM (filespec)
613   (cond
614         ((null filespec) (error "not handled yet"))
615         (t (open (|make_filename| filespec) :direction :output
616               #+(or :cmucl :openmcl :sbcl) :if-exists
617               #+(or :cmucl :sbcl) :supersede
618               #+:openmcl :ignored))))
619
620(defun |make_out_stream| (filespec) (CONS T (MAKE_OUTSTREAM filespec)))
621
622(defun MAKE_APPENDSTREAM (filespec)
623 "fortran support"
624 (cond
625  ((null filespec) (error "MAKE_APPENDSTREAM: not handled yet"))
626  ('else (open (|make_filename| filespec) :direction :output
627          :if-exists :append :if-does-not-exist :create))))
628
629(defun |make_append_stream| (filespec)
630    (CONS T (MAKE_APPENDSTREAM filespec)))
631
632(defun |mkOutputConsoleStream| () (CONS NIL *standard-output*))
633
634(defun SHUT (st) (if (streamp st) (close st) -1))
635
636(defun EOFP (stream) (null (peek-char nil stream nil nil)))
637
638; 48.0 Miscellaneous CMS Interactions
639
640(defun CurrentTime ()
641  (multiple-value-bind (sec min hour day month year) (get-decoded-time)
642    (format nil "~2,'0D/~2,'0D/~2,'0D~2,'0D:~2,'0D:~2,'0D"
643            month day (rem year 100) hour min sec)))
644
645; 99.0 Ancient Stuff We Decided To Keep
646
647(defvar *read-place-holder* (make-symbol "%.EOF")
648   "default value returned by read and read-line at end-of-file")
649
650(defun PLACEP (item) (eq item *read-place-holder*))
651(defun get_read_placeholder() *read-place-holder*)
652(defun VMREAD (st) (read st nil *read-place-holder*))
653(defun |read_line| (st) (read-line st nil nil))
654
655#+(OR IBCL KCL)
656(defun gcmsg (x)
657   (prog1 system:*gbc-message* (setq system:*gbc-message* x)))
658#+:cmu
659(defun gcmsg (x)
660   (prog1 ext:*gc-verbose* (setq ext:*gc-verbose* x)))
661#+:allegro
662(defun gcmsg (x))
663#+:sbcl
664(defun gcmsg (x))
665#+:openmcl
666(defun gcmsg (x))
667#+:clisp
668(defun gcmsg (x))
669#+:ecl
670(defun gcmsg (x))
671#+:poplog
672(defun gcmsg (x))
673#+:lispworks
674(defun gcmsg (x))
675
676#+abcl
677(defun reclaim () (ext::gc))
678#+:allegro
679(defun reclaim () (excl::gc t))
680#+clisp
681(defun reclaim () (#+lisp=cl ext::gc #-lisp=cl lisp::gc))
682#+:cmu
683(defun reclaim () (ext:gc))
684#+cormanlisp
685(defun reclaim () (cl::gc))
686#+:GCL
687(defun reclaim () (si::gbc t))
688#+lispworks
689(defun reclaim () )
690#+sbcl
691(defun reclaim () (sb-ext::gc))
692#+openmcl
693(defun reclaim () (ccl::gc))
694#+:ecl
695(defun reclaim () (si::gc t))
696#+:poplog
697(defun reclaim () nil)
698
699
700#+(OR IBCL KCL)
701(defun BPINAME (func)
702  (if (functionp func)
703      (cond ((symbolp func) func)
704            ((and (consp func) (eq (car func) 'LAMBDA-BLOCK))
705              (cadr func))
706            ((compiled-function-p func)
707             (system:compiled-function-name func))
708            ('t func))))
709#+:cmu
710(defun BPINAME (func)
711 (when (functionp func)
712  (cond
713    ((symbolp func) func)
714    ((and (consp func) (eq (car func) 'lambda)) (second (third func)))
715    ((compiled-function-p func)
716     (kernel::%function-name func))
717    ('t func))))
718
719#+(or :sbcl :clisp :openmcl :ecl :lispworks :poplog)
720(defun BPINAME (func)
721  (cond
722      ((functionp func)
723         (let (d1 d2 res)
724             (setf (values d1 d2 res) (function-lambda-expression func))
725             (if (and res (symbolp res) (fboundp res))
726                 res
727                 func)))
728      ((symbolp func) func)))
729
730#+:cmu
731(defun OBEY (S)
732  (ext::process-exit-code
733   (ext::run-program "sh" (list "-c" S) :input t :output t)))
734
735#+:GCL
736(defun OBEY (S) (LISP::SYSTEM S))
737
738#+:allegro
739(defun OBEY (S) (excl::run-shell-command s))
740
741#+:sbcl
742(defun OBEY (S)
743   #-:win32 (sb-ext::process-exit-code
744             (sb-ext::run-program "/bin/sh"
745                    (list "-c" S) :input t :output t :error t))
746   #+:win32 (sb-ext::process-exit-code
747             (sb-ext::run-program "sh"
748                    (list "-c" S) :input t :output t :error t :search t)))
749
750#+:openmcl
751(defun OBEY (S)
752  (ccl::run-program "sh" (list "-c" S) :input t :output t :error t))
753
754#+(and :clisp (or :win32 :unix))
755(defun OBEY (S)
756   (ext:run-shell-command S))
757
758#+:ecl
759(defun OBEY (S)
760   (ext:system S))
761
762#+:poplog
763(defun OBEY (S)
764   (POP11:sysobey S))
765
766
767#+:lispworks
768(defun OBEY (S)
769   (system:call-system S))
770
771;;; moved from hash.lisp
772
773;17.0 Operations on Hashtables
774
775;17.1 Creation
776
777(defun MAKE_HASHTABLE (id1)
778   (let ((test (case id1
779                     ((EQ ID) #'eq)
780                     (CVEC #'equal)
781                     (EQL #'eql)
782                     #+Lucid ((UEQUAL EQUALP) #'EQUALP)
783                     #-Lucid ((UEQUAL EQUAL) #'equal)
784                     (otherwise (error "bad arg to MAKE_HASHTABLE")))))
785      (make-hash-table :test test)))
786
787;17.2 Accessing
788
789(defun HKEYS (table)
790   (let (keys)
791      (maphash
792        #'(lambda (key val) (declare (ignore val)) (push key keys)) table)
793        keys))
794
795(define-function 'HASHTABLE_CLASS #'hash-table-test)
796
797(define-function 'HCOUNT #'hash-table-count)
798
799;17.4 Searching and Updating
800
801(defun HREMPROP (table key property)
802  (let ((plist (gethash key table)))
803    (if plist (setf (gethash key table)
804                    (delete property plist :test #'equal :key #'car)))))
805
806;17.6 Miscellaneous
807
808(define-function 'HASHTABLEP #'hash-table-p)
809
810(define-function 'HASHEQ #'sxhash)
811
812;;; end of moved fragment
813
814;;; ---------------------------------------------
815
816;; Contributed by Juergen Weiss from a suggestion by Arthur Norman.
817;; This is a Mantissa and Exponent function.
818(defun manexp (u)
819  (multiple-value-bind (f e s)
820    (decode-float u)
821    (cons (* s f) e)))
822
823;;; Contributed by Juergen Weiss from Arthur Norman's CCL.
824(defun cot (a)
825  (if (or (> a 1000.0) (< a -1000.0))
826    (/ (cos a) (sin a))
827    (/ 1.0 (tan a))))
828
829;;; moved from unlisp.lisp
830(defun |AlistAssocQ| (key l)
831  (assoc key l :test #'eq) )
832
833(defun |AlistRemoveQ| (key l)
834   (let ((pr (assoc key l :test #'eq)))
835       (if pr
836           (remove pr l :test #'eq)
837           l) ))
838
839(defun log10 (u) (log u 10.0d0))
840
841(defun |make_spaces| (len)
842    (make-string len :initial-element #\ ))
843
844;;; end of moved fragment
845
846;;; moved from bits.lisp
847
848;;; The types "bit" and "bit vector" are implemented differently
849;;; in different variants of lisp.
850;;; These lisp macros/functions will have different implementations
851;;; on different lisp systems.
852
853;;; The operations which traverse entire vectors are given as functions
854;;; since the function calling overhead will be relatively small.
855;;; The operations which extract or set a single part of the vector are
856;;; provided as macros.
857
858;;; SMW Nov 88: Created
859
860(defun    |make_BVEC| (n x)
861    (make-array (list n) :element-type 'bit :initial-element x))
862
863(defun    |copy_BVEC|      (bv)      (copy-seq bv))
864(defun    |concat_BVEC|    (bv1 bv2) (concatenate '(vector bit) bv1 bv2))
865(defun    |equal_BVEC|     (bv1 bv2) (equal    bv1 bv2))
866(defun    |greater_BVEC|   (bv1 bv2)
867  (let ((pos (mismatch bv1 bv2)))
868    (cond ((or (null pos) (>= pos (length bv1))) nil)
869          ((< pos (length bv2)) (> (bit bv1 pos) (bit bv2 pos)))
870          ((find 1 bv1 :start pos) t)
871          (t nil))))
872(defun    |and_BVEC|       (bv1 bv2) (bit-and  bv1 bv2))
873(defun    |or_BVEC|        (bv1 bv2) (bit-ior  bv1 bv2))
874(defun    |xor_BVEC|       (bv1 bv2) (bit-xor  bv1 bv2))
875(defun    |nand_BVEC|      (bv1 bv2) (bit-nand bv1 bv2))
876(defun    |nor_BVEC|       (bv1 bv2) (bit-nor  bv1 bv2))
877(defun    |not_BVEC|       (bv)      (bit-not  bv))
878
879;;; end of moved fragment
880