|
|
1.1 root 1: ;;
2: ;; array.l -[Tue Jul 5 23:51:48 1983 by layer]-
3: ;;
4: ;; maclisp compatible array package. This implements maclisp
5: ;; compatible arrays.
6: ;;
7: ;; features of the new package:
8: ;; Most array will be notype arrays. This is because they are the most
9: ;; efficient in Franz. What used to be fixnum and flonums arrays are
10: ;; now fixnum-block and flonum-block arrays.
11: ;; The array access functions are more specialized and much faster now.
12: ;; The array access functions have different semantics. Now they are
13: ;; responsible for both accessing and storing in an array.
14: ;; When an access function is asked to access a value, it will be given
15: ;; the subscripts already evaluated and the array object. These will
16: ;; be stacked, so the array access function should be a lexpr to read them.
17: ;; When an access function is asked to store a value that value will be
18: ;; the first argument, the subscripts will follow and finally there will
19: ;; be the array object.
20: ;; It is up to the access function to determine if it is being asked to
21: ;; store or retrieve a value, and this determination will probably
22: ;; be made by looking at the number of arguments.
23:
24:
25: (setq rcs-array-
26: "$Header: array.l 1.5 83/07/05 23:51:58 layer Exp $")
27:
28: (declare (special gcdisable)
29: (macros t))
30:
31: (def array
32: (macro ($lis$)
33: `(*array ',(cadr $lis$) ',(caddr $lis$) ,@(cdddr $lis$))))
34:
35: (def *array
36: (lexpr (nargs)
37: (prog (name type rtype dims size tname numdims)
38:
39: (cond ((lessp (setq numdims (- nargs 2)) 1)
40: (error "no bounds to array declaration ")))
41:
42: (setq name (arg 1)
43: type (arg 2)
44: rtype (cond ((memq type '(t nil fixnum flonum))
45: 'value)
46: ((eq type 'fixnum-block)
47: 'fixnum)
48: ((eq type 'flonum-block)
49: 'flonum)
50: (t (error "array: bad type: " type)))
51: dims (do ((i nargs (1- i))
52: (res nil (cons (arg i) res)))
53: ((eq i 2) res))
54:
55: size (apply 'times dims))
56:
57: (cond ((null type) (setq type 'unmarked_array)))
58:
59: ; we disable gc during the next calculation since
60: ; the data returned from small-segment is unprotected
61: ; and a gc would cause its data to be put on the
62: ; free list.
63: (let ((gcdisable t))
64: (setq tname
65: (marray (small-segment rtype size)
66: (cond ((eq rtype 'value)
67: (cond ((eq numdims 1)
68: (getd 'arrac-oneD))
69: ((eq numdims 2)
70: (getd 'arrac-twoD))
71: (t (getd 'arrac-nD))))
72: (t (getd 'arrac-nD)))
73: (cons type dims)
74: size
75: (sizeof rtype))))
76: ; if type is fixnum or flonum
77: ; we must intialize to 0 or 0.0
78: (cond ((or (and (eq 'fixnum type)
79: (setq rtype 0))
80: (and (eq 'flonum type)
81: (setq rtype 0.0))
82: (and (or (status feature 68k)
83: (status feature for-68k))
84: (progn (setq rtype nil) t)))
85: (do ((i size))
86: ((zerop i))
87: (set (arrayref tname (setq i (1- i))) rtype))))
88:
89: (cond (name (putd name tname)))
90: (return tname))))
91:
92: (defmacro arraycall (type array &rest indexes)
93: `(funcall ,array ,@indexes))
94:
95: ;--- array-type :: return type of array
96: ;
97: (defun array-type (arr)
98: (cond ((not (arrayp arr)) (error "array-type: non array passed " arr))
99: (t (car (getaux arr)))))
100:
101: ; this is used by the old array scheme. Keep this around until
102: ; everything is recompiled
103:
104: (defun ev-arraycall (type array indexes)
105: (apply array indexes))
106:
107:
108: ;;;---- array access functions.
109:
110: ; we first define a macro to evaluate a value cell. In compiled code cdr
111: ; is the fastest way to do this, in interpreted code the type checker
112: ; would not let us use cdr so we have to use eval.
113: (eval-when (compile)
114: (defmacro value-eval (x) `(cdr ,x)) ; one level of indirection
115: (defmacro simple-arrayref (arr ind) `(offset-cxr ,ind (getdata ,arr))))
116:
117: (eval-when (eval)
118: (defun value-eval (x) (eval x))
119: (defun simple-arrayref (arr ind) (arrayref arr ind)))
120:
121: ;- one dimensional
122: (defun arrac-oneD n
123: (cond ((eq n 2) (value-eval (simple-arrayref (arg 2) (arg 1))))
124: ((eq n 3) (set (simple-arrayref (arg 3) (arg 2)) (arg 1)))
125: (t (error " wrong number of subscripts to array: " (arg n)))))
126:
127: (defun arrac-twoD n
128: (let ((aux (getaux (arg n))))
129: (cond ((eq n 3)
130: (value-eval (simple-arrayref
131: (arg n)
132: (+ (* (arg 1) (caddr aux)) (arg 2)))))
133: ((eq n 4)
134: (set (simple-arrayref (arg n)
135: (+ (* (arg 2) (caddr aux)) (arg 3)))
136: (arg 1)))
137: (t (error " wrong number of subscripts to array: " (arg n))))))
138:
139: ;-- n dimensional array access function.
140: (defun arrac-nD n
141: (let ((aux (getaux (arg n)))
142: firstsub subs
143: store
144: (index 0))
145:
146: (setq subs (length (cdr aux)))
147: (cond ((eq n (1+ subs))
148: (setq firstsub 1))
149: ((eq n (+ 2 subs))
150: (setq firstsub 2 store t))
151: (t (error "wrong number of subscripts to array: " (arg n))))
152:
153: (setq index (arg firstsub))
154: (do ((bounds (cddr aux) (cdr bounds))
155: (i firstsub))
156: ((null bounds))
157: (setq index (+ (* index (car bounds)) (arg (setq i (1+ i))))))
158:
159: (setq subs (arrayref (arg n) index)) ; get cell requested
160: (cond ((memq (car aux) '(fixnum-block flonum-block))
161: (cond (store (replace subs (arg 1)))
162: (t (cpy1 subs))))
163: (t (cond (store (set subs (arg 1)))
164: (t (value-eval subs)))))))
165:
166:
167: (defmacro store ( (arrname . indexes) value)
168: (do ((fnd))
169: (nil)
170: (cond ((eq 'funcall arrname)
171: (return `(funcall ,(car indexes) ,value . ,(cdr indexes))))
172: ((eq 'apply arrname)
173: (return `(apply ,(car indexes) (cons ,value ,@(cdr indexes)))))
174: ((eq 'arraycall arrname)
175: (return `(funcall ,(cadr indexes) ,value ,@(cddr indexes))))
176: ((arrayp arrname)
177: (return `(funcall ',arrname ,value ,@indexes))))
178: (setq fnd (getd arrname))
179: (cond ((or (and (dtpr fnd) (eq 'macro (car fnd)))
180: (and (bcdp fnd) (eq 'macro (getdisc fnd))))
181: (setq fnd (apply arrname (cons arrname indexes)))
182: (setq arrname (car fnd)
183: indexes (cdr fnd)))
184: (t (return `(,arrname ,value . ,indexes))))))
185:
186: ;-- storeintern - there may be residual calls to storeintern from
187: ; old code, we handle it here. this routine can be eliminated when
188: ; code is recompiled
189:
190: (defun storeintern (arrnam value indexes)
191: (apply arrnam (cons value indexes)))
192:
193: ;--- small segment storage allocators.
194:
195: ; this function allocates segments of storage and attempt to use the whole
196: ; block instead of throwing away what isnt used
197: ;
198:
199: (declare (special gcdisable))
200:
201: (defun small-segment (type n)
202: (prog (lastseg retv elementsize itemsperpage-1 gcdisable tmp)
203: (setq gcdisable t) ; its not a good idea to gc while we are
204: ; handling pointers to things segment returns.
205: (desetq (elementsize . itemsperpage-1) (get 'segment-sizes type))
206: (cond ((null elementsize) (error "small-segment: bad type " type)))
207: (setq lastseg (get 'segment-types type))
208: (cond ((and lastseg (not (lessp (car lastseg) n))))
209: (t ; must allocate a block of storage, want to the least number of
210: ; pages which includes n elements
211: ; there are elementsize elements per page, and
212: ; itemsperpage-1 is the number of elements on a page minus 1
213: (setq retv (boole 4
214: (+ n itemsperpage-1)
215: itemsperpage-1)) ; 4 is x & ~y
216: (setq lastseg (cons retv (maknum (segment type retv))))))
217: (setq retv (cdr lastseg))
218: (rplaca lastseg (- (car lastseg) n))
219: (rplacd lastseg (+ (cdr lastseg) (* elementsize n)))
220: (cond ((greaterp (car lastseg) 0)
221: (putprop 'segment-types lastseg type)
222: (cond ((null (setq tmp (get 'segment-arrays type)))
223: (putprop 'segment-arrays
224: (setq tmp (marray nil nil nil nil nil))
225: type)))
226: (putdata tmp (fake (cdr lastseg)))
227: (putlength tmp (car lastseg))
228: (putdelta tmp elementsize))
229: (t ; remove all counters since we no longer have any space
230: ; left and we can't have a zero length array
231: (remprop 'segment-types type)
232: (remprop 'segment-arrays type)))
233: (return (fake retv))))
234:
235: ; data base for small-segment
236: (putprop 'segment-sizes '( 4 . 127) 'value)
237: (putprop 'segment-sizes '( 4 . 127) 'fixnum)
238: (putprop 'segment-sizes '( 8 . 63) 'flonum)
239:
240:
241: (def arraydims (lambda (arg) (cond ((symbolp arg) (getaux (getd arg)))
242: ((arrayp arg) (getaux arg))
243: (t (break '"non array arg to arraydims")))))
244:
245: ; fill array from list or array
246:
247: (def fillarray
248: (lambda (arr lis)
249: (prog (maxv typept)
250: (cond ((symbolp arr) (setq arr (getd arr))))
251:
252: (cond ((symbolp lis)
253: (setq lis (getd lis))
254: (return (fillarrayarray arr lis)))
255:
256: ((arrayp lis) (return (fillarrayarray arr lis))))
257:
258: (setq maxv (1- (getlength arr))
259: typept (cond ((memq (car (getaux arr))
260: '(t fixnum flonum unmarked_array))
261: t)
262: (t nil)))
263: (do ((ls lis)
264: (i 0 (1+ i)))
265: ((>& i maxv))
266:
267: (cond (typept (set (arrayref arr i) (car ls)))
268: (t (replace (arrayref arr i) (car ls))))
269:
270: (cond ((cdr ls) (setq ls (cdr ls))))))))
271:
272: (def fillarrayarray
273: (lambda (arrto arrfrom)
274: (prog (maxv)
275: (setq maxv (1- (min (getlength arrto)
276: (getlength arrfrom))))
277: (do ((i 0 (1+ i)))
278: ((>& i maxv))
279: (replace (arrayref arrto i) (arrayref arrfrom i))))))
280:
281: (def listarray
282: (lexpr (n)
283: (prog (arr size typ ret newv)
284: (setq arr (arg 1))
285: (cond ((arrayp arr))
286: ((and (symbolp arr) (arrayp (setq arr (getd arr)))))
287: (t (error "Non array to listarray " arr)))
288: (setq size (cond ((eq n 2) (arg 2))
289: (t (apply '* (cdr (arraydims arr))))))
290: (setq typ (car (getaux arr)))
291: (cond ((memq typ '(t fixnum flonum unmarked_array))
292: (setq typ t))
293: (t (setq typ nil)))
294: (do ((i (1- size) (1- i)))
295: ((lessp i 0))
296: (setq newv (arrayref arr i))
297: (setq ret (cons (cond (typ (eval newv))
298: (t (cpy1 newv)))
299: ret)))
300: (return ret))))
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.