Kernel-Collections.st 28 KB

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