Kernel-Collections.st 28 KB

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