forked from g000001/Starlisp-simulator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
utilities.lisp
203 lines (168 loc) · 6.21 KB
/
utilities.lisp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
;;; -*- Mode: LISP; Syntax: COMMON-LISP; Package: *SIM-I; Base: 10; Muser: yes -*-
(in-package :*sim-i)
;;;> *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
;;;>
;;;> The Thinking Machines *Lisp Simulator is in the public domain.
;;;> You are free to do whatever you like with it, including but
;;;> not limited to distributing, modifying, and copying.
;;;>
;;;> *+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+
;;; Author: JP Massar.
(defun iota (n)
(let ((result nil))
(dotimes (j n) (push j result))
(nreverse result)
))
(defun power-of-two-p (x) (and (plusp x) (eql 1 (logcount x))))
(defun next-power-of-two->= (x)
(assert (and (integerp x) (> x 0)) () "The domain of next-power-of-two->= is positive integers")
(labels
((next (power-of-two) (if (<= x power-of-two) power-of-two (next (* power-of-two 2)))))
(next 1)
))
(defun fill-array (array value)
(declare (optimize (speed 3) (safety 0) (debug 0) (space 0)))
;; Fill a vector with a value.
;; Usually this is a pvar array, which is a (vector t),
;; but it could be a context array, which is (vector bit).
(let ((size (length array))
(array array)
)
(declare (type simple-vector array))
(declare (type fixnum size))
(dotimes (j size)
(declare (type fixnum j))
(setf (aref array j) value)
)))
(defun return-pvar-p-declaration-p (declare-form)
(and
(eql 2 (length declare-form))
(listp (second declare-form))
(eq 'return-pvar-p (first (second declare-form)))
(eql 2 (length (second declare-form)))
(member (second (second declare-form)) '(t nil))
t
))
(defun return-pvar-p-declaration-value (return-pvar-p-declaration)
(second (second return-pvar-p-declaration))
)
(defun char-flipcase (char)
(if (upper-case-p char)
(char-downcase char)
(if (lower-case-p char)
(char-upcase char)
char
)))
(defun compare (x y)
(safety-check
(when (or (not (and (numberp x) (not (complexp x))))
(not (and (numberp y) (not (complexp y))))
)
(error "Only non-complex numeric values may be used in COMPARE")
))
(if (< x y) -1 (if (> x y) 1 0))
)
(defun starlisp-sqrt (x)
(safety-check
(when (and (not (complexp x)) (minusp x))
(error "Taking the square root of a negative non-complex number is illegal in *Lisp.~@
Use complex!! to first coerce the pvar to have complex values."
)))
(sqrt x)
)
(defun starlisp-expt (base power)
(safety-check
(when (or (not (complexp base)) (not (complexp power)))
(when (and (floatp base) (minusp base) (floatp power))
(error "Raising a negative floating point number to a floating point power is illegal in *Lisp.~@
Use complex!! to first coerce the base to have complex values."
))
(when (and (integerp base) (integerp power) (minusp power))
(error "Raising an integer to a negative integer power is illegal in *Lisp.~@
Use float!! to first coerce the base to have floating point values"
))))
(expt base power)
)
(defun starlisp-log (number &optional base)
(safety-check
(when (and (not (complexp number)) (minusp number))
(error "Taking the log of a negative non-complex number is illegal in *Lisp.~@
Use complex!! to first coerce the pvar to have complex values."
))
(when (and base (not (complexp base)) (minusp base))
(error "Taking the log of a number to a negative non-complex base is illegal in *Lisp.~@
Use complex!! to first coerce the base pvar to have complex values."
)))
(if base
(log number base)
(log number)
))
(defun starlisp-asin (x)
(safety-check
(when (and (not (complexp x)) (> x 1.0))
(error "Taking the arc-sine of a non-complex number which is greater than 1.0 is illegal in *Lisp.~@
Use complex!! to first coerce the argument to have complex values."
)))
(asin x)
)
(defun starlisp-acos (x)
(safety-check
(when (and (not (complexp x)) (> x 1.0))
(error "Taking the arc-cosine of a non-complex number which is greater than 1.0 is illegal in *Lisp.~@
Use complex!! to first coerce the argument to have complex values."
)))
(acos x)
)
(defun starlisp-acosh (x)
(safety-check
(when (and (not (complexp x)) (< x 1.0))
(error "Taking the acosh of a non-complex number which is less than 1.0 is illegal in *Lisp.~@
Use complex!! to first coerce the argument to have complex values."
))
(acosh x)
))
(defun starlisp-atanh (x)
(safety-check
(when (and (not (complexp x)) (> x 1.0))
(error "Taking the atanh of a non-complex number which is less than 1.0 is illegal in *Lisp.~@
Use complex!! to first coerce the argument to have complex values."
))
(atanh x)
))
(defun front-end-gray-code-from-integer (integer)
(logxor integer (ash integer -1))
)
(defun front-end-integer-from-gray-code (gray-code)
(let ((answer 0))
(dotimes (bit (integer-length (abs gray-code)))
(setq answer (logxor answer (ash gray-code (- bit))))
)
answer
))
(defun load-byte (source position size)
(ldb (byte size position) source)
)
(defun n-bits-for-address (number)
(assert (plusp number))
(max 1 (integer-length (1- number)))
)
;;; A quicker, more mnemonic function for jumping immediately
;;; into or out of the *Lisp package: (W.R.S. -- 8/11/89)
;;; A non-NIL argument puts you in the *Lisp package, a NIL argument puts you
;;; in the User package, and no argument toggles you between the two.
(defun *lisp (&optional (select-*lisp :toggle))
(eval `(in-package
,(if (eq select-*lisp :toggle)
(if (eq *package* (find-package :*lisp))
:cl-user
:*lisp)
(if select-*lisp :*lisp :cl-user))))
(format t "Default package is now ~A.~%" (package-name *package*))
(values))
(defun cl-user::*lisp (&optional (select-*lisp :toggle))
(*lisp select-*lisp))
(defun non-negative-integer-p (x) (and (integerp x) (> x -1)))
#+Allegro
(defun string-char-p (x) (excl::string-char-p x))
#-Allegro
(defun string-char-p (x) (characterp x))