Kernel-Objects.st 22 KB

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