Kernel-Objects.st 22 KB

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