Kernel-Collections.st 30 KB

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