001: /*=============================================================================
002: * Copyright Texas Instruments 2000-2004. All Rights Reserved.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * $ProjectHeader: OSCRIPT 0.155 Fri, 20 Dec 2002 18:34:22 -0800 rclark $
019: */
020:
021: package oscript.data;
022:
023: import oscript.exceptions.*;
024:
025: /**
026: * An exact number. An <code>OExactNumber</code> is immutable, meaning once
027: * the instance is constructed, it won't change.
028: *
029: * @author Rob Clark (rob@ti.com)
030: */
031: public class OExactNumber extends OObject implements
032: java.io.Externalizable {
033: /**
034: * The type object for an instance of ExactNumber.
035: */
036: public final static Value TYPE = BuiltinType
037: .makeBuiltinType("oscript.data.OExactNumber");
038: public final static String PARENT_TYPE_NAME = "oscript.data.OObject";
039: public final static String TYPE_NAME = "ExactNumber";
040: public final static String[] MEMBER_NAMES = new String[] {
041: "castToString", "castToExactNumber", "castToInexactNumber",
042: "castToJavaObject", "intValue", "floatValue", "shortValue",
043: "charValue", "byteValue", "bopBitwiseOr", "bopBitwiseOrR",
044: "bopBitwiseXor", "bopBitwiseXorR", "bopBitwiseAnd",
045: "bopBitwiseAndR", "bopEquals", "bopEqualsR",
046: "bopNotEquals", "bopNotEqualsR", "bopLessThan",
047: "bopLessThanR", "bopGreaterThan", "bopGreaterThanR",
048: "bopLessThanOrEquals", "bopLessThanOrEqualsR",
049: "bopGreaterThanOrEquals", "bopGreaterThanOrEqualsR",
050: "bopLeftShift", "bopLeftShiftR", "bopSignedRightShift",
051: "bopSignedRightShiftR", "bopUnsignedRightShift",
052: "bopUnsignedRightShiftR", "bopPlus", "bopPlusR",
053: "bopMinus", "bopMinusR", "bopMultiply", "bopMultiplyR",
054: "bopDivide", "bopDivideR", "bopRemainder", "bopRemainderR",
055: "uopIncrement", "uopDecrement", "uopPlus", "uopMinus",
056: "uopBitwiseNot" };
057:
058: /**
059: * On the theory that many OExactNumbers or on the range 0..?? and are
060: * short lived (for example, for loops, etc), a table of pre-allocated
061: * OExactNumbers is used
062: */
063: private static final int MIN_CACHED_EXACT_NUMBER = -100;
064: private static final int MAX_CACHED_EXACT_NUMBER = 2000;
065: private static final OExactNumber[] EXACT_NUMBERS = new OExactNumber[MAX_CACHED_EXACT_NUMBER
066: - MIN_CACHED_EXACT_NUMBER + 1];
067: static {
068: for (int i = MIN_CACHED_EXACT_NUMBER; i <= MAX_CACHED_EXACT_NUMBER; i++)
069: EXACT_NUMBERS[i - MIN_CACHED_EXACT_NUMBER] = new OExactNumber(
070: i);
071: }
072:
073: /*=======================================================================*/
074: /**
075: */
076: public static final OExactNumber makeExactNumber(long longVal) {
077: if ((MIN_CACHED_EXACT_NUMBER <= longVal)
078: && (longVal <= MAX_CACHED_EXACT_NUMBER))
079: return EXACT_NUMBERS[(int) longVal
080: - MIN_CACHED_EXACT_NUMBER];
081: //System.out.println("makeExactNumber: " + longVal);
082: return new OExactNumber(longVal);
083: }
084:
085: /*=======================================================================*/
086: // members:
087: private long longVal;
088:
089: // Externalizable support:
090: public OExactNumber() {
091: }
092:
093: /**
094: * Derived class that implements {@link java.io.Externalizable} must
095: * call this if it overrides it. It should override it to save/restore
096: * it's own state.
097: */
098: public void readExternal(java.io.ObjectInput in)
099: throws java.io.IOException {
100: longVal = in.readLong();
101: }
102:
103: /**
104: * Derived class that implements {@link java.io.Externalizable} must
105: * call this if it overrides it. It should override it to save/restore
106: * it's own state.
107: */
108: public void writeExternal(java.io.ObjectOutput out)
109: throws java.io.IOException {
110: out.writeLong(longVal);
111: }
112:
113: /*=======================================================================*/
114:
115: /*=======================================================================*/
116: /**
117: * Class Constructor.
118: *
119: * @param longVal the longeger value corresponding to this number
120: */
121: public OExactNumber(long longVal) {
122: super ();
123: this .longVal = longVal;
124: }
125:
126: /*=======================================================================*/
127: /**
128: * Class Constructor. This is the constructor that is called via a
129: * <code>BuiltinType</code> instance.
130: *
131: * @param args arguments to this constructor
132: * @throws PackagedScriptObjectException(Exception) if wrong number of args
133: */
134: public OExactNumber(oscript.util.MemberTable args) {
135: super ();
136:
137: if (args.length() != 1)
138: throw PackagedScriptObjectException
139: .makeExceptionWrapper(new OIllegalArgumentException(
140: "wrong number of args!"));
141: else
142: longVal = args.referenceAt(0).castToExactNumber();
143: }
144:
145: /*=======================================================================*/
146: /**
147: * Get the type of this object. The returned type doesn't have to take
148: * into account the possibility of a script type extending a built-in
149: * type, since that is handled by {@link #getType}.
150: *
151: * @return the object's type
152: */
153: protected Value getTypeImpl() {
154: return TYPE;
155: }
156:
157: /*=======================================================================*/
158: /**
159: * Return a hash code value for this object.
160: *
161: * @return a hash code value
162: * @see java.lang.Object#hashCode()
163: */
164: public int hashCode() {
165: return castToJavaObject().hashCode();
166: }
167:
168: /*=======================================================================*/
169: /**
170: * Compare two objects for equality.
171: *
172: * @param obj the object to compare to this object
173: * @return <code>true</code> if equals, else <code>false</code>
174: * @see java.lang.Object#equals(java.lang.Object)
175: */
176: public boolean equals(Object obj) {
177: if ((obj instanceof OExactNumber)
178: && (((OExactNumber) obj).longVal == longVal)) {
179: return true;
180: } else if ((obj instanceof Number)
181: && (((Number) obj).longValue() == longVal)) {
182: return true;
183: } else {
184: return false;
185: }
186: }
187:
188: /*=======================================================================*/
189: /**
190: * Convert this object to a native java <code>String</code> value.
191: *
192: * @return a String value
193: * @throws PackagedScriptObjectException(NoSuchMethodException)
194: */
195: public String castToString() throws PackagedScriptObjectException {
196: return String.valueOf(longVal);
197: }
198:
199: /*=======================================================================*/
200: /**
201: * Convert this object to a native java <code>long</code> value.
202: *
203: * @return a long value
204: * @throws PackagedScriptObjectException(NoSuchMethodException)
205: */
206: public long castToExactNumber()
207: throws PackagedScriptObjectException {
208: return longVal;
209: }
210:
211: public static Value _bopCast(Value val) {
212: if (val instanceof OExactNumber)
213: return val;
214: return makeExactNumber(val.castToExactNumber());
215: }
216:
217: /*=======================================================================*/
218: /**
219: * Convert this object to a native java <code>double</code> value.
220: *
221: * @return a double value
222: * @throws PackagedScriptObjectException(NoSuchMethodException)
223: */
224: public double castToInexactNumber()
225: throws PackagedScriptObjectException {
226: return (double) longVal;
227: }
228:
229: /*=======================================================================*/
230: /**
231: * Convert this object to a native java <code>Object</code> value.
232: *
233: * @return a java object
234: * @throws PackagedScriptObjectException(NoSuchMemberException)
235: */
236: public Object castToJavaObject()
237: throws PackagedScriptObjectException {
238: if (((long) ((int) longVal)) == longVal)
239: return new Integer((int) longVal);
240: else
241: return new Long(longVal);
242: }
243:
244: public int intValue() {
245: return (int) longVal;
246: }
247:
248: public float floatValue() {
249: return (float) longVal;
250: }
251:
252: public short shortValue() {
253: return (short) longVal;
254: }
255:
256: public char charValue() {
257: return (char) longVal;
258: }
259:
260: public byte byteValue() {
261: return (byte) longVal;
262: }
263:
264: /*=======================================================================*/
265: /* The binary operators:
266: */
267:
268: /*=======================================================================*/
269: /**
270: * Perform the bitwise OR operation.
271: *
272: * @param val the other value
273: * @return the result
274: * @throws PackagedScriptObjectException(NoSuchMethodException)
275: */
276: public Value bopBitwiseOr(Value val)
277: throws PackagedScriptObjectException {
278: try {
279: return OExactNumber.makeExactNumber(longVal
280: | val.castToExactNumber());
281: } catch (PackagedScriptObjectException e) {
282: return val.bopBitwiseOrR(this , e);
283: }
284: }
285:
286: public Value bopBitwiseOrR(Value val,
287: PackagedScriptObjectException e)
288: throws PackagedScriptObjectException {
289: return OExactNumber.makeExactNumber(val.castToExactNumber()
290: | longVal);
291: }
292:
293: /*=======================================================================*/
294: /**
295: * Perform the bitwise XOR operation.
296: *
297: * @param val the other value
298: * @return the result
299: * @throws PackagedScriptObjectException(NoSuchMethodException)
300: */
301: public Value bopBitwiseXor(Value val)
302: throws PackagedScriptObjectException {
303: try {
304: return OExactNumber.makeExactNumber(longVal
305: ^ val.castToExactNumber());
306: } catch (PackagedScriptObjectException e) {
307: return val.bopBitwiseXorR(this , e);
308: }
309: }
310:
311: public Value bopBitwiseXorR(Value val,
312: PackagedScriptObjectException e)
313: throws PackagedScriptObjectException {
314: return OExactNumber.makeExactNumber(val.castToExactNumber()
315: ^ longVal);
316: }
317:
318: /*=======================================================================*/
319: /**
320: * Perform the bitwise AND operation.
321: *
322: * @param val the other value
323: * @return the result
324: * @throws PackagedScriptObjectException(NoSuchMethodException)
325: */
326: public Value bopBitwiseAnd(Value val)
327: throws PackagedScriptObjectException {
328: try {
329: return OExactNumber.makeExactNumber(longVal
330: & val.castToExactNumber());
331: } catch (PackagedScriptObjectException e) {
332: return val.bopBitwiseAndR(this , e);
333: }
334: }
335:
336: public Value bopBitwiseAndR(Value val,
337: PackagedScriptObjectException e)
338: throws PackagedScriptObjectException {
339: return OExactNumber.makeExactNumber(val.castToExactNumber()
340: & longVal);
341: }
342:
343: /*=======================================================================*/
344: /**
345: * Perform the "==" operation.
346: *
347: * @param val the other value
348: * @return the result
349: * @throws PackagedScriptObjectException(NoSuchMethodException)
350: */
351: public Value bopEquals(Value val)
352: throws PackagedScriptObjectException {
353: try {
354: return OBoolean.makeBoolean(longVal == val
355: .castToExactNumber());
356: } catch (PackagedScriptObjectException e) {
357: return val.bopEqualsR(this , e);
358: }
359: }
360:
361: public Value bopEqualsR(Value val, PackagedScriptObjectException e)
362: throws PackagedScriptObjectException {
363: return OBoolean.makeBoolean(val.castToExactNumber() == longVal);
364: }
365:
366: /*=======================================================================*/
367: /**
368: * Perform the "!=" operation.
369: *
370: * @param val the other value
371: * @return the result
372: * @throws PackagedScriptObjectException(NoSuchMethodException)
373: */
374: public Value bopNotEquals(Value val)
375: throws PackagedScriptObjectException {
376: try {
377: return OBoolean.makeBoolean(longVal != val
378: .castToExactNumber());
379: } catch (PackagedScriptObjectException e) {
380: return val.bopNotEqualsR(this , e);
381: }
382: }
383:
384: public Value bopNotEqualsR(Value val,
385: PackagedScriptObjectException e)
386: throws PackagedScriptObjectException {
387: return OBoolean.makeBoolean(val.castToExactNumber() != longVal);
388: }
389:
390: /*=======================================================================*/
391: /**
392: * Perform the "<" operation.
393: *
394: * @param val the other value
395: * @return the result
396: * @throws PackagedScriptObjectException(NoSuchMethodException)
397: */
398: public Value bopLessThan(Value val)
399: throws PackagedScriptObjectException {
400: try {
401: return OBoolean.makeBoolean(longVal < val
402: .castToExactNumber());
403: } catch (PackagedScriptObjectException e) {
404: return val.bopLessThanR(this , e);
405: }
406: }
407:
408: public Value bopLessThanR(Value val, PackagedScriptObjectException e)
409: throws PackagedScriptObjectException {
410: return OBoolean.makeBoolean(val.castToExactNumber() < longVal);
411: }
412:
413: /*=======================================================================*/
414: /**
415: * Perform the ">" operation.
416: *
417: * @param val the other value
418: * @return the result
419: * @throws PackagedScriptObjectException(NoSuchMethodException)
420: */
421: public Value bopGreaterThan(Value val)
422: throws PackagedScriptObjectException {
423: try {
424: return OBoolean.makeBoolean(longVal > val
425: .castToExactNumber());
426: } catch (PackagedScriptObjectException e) {
427: return val.bopGreaterThanR(this , e);
428: }
429: }
430:
431: public Value bopGreaterThanR(Value val,
432: PackagedScriptObjectException e)
433: throws PackagedScriptObjectException {
434: return OBoolean.makeBoolean(val.castToExactNumber() > longVal);
435: }
436:
437: /*=======================================================================*/
438: /**
439: * Perform the "<=" operation.
440: *
441: * @param val the other value
442: * @return the result
443: * @throws PackagedScriptObjectException(NoSuchMethodException)
444: */
445: public Value bopLessThanOrEquals(Value val)
446: throws PackagedScriptObjectException {
447: try {
448: return OBoolean.makeBoolean(longVal <= val
449: .castToExactNumber());
450: } catch (PackagedScriptObjectException e) {
451: return val.bopLessThanOrEqualsR(this , e);
452: }
453: }
454:
455: public Value bopLessThanOrEqualsR(Value val,
456: PackagedScriptObjectException e)
457: throws PackagedScriptObjectException {
458: return OBoolean.makeBoolean(val.castToExactNumber() <= longVal);
459: }
460:
461: /*=======================================================================*/
462: /**
463: * Perform the ">=" operation.
464: *
465: * @param val the other value
466: * @return the result
467: * @throws PackagedScriptObjectException(NoSuchMethodException)
468: */
469: public Value bopGreaterThanOrEquals(Value val)
470: throws PackagedScriptObjectException {
471: try {
472: return OBoolean.makeBoolean(longVal >= val
473: .castToExactNumber());
474: } catch (PackagedScriptObjectException e) {
475: return val.bopGreaterThanOrEqualsR(this , e);
476: }
477: }
478:
479: public Value bopGreaterThanOrEqualsR(Value val,
480: PackagedScriptObjectException e)
481: throws PackagedScriptObjectException {
482: return OBoolean.makeBoolean(val.castToExactNumber() >= longVal);
483: }
484:
485: /*=======================================================================*/
486: /**
487: * Perform the "<<" operation.
488: *
489: * @param val the other value
490: * @return the result
491: * @throws PackagedScriptObjectException(NoSuchMethodException)
492: */
493: public Value bopLeftShift(Value val)
494: throws PackagedScriptObjectException {
495: try {
496: return OExactNumber.makeExactNumber(longVal << val
497: .castToExactNumber());
498: } catch (PackagedScriptObjectException e) {
499: return val.bopLeftShiftR(this , e);
500: }
501: }
502:
503: public Value bopLeftShiftR(Value val,
504: PackagedScriptObjectException e)
505: throws PackagedScriptObjectException {
506: return OExactNumber
507: .makeExactNumber(val.castToExactNumber() << longVal);
508: }
509:
510: /*=======================================================================*/
511: /**
512: * Perform the ">>" operation.
513: *
514: * @param val the other value
515: * @return the result
516: * @throws PackagedScriptObjectException(NoSuchMethodException)
517: */
518: public Value bopSignedRightShift(Value val)
519: throws PackagedScriptObjectException {
520: try {
521: return OExactNumber.makeExactNumber(longVal >> val
522: .castToExactNumber());
523: } catch (PackagedScriptObjectException e) {
524: return val.bopSignedRightShiftR(this , e);
525: }
526: }
527:
528: public Value bopSignedRightShiftR(Value val,
529: PackagedScriptObjectException e)
530: throws PackagedScriptObjectException {
531: return OExactNumber
532: .makeExactNumber(val.castToExactNumber() >> longVal);
533: }
534:
535: /*=======================================================================*/
536: /**
537: * Perform the ">>>" operation.
538: *
539: * @param val the other value
540: * @return the result
541: * @throws PackagedScriptObjectException(NoSuchMethodException)
542: */
543: public Value bopUnsignedRightShift(Value val)
544: throws PackagedScriptObjectException {
545: try {
546: return OExactNumber.makeExactNumber(longVal >>> val
547: .castToExactNumber());
548: } catch (PackagedScriptObjectException e) {
549: return val.bopUnsignedRightShiftR(this , e);
550: }
551: }
552:
553: public Value bopUnsignedRightShiftR(Value val,
554: PackagedScriptObjectException e)
555: throws PackagedScriptObjectException {
556: return OExactNumber
557: .makeExactNumber(val.castToExactNumber() >>> longVal);
558: }
559:
560: /*=======================================================================*/
561: /**
562: * Perform the "+" operation.
563: *
564: * @param val the other value
565: * @return the result
566: * @throws PackagedScriptObjectException(NoSuchMethodException)
567: */
568: public Value bopPlus(Value val)
569: throws PackagedScriptObjectException {
570: try {
571: return OExactNumber.makeExactNumber(longVal
572: + val.castToExactNumber());
573: } catch (PackagedScriptObjectException e) {
574: return val.bopPlusR(this , e);
575: }
576: }
577:
578: public Value bopPlusR(Value val, PackagedScriptObjectException e)
579: throws PackagedScriptObjectException {
580: return OExactNumber.makeExactNumber(val.castToExactNumber()
581: + longVal);
582: }
583:
584: /*=======================================================================*/
585: /**
586: * Perform the "-" operation.
587: *
588: * @param val the other value
589: * @return the result
590: * @throws PackagedScriptObjectException(NoSuchMethodException)
591: */
592: public Value bopMinus(Value val)
593: throws PackagedScriptObjectException {
594: try {
595: return OExactNumber.makeExactNumber(longVal
596: - val.castToExactNumber());
597: } catch (PackagedScriptObjectException e) {
598: return val.bopMinusR(this , e);
599: }
600: }
601:
602: public Value bopMinusR(Value val, PackagedScriptObjectException e)
603: throws PackagedScriptObjectException {
604: return OExactNumber.makeExactNumber(val.castToExactNumber()
605: - longVal);
606: }
607:
608: /*=======================================================================*/
609: /**
610: * Perform the "*" operation.
611: *
612: * @param val the other value
613: * @return the result
614: * @throws PackagedScriptObjectException(NoSuchMethodException)
615: */
616: public Value bopMultiply(Value val)
617: throws PackagedScriptObjectException {
618: try {
619: return OExactNumber.makeExactNumber(longVal
620: * val.castToExactNumber());
621: } catch (PackagedScriptObjectException e) {
622: return val.bopMultiplyR(this , e);
623: }
624: }
625:
626: public Value bopMultiplyR(Value val, PackagedScriptObjectException e)
627: throws PackagedScriptObjectException {
628: return OExactNumber.makeExactNumber(val.castToExactNumber()
629: * longVal);
630: }
631:
632: /*=======================================================================*/
633: /**
634: * Perform the "/" operation.
635: *
636: * @param val the other value
637: * @return the result
638: * @throws PackagedScriptObjectException(NoSuchMethodException)
639: */
640: public Value bopDivide(Value val)
641: throws PackagedScriptObjectException {
642: long l;
643: try {
644: l = val.castToExactNumber();
645: } catch (PackagedScriptObjectException e) {
646: return val.bopDivideR(this , e);
647: }
648:
649: if (l == 0)
650: throw PackagedScriptObjectException
651: .makeExceptionWrapper(new OException(
652: "divide by zero"));
653:
654: return OExactNumber.makeExactNumber(longVal / l);
655: }
656:
657: public Value bopDivideR(Value val, PackagedScriptObjectException e)
658: throws PackagedScriptObjectException {
659: return OExactNumber.makeExactNumber(val.castToExactNumber()
660: / longVal);
661: }
662:
663: /*=======================================================================*/
664: /**
665: * Perform the "%" operation.
666: *
667: * @param val the other value
668: * @return the result
669: * @throws PackagedScriptObjectException(NoSuchMethodException)
670: */
671: public Value bopRemainder(Value val)
672: throws PackagedScriptObjectException {
673: try {
674: return OExactNumber.makeExactNumber(longVal
675: % val.castToExactNumber());
676: } catch (PackagedScriptObjectException e) {
677: return val.bopRemainderR(this , e);
678: }
679: }
680:
681: public Value bopRemainderR(Value val,
682: PackagedScriptObjectException e)
683: throws PackagedScriptObjectException {
684: return OExactNumber.makeExactNumber(val.castToExactNumber()
685: % longVal);
686: }
687:
688: /*=======================================================================*/
689: /* The unary operators:
690: */
691:
692: /*=======================================================================*/
693: /**
694: * Perform the "++" operation.
695: *
696: * @param val the other value
697: * @return the result
698: * @throws PackagedScriptObjectException(NoSuchMethodException)
699: */
700: public Value uopIncrement() throws PackagedScriptObjectException {
701: return OExactNumber.makeExactNumber(longVal + 1);
702: }
703:
704: /*=======================================================================*/
705: /**
706: * Perform the "--" operation.
707: *
708: * @param val the other value
709: * @return the result
710: * @throws PackagedScriptObjectException(NoSuchMethodException)
711: */
712: public Value uopDecrement() throws PackagedScriptObjectException {
713: return OExactNumber.makeExactNumber(longVal - 1);
714: }
715:
716: /*=======================================================================*/
717: /**
718: * Perform the "+" operation.
719: *
720: * @param val the other value
721: * @return the result
722: * @throws PackagedScriptObjectException(NoSuchMethodException)
723: */
724: public Value uopPlus() throws PackagedScriptObjectException {
725: return OExactNumber.makeExactNumber(+longVal);
726: }
727:
728: /*=======================================================================*/
729: /**
730: * Perform the "-" operation.
731: *
732: * @param val the other value
733: * @return the result
734: * @throws PackagedScriptObjectException(NoSuchMethodException)
735: */
736: public Value uopMinus() throws PackagedScriptObjectException {
737: return OExactNumber.makeExactNumber(-longVal);
738: }
739:
740: /*=======================================================================*/
741: /**
742: * Perform the "~" operation.
743: *
744: * @param val the other value
745: * @return the result
746: * @throws PackagedScriptObjectException(NoSuchMethodException)
747: */
748: public Value uopBitwiseNot() throws PackagedScriptObjectException {
749: return OExactNumber.makeExactNumber(~longVal);
750: }
751: }
752:
753: /*
754: * Local Variables:
755: * tab-width: 2
756: * indent-tabs-mode: nil
757: * mode: java
758: * c-indentation-style: java
759: * c-basic-offset: 2
760: * eval: (c-set-offset 'substatement-open '0)
761: * eval: (c-set-offset 'case-label '+)
762: * eval: (c-set-offset 'inclass '+)
763: * eval: (c-set-offset 'inline-open '0)
764: * End:
765: */
|