Kernel-Objects.st 22 KB

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