Kernel-Objects.st 23 KB

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