home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / scheme / schmlbrr / schem_lb.lha / unsupported / CScheme / array.scm < prev    next >
Encoding:
Text File  |  1991-08-05  |  8.2 KB  |  270 lines

  1. ;;;-*- Base: 10; Mode: Scheme; Syntax: MIT Scheme; Package: USER -*-
  2. ;;
  3. ;; ARRAY.SCM
  4. ;;
  5. ;; July 1, 1991
  6. ;; Minghsun Liu
  7. ;;
  8. ;; This file contains procedures written in MIT Scheme that implement
  9. ;; a data type that is anologous to the arrays found in CommonLisp.
  10. ;; The main idea is to use vectors whose elements are also vectors to
  11. ;; implement the multi-dimensionality of arrays.  
  12. ;;
  13. ;; July 19, 1991
  14. ;; Major Overhawl: All the codes are re-written using message passing
  15. ;; style of programming.
  16. ;;
  17. ;; July 26, 1991
  18. ;; Yet Another Major Overhawl: the requirement of :displaced-to suggests
  19. ;; that a flattened internal representation of the array is the ideal
  20. ;; implementation. 
  21. ;;
  22. ;; July 30, 1991
  23. ;; Elimination of support for :displaced-to keyword.  The original
  24. ;; implementation with support for :displaced-to can be found in
  25. ;; array-displaced.scm
  26. ;;
  27. ;; 
  28. ;; The following(s) are(is) defined:
  29. ;;
  30. ;; :INITIAL-CONTENTS
  31. ;; :INITIAL-ELEMENT
  32. ;; (MAKE-ARRAY DIMENSIONS . OPTIONS)
  33. ;; (AREF ARRAY . SUBSCRIPTS)
  34. ;; (ARRAY-RANK ARRAY)
  35. ;; (ARRAY-DIMENSIONS)
  36. ;; (ARRAY-DIMENSION ARRAY AXIS-NUMBER)
  37. ;; (ARRAY? ARRAY)
  38. ;; (ARRAY-SET! ARRAY OBJ . SUBSCRIPTS)
  39. ;; (JUST-THE-ARRAY-MAAM ARRAY)
  40. ;; (CHANGE-MYSELF ARRAY NEW-DATA)
  41. ;;
  42. (declare (usual-integrations))
  43.  
  44. ;;
  45. ;; :INITIAL-CONTENTS
  46. ;; :INITIAL-ELEMENT
  47. ;;
  48. ;; are constants whose values should not be changed.
  49. ;;
  50. (define :initial-contents (cons ':initial-contents 'keyword-constant))
  51. (define :initial-element (cons ':initial-element 'keyword-constant))
  52.  
  53. ;;
  54. ;; (MAKE-ARRAY DIMENSIONS #!REST OPTIONS)
  55. ;;
  56. ;; creates a array with its dimensions specified by DIMENSIONS which
  57. ;; should be a list of non-negative integers with the length of the
  58. ;; list being the rank of the array.
  59. ;;
  60. (define (make-array dimensions #!rest options)
  61.   (let ((initialize-array? #f)
  62.     (initial-element? #t)
  63.     (cur-array '())
  64.     (initial-object '()))
  65.     (define (flatten a-list)  ;; ahhh....a-list been run over by a truck
  66.       (cond ((null? a-list)
  67.          '())
  68.         ((pair? (car a-list))
  69.          (append (flatten (car a-list))
  70.              (flatten (cdr a-list))))
  71.         (else
  72.          (cons (car a-list)
  73.            (flatten (cdr a-list))))))
  74.     (define (list->array dims flat-list)
  75.       (if (and (= (length flat-list) dims)
  76.            (not (list-transform-positive flat-list pair?)))
  77.       (list->vector flat-list)
  78.       (error "MAKE-ARRAY: displaced -> something is WRONG!!" flat-list dims)))
  79.     (define (check-options options-left)
  80.       (cond ((null? options-left)
  81.          'done)
  82.         ((equal? (car options-left) :initial-contents)
  83.          (set! initial-element? #f)
  84.          (set! initialize-array? #t)
  85.          (set! initial-object (cadr options-left))
  86.          (check-options (cddr options-left)))
  87.         ((equal? (car options-left) :initial-element)
  88.              (set! initialize-array? #t)
  89.          (set! initial-object (cadr options-left))
  90.          (check-options (cddr options-left)))
  91.         (else (error "MAKE-ARRAY: unknown keyword" options-left))))
  92.     (define (translate subscripts)  ;; collapse the world down to 1D
  93.       (define (trans-aux subs dims)
  94.     (if (null? (cddr subs)) 
  95.         (+ (* (cadr subs) (car dims)) (car subs))
  96.         (trans-aux (cons (+ (* (cadr subs) (car dims)) (car subs))
  97.                  (cddr subs))
  98.                (cons (* (car dims) (cadr dims)) (cddr dims)))))
  99.       (let ((trans-index
  100.          (if (= (length subscripts) (length dimensions))
  101.          (if (= (length subscripts) 1)
  102.              (car subscripts)
  103.              (trans-aux (reverse subscripts) (reverse dimensions)))
  104.          (error "ARRAY: invalid index" subscripts dimensions))))
  105.     (if (>= trans-index (vector-length cur-array))
  106.         (error "TRANSLATE-ARRAY: bad index" subscripts trans-index)
  107.         trans-index)))
  108.     (define (m-array-ref subscripts)
  109.       (cond ((and (null? subscripts) (not (vector? cur-array)) (null? dimensions))
  110.          cur-array)
  111.         ((list? subscripts)
  112.          (vector-ref cur-array (translate subscripts)))
  113.         (else
  114.          (error "AREF: array corrupt or bad index" cur-array subscripts dimensions))))
  115.     (define (m-array-rank)
  116.       (length dimensions))
  117.     (define (m-array-dimension axis-number)
  118.       (list-ref axis-number dimensions))
  119.     (define (m-array-dimensions)
  120.       (if (null? dimensions)
  121.       '()
  122.       dimensions))
  123.     (define (m-array-set! arguements)
  124.       (let ((obj (car arguements))
  125.         (ind (if (null? (cdr arguements))
  126.              '()
  127.              (translate (cdr arguements)))))
  128.     (define (array-set-aux!)
  129.       (vector-set! cur-array ind obj)
  130.       obj)
  131.     (define (array-set-aux-2!)
  132.       (set! cur-array obj)
  133.       obj)
  134.     (if (and (null? ind) (null? dimensions))
  135.         (array-set-aux-2!)
  136.         (if (and (not (null? ind)) (not (null? dimensions)))
  137.         (array-set-aux!)
  138.         (error "ARRAY-SET: bad index" arguements)))))
  139.     (define (array-type msg #!rest args)
  140.       (case msg
  141.     ((array-ref) (m-array-ref args))
  142.     ((array-rank) (m-array-rank))
  143.     ((array-dimension) (m-array-dimension (car args)))
  144.     ((array?) #t)
  145.     ((array-dimensions) (m-array-dimensions))
  146.     ((array-set!) (m-array-set! args))
  147.     ((just-the-array-maam) cur-array)
  148.     ((change-myself) (set! cur-array (car args)))  ;; change yourself, i.e. destructive.
  149.     (else (error "ARRAY: not a valid method" msg))))
  150.     (check-options options)
  151.     (set! cur-array
  152.       (if (or (number? dimensions) (= 1 (length dimensions)) (null? dimensions))
  153.           (if (number? dimensions)
  154.           (if initialize-array? 
  155.               (if initial-element?
  156.               (make-vector dimensions initial-object)
  157.               (if (= (length initial-object) dimensions)
  158.                   (list->vector initial-object)
  159.                   (error "MAKE-ARRAY: array is not of correct size"
  160.                      dimensions initial-object)))
  161.               (make-vector dimensions))
  162.           (if (null? dimensions)
  163.               (if initialize-array?
  164.               initial-object
  165.               0)
  166.               (if initialize-array?
  167.               (if initial-element?
  168.                   (make-vector (car dimensions) initial-object)
  169.                   (if (= (length initial-object) (car dimensions))
  170.                   (list->vector initial-object)
  171.                   (error "MAKE-ARRAY: array is not of correct size"
  172.                      (car dimensions) initial-object)))
  173.               (make-vector (car dimensions)))))
  174.           (if (and initialize-array? (not initial-element?))
  175.           (list->array (apply * dimensions) (flatten initial-object))
  176.           (if initial-element?
  177.               (make-vector (apply * dimensions) initial-object)
  178.               (make-vector (apply * dimensions))))))
  179.     array-type))
  180.  
  181.  
  182. ;;
  183. ;; (AREF ARRAY . SUBSCRIPTS)
  184. ;;
  185. ;; access and returns the element of array specified by the SUBSCRIPTS
  186. ;; whose number must equal the rank of the array.
  187. ;;
  188. (define (aref array #!rest subscripts)
  189.   (apply array 'array-ref subscripts))
  190.  
  191.  
  192. ;;
  193. ;; (ARRAY-RANK ARRAY)
  194. ;;
  195. ;; returns the number of dimensions of ARRAY.  One limitation of
  196. ;; current implementation is that the elements in the array can't
  197. ;; be vectors.
  198. ;;
  199. (define (array-rank array)
  200.   (array 'array-rank))
  201.  
  202.  
  203. ;;
  204. ;; (ARRAY-DIMENSION ARRAY AXIS-NUMBER)
  205. ;;
  206. ;; returns the length of dimension number AXIS-NUMBER of ARRAY.
  207. ;;
  208. (define (array-dimensions array axis-number)
  209.   (array 'array-dimensions axis-number))
  210.  
  211.  
  212. ;;
  213. ;; (ARRAY-DIMENSIONS ARRAY)
  214. ;;
  215. ;; get the dimensions of ARRAY.
  216. ;;
  217. (define (array-dimensions array)
  218.   (array 'array-dimensions))
  219.  
  220.  
  221. ;;
  222. ;; (ARRAY? OBJECT)
  223. ;;
  224. ;; tests if object is an array.
  225. ;;
  226. (define (array? object)
  227.   (if (procedure? object)
  228.       (object 'array?)
  229.       #f))
  230.  
  231.  
  232. ;;
  233. ;; (ARRAY-SET! ARRAY OBJ . SUBSCRIPTS)
  234. ;;
  235. ;; destructively replace an array element of index SUBSCRIPTS with the
  236. ;; value OBJ.  (Note: the ordering of arguements is a little different
  237. ;; from that in CL: (setf (aref an-array ind) obj).)
  238. ;;
  239. (define (array-set! array obj #!rest subscripts)
  240.   (apply array 'array-set! obj subscripts))
  241.  
  242.  
  243. ;;
  244. ;; (JUST-THE-ARRAY-MAAM ARRAY)
  245. ;;
  246. ;; like the name says: a wicked way to get the vector that stores
  247. ;; the data in the array only, instead of the whole procedural object.
  248. ;; This is one way to implement operations on the array without adding
  249. ;; methods to the object.
  250. ;;
  251. (define (just-the-array-maam array)
  252.   (array 'just-the-array-maam))
  253.  
  254.  
  255. ;;
  256. ;; (CHANGE-MYSELF ARRAY NEW-DATA)
  257. ;;
  258. ;; coupled with the above procedure, JUST-THE-ARRAY-MAAM, provide the
  259. ;; facilities to write operations on arrays as independent procedures,
  260. ;; instead of a new method in the ARRAY object.  This method, however,
  261. ;; does not check the consistency of NEW-DATA with the characteristics
  262. ;; of the array.  (e.g. If the array is a 2 by 2 array, it is assumed
  263. ;; that NEW-DATA is a vector that contains at least 4 elements.)
  264. ;;
  265. (define (change-myself array new-data)
  266.   (array 'change-myself new-data))
  267.  
  268.  
  269.  
  270.