Kernel-Objects.st 22 KB

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