2
0

Kernel-Collections.st 28 KB

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