Kernel-Objects.st 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389
  1. Smalltalk createPackage: 'Kernel-Objects'!
  2. nil subclass: #ProtoObject
  3. instanceVariableNames: ''
  4. package: 'Kernel-Objects'!
  5. !ProtoObject commentStamp!
  6. I implement the basic behavior required for any object in Amber.
  7. In most cases, subclassing `ProtoObject` is wrong and `Object` should be used instead. However subclassing `ProtoObject` can be useful in some special cases like proxy implementations.!
  8. !ProtoObject methodsFor: 'accessing'!
  9. class
  10. <return self.klass>
  11. !
  12. identityHash
  13. <
  14. var hash=self.identityHash;
  15. if (hash) return hash;
  16. hash=smalltalk.nextId();
  17. Object.defineProperty(self, 'identityHash', {value:hash});
  18. return hash;
  19. >
  20. !
  21. instVarAt: aString
  22. < return self['@'+aString] >
  23. !
  24. instVarAt: aString put: anObject
  25. < self['@' + aString] = anObject >
  26. !
  27. yourself
  28. ^ self
  29. ! !
  30. !ProtoObject methodsFor: 'comparing'!
  31. = anObject
  32. ^ self == anObject
  33. !
  34. == anObject
  35. ^ self identityHash = anObject identityHash
  36. !
  37. ~= anObject
  38. ^ (self = anObject) = false
  39. !
  40. ~~ anObject
  41. ^ (self == anObject) = false
  42. ! !
  43. !ProtoObject methodsFor: 'converting'!
  44. asString
  45. ^ self printString
  46. ! !
  47. !ProtoObject methodsFor: 'error handling'!
  48. doesNotUnderstand: aMessage
  49. MessageNotUnderstood new
  50. receiver: self;
  51. message: aMessage;
  52. signal
  53. ! !
  54. !ProtoObject methodsFor: 'initialization'!
  55. initialize
  56. ! !
  57. !ProtoObject methodsFor: 'inspecting'!
  58. inspect
  59. Inspector inspect: self
  60. !
  61. inspectOn: anInspector
  62. ! !
  63. !ProtoObject methodsFor: 'message handling'!
  64. perform: aString
  65. ^ self perform: aString withArguments: #()
  66. !
  67. perform: aString withArguments: aCollection
  68. <return smalltalk.send(self, aString._asSelector(), aCollection)>
  69. ! !
  70. !ProtoObject methodsFor: 'printing'!
  71. printOn: aStream
  72. aStream nextPutAll: (self class name first isVowel
  73. ifTrue: [ 'an ' ]
  74. ifFalse: [ 'a ' ]).
  75. aStream nextPutAll: self class name
  76. !
  77. printString
  78. ^ String streamContents: [ :str |
  79. self printOn: str ]
  80. ! !
  81. !ProtoObject class methodsFor: 'accessing'!
  82. heliosClass
  83. "Should be an Helios extension. Unfortunately, since helios can browse remote
  84. environments, we can't extend base classes"
  85. ^ 'class'
  86. ! !
  87. !ProtoObject class methodsFor: 'initialization'!
  88. initialize
  89. ! !
  90. ProtoObject subclass: #Object
  91. instanceVariableNames: ''
  92. package: 'Kernel-Objects'!
  93. !Object commentStamp!
  94. **I am the root of the Smalltalk class system**. With the exception of unual subclasses of `ProtoObject`, all other classes in the system are subclasses of me.
  95. I provide default behavior common to all normal objects (some of it inherited from `ProtoObject`), such as:
  96. - accessing
  97. - copying
  98. - comparison
  99. - error handling
  100. - message sending
  101. - reflection
  102. Also utility messages that all objects should respond to are defined here.
  103. I have no instance variable.
  104. ##Access
  105. Instance variables can be accessed with `#instVarAt:` and `#instVarAt:put:`. `#instanceVariableNames` answers a collection of all instance variable names.
  106. Accessing JavaScript properties of an object is done through `#basicAt:`, `#basicAt:put:` and `basicDelete:`.
  107. ##Copying
  108. Copying an object is handled by `#copy` and `#deepCopy`. The first one performs a shallow copy of the receiver, while the second one performs a deep copy.
  109. The hook method `#postCopy` can be overriden in subclasses to copy fields as necessary to complete the full copy. It will be sent by the copy of the receiver.
  110. ##Comparison
  111. I understand equality `#=` and identity `#==` comparison.
  112. ##Error handling
  113. - `#halt` is the typical message to use for inserting breakpoints during debugging.
  114. - `#error:` throws a generic error exception
  115. - `#doesNotUnderstand:` handles the fact that there was an attempt to send the given message to the receiver but the receiver does not understand this message.
  116. Overriding this message can be useful to implement proxies for example.!
  117. !Object methodsFor: 'accessing'!
  118. basicAt: aString
  119. <return self[aString]>
  120. !
  121. basicAt: aString put: anObject
  122. <return self[aString] = anObject>
  123. !
  124. basicDelete: aString
  125. <delete self[aString]; return aString>
  126. !
  127. size
  128. self error: 'Object not indexable'
  129. !
  130. value
  131. <return self.valueOf()>
  132. ! !
  133. !Object methodsFor: 'browsing'!
  134. browse
  135. Finder findClass: self class
  136. ! !
  137. !Object methodsFor: 'converting'!
  138. -> anObject
  139. ^ Association key: self value: anObject
  140. !
  141. asJSON
  142. | variables |
  143. variables := HashedCollection new.
  144. self class allInstanceVariableNames do: [ :each |
  145. variables at: each put: (self instVarAt: each) asJSON ].
  146. ^ variables
  147. !
  148. asJSONString
  149. ^ JSON stringify: self asJSON
  150. !
  151. asJavascript
  152. ^ self asString
  153. ! !
  154. !Object methodsFor: 'copying'!
  155. copy
  156. ^ self shallowCopy postCopy
  157. !
  158. deepCopy
  159. <
  160. var copy = self.klass._new();
  161. Object.keys(self).forEach(function (i) {
  162. if(/^@.+/.test(i)) {
  163. copy[i] = self[i]._deepCopy();
  164. }
  165. });
  166. return copy;
  167. >
  168. !
  169. postCopy
  170. !
  171. shallowCopy
  172. <
  173. var copy = self.klass._new();
  174. Object.keys(self).forEach(function(i) {
  175. if(/^@.+/.test(i)) {
  176. copy[i] = self[i];
  177. }
  178. });
  179. return copy;
  180. >
  181. ! !
  182. !Object methodsFor: 'error handling'!
  183. deprecatedAPI
  184. "Just a simple way to deprecate methods.
  185. #deprecatedAPI is in the 'error handling' protocol even if it doesn't throw an error,
  186. but it could in the future."
  187. console warn: thisContext home asString, ' is deprecated!! (in ', thisContext home home asString, ')'
  188. !
  189. error: aString
  190. Error signal: aString
  191. !
  192. halt
  193. self error: 'Halt encountered'
  194. !
  195. shouldNotImplement
  196. self error: 'This method should not be implemented in ', self class name
  197. !
  198. subclassResponsibility
  199. self error: 'This method is a responsibility of a subclass'
  200. !
  201. throw: anObject
  202. < throw anObject >
  203. !
  204. try: aBlock catch: anotherBlock
  205. self deprecatedAPI.
  206. ^ aBlock tryCatch: anotherBlock
  207. ! !
  208. !Object methodsFor: 'inspecting'!
  209. inspectOn: anInspector
  210. | variables |
  211. variables := Dictionary new.
  212. variables at: '#self' put: self.
  213. self class allInstanceVariableNames do: [ :each |
  214. variables at: each put: (self instVarAt: each) ].
  215. anInspector
  216. setLabel: self printString;
  217. setVariables: variables
  218. ! !
  219. !Object methodsFor: 'message handling'!
  220. basicPerform: aString
  221. ^ self basicPerform: aString withArguments: #()
  222. !
  223. basicPerform: aString withArguments: aCollection
  224. <return self[aString].apply(self, aCollection);>
  225. ! !
  226. !Object methodsFor: 'streaming'!
  227. putOn: aStream
  228. aStream nextPut: self
  229. ! !
  230. !Object methodsFor: 'testing'!
  231. ifNil: aBlock
  232. "inlined in the Compiler"
  233. ^ self
  234. !
  235. ifNil: aBlock ifNotNil: anotherBlock
  236. "inlined in the Compiler"
  237. ^ anotherBlock value: self
  238. !
  239. ifNotNil: aBlock
  240. "inlined in the Compiler"
  241. ^ aBlock value: self
  242. !
  243. ifNotNil: aBlock ifNil: anotherBlock
  244. "inlined in the Compiler"
  245. ^ aBlock value: self
  246. !
  247. isBehavior
  248. ^ false
  249. !
  250. isBoolean
  251. ^ false
  252. !
  253. isClass
  254. ^ false
  255. !
  256. isCompiledMethod
  257. ^ false
  258. !
  259. isImmutable
  260. ^ false
  261. !
  262. isKindOf: aClass
  263. ^ (self isMemberOf: aClass)
  264. ifTrue: [ true ]
  265. ifFalse: [ self class inheritsFrom: aClass ]
  266. !
  267. isMemberOf: aClass
  268. ^ self class = aClass
  269. !
  270. isMetaclass
  271. ^ false
  272. !
  273. isNil
  274. ^ false
  275. !
  276. isNumber
  277. ^ false
  278. !
  279. isPackage
  280. ^ false
  281. !
  282. isParseFailure
  283. ^ false
  284. !
  285. isString
  286. ^ false
  287. !
  288. isSymbol
  289. ^ false
  290. !
  291. notNil
  292. ^ self isNil not
  293. !
  294. respondsTo: aSelector
  295. ^ self class canUnderstand: aSelector
  296. ! !
  297. !Object class methodsFor: 'helios'!
  298. accessorProtocolWith: aGenerator
  299. aGenerator accessorProtocolForObject
  300. !
  301. accessorsSourceCodesWith: aGenerator
  302. aGenerator accessorsForObject
  303. !
  304. heliosClass
  305. "Should be an Helios extension. Unfortunately, since helios can browse remote
  306. environments, we can't extend base classes"
  307. ^ 'class'
  308. !
  309. initializeProtocolWith: aGenerator
  310. aGenerator initializeProtocolForObject
  311. !
  312. initializeSourceCodesWith: aGenerator
  313. aGenerator initializeForObject
  314. ! !
  315. !Object class methodsFor: 'initialization'!
  316. initialize
  317. "no op"
  318. ! !
  319. Object subclass: #Boolean
  320. instanceVariableNames: ''
  321. package: 'Kernel-Objects'!
  322. !Boolean commentStamp!
  323. I define the protocol for logic testing operations and conditional control structures for the logical values (see the `controlling` protocol).
  324. I have two instances, `true` and `false`.
  325. I am directly mapped to JavaScript Boolean. The `true` and `false` objects are the JavaScript boolean objects.
  326. ## Usage Example:
  327. aBoolean not ifTrue: [ ... ] ifFalse: [ ... ]!
  328. !Boolean methodsFor: 'comparing'!
  329. = aBoolean
  330. <
  331. return aBoolean !!= null &&
  332. typeof aBoolean._isBoolean === "function" &&
  333. aBoolean._isBoolean() &&
  334. Boolean(self == true) == aBoolean
  335. >
  336. !
  337. == aBoolean
  338. ^ self = aBoolean
  339. ! !
  340. !Boolean methodsFor: 'controlling'!
  341. & aBoolean
  342. <
  343. if(self == true) {
  344. return aBoolean;
  345. } else {
  346. return false;
  347. }
  348. >
  349. !
  350. and: aBlock
  351. ^ self = true
  352. ifTrue: aBlock
  353. ifFalse: [ false ]
  354. !
  355. ifFalse: aBlock
  356. "inlined in the Compiler"
  357. ^ self ifTrue: [] ifFalse: aBlock
  358. !
  359. ifFalse: aBlock ifTrue: anotherBlock
  360. "inlined in the Compiler"
  361. ^ self ifTrue: anotherBlock ifFalse: aBlock
  362. !
  363. ifTrue: aBlock
  364. "inlined in the Compiler"
  365. ^ self ifTrue: aBlock ifFalse: []
  366. !
  367. ifTrue: aBlock ifFalse: anotherBlock
  368. "inlined in the Compiler"
  369. <
  370. if(self == true) {
  371. return aBlock._value();
  372. } else {
  373. return anotherBlock._value();
  374. }
  375. >
  376. !
  377. not
  378. ^ self = false
  379. !
  380. or: aBlock
  381. ^ self = true
  382. ifTrue: [ true ]
  383. ifFalse: aBlock
  384. !
  385. | aBoolean
  386. <
  387. if(self == true) {
  388. return true;
  389. } else {
  390. return aBoolean;
  391. }
  392. >
  393. ! !
  394. !Boolean methodsFor: 'converting'!
  395. asBit
  396. ^ self ifTrue: [ 1 ] ifFalse: [ 0 ]
  397. !
  398. asJSON
  399. ^ self
  400. !
  401. asString
  402. < return self.toString() >
  403. ! !
  404. !Boolean methodsFor: 'copying'!
  405. deepCopy
  406. ^ self
  407. !
  408. shallowCopy
  409. ^ self
  410. ! !
  411. !Boolean methodsFor: 'printing'!
  412. printOn: aStream
  413. aStream nextPutAll: self asString
  414. ! !
  415. !Boolean methodsFor: 'testing'!
  416. isBoolean
  417. ^ true
  418. !
  419. isImmutable
  420. ^ true
  421. ! !
  422. Object subclass: #Date
  423. instanceVariableNames: ''
  424. package: 'Kernel-Objects'!
  425. !Date commentStamp!
  426. I am used to work with both dates and times. Therefore `Date today` and `Date now` are both valid in
  427. Amber and answer the same date object.
  428. Date directly maps to the `Date()` JavaScript constructor, and Amber date objects are JavaScript date objects.
  429. ## API
  430. The class-side `instance creation` protocol contains some convenience methods for creating date/time objects such as `#fromSeconds:`.
  431. Arithmetic and comparison is supported (see the `comparing` and `arithmetic` protocols).
  432. The `converting` protocol provides convenience methods for various convertions (to numbers, strings, etc.).!
  433. !Date methodsFor: 'accessing'!
  434. day
  435. ^ self dayOfWeek
  436. !
  437. day: aNumber
  438. self dayOfWeek: aNumber
  439. !
  440. dayOfMonth
  441. <return self.getDate()>
  442. !
  443. dayOfMonth: aNumber
  444. <self.setDate(aNumber)>
  445. !
  446. dayOfWeek
  447. <return self.getDay() + 1>
  448. !
  449. dayOfWeek: aNumber
  450. <return self.setDay(aNumber - 1)>
  451. !
  452. hours
  453. <return self.getHours()>
  454. !
  455. hours: aNumber
  456. <self.setHours(aNumber)>
  457. !
  458. milliseconds
  459. <return self.getMilliseconds()>
  460. !
  461. milliseconds: aNumber
  462. <self.setMilliseconds(aNumber)>
  463. !
  464. minutes
  465. <return self.getMinutes()>
  466. !
  467. minutes: aNumber
  468. <self.setMinutes(aNumber)>
  469. !
  470. month
  471. <return self.getMonth() + 1>
  472. !
  473. month: aNumber
  474. <self.setMonth(aNumber - 1)>
  475. !
  476. seconds
  477. <return self.getSeconds()>
  478. !
  479. seconds: aNumber
  480. <self.setSeconds(aNumber)>
  481. !
  482. time
  483. <return self.getTime()>
  484. !
  485. time: aNumber
  486. <self.setTime(aNumber)>
  487. !
  488. year
  489. <return self.getFullYear()>
  490. !
  491. year: aNumber
  492. <self.setFullYear(aNumber)>
  493. ! !
  494. !Date methodsFor: 'arithmetic'!
  495. + aDate
  496. <return self + aDate>
  497. !
  498. - aDate
  499. <return self - aDate>
  500. ! !
  501. !Date methodsFor: 'comparing'!
  502. < aDate
  503. <return self < aDate>
  504. !
  505. <= aDate
  506. <return self <= aDate>
  507. !
  508. > aDate
  509. <return self >> aDate>
  510. !
  511. >= aDate
  512. <return self >>= aDate>
  513. ! !
  514. !Date methodsFor: 'converting'!
  515. asDateString
  516. <return self.toDateString()>
  517. !
  518. asLocaleString
  519. <return self.toLocaleString()>
  520. !
  521. asMilliseconds
  522. ^ self time
  523. !
  524. asNumber
  525. ^ self asMilliseconds
  526. !
  527. asString
  528. <return self.toString()>
  529. !
  530. asTimeString
  531. <return self.toTimeString()>
  532. ! !
  533. !Date methodsFor: 'printing'!
  534. printOn: aStream
  535. aStream nextPutAll: self asString
  536. ! !
  537. !Date class methodsFor: 'helios'!
  538. heliosClass
  539. ^ 'magnitude'
  540. ! !
  541. !Date class methodsFor: 'instance creation'!
  542. fromMilliseconds: aNumber
  543. ^ self new: aNumber
  544. !
  545. fromSeconds: aNumber
  546. ^ self fromMilliseconds: aNumber * 1000
  547. !
  548. fromString: aString
  549. "Example: Date fromString('2011/04/15 00:00:00')"
  550. ^ self new: aString
  551. !
  552. millisecondsToRun: aBlock
  553. | t |
  554. t := Date now.
  555. aBlock value.
  556. ^ Date now - t
  557. !
  558. new: anObject
  559. <return new Date(anObject)>
  560. !
  561. now
  562. ^ self today
  563. !
  564. today
  565. ^ self new
  566. ! !
  567. Object subclass: #Number
  568. instanceVariableNames: ''
  569. package: 'Kernel-Objects'!
  570. !Number commentStamp!
  571. I am the Amber representation for all numbers.
  572. I am directly mapped to JavaScript Number.
  573. ## API
  574. I provide all necessary methods for arithmetic operations, comparison, conversion and so on with numbers.
  575. My instances can also be used to evaluate a block a fixed number of times:
  576. 5 timesRepeat: [ Transcript show: 'This will be printed 5 times'; cr ].
  577. 1 to: 5 do: [ :aNumber| Transcript show: aNumber asString; cr ].
  578. 1 to: 10 by: 2 do: [ :aNumber| Transcript show: aNumber asString; cr ].!
  579. !Number methodsFor: 'accessing'!
  580. identityHash
  581. ^ self asString, 'n'
  582. ! !
  583. !Number methodsFor: 'arithmetic'!
  584. * aNumber
  585. "Inlined in the Compiler"
  586. <return self * aNumber>
  587. !
  588. + aNumber
  589. "Inlined in the Compiler"
  590. <return self + aNumber>
  591. !
  592. - aNumber
  593. "Inlined in the Compiler"
  594. <return self - aNumber>
  595. !
  596. / aNumber
  597. "Inlined in the Compiler"
  598. <return self / aNumber>
  599. !
  600. // aNumber
  601. ^ (self / aNumber) floor
  602. !
  603. \\ aNumber
  604. <return self % aNumber>
  605. !
  606. abs
  607. <return Math.abs(self);>
  608. !
  609. max: aNumber
  610. <return Math.max(self, aNumber);>
  611. !
  612. min: aNumber
  613. <return Math.min(self, aNumber);>
  614. !
  615. negated
  616. ^ 0 - self
  617. ! !
  618. !Number methodsFor: 'comparing'!
  619. < aNumber
  620. "Inlined in the Compiler"
  621. <return self < aNumber>
  622. !
  623. <= aNumber
  624. "Inlined in the Compiler"
  625. <return self <= aNumber>
  626. !
  627. = aNumber
  628. <
  629. return aNumber !!= null &&
  630. typeof aNumber._isNumber === "function" &&
  631. aNumber._isNumber() &&
  632. Number(self) == aNumber
  633. >
  634. !
  635. > aNumber
  636. "Inlined in the Compiler"
  637. <return self >> aNumber>
  638. !
  639. >= aNumber
  640. "Inlined in the Compiler"
  641. <return self >>= aNumber>
  642. ! !
  643. !Number methodsFor: 'converting'!
  644. & aNumber
  645. <return self & aNumber>
  646. !
  647. @ aNumber
  648. ^ Point x: self y: aNumber
  649. !
  650. asJSON
  651. ^ self
  652. !
  653. asJavascript
  654. ^ '(', self printString, ')'
  655. !
  656. asNumber
  657. ^ self
  658. !
  659. asPoint
  660. ^ Point x: self y: self
  661. !
  662. asString
  663. < return String(self) >
  664. !
  665. atRandom
  666. ^ (Random new next * self) truncated + 1
  667. !
  668. ceiling
  669. <return Math.ceil(self);>
  670. !
  671. floor
  672. <return Math.floor(self);>
  673. !
  674. rounded
  675. <return Math.round(self);>
  676. !
  677. to: aNumber
  678. | array first last count |
  679. first := self truncated.
  680. last := aNumber truncated + 1.
  681. count := 1.
  682. array := Array new.
  683. (last - first) timesRepeat: [
  684. array at: count put: first.
  685. count := count + 1.
  686. first := first + 1 ].
  687. ^ array
  688. !
  689. to: stop by: step
  690. | array value pos |
  691. value := self.
  692. array := Array new.
  693. pos := 1.
  694. step = 0 ifTrue: [ self error: 'step must be non-zero' ].
  695. step < 0
  696. ifTrue: [ [ value >= stop ] whileTrue: [
  697. array at: pos put: value.
  698. pos := pos + 1.
  699. value := value + step ]]
  700. ifFalse: [ [ value <= stop ] whileTrue: [
  701. array at: pos put: value.
  702. pos := pos + 1.
  703. value := value + step ]].
  704. ^ array
  705. !
  706. truncated
  707. <
  708. if(self >>= 0) {
  709. return Math.floor(self);
  710. } else {
  711. return Math.floor(self * (-1)) * (-1);
  712. };
  713. >
  714. !
  715. | aNumber
  716. <return self | aNumber>
  717. ! !
  718. !Number methodsFor: 'copying'!
  719. copy
  720. ^ self
  721. !
  722. deepCopy
  723. ^ self copy
  724. ! !
  725. !Number methodsFor: 'enumerating'!
  726. timesRepeat: aBlock
  727. | count |
  728. count := 1.
  729. [ count > self ] whileFalse: [
  730. aBlock value.
  731. count := count + 1 ]
  732. !
  733. to: stop by: step do: aBlock
  734. | value |
  735. value := self.
  736. step = 0 ifTrue: [ self error: 'step must be non-zero' ].
  737. step < 0
  738. ifTrue: [ [ value >= stop ] whileTrue: [
  739. aBlock value: value.
  740. value := value + step ]]
  741. ifFalse: [ [ value <= stop ] whileTrue: [
  742. aBlock value: value.
  743. value := value + step ]]
  744. !
  745. to: stop do: aBlock
  746. "Evaluate aBlock for each number from self to aNumber."
  747. | nextValue |
  748. nextValue := self.
  749. [ nextValue <= stop ]
  750. whileTrue:
  751. [ aBlock value: nextValue.
  752. nextValue := nextValue + 1 ]
  753. ! !
  754. !Number methodsFor: 'mathematical functions'!
  755. ** exponent
  756. ^ self raisedTo: exponent
  757. !
  758. arcCos
  759. <return Math.acos(self);>
  760. !
  761. arcSin
  762. <return Math.asin(self);>
  763. !
  764. arcTan
  765. <return Math.atan(self);>
  766. !
  767. cos
  768. <return Math.cos(self);>
  769. !
  770. ln
  771. <return Math.log(self);>
  772. !
  773. log
  774. <return Math.log(self) / Math.LN10;>
  775. !
  776. log: aNumber
  777. <return Math.log(self) / Math.log(aNumber);>
  778. !
  779. raisedTo: exponent
  780. <return Math.pow(self, exponent);>
  781. !
  782. sign
  783. self isZero
  784. ifTrue: [ ^ 0 ].
  785. self positive
  786. ifTrue: [ ^ 1 ]
  787. ifFalse: [ ^ -1 ].
  788. !
  789. sin
  790. <return Math.sin(self);>
  791. !
  792. sqrt
  793. <return Math.sqrt(self)>
  794. !
  795. squared
  796. ^ self * self
  797. !
  798. tan
  799. <return Math.tan(self);>
  800. ! !
  801. !Number methodsFor: 'printing'!
  802. printOn: aStream
  803. aStream nextPutAll: self asString
  804. !
  805. printShowingDecimalPlaces: placesDesired
  806. <return self.toFixed(placesDesired)>
  807. ! !
  808. !Number methodsFor: 'testing'!
  809. even
  810. ^ 0 = (self \\ 2)
  811. !
  812. isImmutable
  813. ^ true
  814. !
  815. isNumber
  816. ^ true
  817. !
  818. isZero
  819. ^ self = 0
  820. !
  821. negative
  822. "Answer whether the receiver is mathematically negative."
  823. ^ self < 0
  824. !
  825. odd
  826. ^ self even not
  827. !
  828. positive
  829. "Answer whether the receiver is positive or equal to 0. (ST-80 protocol)."
  830. ^ self >= 0
  831. ! !
  832. !Number class methodsFor: 'helios'!
  833. heliosClass
  834. ^ 'magnitude'
  835. ! !
  836. !Number class methodsFor: 'instance creation'!
  837. e
  838. <return Math.E;>
  839. !
  840. pi
  841. <return Math.PI>
  842. ! !
  843. Object subclass: #Point
  844. instanceVariableNames: 'x y'
  845. package: 'Kernel-Objects'!
  846. !Point commentStamp!
  847. I represent an x-y pair of numbers usually designating a geometric coordinate.
  848. ## API
  849. Instances are traditionally created using the binary `#@` message to a number:
  850. 100@120
  851. Points can then be arithmetically manipulated:
  852. 100@100 + (10@10)
  853. ...or for example:
  854. (100@100) * 2
  855. **NOTE:** Creating a point with a negative y-value will need a space after `@` in order to avoid a parsing error:
  856. 100@ -100 "but 100@-100 would not parse"!
  857. !Point methodsFor: 'accessing'!
  858. x
  859. ^ x
  860. !
  861. x: aNumber
  862. x := aNumber
  863. !
  864. y
  865. ^ y
  866. !
  867. y: aNumber
  868. y := aNumber
  869. ! !
  870. !Point methodsFor: 'arithmetic'!
  871. * aPoint
  872. ^ Point x: self x * aPoint asPoint x y: self y * aPoint asPoint y
  873. !
  874. + aPoint
  875. ^ Point x: self x + aPoint asPoint x y: self y + aPoint asPoint y
  876. !
  877. - aPoint
  878. ^ Point x: self x - aPoint asPoint x y: self y - aPoint asPoint y
  879. !
  880. / aPoint
  881. ^ Point x: self x / aPoint asPoint x y: self y / aPoint asPoint y
  882. ! !
  883. !Point methodsFor: 'comparing'!
  884. < aPoint
  885. ^ self x < aPoint x and: [
  886. self y < aPoint y ]
  887. !
  888. <= aPoint
  889. ^ self x <= aPoint x and: [
  890. self y <= aPoint y ]
  891. !
  892. = aPoint
  893. ^ aPoint class = self class and: [
  894. (aPoint x = self x) & (aPoint y = self y) ]
  895. !
  896. > aPoint
  897. ^ self x > aPoint x and: [
  898. self y > aPoint y ]
  899. !
  900. >= aPoint
  901. ^ self x >= aPoint x and: [
  902. self y >= aPoint y ]
  903. ! !
  904. !Point methodsFor: 'converting'!
  905. asPoint
  906. ^ self
  907. ! !
  908. !Point methodsFor: 'printing'!
  909. printOn: aStream
  910. "Print receiver in classic x@y notation."
  911. x printOn: aStream.
  912. aStream nextPutAll: '@'.
  913. (y notNil and: [ y negative ]) ifTrue: [
  914. "Avoid ambiguous @- construct"
  915. aStream space ].
  916. y printOn: aStream
  917. ! !
  918. !Point methodsFor: 'transforming'!
  919. dist: aPoint
  920. "Answer the distance between aPoint and the receiver."
  921. | dx dy |
  922. dx := aPoint x - x.
  923. dy := aPoint y - y.
  924. ^ (dx * dx + (dy * dy)) sqrt
  925. !
  926. translateBy: delta
  927. "Answer a Point translated by delta (an instance of Point)."
  928. ^ (delta x + x) @ (delta y + y)
  929. ! !
  930. !Point class methodsFor: 'helios'!
  931. heliosClass
  932. ^ 'magnitude'
  933. ! !
  934. !Point class methodsFor: 'instance creation'!
  935. x: aNumber y: anotherNumber
  936. ^ self new
  937. x: aNumber;
  938. y: anotherNumber;
  939. yourself
  940. ! !
  941. Object subclass: #Random
  942. instanceVariableNames: ''
  943. package: 'Kernel-Objects'!
  944. !Random commentStamp!
  945. I an used to generate a random number and I am implemented as a trivial wrapper around javascript `Math.random()`.
  946. ## API
  947. The typical use case it to use the `#next` method like the following:
  948. Random new next
  949. This will return a float x where x < 1 and x > 0. If you want a random integer from 1 to 10 you can use `#atRandom`
  950. 10 atRandom
  951. A random number in a specific interval can be obtained with the following:
  952. (3 to: 7) atRandom
  953. Be aware that `#to:` does not create an Interval as in other Smalltalk implementations but in fact an `Array` of numbers, so it's better to use:
  954. 5 atRandom + 2
  955. Since `#atRandom` is implemented in `SequencableCollection` you can easy pick an element at random:
  956. #('a' 'b' 'c') atRandom
  957. As well as letter from a `String`:
  958. 'abc' atRandom
  959. Since Amber does not have Characters this will return a `String` of length 1 like for example `'b'`.!
  960. !Random methodsFor: 'accessing'!
  961. next
  962. <return Math.random()>
  963. !
  964. next: anInteger
  965. ^ (1 to: anInteger) collect: [ :each | self next ]
  966. ! !
  967. Object subclass: #UndefinedObject
  968. instanceVariableNames: ''
  969. package: 'Kernel-Objects'!
  970. !UndefinedObject commentStamp!
  971. I describe the behavior of my sole instance, `nil`. `nil` represents a prior value for variables that have not been initialized, or for results which are meaningless.
  972. `nil` is the Smalltalk equivalent of the `undefined` JavaScript object.
  973. __note:__ When sending messages to the `undefined` JavaScript object, it will be replaced by `nil`.!
  974. !UndefinedObject methodsFor: 'class creation'!
  975. subclass: aString instanceVariableNames: anotherString
  976. ^ self subclass: aString instanceVariableNames: anotherString package: nil
  977. !
  978. subclass: aString instanceVariableNames: aString2 category: aString3
  979. "Kept for compatibility."
  980. self deprecatedAPI.
  981. ^ self subclass: aString instanceVariableNames: aString2 package: aString3
  982. !
  983. subclass: aString instanceVariableNames: aString2 package: aString3
  984. ^ ClassBuilder new
  985. superclass: self subclass: aString asString instanceVariableNames: aString2 package: aString3
  986. ! !
  987. !UndefinedObject methodsFor: 'converting'!
  988. asJSON
  989. ^ null
  990. ! !
  991. !UndefinedObject methodsFor: 'copying'!
  992. deepCopy
  993. ^ self
  994. !
  995. shallowCopy
  996. ^ self
  997. ! !
  998. !UndefinedObject methodsFor: 'printing'!
  999. printOn: aStream
  1000. aStream nextPutAll: 'nil'
  1001. ! !
  1002. !UndefinedObject methodsFor: 'testing'!
  1003. ifNil: aBlock
  1004. "inlined in the Compiler"
  1005. ^ self ifNil: aBlock ifNotNil: []
  1006. !
  1007. ifNil: aBlock ifNotNil: anotherBlock
  1008. "inlined in the Compiler"
  1009. ^ aBlock value
  1010. !
  1011. ifNotNil: aBlock
  1012. "inlined in the Compiler"
  1013. ^ self
  1014. !
  1015. ifNotNil: aBlock ifNil: anotherBlock
  1016. "inlined in the Compiler"
  1017. ^ anotherBlock value
  1018. !
  1019. isImmutable
  1020. ^ true
  1021. !
  1022. isNil
  1023. ^ true
  1024. !
  1025. notNil
  1026. ^ false
  1027. ! !
  1028. !UndefinedObject class methodsFor: 'instance creation'!
  1029. new
  1030. self error: 'You cannot create new instances of UndefinedObject. Use nil'
  1031. ! !