Kernel-Collections.st 28 KB

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