Kernel-Collections.st 28 KB

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