Kernel-Objects.st 22 KB

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