Kernel-Collections.st 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784
  1. Smalltalk current createPackage: 'Kernel-Collections' properties: #{}!
  2. Object subclass: #Association
  3. instanceVariableNames: 'key value'
  4. package: 'Kernel-Collections'!
  5. !Association methodsFor: 'accessing'!
  6. key
  7. ^key
  8. !
  9. key: aKey
  10. key := aKey
  11. !
  12. value
  13. ^value
  14. !
  15. value: aValue
  16. value := aValue
  17. ! !
  18. !Association methodsFor: 'comparing'!
  19. = anAssociation
  20. ^self class = anAssociation class and: [
  21. self key = anAssociation key and: [
  22. self value = anAssociation value]]
  23. ! !
  24. !Association methodsFor: 'printing'!
  25. printString
  26. "print the contents of the Association into a string and return the string"
  27. ^String streamContents: [:aStream |
  28. self storeOn: aStream]
  29. !
  30. storeOn: aStream
  31. "Store in the format: key->value"
  32. key storeOn: aStream.
  33. aStream nextPutAll: '->'.
  34. value storeOn: aStream.
  35. ! !
  36. !Association class methodsFor: 'instance creation'!
  37. key: aKey value: aValue
  38. ^self new
  39. key: aKey;
  40. value: aValue;
  41. yourself
  42. ! !
  43. Object subclass: #Collection
  44. instanceVariableNames: ''
  45. package: 'Kernel-Collections'!
  46. !Collection methodsFor: 'accessing'!
  47. occurrencesOf: anObject
  48. "Answer how many of the receiver's elements are equal to anObject."
  49. | tally |
  50. tally := 0.
  51. self do: [:each | anObject = each ifTrue: [tally := tally + 1]].
  52. ^tally
  53. !
  54. readStream
  55. ^self stream
  56. !
  57. size
  58. self subclassResponsibility
  59. !
  60. stream
  61. ^self streamClass on: self
  62. !
  63. streamClass
  64. ^self class streamClass
  65. !
  66. writeStream
  67. ^self stream
  68. ! !
  69. !Collection methodsFor: 'adding/removing'!
  70. add: anObject
  71. self subclassResponsibility
  72. !
  73. addAll: aCollection
  74. aCollection do: [:each |
  75. self add: each].
  76. ^aCollection
  77. !
  78. remove: anObject
  79. ^self remove: anObject ifAbsent: [self errorNotFound]
  80. !
  81. remove: anObject ifAbsent: aBlock
  82. self subclassResponsibility
  83. ! !
  84. !Collection methodsFor: 'converting'!
  85. asArray
  86. ^Array withAll: self
  87. !
  88. asJSON
  89. ^self asArray collect: [:each | each asJSON]
  90. !
  91. asOrderedCollection
  92. ^self asArray
  93. !
  94. asSet
  95. ^Set withAll: self
  96. ! !
  97. !Collection methodsFor: 'copying'!
  98. , aCollection
  99. ^self copy
  100. addAll: aCollection;
  101. yourself
  102. !
  103. copyWith: anObject
  104. ^self copy add: anObject; yourself
  105. !
  106. copyWithAll: aCollection
  107. ^self copy addAll: aCollection; yourself
  108. !
  109. copyWithoutAll: aCollection
  110. "Answer a copy of the receiver that does not contain any elements
  111. equal to those in aCollection."
  112. ^ self reject: [:each | aCollection includes: each]
  113. ! !
  114. !Collection methodsFor: 'enumerating'!
  115. collect: aBlock
  116. | stream |
  117. stream := self class new writeStream.
  118. self do: [ :each |
  119. stream nextPut: (aBlock value: each) ].
  120. ^stream contents
  121. !
  122. detect: aBlock
  123. ^self detect: aBlock ifNone: [self errorNotFound]
  124. !
  125. detect: aBlock ifNone: anotherBlock
  126. self subclassResponsibility
  127. !
  128. do: aBlock
  129. self subclassResponsibility
  130. !
  131. do: aBlock separatedBy: anotherBlock
  132. | actionBeforeElement |
  133. actionBeforeElement := [actionBeforeElement := anotherBlock].
  134. self do: [:each |
  135. actionBeforeElement value.
  136. aBlock value: each]
  137. !
  138. inject: anObject into: aBlock
  139. | result |
  140. result := anObject.
  141. self do: [:each |
  142. result := aBlock value: result value: each].
  143. ^result
  144. !
  145. intersection: aCollection
  146. "Answer the set theoretic intersection of two collections."
  147. | set outputSet |
  148. set := self asSet.
  149. outputSet := Set new.
  150. aCollection do: [ :each |
  151. ((set includes: each) and: [(outputSet includes: each) not])
  152. ifTrue: [
  153. outputSet add: each]].
  154. ^ self class withAll: outputSet asArray
  155. !
  156. reject: aBlock
  157. ^self select: [:each | (aBlock value: each) = false]
  158. !
  159. select: aBlock
  160. | stream |
  161. stream := self class new writeStream.
  162. self do: [:each |
  163. (aBlock value: each) ifTrue: [
  164. stream nextPut: each]].
  165. ^stream contents
  166. ! !
  167. !Collection methodsFor: 'error handling'!
  168. errorNotFound
  169. self error: 'Object is not in the collection'
  170. ! !
  171. !Collection methodsFor: 'printing'!
  172. printString
  173. "print the contents of the Collection into a string and return it"
  174. ^String streamContents: [:aStream |
  175. aStream
  176. nextPutAll: super printString, ' ('.
  177. self do: [:each | aStream nextPutAll: each printString]
  178. separatedBy: [aStream nextPutAll: ' '].
  179. aStream nextPutAll: ')']
  180. ! !
  181. !Collection methodsFor: 'testing'!
  182. ifEmpty: aBlock
  183. "Evaluate the given block with the receiver as argument, answering its value if the receiver is empty, otherwise answer the receiver. Note that the fact that this method returns its argument in case the receiver is not empty allows one to write expressions like the following ones: self classifyMethodAs:
  184. (myProtocol ifEmpty: ['As yet unclassified'])"
  185. ^ self isEmpty
  186. ifTrue: [ aBlock value ]
  187. ifFalse: [ self ]
  188. !
  189. ifNotEmpty: aBlock
  190. self notEmpty ifTrue: aBlock.
  191. !
  192. includes: anObject
  193. | sentinel |
  194. sentinel := Object new.
  195. ^(self detect: [ :each | each = anObject] ifNone: [ sentinel ]) ~= sentinel
  196. !
  197. isEmpty
  198. ^self size = 0
  199. !
  200. notEmpty
  201. ^self isEmpty not
  202. ! !
  203. !Collection class methodsFor: 'accessing'!
  204. streamClass
  205. ^Stream
  206. ! !
  207. !Collection class methodsFor: 'instance creation'!
  208. new: anInteger
  209. ^self new
  210. !
  211. with: anObject
  212. ^self new
  213. add: anObject;
  214. yourself
  215. !
  216. with: anObject with: anotherObject
  217. ^self new
  218. add: anObject;
  219. add: anotherObject;
  220. yourself
  221. !
  222. with: firstObject with: secondObject with: thirdObject
  223. ^self new
  224. add: firstObject;
  225. add: secondObject;
  226. add: thirdObject;
  227. yourself
  228. !
  229. withAll: aCollection
  230. ^self new
  231. addAll: aCollection;
  232. yourself
  233. ! !
  234. Collection subclass: #IndexableCollection
  235. instanceVariableNames: ''
  236. package: 'Kernel-Collections'!
  237. IndexableCollection subclass: #HashedCollection
  238. instanceVariableNames: ''
  239. package: 'Kernel-Collections'!
  240. !HashedCollection commentStamp!
  241. A HashedCollection is a traditional JavaScript object, or a Smalltalk Dictionary.
  242. Unlike a Dictionary, it can only have strings as keys.!
  243. !HashedCollection methodsFor: 'accessing'!
  244. associations
  245. | associations |
  246. associations := #().
  247. self associationsDo: [:each | associations add: each].
  248. ^associations
  249. !
  250. at: aKey
  251. ^self at: aKey ifAbsent: [self errorNotFound]
  252. !
  253. at: aKey ifAbsent: aBlock
  254. ^(self includesKey: aKey)
  255. ifTrue: [self basicAt: aKey]
  256. ifFalse: aBlock
  257. !
  258. at: aKey ifAbsentPut: aBlock
  259. ^self at: aKey ifAbsent: [
  260. self at: aKey put: aBlock value]
  261. !
  262. at: aKey ifPresent: aBlock
  263. "Lookup the given key in the receiver.
  264. If it is present, answer the value of evaluating the given block with the value associated with the key.
  265. Otherwise, answer nil."
  266. ^(self includesKey: aKey)
  267. ifTrue: [ aBlock value: (self at: aKey) ]
  268. ifFalse: [ nil ]
  269. !
  270. at: aKey ifPresent: aBlock ifAbsent: anotherBlock
  271. "Lookup the given key in the receiver.
  272. If it is present, answer the value of evaluating the oneArgBlock with the value associated with the key,
  273. otherwise answer the value of absentBlock."
  274. ^(self includesKey: aKey)
  275. ifTrue: [ aBlock value: (self at: aKey) ]
  276. ifFalse: anotherBlock
  277. !
  278. at: aKey put: aValue
  279. ^self basicAt: aKey put: aValue
  280. !
  281. keys
  282. <
  283. if ('function'===typeof Object.keys) return Object.keys(self);
  284. var keys = [];
  285. for(var i in self) {
  286. if(self.hasOwnProperty(i)) {
  287. keys.push(i);
  288. }
  289. };
  290. return keys;
  291. >
  292. !
  293. size
  294. ^self keys size
  295. !
  296. values
  297. ^self keys collect: [:each | self at: each]
  298. ! !
  299. !HashedCollection methodsFor: 'adding/removing'!
  300. add: anAssociation
  301. self at: anAssociation key put: anAssociation value
  302. !
  303. addAll: aHashedCollection
  304. super addAll: aHashedCollection associations.
  305. ^aHashedCollection
  306. !
  307. remove: aKey ifAbsent: aBlock
  308. ^self removeKey: aKey ifAbsent: aBlock
  309. !
  310. removeKey: aKey
  311. ^self remove: aKey
  312. !
  313. removeKey: aKey ifAbsent: aBlock
  314. ^(self includesKey: aKey)
  315. ifFalse: [aBlock value]
  316. ifTrue: [self basicDelete: aKey]
  317. ! !
  318. !HashedCollection methodsFor: 'comparing'!
  319. = aHashedCollection
  320. self class = aHashedCollection class ifFalse: [^false].
  321. self size = aHashedCollection size ifFalse: [^false].
  322. ^self associations = aHashedCollection associations
  323. ! !
  324. !HashedCollection methodsFor: 'converting'!
  325. asDictionary
  326. ^Dictionary fromPairs: self associations
  327. !
  328. asJSON
  329. | c |
  330. c := self class new.
  331. self keysAndValuesDo: [:key :value |
  332. c at: key put: value asJSON].
  333. ^c
  334. ! !
  335. !HashedCollection methodsFor: 'copying'!
  336. , aCollection
  337. self shouldNotImplement
  338. !
  339. deepCopy
  340. | copy |
  341. copy := self class new.
  342. self keysAndValuesDo: [:key :value |
  343. copy at: key put: value deepCopy].
  344. ^copy
  345. !
  346. shallowCopy
  347. | copy |
  348. copy := self class new.
  349. self keysAndValuesDo: [:key :value |
  350. copy at: key put: value].
  351. ^copy
  352. ! !
  353. !HashedCollection methodsFor: 'enumerating'!
  354. associationsDo: aBlock
  355. self keysAndValuesDo: [:key :value |
  356. aBlock value: (Association key: key value: value)]
  357. !
  358. collect: aBlock
  359. | newDict |
  360. newDict := self class new.
  361. self keysAndValuesDo: [:key :value |
  362. newDict at: key put: (aBlock value: value)].
  363. ^newDict
  364. !
  365. detect: aBlock ifNone: anotherBlock
  366. ^self values detect: aBlock ifNone: anotherBlock
  367. !
  368. do: aBlock
  369. self valuesDo: aBlock
  370. !
  371. includes: anObject
  372. ^self values includes: anObject
  373. !
  374. keysAndValuesDo: aBlock
  375. self keysDo: [:each |
  376. aBlock value: each value: (self at: each)]
  377. !
  378. keysDo: aBlock
  379. self keys do: aBlock
  380. !
  381. select: aBlock
  382. | newDict |
  383. newDict := self class new.
  384. self keysAndValuesDo: [:key :value |
  385. (aBlock value: value) ifTrue: [newDict at: key put: value]].
  386. ^newDict
  387. !
  388. valuesDo: aBlock
  389. self keysAndValuesDo: [ :key :value | aBlock value: value ]
  390. ! !
  391. !HashedCollection methodsFor: 'printing'!
  392. printString
  393. "print the contents of the HashedCollection into a string and return the string"
  394. ^String streamContents: [:aStream |
  395. aStream nextPutAll: 'a ', self class name, '('.
  396. self associations
  397. do: [:each | each storeOn: aStream]
  398. separatedBy: [ aStream nextPutAll: ' , '].
  399. aStream nextPutAll: ')']
  400. !
  401. storeOn: aStream
  402. aStream nextPutAll: '#{'.
  403. self associations
  404. do: [:each | each storeOn: aStream]
  405. separatedBy: [ aStream nextPutAll: '. '].
  406. aStream nextPutAll: '}'
  407. ! !
  408. !HashedCollection methodsFor: 'testing'!
  409. includesKey: aKey
  410. <return self.hasOwnProperty(aKey)>
  411. ! !
  412. !HashedCollection class methodsFor: 'instance creation'!
  413. fromPairs: aCollection
  414. | dict |
  415. dict := self new.
  416. aCollection do: [:each | dict add: each].
  417. ^dict
  418. ! !
  419. HashedCollection subclass: #Dictionary
  420. instanceVariableNames: 'keys values'
  421. package: 'Kernel-Collections'!
  422. !Dictionary methodsFor: 'accessing'!
  423. at: aKey ifAbsent: aBlock
  424. <
  425. var index = self._positionOfKey_(aKey);
  426. return index >>=0 ? self['@values'][index] : aBlock();
  427. >
  428. !
  429. at: aKey put: aValue
  430. <
  431. var index = self._positionOfKey_(aKey);
  432. if(index === -1) {
  433. var keys = self['@keys'];
  434. index = keys.length;
  435. keys.push(aKey);
  436. }
  437. return self['@values'][index] = aValue;
  438. >
  439. !
  440. keyAtValue: anObject
  441. ^ (self associations
  442. detect:[:k :v| v == anObject]
  443. ifNone:[self error: 'Not found']) key
  444. !
  445. keys
  446. ^keys copy
  447. !
  448. values
  449. ^values copy
  450. ! !
  451. !Dictionary methodsFor: 'adding/removing'!
  452. removeKey: aKey ifAbsent: aBlock
  453. <
  454. var index = self._positionOfKey_(aKey);
  455. if(index === -1) {
  456. return aBlock()
  457. } else {
  458. var keys = self['@keys'], values = self['@values'];
  459. var value = values[index], l = keys.length;
  460. keys[index] = keys[l-1];
  461. keys.pop();
  462. values[index] = values[l-1];
  463. values.pop();
  464. return value;
  465. }
  466. >
  467. ! !
  468. !Dictionary methodsFor: 'converting'!
  469. asHashedCollection
  470. ^HashedCollection fromPairs: self associations
  471. !
  472. asJSON
  473. ^self asHashedCollection asJSON
  474. ! !
  475. !Dictionary methodsFor: 'enumerating'!
  476. keysAndValuesDo: aBlock
  477. ^keys with: values do: aBlock
  478. !
  479. keysDo: aBlock
  480. ^keys do: aBlock
  481. !
  482. valuesDo: aBlock
  483. ^values do: aBlock
  484. ! !
  485. !Dictionary methodsFor: 'initialization'!
  486. initialize
  487. super initialize.
  488. keys := #().
  489. values := #()
  490. ! !
  491. !Dictionary methodsFor: 'private'!
  492. positionOfKey: anObject
  493. <
  494. var keys = self['@keys'];
  495. for(var i=0;i<keys.length;i++){
  496. if(keys[i].__eq(anObject)) { return i;}
  497. }
  498. return -1;
  499. >
  500. ! !
  501. !Dictionary methodsFor: 'testing'!
  502. includesKey: aKey
  503. < return self._positionOfKey_(aKey) >>= 0; >
  504. ! !
  505. Collection subclass: #SequenceableCollection
  506. instanceVariableNames: ''
  507. package: 'Kernel-Collections'!
  508. !SequenceableCollection methodsFor: 'accessing'!
  509. allButFirst
  510. ^self copyFrom: 2 to: self size
  511. !
  512. allButLast
  513. ^self copyFrom: 1 to: self size - 1
  514. !
  515. at: anIndex
  516. ^self at: anIndex ifAbsent: [
  517. self errorNotFound]
  518. !
  519. at: anIndex ifAbsent: aBlock
  520. self subclassResponsibility
  521. !
  522. at: anIndex put: anObject
  523. self subclassResponsibility
  524. !
  525. atRandom
  526. ^ self at: self size atRandom
  527. !
  528. first
  529. ^self at: 1
  530. !
  531. first: n
  532. "Answer the first n elements of the receiver.
  533. Raise an error if there are not enough elements."
  534. ^ self copyFrom: 1 to: n
  535. !
  536. fourth
  537. ^self at: 4
  538. !
  539. indexOf: anObject
  540. ^self indexOf: anObject ifAbsent: [self errorNotFound]
  541. !
  542. indexOf: anObject ifAbsent: aBlock
  543. <
  544. for(var i=0;i<self.length;i++) {
  545. if(self[i].__eq(anObject)) {return i+1}
  546. };
  547. return aBlock();
  548. >
  549. !
  550. indexOf: anObject startingAt: start
  551. "Answer the index of the first occurence of anElement after start
  552. within the receiver. If the receiver does not contain anElement,
  553. answer 0."
  554. ^self indexOf: anObject startingAt: start ifAbsent: [0]
  555. !
  556. indexOf: anObject startingAt: start ifAbsent: aBlock
  557. <
  558. for(var i=start-1;i<self.length;i++){
  559. if(self[i].__eq(anObject)) {return i+1}
  560. }
  561. return aBlock();
  562. >
  563. !
  564. last
  565. ^self at: self size
  566. !
  567. second
  568. ^self at: 2
  569. !
  570. third
  571. ^self at: 3
  572. ! !
  573. !SequenceableCollection methodsFor: 'adding'!
  574. addLast: anObject
  575. self add: anObject
  576. !
  577. removeLast
  578. self remove: self last
  579. ! !
  580. !SequenceableCollection methodsFor: 'comparing'!
  581. = aCollection
  582. (self class = aCollection class and: [
  583. self size = aCollection size]) ifFalse: [^false].
  584. self withIndexDo: [:each :i |
  585. (aCollection at: i) = each ifFalse: [^false]].
  586. ^true
  587. ! !
  588. !SequenceableCollection methodsFor: 'converting'!
  589. reversed
  590. self subclassResponsibility
  591. ! !
  592. !SequenceableCollection methodsFor: 'copying'!
  593. copyFrom: anIndex to: anotherIndex
  594. | range newCollection |
  595. range := anIndex to: anotherIndex.
  596. newCollection := self class new: range size.
  597. range withIndexDo: [:each :i |
  598. newCollection at: i put: (self at: each)].
  599. ^newCollection
  600. !
  601. deepCopy
  602. | newCollection |
  603. newCollection := self class new: self size.
  604. self withIndexDo: [:each :index |
  605. newCollection at: index put: each deepCopy].
  606. ^newCollection
  607. !
  608. shallowCopy
  609. | newCollection |
  610. newCollection := self class new: self size.
  611. self withIndexDo: [ :each :index |
  612. newCollection at: index put: each].
  613. ^newCollection
  614. ! !
  615. !SequenceableCollection methodsFor: 'enumerating'!
  616. detect: aBlock ifNone: anotherBlock
  617. <
  618. for(var i = 0; i < self.length; i++)
  619. if(aBlock(self[i]))
  620. return self[i];
  621. return anotherBlock();
  622. >
  623. !
  624. do: aBlock
  625. <for(var i=0;i<self.length;i++){aBlock(self[i]);}>
  626. !
  627. with: anotherCollection do: aBlock
  628. <for(var i=0;i<self.length;i++){aBlock(self[i], anotherCollection[i]);}>
  629. !
  630. withIndexDo: aBlock
  631. <for(var i=0;i<self.length;i++){aBlock(self[i], i+1);}>
  632. ! !
  633. !SequenceableCollection methodsFor: 'testing'!
  634. includes: anObject
  635. ^(self indexOf: anObject ifAbsent: [nil]) notNil
  636. ! !
  637. SequenceableCollection subclass: #Array
  638. instanceVariableNames: ''
  639. package: 'Kernel-Collections'!
  640. !Array methodsFor: 'accessing'!
  641. at: anIndex ifAbsent: aBlock
  642. <
  643. if((anIndex < 1) || (self.length < anIndex)) {return aBlock()};
  644. return self[anIndex - 1];
  645. >
  646. !
  647. at: anIndex put: anObject
  648. <return self[anIndex - 1] = anObject>
  649. !
  650. size
  651. <return self.length>
  652. ! !
  653. !Array methodsFor: 'adding/removing'!
  654. add: anObject
  655. <self.push(anObject); return anObject;>
  656. !
  657. remove: anObject ifAbsent: aBlock
  658. <
  659. for(var i=0;i<self.length;i++) {
  660. if(self[i] == anObject) {
  661. self.splice(i,1);
  662. return self;
  663. }
  664. };
  665. aBlock._value();
  666. >
  667. !
  668. removeFrom: aNumber to: anotherNumber
  669. <self.splice(aNumber - 1,anotherNumber - 1)>
  670. ! !
  671. !Array methodsFor: 'converting'!
  672. asJavascript
  673. ^'[', ((self collect: [:each | each asJavascript]) join: ', '), ']'
  674. !
  675. reversed
  676. <return self._copy().reverse()>
  677. ! !
  678. !Array methodsFor: 'enumerating'!
  679. join: aString
  680. <return self.join(aString)>
  681. !
  682. sort
  683. ^self basicPerform: 'sort'
  684. !
  685. sort: aBlock
  686. <
  687. return self.sort(function(a, b) {
  688. if(aBlock(a,b)) {return -1} else {return 1}
  689. })
  690. >
  691. !
  692. sorted
  693. ^self copy sort
  694. !
  695. sorted: aBlock
  696. ^self copy sort: aBlock
  697. ! !
  698. !Array class methodsFor: 'instance creation'!
  699. new: anInteger
  700. <return new Array(anInteger)>
  701. !
  702. with: anObject
  703. ^(self new: 1)
  704. at: 1 put: anObject;
  705. yourself
  706. !
  707. with: anObject with: anObject2
  708. ^(self new: 2)
  709. at: 1 put: anObject;
  710. at: 2 put: anObject2;
  711. yourself
  712. !
  713. with: anObject with: anObject2 with: anObject3
  714. ^(self new: 3)
  715. at: 1 put: anObject;
  716. at: 2 put: anObject2;
  717. at: 3 put: anObject3;
  718. yourself
  719. !
  720. withAll: aCollection
  721. | instance index |
  722. index := 1.
  723. instance := self new: aCollection size.
  724. aCollection do: [:each |
  725. instance at: index put: each.
  726. index := index + 1].
  727. ^instance
  728. ! !
  729. SequenceableCollection subclass: #CharacterArray
  730. instanceVariableNames: ''
  731. package: 'Kernel-Collections'!
  732. !CharacterArray methodsFor: 'accessing'!
  733. at: anIndex put: anObject
  734. self errorReadOnly
  735. ! !
  736. !CharacterArray methodsFor: 'adding'!
  737. add: anObject
  738. self errorReadOnly
  739. !
  740. remove: anObject
  741. self errorReadOnly
  742. ! !
  743. !CharacterArray methodsFor: 'converting'!
  744. asLowercase
  745. ^self class fromString: self asString asLowercase
  746. !
  747. asNumber
  748. ^self asString asNumber
  749. !
  750. asString
  751. ^self subclassResponsibility
  752. !
  753. asSymbol
  754. ^self subclassResponsibility
  755. !
  756. asUppercase
  757. ^self class fromString: self asString asUppercase
  758. ! !
  759. !CharacterArray methodsFor: 'copying'!
  760. , aString
  761. ^self asString, aString asString
  762. ! !
  763. !CharacterArray methodsFor: 'error handling'!
  764. errorReadOnly
  765. self error: 'Object is read-only'
  766. ! !
  767. !CharacterArray methodsFor: 'printing'!
  768. printString
  769. ^self asString printString
  770. ! !
  771. !CharacterArray class methodsFor: 'instance creation'!
  772. fromString: aString
  773. self subclassResponsibility
  774. ! !
  775. CharacterArray subclass: #String
  776. instanceVariableNames: ''
  777. package: 'Kernel-Collections'!
  778. !String methodsFor: 'accessing'!
  779. asciiValue
  780. <return self.charCodeAt(0);>
  781. !
  782. at: anIndex ifAbsent: aBlock
  783. <return String(self).charAt(anIndex - 1) || aBlock()>
  784. !
  785. escaped
  786. <return escape(self)>
  787. !
  788. size
  789. <return self.length>
  790. !
  791. unescaped
  792. <return unescape(self)>
  793. ! !
  794. !String methodsFor: 'comparing'!
  795. < aString
  796. <return String(self) < aString._asString()>
  797. !
  798. <= aString
  799. <return String(self) <= aString._asString()>
  800. !
  801. = aString
  802. <
  803. if(!! aString._isString || !! aString._isString()) {
  804. return false;
  805. }
  806. return String(self) === String(aString)
  807. >
  808. !
  809. == aString
  810. ^self = aString
  811. !
  812. > aString
  813. <return String(self) >> aString._asString()>
  814. !
  815. >= aString
  816. <return String(self) >>= aString._asString()>
  817. ! !
  818. !String methodsFor: 'converting'!
  819. asJSON
  820. ^self
  821. !
  822. asJavaScriptSelector
  823. ^(self asSelector replace: '^_' with: '') replace: '_.*' with: ''.
  824. !
  825. asJavascript
  826. <
  827. if(self.search(/^[a-zA-Z0-9_:.$ ]*$/) == -1)
  828. return "\"" + self.replace(/[\x00-\x1f"\\\x7f-\x9f]/g, function(ch){var c=ch.charCodeAt(0);return "\\x"+("0"+c.toString(16)).slice(-2)}) + "\"";
  829. else
  830. return "\"" + self + "\"";
  831. >
  832. !
  833. asLowercase
  834. <return self.toLowerCase()>
  835. !
  836. asNumber
  837. <return Number(self)>
  838. !
  839. asRegexp
  840. ^ RegularExpression fromString: self
  841. !
  842. asSelector
  843. <return smalltalk.selector(self)>
  844. !
  845. asString
  846. ^self
  847. !
  848. asSymbol
  849. ^Symbol lookup: self
  850. !
  851. asUppercase
  852. <return self.toUpperCase()>
  853. !
  854. reversed
  855. <return self.split("").reverse().join("")>
  856. !
  857. tokenize: aString
  858. <return self.split(aString)>
  859. ! !
  860. !String methodsFor: 'copying'!
  861. , aString
  862. <return self + aString>
  863. !
  864. copyFrom: anIndex to: anotherIndex
  865. <return self.substring(anIndex - 1, anotherIndex)>
  866. !
  867. deepCopy
  868. ^self shallowCopy
  869. !
  870. shallowCopy
  871. ^self class fromString: self
  872. ! !
  873. !String methodsFor: 'enumerating'!
  874. do: aBlock
  875. <for(var i=0;i<self.length;i++){aBlock(self.charAt(i));}>
  876. !
  877. withIndexDo: aBlock
  878. <for(var i=0;i<self.length;i++){aBlock(self.charAt(i), i+1);}>
  879. ! !
  880. !String methodsFor: 'printing'!
  881. printNl
  882. <console.log(self)>
  883. !
  884. printString
  885. ^'''', self, ''''
  886. ! !
  887. !String methodsFor: 'regular expressions'!
  888. match: aRegexp
  889. <return self.search(aRegexp) !!= -1>
  890. !
  891. matchesOf: aRegularExpression
  892. <return self.match(aRegularExpression)>
  893. !
  894. replace: aString with: anotherString
  895. ^self replaceRegexp: (RegularExpression fromString: aString flag: 'g') with: anotherString
  896. !
  897. replaceRegexp: aRegexp with: aString
  898. <return self.replace(aRegexp, aString)>
  899. !
  900. trimBoth
  901. ^self trimBoth: '\s'
  902. !
  903. trimBoth: separators
  904. ^(self trimLeft: separators) trimRight: separators
  905. !
  906. trimLeft
  907. ^self trimLeft: '\s'
  908. !
  909. trimLeft: separators
  910. ^self replaceRegexp: (RegularExpression fromString: '^[', separators, ']+' flag: 'g') with: ''
  911. !
  912. trimRight
  913. ^self trimRight: '\s'
  914. !
  915. trimRight: separators
  916. ^self replaceRegexp: (RegularExpression fromString: '[', separators, ']+$' flag: 'g') with: ''
  917. ! !
  918. !String methodsFor: 'split join'!
  919. join: aCollection
  920. ^ String
  921. streamContents: [:stream | aCollection
  922. do: [:each | stream nextPutAll: each asString]
  923. separatedBy: [stream nextPutAll: self]]
  924. !
  925. lineIndicesDo: aBlock
  926. "execute aBlock with 3 arguments for each line:
  927. - start index of line
  928. - end index of line without line delimiter
  929. - end index of line including line delimiter(s) CR, LF or CRLF"
  930. | cr lf start sz nextLF nextCR |
  931. start := 1.
  932. sz := self size.
  933. cr := String cr.
  934. nextCR := self indexOf: cr startingAt: 1.
  935. lf := String lf.
  936. nextLF := self indexOf: lf startingAt: 1.
  937. [ start <= sz ] whileTrue: [
  938. (nextLF = 0 and: [ nextCR = 0 ])
  939. ifTrue: [ "No more CR, nor LF, the string is over"
  940. aBlock value: start value: sz value: sz.
  941. ^self ].
  942. (nextCR = 0 or: [ 0 < nextLF and: [ nextLF < nextCR ] ])
  943. ifTrue: [ "Found a LF"
  944. aBlock value: start value: nextLF - 1 value: nextLF.
  945. start := 1 + nextLF.
  946. nextLF := self indexOf: lf startingAt: start ]
  947. ifFalse: [ 1 + nextCR = nextLF
  948. ifTrue: [ "Found a CR-LF pair"
  949. aBlock value: start value: nextCR - 1 value: nextLF.
  950. start := 1 + nextLF.
  951. nextCR := self indexOf: cr startingAt: start.
  952. nextLF := self indexOf: lf startingAt: start ]
  953. ifFalse: [ "Found a CR"
  954. aBlock value: start value: nextCR - 1 value: nextCR.
  955. start := 1 + nextCR.
  956. nextCR := self indexOf: cr startingAt: start ]]]
  957. !
  958. lineNumber: anIndex
  959. "Answer a string containing the characters in the given line number."
  960. | lineCount |
  961. lineCount := 0.
  962. self lineIndicesDo: [:start :endWithoutDelimiters :end |
  963. (lineCount := lineCount + 1) = anIndex ifTrue: [^self copyFrom: start to: endWithoutDelimiters]].
  964. ^nil
  965. !
  966. lines
  967. "Answer an array of lines composing this receiver without the line ending delimiters."
  968. | lines |
  969. lines := Array new.
  970. self linesDo: [:aLine | lines add: aLine].
  971. ^lines
  972. !
  973. linesDo: aBlock
  974. "Execute aBlock with each line in this string. The terminating line
  975. delimiters CR, LF or CRLF pairs are not included in what is passed to aBlock"
  976. self lineIndicesDo: [:start :endWithoutDelimiters :end |
  977. aBlock value: (self copyFrom: start to: endWithoutDelimiters)]
  978. ! !
  979. !String methodsFor: 'testing'!
  980. includesSubString: subString
  981. < return self.indexOf(subString) !!= -1 >
  982. !
  983. isString
  984. ^true
  985. ! !
  986. !String class methodsFor: 'accessing'!
  987. cr
  988. <return '\r'>
  989. !
  990. crlf
  991. <return '\r\n'>
  992. !
  993. lf
  994. <return '\n'>
  995. !
  996. space
  997. <return ' '>
  998. !
  999. streamClass
  1000. ^StringStream
  1001. !
  1002. tab
  1003. <return '\t'>
  1004. ! !
  1005. !String class methodsFor: 'instance creation'!
  1006. fromCharCode: anInteger
  1007. <return String.fromCharCode(anInteger)>
  1008. !
  1009. fromString: aString
  1010. <return new self.fn(aString)>
  1011. !
  1012. streamContents: blockWithArg
  1013. |stream|
  1014. stream := (self streamClass on: String new).
  1015. blockWithArg value: stream.
  1016. ^ stream contents
  1017. !
  1018. value: aUTFCharCode
  1019. <return String.fromCharCode(aUTFCharCode);>
  1020. ! !
  1021. CharacterArray subclass: #Symbol
  1022. instanceVariableNames: ''
  1023. package: 'Kernel-Collections'!
  1024. !Symbol methodsFor: 'accessing'!
  1025. at: anIndex ifAbsent: aBlock
  1026. ^self asString at: anIndex ifAbsent: aBlock
  1027. !
  1028. size
  1029. ^self asString size
  1030. ! !
  1031. !Symbol methodsFor: 'comparing'!
  1032. < aSymbol
  1033. ^self asString < aSymbol asString
  1034. !
  1035. <= aSymbol
  1036. ^self asString <= aSymbol asString
  1037. !
  1038. = aSymbol
  1039. aSymbol class = self class ifFalse: [^false].
  1040. ^self asString = aSymbol asString
  1041. !
  1042. > aSymbol
  1043. ^self asString > aSymbol asString
  1044. !
  1045. >= aSymbol
  1046. ^self asString >= aSymbol asString
  1047. ! !
  1048. !Symbol methodsFor: 'converting'!
  1049. asJSON
  1050. ^self asString asJSON
  1051. !
  1052. asJavascript
  1053. ^'smalltalk.symbolFor(', self asString asJavascript, ')'
  1054. !
  1055. asSelector
  1056. ^self asString asSelector
  1057. !
  1058. asString
  1059. <return self.value>
  1060. !
  1061. asSuperSelector
  1062. ^self asString asSuperSelector
  1063. !
  1064. asSymbol
  1065. ^self
  1066. ! !
  1067. !Symbol methodsFor: 'copying'!
  1068. copyFrom: anIndex to: anotherIndex
  1069. ^self class fromString: (self asString copyFrom: anIndex to: anotherIndex)
  1070. !
  1071. deepCopy
  1072. ^self
  1073. !
  1074. shallowCopy
  1075. ^self
  1076. ! !
  1077. !Symbol methodsFor: 'enumerating'!
  1078. collect: aBlock
  1079. ^ (self asString collect: aBlock) asSymbol
  1080. !
  1081. detect: aBlock
  1082. ^ self asString detect: aBlock
  1083. !
  1084. do: aBlock
  1085. self asString do: aBlock
  1086. !
  1087. select: aBlock
  1088. ^ (self asString select: aBlock) asSymbol
  1089. !
  1090. withIndexDo: aBlock
  1091. self asString withIndexDo: aBlock
  1092. ! !
  1093. !Symbol methodsFor: 'evaluating'!
  1094. value: anObject
  1095. ^anObject perform: self
  1096. ! !
  1097. !Symbol methodsFor: 'printing'!
  1098. isSymbol
  1099. ^true
  1100. !
  1101. printString
  1102. ^'#', self asString
  1103. ! !
  1104. !Symbol class methodsFor: 'instance creation'!
  1105. basicNew
  1106. self shouldNotImplement
  1107. !
  1108. fromString: aString
  1109. ^self lookup: aString
  1110. !
  1111. lookup: aString
  1112. <return smalltalk.symbolFor(aString);>
  1113. ! !
  1114. Collection subclass: #Set
  1115. instanceVariableNames: 'elements'
  1116. package: 'Kernel-Collections'!
  1117. !Set methodsFor: 'accessing'!
  1118. size
  1119. ^elements size
  1120. ! !
  1121. !Set methodsFor: 'adding/removing'!
  1122. add: anObject
  1123. <
  1124. var found;
  1125. for(var i=0; i < self['@elements'].length; i++) {
  1126. if(anObject == self['@elements'][i]) {
  1127. found = true;
  1128. break;
  1129. }
  1130. }
  1131. if(!!found) {self['@elements'].push(anObject)}
  1132. >
  1133. !
  1134. remove: anObject
  1135. elements remove: anObject
  1136. ! !
  1137. !Set methodsFor: 'comparing'!
  1138. = aCollection
  1139. self class = aCollection class ifFalse: [ ^ false ].
  1140. self size = aCollection size ifFalse: [ ^ false ].
  1141. self do: [:each | (aCollection includes: each) ifFalse: [ ^ false ] ].
  1142. ^ true
  1143. ! !
  1144. !Set methodsFor: 'converting'!
  1145. asArray
  1146. ^elements copy
  1147. ! !
  1148. !Set methodsFor: 'enumerating'!
  1149. collect: aBlock
  1150. ^self class withAll: (elements collect: aBlock)
  1151. !
  1152. detect: aBlock ifNone: anotherBlock
  1153. ^elements detect: aBlock ifNone: anotherBlock
  1154. !
  1155. do: aBlock
  1156. elements do: aBlock
  1157. !
  1158. select: aBlock
  1159. | collection |
  1160. collection := self class new.
  1161. self do: [:each |
  1162. (aBlock value: each) ifTrue: [
  1163. collection add: each]].
  1164. ^collection
  1165. ! !
  1166. !Set methodsFor: 'initialization'!
  1167. initialize
  1168. super initialize.
  1169. elements := #()
  1170. ! !
  1171. !Set methodsFor: 'testing'!
  1172. includes: anObject
  1173. ^elements includes: anObject
  1174. ! !
  1175. Object subclass: #Queue
  1176. instanceVariableNames: 'read readIndex write'
  1177. package: 'Kernel-Collections'!
  1178. !Queue commentStamp!
  1179. A Queue am a one-sided queue.
  1180. A Queue uses two OrderedCollections inside,
  1181. `read` is at the front, is not modified and only read using `readIndex`.
  1182. `write` is at the back and is appended new items.
  1183. When `read` is exhausted, `write` is promoted to `read` and new `write` is created.
  1184. As a consequence, no data moving is done by the Queue; write appending may do data moving
  1185. when growing `write`, but this is left to engine to implement as good as it chooses to.!
  1186. !Queue methodsFor: 'accessing'!
  1187. back: anObject
  1188. write add: anObject
  1189. !
  1190. front
  1191. ^self frontIfAbsent: [ self error: 'Cannot read from empty Queue.' ]
  1192. !
  1193. frontIfAbsent: aBlock
  1194. | result |
  1195. result := read at: readIndex ifAbsent: [
  1196. write isEmpty ifTrue: [
  1197. readIndex > 1 ifTrue: [ read := #(). readIndex := 1 ].
  1198. ^aBlock value ].
  1199. read := write.
  1200. readIndex := 1.
  1201. write := OrderedCollection new.
  1202. read first ].
  1203. read at: readIndex put: nil.
  1204. readIndex := readIndex + 1.
  1205. ^result
  1206. ! !
  1207. !Queue methodsFor: 'initialization'!
  1208. initialize
  1209. super initialize.
  1210. read := OrderedCollection new.
  1211. write := OrderedCollection new.
  1212. readIndex := 1
  1213. ! !
  1214. Object subclass: #RegularExpression
  1215. instanceVariableNames: ''
  1216. package: 'Kernel-Collections'!
  1217. !RegularExpression methodsFor: 'evaluating'!
  1218. compile: aString
  1219. <return self.compile(aString)>
  1220. !
  1221. exec: aString
  1222. <return self.exec(aString) || nil>
  1223. !
  1224. test: aString
  1225. <return self.test(aString)>
  1226. ! !
  1227. !RegularExpression class methodsFor: 'instance creation'!
  1228. fromString: aString
  1229. ^self fromString: aString flag: ''
  1230. !
  1231. fromString: aString flag: anotherString
  1232. <return new RegExp(aString, anotherString)>
  1233. ! !
  1234. Object subclass: #Stream
  1235. instanceVariableNames: 'collection position streamSize'
  1236. package: 'Kernel-Collections'!
  1237. !Stream methodsFor: 'accessing'!
  1238. collection
  1239. ^collection
  1240. !
  1241. contents
  1242. ^self collection
  1243. copyFrom: 1
  1244. to: self streamSize
  1245. !
  1246. position
  1247. ^position ifNil: [position := 0]
  1248. !
  1249. position: anInteger
  1250. position := anInteger
  1251. !
  1252. setCollection: aCollection
  1253. collection := aCollection
  1254. !
  1255. setStreamSize: anInteger
  1256. streamSize := anInteger
  1257. !
  1258. size
  1259. ^self streamSize
  1260. !
  1261. streamSize
  1262. ^streamSize
  1263. ! !
  1264. !Stream methodsFor: 'actions'!
  1265. close
  1266. !
  1267. flush
  1268. !
  1269. reset
  1270. self position: 0
  1271. !
  1272. resetContents
  1273. self reset.
  1274. self setStreamSize: 0
  1275. ! !
  1276. !Stream methodsFor: 'enumerating'!
  1277. do: aBlock
  1278. [self atEnd] whileFalse: [aBlock value: self next]
  1279. ! !
  1280. !Stream methodsFor: 'positioning'!
  1281. setToEnd
  1282. self position: self size
  1283. !
  1284. skip: anInteger
  1285. self position: ((self position + anInteger) min: self size max: 0)
  1286. ! !
  1287. !Stream methodsFor: 'reading'!
  1288. next
  1289. ^self atEnd
  1290. ifTrue: [nil]
  1291. ifFalse: [
  1292. self position: self position + 1.
  1293. collection at: self position]
  1294. !
  1295. next: anInteger
  1296. | tempCollection |
  1297. tempCollection := self collection class new.
  1298. anInteger timesRepeat: [
  1299. self atEnd ifFalse: [
  1300. tempCollection add: self next]].
  1301. ^tempCollection
  1302. !
  1303. peek
  1304. ^self atEnd ifFalse: [
  1305. self collection at: self position + 1]
  1306. ! !
  1307. !Stream methodsFor: 'testing'!
  1308. atEnd
  1309. ^self position = self size
  1310. !
  1311. atStart
  1312. ^self position = 0
  1313. !
  1314. isEmpty
  1315. ^self size = 0
  1316. ! !
  1317. !Stream methodsFor: 'writing'!
  1318. nextPut: anObject
  1319. self position: self position + 1.
  1320. self collection at: self position put: anObject.
  1321. self setStreamSize: (self streamSize max: self position)
  1322. !
  1323. nextPutAll: aCollection
  1324. aCollection do: [:each |
  1325. self nextPut: each]
  1326. ! !
  1327. !Stream class methodsFor: 'instance creation'!
  1328. on: aCollection
  1329. ^self new
  1330. setCollection: aCollection;
  1331. setStreamSize: aCollection size;
  1332. yourself
  1333. ! !
  1334. Stream subclass: #StringStream
  1335. instanceVariableNames: ''
  1336. package: 'Kernel-Collections'!
  1337. !StringStream methodsFor: 'reading'!
  1338. next: anInteger
  1339. | tempCollection |
  1340. tempCollection := self collection class new.
  1341. anInteger timesRepeat: [
  1342. self atEnd ifFalse: [
  1343. tempCollection := tempCollection, self next]].
  1344. ^tempCollection
  1345. ! !
  1346. !StringStream methodsFor: 'writing'!
  1347. cr
  1348. ^self nextPutAll: String cr
  1349. !
  1350. crlf
  1351. ^self nextPutAll: String crlf
  1352. !
  1353. lf
  1354. ^self nextPutAll: String lf
  1355. !
  1356. nextPut: aString
  1357. self nextPutAll: aString
  1358. !
  1359. nextPutAll: aString
  1360. self setCollection:
  1361. (self collection copyFrom: 1 to: self position),
  1362. aString,
  1363. (self collection copyFrom: (self position + 1 + aString size) to: self collection size).
  1364. self position: self position + aString size.
  1365. self setStreamSize: (self streamSize max: self position)
  1366. !
  1367. space
  1368. self nextPut: ' '
  1369. ! !