/interpreter/tags/at2dist110511/src/edu/vub/at/objects/natives/NATNumber.java

http://ambienttalk.googlecode.com/ · Java · 654 lines · 470 code · 48 blank · 136 comment · 29 complexity · fe5ba223f978af2fc2d38f167cda9523 MD5 · raw file

  1. /**
  2. * AmbientTalk/2 Project
  3. * NATNumber.java created on 26-jul-2006 at 16:32:54
  4. * (c) Programming Technology Lab, 2006 - 2007
  5. * Authors: Tom Van Cutsem & Stijn Mostinckx
  6. *
  7. * Permission is hereby granted, free of charge, to any person
  8. * obtaining a copy of this software and associated documentation
  9. * files (the "Software"), to deal in the Software without
  10. * restriction, including without limitation the rights to use,
  11. * copy, modify, merge, publish, distribute, sublicense, and/or
  12. * sell copies of the Software, and to permit persons to whom the
  13. * Software is furnished to do so, subject to the following
  14. * conditions:
  15. *
  16. * The above copyright notice and this permission notice shall be
  17. * included in all copies or substantial portions of the Software.
  18. *
  19. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  20. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  21. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  22. * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  23. * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  24. * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  25. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  26. * OTHER DEALINGS IN THE SOFTWARE.
  27. */
  28. package edu.vub.at.objects.natives;
  29. import edu.vub.at.eval.Evaluator;
  30. import edu.vub.at.exceptions.InterpreterException;
  31. import edu.vub.at.exceptions.XIllegalArgument;
  32. import edu.vub.at.exceptions.XSelectorNotFound;
  33. import edu.vub.at.exceptions.XTypeMismatch;
  34. import edu.vub.at.objects.ATBoolean;
  35. import edu.vub.at.objects.ATClosure;
  36. import edu.vub.at.objects.ATContext;
  37. import edu.vub.at.objects.ATFraction;
  38. import edu.vub.at.objects.ATMethod;
  39. import edu.vub.at.objects.ATNil;
  40. import edu.vub.at.objects.ATNumber;
  41. import edu.vub.at.objects.ATNumeric;
  42. import edu.vub.at.objects.ATObject;
  43. import edu.vub.at.objects.ATTable;
  44. import edu.vub.at.objects.ATText;
  45. import edu.vub.at.objects.coercion.NativeTypeTags;
  46. import edu.vub.at.objects.grammar.ATSymbol;
  47. import edu.vub.at.objects.mirrors.DirectNativeMethod;
  48. import edu.vub.at.objects.mirrors.Reflection;
  49. import edu.vub.util.TempFieldGenerator;
  50. import java.util.HashMap;
  51. /**
  52. * The native implementation of an AmbientTalk number.
  53. * A number is implemented by a Java int.
  54. *
  55. * @author smostinc
  56. */
  57. public final class NATNumber extends NATNumeric implements ATNumber {
  58. public static final NATNumber ZERO = new NATNumber(0);
  59. public static final NATNumber ONE = new NATNumber(1);
  60. public static final NATNumber MONE = new NATNumber(-1);
  61. public final int javaValue;
  62. /**
  63. * This method currently serves as a hook for number creation.
  64. * Currently number objects are not reused, but this might change in the future.
  65. */
  66. public static final NATNumber atValue(int javaNumber) {
  67. return new NATNumber(javaNumber);
  68. }
  69. private NATNumber(int javaNumber) {
  70. javaValue = javaNumber;
  71. }
  72. public ATBoolean base__opeql__opeql_(ATObject comparand) throws XTypeMismatch {
  73. if (comparand.isNativeNumber()) {
  74. return NATBoolean.atValue(javaValue == comparand.asNativeNumber().javaValue);
  75. } else {
  76. return NATBoolean._FALSE_;
  77. }
  78. }
  79. public ATNumber asNumber() throws XTypeMismatch { return this; }
  80. public boolean isNativeNumber() { return true; }
  81. public NATNumber asNativeNumber() { return this; }
  82. public NATText meta_print() throws InterpreterException {
  83. return NATText.atValue(String.valueOf(javaValue));
  84. }
  85. public NATText impl_asCode(TempFieldGenerator objectMap) throws InterpreterException {
  86. return NATText.atValue(String.valueOf(javaValue));
  87. }
  88. public ATTable meta_typeTags() throws InterpreterException {
  89. return NATTable.of(NativeTypeTags._NUMBER_, NativeTypeTags._ISOLATE_);
  90. }
  91. // contract with NATNumeric
  92. protected double getJavaValue() { return javaValue; }
  93. public int hashCode() { return javaValue; }
  94. /* -----------------------------------
  95. * - base-level interface to numbers -
  96. * ----------------------------------- */
  97. // iteration constructs
  98. /**
  99. * NBR(n).doTimes: { |i| code } => for i = 1 to n do code.eval(i) ; nil
  100. */
  101. public ATNil base_doTimes_(ATClosure code) throws InterpreterException {
  102. for (int i = 1; i <= javaValue; i++) {
  103. code.base_apply(NATTable.atValue(new ATObject[] { NATNumber.atValue(i) }));
  104. }
  105. return Evaluator.getNil();
  106. }
  107. /**
  108. * NBR(start).to: NBR(stop) do: { |i| code } => for i = start to stop do code.eval(i) ; nil
  109. * Also works if stop > start, in which case it becomes a downTo.
  110. *
  111. * If start = stop, the code is not executed.
  112. */
  113. public ATNil base_to_do_(ATNumber end, ATClosure code) throws InterpreterException {
  114. return this.base_to_step_do_(end, NATNumber.ONE, code);
  115. }
  116. /**
  117. * NBR(start).to: NBR(stop) step: NBR(inc) do: { |i| code } =>
  118. * for i = start; i < stop; i++ do code.eval(i) ; nil
  119. * Also works if stop > start, in which case it becomes a downTo.
  120. */
  121. public ATNil base_to_step_do_(ATNumber end, ATNumber inc, ATClosure code) throws InterpreterException {
  122. int stop = end.asNativeNumber().javaValue;
  123. int step = inc.asNativeNumber().javaValue;
  124. int start = javaValue;
  125. if (start > stop) {
  126. for (int i = start; i > stop; i -= step) {
  127. code.base_apply(NATTable.atValue(new ATObject[] { NATNumber.atValue(i) }));
  128. }
  129. } else {
  130. for (int i = start; i < stop; i+= step) {
  131. code.base_apply(NATTable.atValue(new ATObject[] { NATNumber.atValue(i) }));
  132. }
  133. }
  134. return Evaluator.getNil();
  135. }
  136. /**
  137. * NBR(start) ** NBR(stop) => [ start, ..., stop [
  138. *
  139. * Example:
  140. * 2 ** 5 => [ 2, 3, 4 ]
  141. * 5 ** 2 => [ 5, 4, 3 ]
  142. */
  143. public ATTable base__optms__optms_(ATNumber end) throws InterpreterException {
  144. int stop = end.asNativeNumber().javaValue;
  145. int start = javaValue;
  146. if (start < stop) {
  147. ATObject[] tbl = new ATObject[stop - start];
  148. for (int i = 0; i < tbl.length; i++) {
  149. tbl[i] = NATNumber.atValue(start + i);
  150. }
  151. return NATTable.atValue(tbl);
  152. } else {
  153. ATObject[] tbl = new ATObject[start - stop];
  154. for (int i = 0; i < tbl.length; i++) {
  155. tbl[i] = NATNumber.atValue(start - i);
  156. }
  157. return NATTable.atValue(tbl);
  158. }
  159. }
  160. /**
  161. * NBR(start) *** NBR(stop) => [ start, ..., stop ]
  162. *
  163. * Example:
  164. * 2 *** 5 => [ 2, 3, 4, 5 ]
  165. * 5 *** 2 => [ 5, 4, 3, 2 ]
  166. */
  167. public ATTable base__optms__optms__optms_(ATNumber end) throws InterpreterException {
  168. // x *** y == x ** y+1 iff x < y
  169. // x *** y == x ** y-1 iff y > x
  170. int stop = end.asNativeNumber().javaValue;
  171. if (javaValue <= stop)
  172. return this.base__optms__optms_(end.base_inc().asNumber());
  173. else
  174. return this.base__optms__optms_(end.base_dec().asNumber());
  175. }
  176. // Number arithmetic operations
  177. /**
  178. * NBR(n).inc() => NBR(n+1)
  179. */
  180. public ATNumber base_inc() {
  181. return NATNumber.atValue(javaValue+1);
  182. }
  183. /**
  184. * NBR(n).dec() => NBR(n-1)
  185. */
  186. public ATNumber base_dec() {
  187. return NATNumber.atValue(javaValue-1);
  188. }
  189. /**
  190. * NBR(n).abs() => NBR(abs(n))
  191. */
  192. public ATNumber base_abs() {
  193. return NATNumber.atValue(Math.abs(javaValue));
  194. }
  195. public ATNumber base_ceiling() throws InterpreterException {
  196. return this;
  197. }
  198. public ATNumber base_floor() throws InterpreterException {
  199. return this;
  200. }
  201. public ATNumber base_round() throws InterpreterException {
  202. return this;
  203. }
  204. /**
  205. * NBR(start) ?? NBR(stop) => FRC(n) where n chosen randomly in [ start, stop [
  206. */
  207. public ATFraction base__opque__opque_(ATNumber nbr) throws InterpreterException {
  208. int stop = nbr.asNativeNumber().javaValue;
  209. double rnd = Math.random(); // 0 <= rnd < 1.0
  210. double frc = (rnd * (stop - javaValue)) + javaValue;
  211. return NATFraction.atValue(frc);
  212. }
  213. /**
  214. * NBR(n) % NBR(r) => NBR(n % r)
  215. */
  216. public ATNumber base__oprem_(ATNumber n) throws InterpreterException {
  217. return NATNumber.atValue(javaValue % n.asNativeNumber().javaValue);
  218. }
  219. /**
  220. * NBR(n) /- NBR(d) => NBR(n / d)
  221. */
  222. public ATNumber base__opdiv__opmns_(ATNumber n) throws InterpreterException {
  223. return NATNumber.atValue(javaValue / n.asNativeNumber().javaValue);
  224. }
  225. // Numeric arithmetic operations
  226. // addition +
  227. public ATNumeric base__oppls_(ATNumeric other) throws InterpreterException {
  228. return other.base_addNumber(this);
  229. }
  230. public ATNumeric base_addNumber(ATNumber other) throws InterpreterException {
  231. return NATNumber.atValue(other.asNativeNumber().javaValue + javaValue);
  232. }
  233. public ATNumeric base_addFraction(ATFraction other) throws InterpreterException {
  234. return NATFraction.atValue(other.asNativeFraction().javaValue + javaValue);
  235. }
  236. // subtraction -
  237. public ATNumeric base__opmns_(ATNumeric other) throws InterpreterException {
  238. return other.base_subtractNumber(this);
  239. }
  240. public ATNumeric base_subtractNumber(ATNumber other) throws InterpreterException {
  241. return NATNumber.atValue(other.asNativeNumber().javaValue - javaValue);
  242. }
  243. public ATNumeric base_subtractFraction(ATFraction other) throws InterpreterException {
  244. return NATFraction.atValue(other.asNativeFraction().javaValue - javaValue);
  245. }
  246. // multiplication *
  247. public ATNumeric base__optms_(ATNumeric other) throws InterpreterException {
  248. return other.base_timesNumber(this);
  249. }
  250. public ATNumeric base_timesNumber(ATNumber other) throws InterpreterException {
  251. return NATNumber.atValue(other.asNativeNumber().javaValue * javaValue);
  252. }
  253. public ATNumeric base_timesFraction(ATFraction other) throws InterpreterException {
  254. return NATFraction.atValue(other.asNativeFraction().javaValue * javaValue);
  255. }
  256. // division /
  257. public ATNumeric base__opdiv_(ATNumeric other) throws InterpreterException {
  258. return other.base_divideNumber(this);
  259. }
  260. public ATNumeric base_divideNumber(ATNumber other) throws InterpreterException {
  261. if (javaValue == 0)
  262. throw new XIllegalArgument("Division by zero: " + other);
  263. return NATFraction.atValue((other.asNativeNumber().javaValue * 1.0) / javaValue);
  264. }
  265. public ATNumeric base_divideFraction(ATFraction other) throws InterpreterException {
  266. if (javaValue == 0)
  267. throw new XIllegalArgument("Division by zero: " + other);
  268. return NATFraction.atValue(other.asNativeFraction().javaValue / javaValue);
  269. }
  270. // comparison: generalized equality <=>
  271. public ATNumeric base__opltx__opeql__opgtx_(ATNumeric other) throws InterpreterException {
  272. return other.base_gequalsNumber(this);
  273. }
  274. public ATNumeric base_gequalsNumber(ATNumber other) throws InterpreterException {
  275. int n = other.asNativeNumber().javaValue;
  276. if (n < javaValue) {
  277. return NATNumber.MONE; // -1
  278. } else if (n > javaValue) {
  279. return NATNumber.ONE; // +1
  280. } else {
  281. return NATNumber.ZERO; // 0
  282. }
  283. }
  284. public ATNumeric base_gequalsFraction(ATFraction other) throws InterpreterException {
  285. double n = other.asNativeFraction().javaValue;
  286. if (n < javaValue) {
  287. return NATNumber.MONE; // -1
  288. } else if (n > javaValue) {
  289. return NATNumber.ONE; // +1
  290. } else {
  291. return NATNumber.ZERO; // 0
  292. }
  293. }
  294. /**
  295. * Converts an AmbientTalk number representing a time period in milliseconds
  296. * into a Java long representing the same time period in milliseconds.
  297. *
  298. * @return a Java long representation of self.
  299. */
  300. public long base_millisec() throws InterpreterException {
  301. return javaValue;
  302. }
  303. /**
  304. * Converts an AmbientTalk number representing a time period in seconds
  305. * into a Java long * 1000 representing a time period in milliseconds.
  306. *
  307. * @return a Java long representation of self * 1000.
  308. */
  309. public long base_seconds() throws InterpreterException {
  310. return javaValue * 1000;
  311. }
  312. /**
  313. * Converts an AmbientTalk number representing a minute time period
  314. * into a Java long * 1000 * 60 representing a
  315. * millisecond time period.
  316. *
  317. * @return a Java long representation of self * 1000 * 60.
  318. */
  319. public long base_minutes() throws InterpreterException {
  320. return javaValue * 60 * 1000;
  321. }
  322. /**
  323. * NUM(n).toText() = TXT(String.valueOf(n))
  324. */
  325. public ATText base_toText() throws InterpreterException {
  326. return NATText.atValue(String.valueOf(javaValue));
  327. }
  328. /**
  329. * This hashmap stores all native methods of native AmbientTalk numbers.
  330. * It is populated when this class is loaded, and shared between all
  331. * AmbientTalk actors on this VM. This is safe, since {@link DirectNativeMethod}
  332. * instances are all immutable.
  333. */
  334. private static final HashMap<String, ATMethod> _meths = new HashMap<String, ATMethod>();
  335. // initialize NATNumber methods
  336. static {
  337. _meths.put("doTimes:", new DirectNativeMethod("doTimes:") {
  338. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  339. NATNumber self = ctx.base_receiver().asNativeNumber();
  340. checkArity(args, 1);
  341. ATClosure code = get(args, 1).asClosure();
  342. return self.base_doTimes_(code);
  343. }
  344. });
  345. _meths.put("to:do:", new DirectNativeMethod("to:do:") {
  346. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  347. NATNumber self = ctx.base_receiver().asNativeNumber();
  348. checkArity(args, 2);
  349. ATNumber nbr = get(args, 1).asNumber();
  350. ATClosure code = get(args, 2).asClosure();
  351. return self.base_to_do_(nbr, code);
  352. }
  353. });
  354. _meths.put("to:step:do:", new DirectNativeMethod("to:step:do:") {
  355. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  356. NATNumber self = ctx.base_receiver().asNativeNumber();
  357. checkArity(args, 3);
  358. ATNumber nbr = get(args, 1).asNumber();
  359. ATNumber step = get(args, 2).asNumber();
  360. ATClosure code = get(args, 3).asClosure();
  361. return self.base_to_step_do_(nbr, step, code);
  362. }
  363. });
  364. _meths.put("**", new DirectNativeMethod("**") {
  365. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  366. NATNumber self = ctx.base_receiver().asNativeNumber();
  367. checkArity(args, 1);
  368. ATNumber end = get(args, 1).asNumber();
  369. return self.base__optms__optms_(end);
  370. }
  371. });
  372. _meths.put("***", new DirectNativeMethod("***") {
  373. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  374. NATNumber self = ctx.base_receiver().asNativeNumber();
  375. checkArity(args, 1);
  376. ATNumber end = get(args, 1).asNumber();
  377. return self.base__optms__optms__optms_(end);
  378. }
  379. });
  380. _meths.put("inc", new DirectNativeMethod("inc") {
  381. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  382. NATNumber self = ctx.base_receiver().asNativeNumber();
  383. checkArity(args, 0);
  384. return self.base_inc();
  385. }
  386. });
  387. _meths.put("dec", new DirectNativeMethod("dec") {
  388. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  389. NATNumber self = ctx.base_receiver().asNativeNumber();
  390. checkArity(args, 0);
  391. return self.base_dec();
  392. }
  393. });
  394. _meths.put("abs", new DirectNativeMethod("abs") {
  395. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  396. NATNumber self = ctx.base_receiver().asNativeNumber();
  397. checkArity(args, 0);
  398. return self.base_abs();
  399. }
  400. });
  401. _meths.put("ceiling", new DirectNativeMethod("ceiling") {
  402. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  403. NATNumber self = ctx.base_receiver().asNativeNumber();
  404. checkArity(args, 0);
  405. return self.base_ceiling();
  406. }
  407. });
  408. _meths.put("floor", new DirectNativeMethod("floor") {
  409. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  410. NATNumber self = ctx.base_receiver().asNativeNumber();
  411. checkArity(args, 0);
  412. return self.base_floor();
  413. }
  414. });
  415. _meths.put("round", new DirectNativeMethod("round") {
  416. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  417. NATNumber self = ctx.base_receiver().asNativeNumber();
  418. checkArity(args, 0);
  419. return self.base_round();
  420. }
  421. });
  422. _meths.put("??", new DirectNativeMethod("??") {
  423. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  424. NATNumber self = ctx.base_receiver().asNativeNumber();
  425. checkArity(args, 1);
  426. ATNumber nbr = get(args,1).asNumber();
  427. return self.base__opque__opque_(nbr);
  428. }
  429. });
  430. _meths.put("%", new DirectNativeMethod("%") {
  431. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  432. NATNumber self = ctx.base_receiver().asNativeNumber();
  433. checkArity(args, 1);
  434. ATNumber nbr = get(args,1).asNumber();
  435. return self.base__oprem_(nbr);
  436. }
  437. });
  438. _meths.put("/-", new DirectNativeMethod("/-") {
  439. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  440. NATNumber self = ctx.base_receiver().asNativeNumber();
  441. checkArity(args, 1);
  442. ATNumber nbr = get(args,1).asNumber();
  443. return self.base__opdiv__opmns_(nbr);
  444. }
  445. });
  446. _meths.put("+", new DirectNativeMethod("+") {
  447. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  448. NATNumber self = ctx.base_receiver().asNativeNumber();
  449. checkArity(args, 1);
  450. ATNumeric nbr = get(args,1).asNativeNumeric();
  451. return self.base__oppls_(nbr);
  452. }
  453. });
  454. _meths.put("addNumber", new DirectNativeMethod("addNumber") {
  455. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  456. NATNumber self = ctx.base_receiver().asNativeNumber();
  457. checkArity(args, 1);
  458. ATNumber nbr = get(args,1).asNumber();
  459. return self.base_addNumber(nbr);
  460. }
  461. });
  462. _meths.put("addFraction", new DirectNativeMethod("addFraction") {
  463. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  464. NATNumber self = ctx.base_receiver().asNativeNumber();
  465. checkArity(args, 1);
  466. ATFraction frc = get(args,1).asNativeFraction();
  467. return self.base_addFraction(frc);
  468. }
  469. });
  470. _meths.put("-", new DirectNativeMethod("-") {
  471. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  472. NATNumber self = ctx.base_receiver().asNativeNumber();
  473. checkArity(args, 1);
  474. ATNumeric nbr = get(args,1).asNativeNumeric();
  475. return self.base__opmns_(nbr);
  476. }
  477. });
  478. _meths.put("subtractNumber", new DirectNativeMethod("subtractNumber") {
  479. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  480. NATNumber self = ctx.base_receiver().asNativeNumber();
  481. checkArity(args, 1);
  482. ATNumber nbr = get(args,1).asNumber();
  483. return self.base_subtractNumber(nbr);
  484. }
  485. });
  486. _meths.put("subtractFraction", new DirectNativeMethod("subtractFraction") {
  487. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  488. NATNumber self = ctx.base_receiver().asNativeNumber();
  489. checkArity(args, 1);
  490. ATFraction frc = get(args,1).asNativeFraction();
  491. return self.base_subtractFraction(frc);
  492. }
  493. });
  494. _meths.put("*", new DirectNativeMethod("*") {
  495. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  496. NATNumber self = ctx.base_receiver().asNativeNumber();
  497. checkArity(args, 1);
  498. ATNumeric nbr = get(args,1).asNativeNumeric();
  499. return self.base__optms_(nbr);
  500. }
  501. });
  502. _meths.put("timesNumber", new DirectNativeMethod("timesNumber") {
  503. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  504. NATNumber self = ctx.base_receiver().asNativeNumber();
  505. checkArity(args, 1);
  506. ATNumber nbr = get(args,1).asNumber();
  507. return self.base_timesNumber(nbr);
  508. }
  509. });
  510. _meths.put("timesFraction", new DirectNativeMethod("timesFraction") {
  511. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  512. NATNumber self = ctx.base_receiver().asNativeNumber();
  513. checkArity(args, 1);
  514. ATFraction frc = get(args,1).asNativeFraction();
  515. return self.base_timesFraction(frc);
  516. }
  517. });
  518. _meths.put("/", new DirectNativeMethod("/") {
  519. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  520. NATNumber self = ctx.base_receiver().asNativeNumber();
  521. checkArity(args, 1);
  522. ATNumeric nbr = get(args,1).asNativeNumeric();
  523. return self.base__opdiv_(nbr);
  524. }
  525. });
  526. _meths.put("divideNumber", new DirectNativeMethod("divideNumber") {
  527. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  528. NATNumber self = ctx.base_receiver().asNativeNumber();
  529. checkArity(args, 1);
  530. ATNumber nbr = get(args,1).asNumber();
  531. return self.base_divideNumber(nbr);
  532. }
  533. });
  534. _meths.put("divideFraction", new DirectNativeMethod("divideFraction") {
  535. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  536. NATNumber self = ctx.base_receiver().asNativeNumber();
  537. checkArity(args, 1);
  538. ATFraction frc = get(args,1).asNativeFraction();
  539. return self.base_divideFraction(frc);
  540. }
  541. });
  542. _meths.put("<=>", new DirectNativeMethod("<=>") {
  543. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  544. NATNumber self = ctx.base_receiver().asNativeNumber();
  545. checkArity(args, 1);
  546. ATNumeric nbr = get(args,1).asNativeNumeric();
  547. return self.base__opltx__opeql__opgtx_(nbr);
  548. }
  549. });
  550. _meths.put("gequalsNumber", new DirectNativeMethod("gequalsNumber") {
  551. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  552. NATNumber self = ctx.base_receiver().asNativeNumber();
  553. checkArity(args, 1);
  554. ATNumber nbr = get(args,1).asNumber();
  555. return self.base_gequalsNumber(nbr);
  556. }
  557. });
  558. _meths.put("gequalsFraction", new DirectNativeMethod("gequalsFraction") {
  559. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  560. NATNumber self = ctx.base_receiver().asNativeNumber();
  561. checkArity(args, 1);
  562. ATFraction frc = get(args,1).asNativeFraction();
  563. return self.base_gequalsFraction(frc);
  564. }
  565. });
  566. _meths.put("==", new DirectNativeMethod("==") {
  567. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  568. NATNumber self = ctx.base_receiver().asNativeNumber();
  569. checkArity(args, 1);
  570. ATObject comparand = get(args, 1);
  571. return self.base__opeql__opeql_(comparand);
  572. }
  573. });
  574. _meths.put("toText", new DirectNativeMethod("toText") {
  575. public ATObject base_apply(ATTable args, ATContext ctx) throws InterpreterException {
  576. NATNumber self = ctx.base_receiver().asNativeNumber();
  577. checkArity(args, 0);
  578. return self.base_toText();
  579. }
  580. });
  581. }
  582. /**
  583. * Overrides the default AmbientTalk native object behavior of extracting native
  584. * methods based on the 'base_' naming convention. Instead, native AT numbers use
  585. * an explicit hashmap of native methods. This is much faster than the default
  586. * behavior, which requires reflection.
  587. */
  588. protected boolean hasLocalMethod(ATSymbol atSelector) throws InterpreterException {
  589. if (_meths.containsKey(atSelector.base_text().asNativeText().javaValue)) {
  590. return true;
  591. } else {
  592. return super.hasLocalMethod(atSelector);
  593. }
  594. }
  595. /**
  596. * @see NATNumber#hasLocalMethod(ATSymbol)
  597. */
  598. protected ATMethod getLocalMethod(ATSymbol selector) throws InterpreterException {
  599. ATMethod val = _meths.get(selector.base_text().asNativeText().javaValue);
  600. if (val == null) {
  601. return super.getLocalMethod(selector);
  602. //throw new XSelectorNotFound(selector, this);
  603. }
  604. return val;
  605. }
  606. }