Annotation of 43BSD/ucb/lisp/lisplib/array.l, revision 1.1.1.1

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))))

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.