Kernel-Collections.st 27 KB

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