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