Kernel-Objects.st 22 KB

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