PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/runtime-collections-vector.scm

http://github.com/pablomarx/Thomas
Scheme | 443 lines | 334 code | 43 blank | 66 comment | 0 complexity | fb4b93c27bcbbf5a291e15aa8b1af314 MD5 | raw file
  1. ;* Copyright 1992 Digital Equipment Corporation
  2. ;* All Rights Reserved
  3. ;*
  4. ;* Permission to use, copy, and modify this software and its documentation is
  5. ;* hereby granted only under the following terms and conditions. Both the
  6. ;* above copyright notice and this permission notice must appear in all copies
  7. ;* of the software, derivative works or modified versions, and any portions
  8. ;* thereof, and both notices must appear in supporting documentation.
  9. ;*
  10. ;* Users of this software agree to the terms and conditions set forth herein,
  11. ;* and hereby grant back to Digital a non-exclusive, unrestricted, royalty-free
  12. ;* right and license under any changes, enhancements or extensions made to the
  13. ;* core functions of the software, including but not limited to those affording
  14. ;* compatibility with other hardware or software environments, but excluding
  15. ;* applications which incorporate this software. Users further agree to use
  16. ;* their best efforts to return to Digital any such changes, enhancements or
  17. ;* extensions that they make and inform Digital of noteworthy uses of this
  18. ;* software. Correspondence should be provided to Digital at:
  19. ;*
  20. ;* Director, Cambridge Research Lab
  21. ;* Digital Equipment Corp
  22. ;* One Kendall Square, Bldg 700
  23. ;* Cambridge MA 02139
  24. ;*
  25. ;* This software may be distributed (but not offered for sale or transferred
  26. ;* for compensation) to third parties, provided such third parties agree to
  27. ;* abide by the terms and conditions of this notice.
  28. ;*
  29. ;* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  30. ;* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
  31. ;* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
  32. ;* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  33. ;* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  34. ;* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  35. ;* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  36. ;* SOFTWARE.
  37. ; $Id: runtime-collections-vector.scm,v 1.13 1992/08/31 05:35:35 birkholz Exp $
  38. ;;;;; This file contains all the specializations for vector,
  39. ;;;;; simple-object-vector, and stretchy-vector types
  40. (add-method dylan:shallow-copy ; To override <array> handling
  41. (dylan::function->method
  42. (make-param-list `((vector ,<vector>)) #F #F #F)
  43. (lambda (seq)
  44. (dylan-call dylan:copy-sequence seq))))
  45. (add-method dylan:as
  46. (dylan::function->method
  47. (make-param-list `((CLASS ,(dylan::make-singleton <vector>))
  48. (COLLECTION ,<collection>)) #F #F #F)
  49. (lambda (class collection)
  50. class ; Ignored
  51. (if (dylan-call dylan:instance? collection <vector>)
  52. collection
  53. (dylan-call dylan:as <simple-object-vector> collection)))))
  54. (add-method dylan:as
  55. (dylan::function->method
  56. (make-param-list `((CLASS ,(dylan::make-singleton <simple-object-vector>))
  57. (COLLECTION ,<collection>)) #F #F #F)
  58. (lambda (class collection)
  59. class ; Ignored
  60. (if (dylan-call dylan:instance? collection <simple-object-vector>)
  61. collection
  62. (let* ((size (dylan-call dylan:size collection))
  63. (new-vector (make-vector size)))
  64. (do ((state (dylan-call dylan:initial-state collection)
  65. (dylan-call dylan:next-state collection state))
  66. (index 0 (+ index 1)))
  67. ((not state) new-vector)
  68. (vector-set!
  69. new-vector index
  70. (dylan-call dylan:current-element collection state))))))))
  71. (add-method dylan:as
  72. (dylan::function->method
  73. (make-param-list `((CLASS ,(dylan::make-singleton <stretchy-vector>))
  74. (COLLECTION ,<collection>)) #F #F #F)
  75. (lambda (class collection)
  76. class ; Ignored
  77. (if (dylan-call dylan:instance? collection <stretchy-vector>)
  78. collection
  79. (let* ((size (dylan-call dylan:size collection))
  80. (new-s-vector
  81. (dylan-call dylan:make <stretchy-vector> 'size: size))
  82. (vector-value (dylan-call dylan:get-array-value new-s-vector)))
  83. (do ((state (dylan-call dylan:initial-state collection)
  84. (dylan-call dylan:next-state collection state))
  85. (index 0 (+ index 1)))
  86. ((not state) new-s-vector)
  87. (vector-set!
  88. vector-value index
  89. (dylan-call dylan:current-element collection state))))))))
  90. ;;;
  91. ;;; VECTOR SPECIALIZED MAKE
  92. ;;; <vector> ... like the book says, this yields a
  93. ;;; <simple-object-vector>
  94. ;;;
  95. (add-method dylan:make
  96. (dylan::function->method
  97. (make-param-list `((VECTOR ,(dylan::make-singleton <vector>)))
  98. #F #F #T)
  99. (lambda (class . rest)
  100. class ; Ignored
  101. (dylan-apply dylan:make <simple-object-vector> rest))))
  102. ;;;
  103. ;;; SIMPLE-OBJECT-VECTOR SPECIALIZED MAKE
  104. ;;; <simple-object-vector> generates a Scheme vector
  105. ;;;
  106. (add-method
  107. dylan:make
  108. (dylan::dylan-callable->method
  109. (make-param-list `((SOV ,(dylan::make-singleton
  110. <simple-object-vector>)))
  111. #F #F '(size: fill:))
  112. (lambda (multiple-values next-method class . rest)
  113. multiple-values class ; Not used
  114. (dylan::keyword-validate next-method rest '(size: fill:))
  115. (let* ((size (dylan::find-keyword rest 'size: (lambda () 0)))
  116. (fill (dylan::find-keyword rest 'fill: (lambda () #F))))
  117. (if (or (not (integer? size)) (negative? size))
  118. (dylan-call
  119. dylan:error
  120. "(make (singleton <simple-object-vector>)) -- size: invalid" size))
  121. (make-vector size fill)))))
  122. ;;;
  123. ;;; STRETCHY-VECTOR SPECIALIZED MAKE
  124. ;;; <stretchy-vector> has one slot, for the vector itself. I'm using
  125. ;;; the slot that is inherited from <array> for this purpose.
  126. ;;; Dimensions here is a list of one number.
  127. ;;;
  128. (add-method
  129. dylan:make
  130. (dylan::dylan-callable->method
  131. (make-param-list `((SV ,(dylan::make-singleton <stretchy-vector>)))
  132. #F #F '(size: fill:))
  133. (lambda (multiple-values next-method class . rest)
  134. multiple-values class ; Not used
  135. (dylan::keyword-validate next-method rest '(size: fill:))
  136. (let* ((size (dylan::find-keyword rest 'size: (lambda () 0)))
  137. (fill (dylan::find-keyword rest 'fill: (lambda () #F))))
  138. (if (or (not (integer? size)) (negative? size))
  139. (dylan-call dylan:error
  140. "(make (singleton <stretchy-vector>)) size: invalid"
  141. size))
  142. (let ((instance (dylan::make-<object> <stretchy-vector>)))
  143. (dylan-call dylan:set-array-value!
  144. instance (make-vector size fill))
  145. (dylan-call dylan:set-array-dimensions! instance (list size))
  146. instance)))))
  147. ;;;
  148. ;;; Functions for collections
  149. ;;;
  150. (add-method dylan:size
  151. (one-arg 'SOV <vector>
  152. (lambda (vect) (vector-length (dylan-call dylan:get-array-value vect)))))
  153. ;;;
  154. ;;; Functions for sequences
  155. ;;;
  156. (add-method dylan:add
  157. (dylan::function->method one-vector-and-an-object
  158. (lambda (vector new-element)
  159. (let ((new-vector (dylan-call dylan:make <vector>))
  160. (size (car (dylan-call dylan:get-array-dimensions vector))))
  161. (dylan-call dylan:set-array-value!
  162. new-vector
  163. (list->vector (cons new-element (vector->list vector))))
  164. (dylan-call dylan:set-array-dimensions! new-vector (list (+ size 1)))
  165. new-vector))))
  166. (add-method dylan:add
  167. (dylan::function->method one-simple-object-vector-and-an-object
  168. (lambda (sov new-element)
  169. (list->vector (cons new-element (vector->list sov))))))
  170. (add-method dylan:add
  171. (dylan::function->method one-stretchy-vector-and-an-object
  172. (lambda (s-vector new-element)
  173. (let ((new-vector (dylan-call dylan:make <stretchy-vector>))
  174. (size (car (dylan-call dylan:get-array-dimensions s-vector))))
  175. (dylan-call dylan:set-array-value!
  176. new-vector
  177. (list->vector (cons new-element (vector->list s-vector))))
  178. (dylan-call dylan:set-array-dimensions!
  179. new-vector (list (+ size 1)))
  180. new-vector))))
  181. (add-method dylan:add!
  182. (dylan::function->method
  183. one-stretchy-vector-and-an-object
  184. (lambda (s-vector new-element)
  185. (let* ((vector (dylan-call dylan:get-array-value s-vector))
  186. (size (car (dylan-call dylan:get-array-dimensions s-vector)))
  187. (new-vector (make-vector (+ size 1))))
  188. (do ((count 0 (+ count 1)))
  189. ((= count size) 'done)
  190. (vector-set! new-vector count (vector-ref vector count)))
  191. (vector-set! new-vector size new-element)
  192. (dylan-call dylan:set-array-value! s-vector new-vector)
  193. (dylan-call dylan:set-array-dimensions! s-vector (list (+ size 1)))
  194. s-vector))))
  195. (add-method dylan:concatenate
  196. (dylan::function->method
  197. (make-param-list `((SOV ,<simple-object-vector>)) #F 'REST #F)
  198. (lambda (vector-1 . rest)
  199. (let loop ((result (vector->list vector-1))
  200. (rest-vectors (map (lambda (seq)
  201. (dylan-call dylan:as
  202. <simple-object-vector> seq))
  203. rest)))
  204. (if (null? rest-vectors)
  205. (list->vector result)
  206. (loop (append result (vector->list (car rest-vectors)))
  207. (cdr rest-vectors)))))))
  208. (add-method dylan:concatenate
  209. (dylan::function->method
  210. (make-param-list `((VECTOR ,<vector>)) #F 'REST #F)
  211. (lambda (vector-1 . rest)
  212. (dylan-call dylan:apply dylan:concatenate vector-1 rest))))
  213. (add-method
  214. dylan:remove!
  215. (dylan::dylan-callable->method
  216. (make-param-list `((STRETCHY-VECTOR ,<stretchy-vector>) (VALUE ,<object>))
  217. #F #F '(test: count:))
  218. (lambda (multiple-values next-method s-vector value . rest)
  219. multiple-values
  220. (dylan::keyword-validate next-method rest '(test: count:))
  221. (let* ((test? (dylan::find-keyword rest 'test: (lambda () dylan:id?)))
  222. (count (dylan::find-keyword
  223. rest 'count:
  224. (lambda ()
  225. (car (dylan-call dylan:get-array-dimensions s-vector)))))
  226. (old-vector (dylan-call dylan:get-array-value s-vector))
  227. (new-vector (dylan-call dylan:remove
  228. old-vector value
  229. 'test: test? 'count: count)))
  230. (dylan-call dylan:set-array-value! s-vector new-vector)
  231. (dylan-call dylan:set-array-dimensions!
  232. s-vector (list (vector-length new-vector)))
  233. s-vector))))
  234. (add-method
  235. dylan:remove-duplicates!
  236. (dylan::dylan-callable->method
  237. (make-param-list `((STRETCHY-VECTOR ,<stretchy-vector>)) #F #F '(test:))
  238. (lambda (multiple-values next-method s-vector . rest)
  239. multiple-values
  240. (dylan::keyword-validate next-method rest '(test:))
  241. (let ((test? (dylan::find-keyword rest 'test: (lambda () dylan:id?))))
  242. (let ((new-vector (dylan-call dylan:remove-duplicates
  243. (dylan-call dylan:get-array-value
  244. s-vector)
  245. 'test: test?)))
  246. (dylan-call dylan:set-array-value! s-vector new-vector)
  247. (dylan-call dylan:set-array-dimensions!
  248. s-vector (list (vector-length new-vector)))
  249. s-vector)))))
  250. (add-method dylan:reverse
  251. (dylan::function->method one-simple-object-vector
  252. (lambda (vector-1)
  253. (let ((result (make-vector (vector-length vector-1))))
  254. (do ((from (- (vector-length vector-1) 1) (- from 1))
  255. (to 0 (+ to 1)))
  256. ((< from 0) result)
  257. (vector-set! result to (vector-ref vector-1 from)))
  258. result))))
  259. (add-method dylan:reverse
  260. (dylan::function->method one-stretchy-vector
  261. (lambda (s-vector)
  262. (let* ((vector-1 (dylan-call dylan:get-array-value s-vector))
  263. (result (make-vector (vector-length vector-1)))
  264. (result-s-vector (dylan-call dylan:make <stretchy-vector>)))
  265. (do ((from (- (vector-length vector-1) 1) (- from 1))
  266. (to 0 (+ to 1)))
  267. ((< from 0) result)
  268. (vector-set! result to (vector-ref vector-1 from)))
  269. (dylan-call dylan:set-array-value! result-s-vector result)
  270. (dylan-call dylan:set-array-dimensions!
  271. result-s-vector (list (vector-length result)))
  272. result-s-vector))))
  273. (add-method dylan:reverse!
  274. (dylan::function->method one-simple-object-vector
  275. (lambda (vector-1)
  276. (do ((from (- (vector-length vector-1) 1) (- from 1))
  277. (to 0 (+ to 1)))
  278. ((<= from to) vector-1)
  279. (let ((to-element (vector-ref vector-1 to)))
  280. (vector-set! vector-1 to (vector-ref vector-1 from))
  281. (vector-set! vector-1 from to-element))))))
  282. (add-method dylan:reverse!
  283. (dylan::function->method one-stretchy-vector
  284. (lambda (s-vector)
  285. (let ((vector-1 (dylan-call dylan:get-array-value s-vector)))
  286. (do ((from (- (vector-length vector-1) 1) (- from 1))
  287. (to 0 (+ to 1)))
  288. ((<= from to) s-vector)
  289. (let ((to-element (vector-ref vector-1 to)))
  290. (vector-set! vector-1 to (vector-ref vector-1 from))
  291. (vector-set! vector-1 from to-element)))))))
  292. (add-method
  293. dylan:sort!
  294. (dylan::dylan-callable->method
  295. (make-param-list `((STRETCHY-VECTOR ,<stretchy-vector>))
  296. #F #F '(test: stable:))
  297. (lambda (multiple-values next-method s-vector . rest)
  298. multiple-values
  299. (dylan::keyword-validate next-method rest '(test: stable:))
  300. (let ((test? (dylan::find-keyword rest 'test: (lambda () dylan:<)))
  301. (stable (dylan::find-keyword rest 'stable: (lambda () #F))))
  302. stable ; Ignored
  303. (dylan-call dylan:set-array-value!
  304. s-vector
  305. (dylan-call dylan:as
  306. <simple-object-vector>
  307. (sort (dylan-call dylan:as <pair> s-vector)
  308. (lambda (x y)
  309. (dylan-call test? x y)))))))))
  310. (add-method dylan:first
  311. (dylan::function->method one-vector
  312. (lambda (vector)
  313. (if (= (vector-length vector) 0)
  314. (dylan-call dylan:error "(first <vector>) -- vector is empty" vector)
  315. (vector-ref vector 0)))))
  316. (add-method dylan:second
  317. (dylan::function->method one-vector
  318. (lambda (vector)
  319. (if (< (vector-length vector) 2)
  320. (dylan-call dylan:error
  321. "(second <vector>) -- vector doesn't have 2 elements"
  322. vector)
  323. (vector-ref vector 1)))))
  324. (add-method dylan:third
  325. (dylan::function->method one-vector
  326. (lambda (vector)
  327. (if (< (vector-length vector) 3 )
  328. (dylan-call dylan:error
  329. "(third <vector>) -- vector doesn't have 3 elements"
  330. vector)
  331. (vector-ref vector 2)))))
  332. (add-method dylan:last
  333. (dylan::function->method one-vector
  334. (lambda (vector)
  335. (let* ((vector-value (dylan-call dylan:get-array-value vector))
  336. (vl (vector-length vector-value)))
  337. (if (zero? vl)
  338. (dylan-call dylan:error "(last <vector>) -- vector is empty" vector)
  339. (vector-ref vector-value (- vl 1)))))))
  340. (define dylan:vector
  341. (dylan::function->method
  342. (make-param-list '() #F 'REST-ARGS #F)
  343. (lambda args
  344. (if (null? args)
  345. (vector)
  346. (apply vector args)))))
  347. (add-method dylan:current-key
  348. (dylan::function->method
  349. (make-param-list `((VECTOR ,<vector>) (STATE ,<object>)) #F #F #F)
  350. (lambda (vector state)
  351. vector ; Ignored
  352. (vector-ref state 0))))
  353. ;;;
  354. ;;; Collection Keys
  355. ;;;
  356. (add-method
  357. dylan:element
  358. (dylan::dylan-callable->method
  359. (make-param-list `((VECTOR ,<vector>) (INDEX ,<integer>)) #F #F '(default:))
  360. (lambda (multiple-values next-method vector index . rest)
  361. multiple-values
  362. (dylan::keyword-validate next-method rest '(default:))
  363. (let ((vector-value (dylan-call dylan:get-array-value vector)))
  364. (let ((size (vector-length vector-value)))
  365. (if (and (>= index 0) (< index size))
  366. (vector-ref vector-value index)
  367. (dylan::find-keyword
  368. rest '(default:)
  369. (lambda ()
  370. (dylan-call dylan:error "(element <vector> <integer>) -- invalid index with no default value" vector-value index)))))))))
  371. ;;;
  372. ;;; Mutable Collections
  373. ;;;
  374. (add-method dylan:setter/current-element/
  375. (dylan::function->method
  376. (make-param-list
  377. `((SOV ,<simple-object-vector>) (STATE ,<object>) (new-value ,<object>))
  378. #F #F #F)
  379. (lambda (sov state new-value)
  380. (vector-set! sov (vector-ref state 0) new-value)
  381. new-value)))
  382. (add-method dylan:setter/current-element/
  383. (dylan::function->method
  384. (make-param-list `((STRETCHY-VECTOR ,<stretchy-vector>)
  385. (STATE ,<object>)
  386. (new-value ,<object>))
  387. #F #F #F)
  388. (lambda (st-vector state new-value)
  389. (vector-set! (dylan-call dylan:get-array-value st-vector)
  390. (vector-ref state 0) new-value)
  391. new-value)))
  392. (add-method dylan:setter/element/
  393. (dylan::function->method
  394. (make-param-list
  395. `((VECTOR ,<vector>) (INDEX ,<object>) (NEW-VALUE ,<object>)) #F #F #F)
  396. (lambda (vector-instance index new-value)
  397. (let ((vector (dylan-call dylan:get-array-value vector-instance)))
  398. (vector-set! vector index new-value)
  399. new-value))))