Kernel-Objects.st 23 KB

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