Kernel-Collections.st 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658
  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. <
  127. for(var i = 0; i < self.length; i++)
  128. if(aBlock(self[i]))
  129. return self[i];
  130. return anotherBlock();
  131. >
  132. !
  133. do: aBlock
  134. <for(var i=0;i<self.length;i++){aBlock(self[i]);}>
  135. !
  136. do: aBlock separatedBy: anotherBlock
  137. | first |
  138. first := true.
  139. self do: [:each |
  140. first
  141. ifTrue: [first := false]
  142. ifFalse: [anotherBlock value].
  143. aBlock value: each]
  144. !
  145. inject: anObject into: aBlock
  146. | result |
  147. result := anObject.
  148. self do: [:each |
  149. result := aBlock value: result value: each].
  150. ^result
  151. !
  152. reject: aBlock
  153. ^self select: [:each | (aBlock value: each) = false]
  154. !
  155. select: aBlock
  156. | stream |
  157. stream := self class new writeStream.
  158. self do: [:each |
  159. (aBlock value: each) ifTrue: [
  160. stream nextPut: each]].
  161. ^stream contents
  162. ! !
  163. !Collection methodsFor: 'error handling'!
  164. errorNotFound
  165. self error: 'Object is not in the collection'
  166. ! !
  167. !Collection methodsFor: 'printing'!
  168. printString
  169. "print the contents of the Collection into a string and return it"
  170. ^String streamContents: [:aStream |
  171. aStream
  172. nextPutAll: super printString, ' ('.
  173. self do: [:each | aStream nextPutAll: each printString]
  174. separatedBy: [aStream nextPutAll: ' '].
  175. aStream nextPutAll: ')']
  176. ! !
  177. !Collection methodsFor: 'testing'!
  178. ifEmpty: aBlock
  179. "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:
  180. (myProtocol ifEmpty: ['As yet unclassified'])"
  181. ^ self isEmpty
  182. ifTrue: [ aBlock value ]
  183. ifFalse: [ self ]
  184. !
  185. ifNotEmpty: aBlock
  186. self notEmpty ifTrue: aBlock.
  187. !
  188. includes: anObject
  189. <
  190. var i = self.length;
  191. while (i--) {
  192. if (smalltalk.send(self[i], "__eq", [anObject])) {return true;}
  193. }
  194. return false
  195. >
  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: #HashedCollection
  235. instanceVariableNames: ''
  236. package: 'Kernel-Collections'!
  237. !HashedCollection commentStamp!
  238. A HashedCollection is a traditional JavaScript object, or a Smalltalk Dictionary.
  239. Unlike a Dictionary, it can only have strings as keys.!
  240. !HashedCollection methodsFor: 'accessing'!
  241. associations
  242. | associations |
  243. associations := #().
  244. self keys do: [:each |
  245. associations add: (Association key: each value: (self at: each))].
  246. ^associations
  247. !
  248. at: aKey
  249. ^self at: aKey ifAbsent: [self errorNotFound]
  250. !
  251. at: aKey ifAbsent: aBlock
  252. ^(self includesKey: aKey)
  253. ifTrue: [self basicAt: aKey]
  254. ifFalse: aBlock
  255. !
  256. at: aKey ifAbsentPut: aBlock
  257. ^self at: aKey ifAbsent: [
  258. self at: aKey put: aBlock value]
  259. !
  260. at: aKey ifPresent: aBlock
  261. "Lookup the given key in the receiver.
  262. If it is present, answer the value of evaluating the given block with the value associated with the key.
  263. Otherwise, answer nil."
  264. ^(self includesKey: aKey)
  265. ifTrue: [ aBlock value: (self at: aKey) ]
  266. ifFalse: [ nil ]
  267. !
  268. at: aKey ifPresent: aBlock ifAbsent: anotherBlock
  269. "Lookup the given key in the receiver.
  270. If it is present, answer the value of evaluating the oneArgBlock with the value associated with the key,
  271. otherwise answer the value of absentBlock."
  272. ^(self includesKey: aKey)
  273. ifTrue: [ aBlock value: (self at: aKey) ]
  274. ifFalse: anotherBlock
  275. !
  276. at: aKey put: aValue
  277. ^self basicAt: aKey put: aValue
  278. !
  279. keys
  280. <
  281. if ('function'===typeof Object.keys) return Object.keys(self);
  282. var keys = [];
  283. for(var i in self) {
  284. if(self.hasOwnProperty(i)) {
  285. keys.push(i);
  286. }
  287. };
  288. return keys;
  289. >
  290. !
  291. size
  292. ^self keys size
  293. !
  294. values
  295. ^self keys collect: [:each | self at: each]
  296. ! !
  297. !HashedCollection methodsFor: 'adding/removing'!
  298. add: anAssociation
  299. self at: anAssociation key put: anAssociation value
  300. !
  301. addAll: aHashedCollection
  302. super addAll: aHashedCollection associations.
  303. ^aHashedCollection
  304. !
  305. remove: aKey ifAbsent: aBlock
  306. ^self removeKey: aKey ifAbsent: aBlock
  307. !
  308. removeKey: aKey
  309. ^self remove: aKey
  310. !
  311. removeKey: aKey ifAbsent: aBlock
  312. ^(self includesKey: aKey)
  313. ifFalse: [aBlock value]
  314. ifTrue: [self basicDelete: aKey]
  315. ! !
  316. !HashedCollection methodsFor: 'comparing'!
  317. = aHashedCollection
  318. self class = aHashedCollection class ifFalse: [^false].
  319. self size = aHashedCollection size ifFalse: [^false].
  320. ^self associations = aHashedCollection associations
  321. ! !
  322. !HashedCollection methodsFor: 'converting'!
  323. asDictionary
  324. ^Dictionary fromPairs: self associations
  325. !
  326. asJSON
  327. | c |
  328. c := self class new.
  329. self keysAndValuesDo: [:key :value |
  330. c at: key put: value asJSON].
  331. ^c
  332. ! !
  333. !HashedCollection methodsFor: 'copying'!
  334. , aCollection
  335. self shouldNotImplement
  336. !
  337. copyFrom: anIndex to: anotherIndex
  338. self shouldNotImplement
  339. !
  340. deepCopy
  341. | copy |
  342. copy := self class new.
  343. self associationsDo: [:each |
  344. copy at: each key put: each value deepCopy].
  345. ^copy
  346. !
  347. shallowCopy
  348. | copy |
  349. copy := self class new.
  350. self associationsDo: [:each |
  351. copy at: each key put: each value].
  352. ^copy
  353. ! !
  354. !HashedCollection methodsFor: 'enumerating'!
  355. associationsDo: aBlock
  356. self associations do: aBlock
  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 values do: aBlock
  370. !
  371. includes: anObject
  372. ^self values includes: anObject
  373. !
  374. keysAndValuesDo: aBlock
  375. self associationsDo: [:each |
  376. aBlock value: each key value: each value]
  377. !
  378. select: aBlock
  379. | newDict |
  380. newDict := self class new.
  381. self keysAndValuesDo: [:key :value |
  382. (aBlock value: value) ifTrue: [newDict at: key put: value]].
  383. ^newDict
  384. ! !
  385. !HashedCollection methodsFor: 'printing'!
  386. printString
  387. "print the contents of the HashedCollection into a string and return the string"
  388. ^String streamContents: [:aStream |
  389. aStream nextPutAll: 'a ', self class name, '('.
  390. self associations
  391. do: [:each | each storeOn: aStream]
  392. separatedBy: [ aStream nextPutAll: ' , '].
  393. aStream nextPutAll: ')']
  394. !
  395. storeOn: aStream
  396. aStream nextPutAll: '#{'.
  397. self associations
  398. do: [:each | each storeOn: aStream]
  399. separatedBy: [ aStream nextPutAll: '. '].
  400. aStream nextPutAll: '}'
  401. ! !
  402. !HashedCollection methodsFor: 'testing'!
  403. includesKey: aKey
  404. <return self.hasOwnProperty(aKey)>
  405. ! !
  406. !HashedCollection class methodsFor: 'instance creation'!
  407. fromPairs: aCollection
  408. | dict |
  409. dict := self new.
  410. aCollection do: [:each | dict add: each].
  411. ^dict
  412. ! !
  413. HashedCollection subclass: #Dictionary
  414. instanceVariableNames: 'keys values'
  415. package: 'Kernel-Collections'!
  416. !Dictionary methodsFor: 'accessing'!
  417. at: aKey ifAbsent: aBlock
  418. <
  419. var index;
  420. for(var i=0;i<self['@keys'].length;i++){
  421. if(self['@keys'][i].__eq(aKey)) {index = i;}
  422. };
  423. if(typeof index === 'undefined') {
  424. return aBlock();
  425. } else {
  426. return self['@values'][index];
  427. }
  428. >
  429. !
  430. at: aKey put: aValue
  431. <
  432. var index = self['@keys'].indexOf(aKey);
  433. if(index === -1) {
  434. self['@values'].push(aValue);
  435. self['@keys'].push(aKey);
  436. } else {
  437. self['@values'][index] = aValue;
  438. };
  439. return aValue;
  440. >
  441. !
  442. keys
  443. ^keys copy
  444. !
  445. values
  446. ^values copy
  447. ! !
  448. !Dictionary methodsFor: 'adding/removing'!
  449. removeKey: aKey ifAbsent: aBlock
  450. <
  451. var index = self['@keys'].indexOf(aKey);
  452. if(index === -1) {
  453. return aBlock()
  454. } else {
  455. var value;
  456. self['@keys'].splice(index, 1);
  457. value = self['@values'].splice(index, 1);
  458. return value[0];
  459. };
  460. >
  461. ! !
  462. !Dictionary methodsFor: 'converting'!
  463. asHashedCollection
  464. ^HashedCollection fromPairs: self associations
  465. !
  466. asJSON
  467. ^self asHashedCollection asJSON
  468. ! !
  469. !Dictionary methodsFor: 'initialization'!
  470. initialize
  471. super initialize.
  472. keys := #().
  473. values := #()
  474. ! !
  475. !Dictionary methodsFor: 'testing'!
  476. includesKey: aKey
  477. ^keys includes: aKey
  478. ! !
  479. Collection subclass: #SequenceableCollection
  480. instanceVariableNames: ''
  481. package: 'Kernel-Collections'!
  482. !SequenceableCollection methodsFor: 'accessing'!
  483. allButFirst
  484. ^self copyFrom: 2 to: self size
  485. !
  486. allButLast
  487. ^self copyFrom: 1 to: self size - 1
  488. !
  489. at: anIndex
  490. ^self at: anIndex ifAbsent: [
  491. self errorNotFound]
  492. !
  493. at: anIndex ifAbsent: aBlock
  494. self subclassResponsibility
  495. !
  496. at: anIndex put: anObject
  497. self subclassResponsibility
  498. !
  499. atRandom
  500. ^ self at: self size atRandom
  501. !
  502. first
  503. ^self at: 1
  504. !
  505. first: n
  506. "Answer the first n elements of the receiver.
  507. Raise an error if there are not enough elements."
  508. ^ self copyFrom: 1 to: n
  509. !
  510. fourth
  511. ^self at: 4
  512. !
  513. indexOf: anObject
  514. ^self indexOf: anObject ifAbsent: [self errorNotFound]
  515. !
  516. indexOf: anObject ifAbsent: aBlock
  517. <
  518. for(var i=0;i<self.length;i++){
  519. if(self[i].__eq(anObject)) {return i+1}
  520. }
  521. return aBlock();
  522. >
  523. !
  524. indexOf: anObject startingAt: start
  525. "Answer the index of the first occurence of anElement after start
  526. within the receiver. If the receiver does not contain anElement,
  527. answer 0."
  528. ^self indexOf: anObject startingAt: start ifAbsent: [0]
  529. !
  530. indexOf: anObject startingAt: start ifAbsent: aBlock
  531. <
  532. for(var i=start-1;i<self.length;i++){
  533. if(self[i].__eq(anObject)) {return i+1}
  534. }
  535. return aBlock();
  536. >
  537. !
  538. last
  539. ^self at: self size
  540. !
  541. second
  542. ^self at: 2
  543. !
  544. third
  545. ^self at: 3
  546. ! !
  547. !SequenceableCollection methodsFor: 'adding'!
  548. addLast: anObject
  549. self add: anObject
  550. !
  551. removeLast
  552. self remove: self last
  553. ! !
  554. !SequenceableCollection methodsFor: 'comparing'!
  555. = aCollection
  556. (self class = aCollection class and: [
  557. self size = aCollection size]) ifFalse: [^false].
  558. self withIndexDo: [:each :i |
  559. (aCollection at: i) = each ifFalse: [^false]].
  560. ^true
  561. ! !
  562. !SequenceableCollection methodsFor: 'converting'!
  563. reversed
  564. self subclassResponsibility
  565. ! !
  566. !SequenceableCollection methodsFor: 'copying'!
  567. copyFrom: anIndex to: anotherIndex
  568. | range newCollection |
  569. range := anIndex to: anotherIndex.
  570. newCollection := self class new: range size.
  571. range withIndexDo: [:each :i |
  572. newCollection at: i put: (self at: each)].
  573. ^newCollection
  574. !
  575. deepCopy
  576. | newCollection |
  577. newCollection := self class new: self size.
  578. self withIndexDo: [:each :index |
  579. newCollection at: index put: each deepCopy].
  580. ^newCollection
  581. !
  582. shallowCopy
  583. | newCollection |
  584. newCollection := self class new: self size.
  585. self withIndexDo: [ :each :index |
  586. newCollection at: index put: each].
  587. ^newCollection
  588. ! !
  589. !SequenceableCollection methodsFor: 'enumerating'!
  590. withIndexDo: aBlock
  591. <for(var i=0;i<self.length;i++){aBlock(self[i], i+1);}>
  592. ! !
  593. SequenceableCollection subclass: #Array
  594. instanceVariableNames: ''
  595. package: 'Kernel-Collections'!
  596. !Array methodsFor: 'accessing'!
  597. at: anIndex ifAbsent: aBlock
  598. <
  599. if((anIndex < 1) || (self.length < anIndex)) {return aBlock()};
  600. return self[anIndex - 1];
  601. >
  602. !
  603. at: anIndex put: anObject
  604. <return self[anIndex - 1] = anObject>
  605. !
  606. size
  607. <return self.length>
  608. ! !
  609. !Array methodsFor: 'adding/removing'!
  610. add: anObject
  611. <self.push(anObject); return anObject;>
  612. !
  613. remove: anObject ifAbsent: aBlock
  614. <
  615. for(var i=0;i<self.length;i++) {
  616. if(self[i] == anObject) {
  617. self.splice(i,1);
  618. return self;
  619. }
  620. }
  621. >.
  622. aBlock value
  623. !
  624. removeFrom: aNumber to: anotherNumber
  625. <self.splice(aNumber - 1,anotherNumber - 1)>
  626. ! !
  627. !Array methodsFor: 'converting'!
  628. asJavascript
  629. ^'[', ((self collect: [:each | each asJavascript]) join: ', '), ']'
  630. !
  631. reversed
  632. <return self._copy().reverse()>
  633. ! !
  634. !Array methodsFor: 'enumerating'!
  635. join: aString
  636. <return self.join(aString)>
  637. !
  638. sort
  639. ^self basicPerform: 'sort'
  640. !
  641. sort: aBlock
  642. <
  643. return self.sort(function(a, b) {
  644. if(aBlock(a,b)) {return -1} else {return 1}
  645. })
  646. >
  647. !
  648. sorted
  649. ^self copy sort
  650. !
  651. sorted: aBlock
  652. ^self copy sort: aBlock
  653. ! !
  654. !Array class methodsFor: 'instance creation'!
  655. new: anInteger
  656. <return new Array(anInteger)>
  657. !
  658. with: anObject
  659. ^(self new: 1)
  660. at: 1 put: anObject;
  661. yourself
  662. !
  663. with: anObject with: anObject2
  664. ^(self new: 2)
  665. at: 1 put: anObject;
  666. at: 2 put: anObject2;
  667. yourself
  668. !
  669. with: anObject with: anObject2 with: anObject3
  670. ^(self new: 3)
  671. at: 1 put: anObject;
  672. at: 2 put: anObject2;
  673. at: 3 put: anObject3;
  674. yourself
  675. !
  676. withAll: aCollection
  677. | instance index |
  678. index := 1.
  679. instance := self new: aCollection size.
  680. aCollection do: [:each |
  681. instance at: index put: each.
  682. index := index + 1].
  683. ^instance
  684. ! !
  685. SequenceableCollection subclass: #CharacterArray
  686. instanceVariableNames: ''
  687. package: 'Kernel-Collections'!
  688. !CharacterArray methodsFor: 'accessing'!
  689. at: anIndex put: anObject
  690. self errorReadOnly
  691. ! !
  692. !CharacterArray methodsFor: 'adding'!
  693. add: anObject
  694. self errorReadOnly
  695. !
  696. remove: anObject
  697. self errorReadOnly
  698. ! !
  699. !CharacterArray methodsFor: 'converting'!
  700. asLowercase
  701. ^self class fromString: self asString asLowercase
  702. !
  703. asNumber
  704. ^self asString asNumber
  705. !
  706. asString
  707. ^self subclassResponsibility
  708. !
  709. asSymbol
  710. ^self subclassResponsibility
  711. !
  712. asUppercase
  713. ^self class fromString: self asString asUppercase
  714. ! !
  715. !CharacterArray methodsFor: 'copying'!
  716. , aString
  717. ^self asString, aString asString
  718. ! !
  719. !CharacterArray methodsFor: 'error handling'!
  720. errorReadOnly
  721. self error: 'Object is read-only'
  722. ! !
  723. !CharacterArray methodsFor: 'printing'!
  724. printString
  725. ^self asString printString
  726. ! !
  727. !CharacterArray class methodsFor: 'instance creation'!
  728. fromString: aString
  729. self subclassResponsibility
  730. ! !
  731. CharacterArray subclass: #String
  732. instanceVariableNames: ''
  733. package: 'Kernel-Collections'!
  734. !String methodsFor: 'accessing'!
  735. asciiValue
  736. <return self.charCodeAt(0);>
  737. !
  738. at: anIndex ifAbsent: aBlock
  739. <return String(self).charAt(anIndex - 1) || aBlock()>
  740. !
  741. escaped
  742. <return escape(self)>
  743. !
  744. size
  745. <return self.length>
  746. !
  747. unescaped
  748. <return unescape(self)>
  749. ! !
  750. !String methodsFor: 'comparing'!
  751. < aString
  752. <return String(self) < aString._asString()>
  753. !
  754. <= aString
  755. <return String(self) <= aString._asString()>
  756. !
  757. = aString
  758. aString class = self class ifFalse: [^false].
  759. <return String(self) === String(aString)>
  760. !
  761. == aString
  762. ^self = aString
  763. !
  764. > aString
  765. <return String(self) >> aString._asString()>
  766. !
  767. >= aString
  768. <return String(self) >>= aString._asString()>
  769. ! !
  770. !String methodsFor: 'converting'!
  771. asJSON
  772. ^self
  773. !
  774. asJavaScriptSelector
  775. ^(self asSelector replace: '^_' with: '') replace: '_.*' with: ''.
  776. !
  777. asJavascript
  778. <
  779. if(self.search(/^[a-zA-Z0-9_:.$ ]*$/) == -1)
  780. return "\"" + self.replace(/[\x00-\x1f"\\\x7f-\x9f]/g, function(ch){var c=ch.charCodeAt(0);return "\\x"+("0"+c.toString(16)).slice(-2)}) + "\"";
  781. else
  782. return "\"" + self + "\"";
  783. >
  784. !
  785. asLowercase
  786. <return self.toLowerCase()>
  787. !
  788. asNumber
  789. <return Number(self)>
  790. !
  791. asSelector
  792. "If you change this method, change smalltalk.convertSelector too (see js/boot.js file)"
  793. | selector |
  794. selector := '_', self.
  795. selector := selector replace: ':' with: '_'.
  796. selector := selector replace: '[+]' with: '_plus'.
  797. selector := selector replace: '-' with: '_minus'.
  798. selector := selector replace: '[*]' with: '_star'.
  799. selector := selector replace: '[/]' with: '_slash'.
  800. selector := selector replace: '>' with: '_gt'.
  801. selector := selector replace: '<' with: '_lt'.
  802. selector := selector replace: '=' with: '_eq'.
  803. selector := selector replace: ',' with: '_comma'.
  804. selector := selector replace: '[@]' with: '_at'.
  805. ^selector
  806. !
  807. asString
  808. ^self
  809. !
  810. asSymbol
  811. ^Symbol lookup: self
  812. !
  813. asUppercase
  814. <return self.toUpperCase()>
  815. !
  816. reversed
  817. <return self.split("").reverse().join("")>
  818. !
  819. tokenize: aString
  820. <return self.split(aString)>
  821. ! !
  822. !String methodsFor: 'copying'!
  823. , aString
  824. <return self + aString>
  825. !
  826. copyFrom: anIndex to: anotherIndex
  827. <return self.substring(anIndex - 1, anotherIndex)>
  828. !
  829. deepCopy
  830. ^self shallowCopy
  831. !
  832. shallowCopy
  833. ^self class fromString: self
  834. ! !
  835. !String methodsFor: 'enumerating'!
  836. do: aBlock
  837. <for(var i=0;i<self.length;i++){aBlock(self.charAt(i));}>
  838. !
  839. withIndexDo: aBlock
  840. <for(var i=0;i<self.length;i++){aBlock(self.charAt(i), i+1);}>
  841. ! !
  842. !String methodsFor: 'printing'!
  843. printNl
  844. <console.log(self)>
  845. !
  846. printString
  847. ^'''', self, ''''
  848. ! !
  849. !String methodsFor: 'regular expressions'!
  850. match: aRegexp
  851. <return self.search(aRegexp) !!= -1>
  852. !
  853. matchesOf: aRegularExpression
  854. <return self.match(aRegularExpression)>
  855. !
  856. replace: aString with: anotherString
  857. ^self replaceRegexp: (RegularExpression fromString: aString flag: 'g') with: anotherString
  858. !
  859. replaceRegexp: aRegexp with: aString
  860. <return self.replace(aRegexp, aString)>
  861. !
  862. trimBoth
  863. ^self trimBoth: '\s'
  864. !
  865. trimBoth: separators
  866. ^(self trimLeft: separators) trimRight: separators
  867. !
  868. trimLeft
  869. ^self trimLeft: '\s'
  870. !
  871. trimLeft: separators
  872. ^self replaceRegexp: (RegularExpression fromString: '^[', separators, ']+' flag: 'g') with: ''
  873. !
  874. trimRight
  875. ^self trimRight: '\s'
  876. !
  877. trimRight: separators
  878. ^self replaceRegexp: (RegularExpression fromString: '[', separators, ']+$' flag: 'g') with: ''
  879. ! !
  880. !String methodsFor: 'split join'!
  881. join: aCollection
  882. ^ String
  883. streamContents: [:stream | aCollection
  884. do: [:each | stream nextPutAll: each asString]
  885. separatedBy: [stream nextPutAll: self]]
  886. !
  887. lineIndicesDo: aBlock
  888. "execute aBlock with 3 arguments for each line:
  889. - start index of line
  890. - end index of line without line delimiter
  891. - end index of line including line delimiter(s) CR, LF or CRLF"
  892. | cr lf start sz nextLF nextCR |
  893. start := 1.
  894. sz := self size.
  895. cr := String cr.
  896. nextCR := self indexOf: cr startingAt: 1.
  897. lf := String lf.
  898. nextLF := self indexOf: lf startingAt: 1.
  899. [ start <= sz ] whileTrue: [
  900. (nextLF = 0 and: [ nextCR = 0 ])
  901. ifTrue: [ "No more CR, nor LF, the string is over"
  902. aBlock value: start value: sz value: sz.
  903. ^self ].
  904. (nextCR = 0 or: [ 0 < nextLF and: [ nextLF < nextCR ] ])
  905. ifTrue: [ "Found a LF"
  906. aBlock value: start value: nextLF - 1 value: nextLF.
  907. start := 1 + nextLF.
  908. nextLF := self indexOf: lf startingAt: start ]
  909. ifFalse: [ 1 + nextCR = nextLF
  910. ifTrue: [ "Found a CR-LF pair"
  911. aBlock value: start value: nextCR - 1 value: nextLF.
  912. start := 1 + nextLF.
  913. nextCR := self indexOf: cr startingAt: start.
  914. nextLF := self indexOf: lf startingAt: start ]
  915. ifFalse: [ "Found a CR"
  916. aBlock value: start value: nextCR - 1 value: nextCR.
  917. start := 1 + nextCR.
  918. nextCR := self indexOf: cr startingAt: start ]]]
  919. !
  920. lineNumber: anIndex
  921. "Answer a string containing the characters in the given line number."
  922. | lineCount |
  923. lineCount := 0.
  924. self lineIndicesDo: [:start :endWithoutDelimiters :end |
  925. (lineCount := lineCount + 1) = anIndex ifTrue: [^self copyFrom: start to: endWithoutDelimiters]].
  926. ^nil
  927. !
  928. lines
  929. "Answer an array of lines composing this receiver without the line ending delimiters."
  930. | lines |
  931. lines := Array new.
  932. self linesDo: [:aLine | lines add: aLine].
  933. ^lines
  934. !
  935. linesDo: aBlock
  936. "Execute aBlock with each line in this string. The terminating line
  937. delimiters CR, LF or CRLF pairs are not included in what is passed to aBlock"
  938. self lineIndicesDo: [:start :endWithoutDelimiters :end |
  939. aBlock value: (self copyFrom: start to: endWithoutDelimiters)]
  940. ! !
  941. !String methodsFor: 'testing'!
  942. includesSubString: subString
  943. < return self.indexOf(subString) !!= -1 >
  944. !
  945. isString
  946. ^true
  947. ! !
  948. !String class methodsFor: 'accessing'!
  949. cr
  950. <return '\r'>
  951. !
  952. crlf
  953. <return '\r\n'>
  954. !
  955. lf
  956. <return '\n'>
  957. !
  958. space
  959. <return ' '>
  960. !
  961. streamClass
  962. ^StringStream
  963. !
  964. tab
  965. <return '\t'>
  966. ! !
  967. !String class methodsFor: 'instance creation'!
  968. fromString: aString
  969. <return new self.fn(aString)>
  970. !
  971. streamContents: blockWithArg
  972. |stream|
  973. stream := (self streamClass on: String new).
  974. blockWithArg value: stream.
  975. ^ stream contents
  976. !
  977. value: aUTFCharCode
  978. <return String.fromCharCode(aUTFCharCode);>
  979. ! !
  980. CharacterArray subclass: #Symbol
  981. instanceVariableNames: ''
  982. package: 'Kernel-Collections'!
  983. !Symbol methodsFor: 'accessing'!
  984. at: anIndex ifAbsent: aBlock
  985. ^self asString at: anIndex ifAbsent: aBlock
  986. !
  987. size
  988. ^self asString size
  989. ! !
  990. !Symbol methodsFor: 'comparing'!
  991. < aSymbol
  992. ^self asString < aSymbol asString
  993. !
  994. <= aSymbol
  995. ^self asString <= aSymbol asString
  996. !
  997. = aSymbol
  998. aSymbol class = self class ifFalse: [^false].
  999. ^self asString = aSymbol asString
  1000. !
  1001. > aSymbol
  1002. ^self asString > aSymbol asString
  1003. !
  1004. >= aSymbol
  1005. ^self asString >= aSymbol asString
  1006. ! !
  1007. !Symbol methodsFor: 'converting'!
  1008. asJSON
  1009. ^self asString asJSON
  1010. !
  1011. asJavascript
  1012. ^'smalltalk.symbolFor("', self asString, '")'
  1013. !
  1014. asSelector
  1015. ^self asString asSelector
  1016. !
  1017. asString
  1018. <return self.value>
  1019. !
  1020. asSymbol
  1021. ^self
  1022. ! !
  1023. !Symbol methodsFor: 'copying'!
  1024. copyFrom: anIndex to: anotherIndex
  1025. ^self class fromString: (self asString copyFrom: anIndex to: anotherIndex)
  1026. !
  1027. deepCopy
  1028. ^self
  1029. !
  1030. shallowCopy
  1031. ^self
  1032. ! !
  1033. !Symbol methodsFor: 'enumerating'!
  1034. collect: aBlock
  1035. ^ (self asString collect: aBlock) asSymbol
  1036. !
  1037. detect: aBlock
  1038. ^ self asString detect: aBlock
  1039. !
  1040. do: aBlock
  1041. self asString do: aBlock
  1042. !
  1043. select: aBlock
  1044. ^ (self asString select: aBlock) asSymbol
  1045. !
  1046. withIndexDo: aBlock
  1047. self asString withIndexDo: aBlock
  1048. ! !
  1049. !Symbol methodsFor: 'printing'!
  1050. isSymbol
  1051. ^true
  1052. !
  1053. printString
  1054. ^'#', self asString
  1055. ! !
  1056. !Symbol class methodsFor: 'instance creation'!
  1057. basicNew
  1058. self shouldNotImplement
  1059. !
  1060. fromString: aString
  1061. ^self lookup: aString
  1062. !
  1063. lookup: aString
  1064. <return smalltalk.symbolFor(aString);>
  1065. ! !
  1066. Collection subclass: #Set
  1067. instanceVariableNames: 'elements'
  1068. package: 'Kernel-Collections'!
  1069. !Set methodsFor: 'accessing'!
  1070. size
  1071. ^elements size
  1072. ! !
  1073. !Set methodsFor: 'adding/removing'!
  1074. add: anObject
  1075. <
  1076. var found;
  1077. for(var i=0; i < self['@elements'].length; i++) {
  1078. if(anObject == self['@elements'][i]) {
  1079. found = true;
  1080. break;
  1081. }
  1082. }
  1083. if(!!found) {self['@elements'].push(anObject)}
  1084. >
  1085. !
  1086. remove: anObject
  1087. elements remove: anObject
  1088. ! !
  1089. !Set methodsFor: 'comparing'!
  1090. = aCollection
  1091. ^self class = aCollection class and: [
  1092. elements = aCollection asArray]
  1093. ! !
  1094. !Set methodsFor: 'converting'!
  1095. asArray
  1096. ^elements copy
  1097. ! !
  1098. !Set methodsFor: 'enumerating'!
  1099. detect: aBlock ifNone: anotherBlock
  1100. ^elements detect: aBlock ifNone: anotherBlock
  1101. !
  1102. do: aBlock
  1103. elements do: aBlock
  1104. !
  1105. select: aBlock
  1106. | collection |
  1107. collection := self class new.
  1108. self do: [:each |
  1109. (aBlock value: each) ifTrue: [
  1110. collection add: each]].
  1111. ^collection
  1112. ! !
  1113. !Set methodsFor: 'initialization'!
  1114. initialize
  1115. super initialize.
  1116. elements := #()
  1117. ! !
  1118. !Set methodsFor: 'testing'!
  1119. includes: anObject
  1120. ^elements includes: anObject
  1121. ! !
  1122. Object subclass: #RegularExpression
  1123. instanceVariableNames: ''
  1124. package: 'Kernel-Collections'!
  1125. !RegularExpression methodsFor: 'evaluating'!
  1126. compile: aString
  1127. <return self.compile(aString)>
  1128. !
  1129. exec: aString
  1130. <return self.exec(aString) || nil>
  1131. !
  1132. test: aString
  1133. <return self.test(aString)>
  1134. ! !
  1135. !RegularExpression class methodsFor: 'instance creation'!
  1136. fromString: aString
  1137. ^self fromString: aString flag: ''
  1138. !
  1139. fromString: aString flag: anotherString
  1140. <return new RegExp(aString, anotherString)>
  1141. ! !
  1142. Object subclass: #Stream
  1143. instanceVariableNames: 'collection position streamSize'
  1144. package: 'Kernel-Collections'!
  1145. !Stream methodsFor: 'accessing'!
  1146. collection
  1147. ^collection
  1148. !
  1149. contents
  1150. ^self collection
  1151. copyFrom: 1
  1152. to: self streamSize
  1153. !
  1154. position
  1155. ^position ifNil: [position := 0]
  1156. !
  1157. position: anInteger
  1158. position := anInteger
  1159. !
  1160. setCollection: aCollection
  1161. collection := aCollection
  1162. !
  1163. setStreamSize: anInteger
  1164. streamSize := anInteger
  1165. !
  1166. size
  1167. ^self streamSize
  1168. !
  1169. streamSize
  1170. ^streamSize
  1171. ! !
  1172. !Stream methodsFor: 'actions'!
  1173. close
  1174. !
  1175. flush
  1176. !
  1177. reset
  1178. self position: 0
  1179. !
  1180. resetContents
  1181. self reset.
  1182. self setStreamSize: 0
  1183. ! !
  1184. !Stream methodsFor: 'enumerating'!
  1185. do: aBlock
  1186. [self atEnd] whileFalse: [aBlock value: self next]
  1187. ! !
  1188. !Stream methodsFor: 'positioning'!
  1189. setToEnd
  1190. self position: self size
  1191. !
  1192. skip: anInteger
  1193. self position: ((self position + anInteger) min: self size max: 0)
  1194. ! !
  1195. !Stream methodsFor: 'reading'!
  1196. next
  1197. ^self atEnd
  1198. ifTrue: [nil]
  1199. ifFalse: [
  1200. self position: self position + 1.
  1201. collection at: self position]
  1202. !
  1203. next: anInteger
  1204. | tempCollection |
  1205. tempCollection := self collection class new.
  1206. anInteger timesRepeat: [
  1207. self atEnd ifFalse: [
  1208. tempCollection add: self next]].
  1209. ^tempCollection
  1210. !
  1211. peek
  1212. ^self atEnd ifFalse: [
  1213. self collection at: self position + 1]
  1214. ! !
  1215. !Stream methodsFor: 'testing'!
  1216. atEnd
  1217. ^self position = self size
  1218. !
  1219. atStart
  1220. ^self position = 0
  1221. !
  1222. isEmpty
  1223. ^self size = 0
  1224. ! !
  1225. !Stream methodsFor: 'writing'!
  1226. nextPut: anObject
  1227. self position: self position + 1.
  1228. self collection at: self position put: anObject.
  1229. self setStreamSize: (self streamSize max: self position)
  1230. !
  1231. nextPutAll: aCollection
  1232. aCollection do: [:each |
  1233. self nextPut: each]
  1234. ! !
  1235. !Stream class methodsFor: 'instance creation'!
  1236. on: aCollection
  1237. ^self new
  1238. setCollection: aCollection;
  1239. setStreamSize: aCollection size;
  1240. yourself
  1241. ! !
  1242. Stream subclass: #StringStream
  1243. instanceVariableNames: ''
  1244. package: 'Kernel-Collections'!
  1245. !StringStream methodsFor: 'reading'!
  1246. next: anInteger
  1247. | tempCollection |
  1248. tempCollection := self collection class new.
  1249. anInteger timesRepeat: [
  1250. self atEnd ifFalse: [
  1251. tempCollection := tempCollection, self next]].
  1252. ^tempCollection
  1253. ! !
  1254. !StringStream methodsFor: 'writing'!
  1255. cr
  1256. ^self nextPutAll: String cr
  1257. !
  1258. crlf
  1259. ^self nextPutAll: String crlf
  1260. !
  1261. lf
  1262. ^self nextPutAll: String lf
  1263. !
  1264. nextPut: aString
  1265. self nextPutAll: aString
  1266. !
  1267. nextPutAll: aString
  1268. self setCollection:
  1269. (self collection copyFrom: 1 to: self position),
  1270. aString,
  1271. (self collection copyFrom: (self position + 1 + aString size) to: self collection size).
  1272. self position: self position + aString size.
  1273. self setStreamSize: (self streamSize max: self position)
  1274. !
  1275. space
  1276. self nextPut: ' '
  1277. ! !