0001: /*
0002: * $Id: Any.java,v 1.92 2002/09/16 08:05:02 jkl Exp $
0003: *
0004: * Copyright (c) 2002 Njet Communications Ltd. All Rights Reserved.
0005: *
0006: * Use is subject to license terms, as defined in
0007: * Anvil Sofware License, Version 1.1. See LICENSE
0008: * file, or http://njet.org/license-1.1.txt
0009: */
0010: package anvil.core;
0011:
0012: import anvil.script.Context;
0013: import anvil.script.Type;
0014: import anvil.script.ClassType;
0015: import anvil.script.Scope;
0016: import anvil.script.Module;
0017: import anvil.script.ScriptException;
0018: import anvil.java.util.BindingEnumeration;
0019: import java.io.Writer;
0020: import java.io.IOException;
0021: import java.io.OutputStream;
0022: import java.util.Enumeration;
0023: import org.apache.oro.text.regex.Pattern;
0024:
0025: /// @class object
0026: /// Object is a root of the class hiearchy: every class has
0027: /// a <code>object</code> as a superclass.
0028:
0029: /**
0030: * class Any
0031: * @author Jani Lehtimäki
0032: */
0033: public class Any implements Cloneable, Comparable {
0034:
0035: transient public final static Any NULL = AnyNull.INSTANCE;
0036: transient public final static Any UNDEFINED = AnyUndefined.INSTANCE;
0037: transient public final static Any FALSE = AnyFalse.INSTANCE;
0038: transient public final static Any TRUE = AnyTrue.INSTANCE;
0039: transient public final static Any ZERO = ObjectPool.createInt(0);
0040: transient public final static Any ONE = ObjectPool.createInt(1);
0041: transient public final static Any TWO = ObjectPool.createInt(2);
0042: transient public final static Any MINUS_ONE = ObjectPool
0043: .createInt(-1);
0044: transient public final static Any DOUBLE_ZERO = new AnyDouble(0.0);
0045: transient public final static Any DOUBLE_ONE = new AnyDouble(1.0);
0046: transient public final static Any DOUBLE_MINUS_ONE = new AnyDouble(
0047: -1.0);
0048: transient public final static Any INF = AnyInfinity.INSTANCE;
0049: transient public final static Any NEG_INF = AnyNegativeInfinity.INSTANCE;
0050: transient public final static Any NAN = new AnyDouble(Double.NaN);
0051: transient public final static Any EMPTY_STRING = new AnyString("");
0052: transient public final static Any[] ARRAY0 = new Any[0];
0053: transient public final static AnyTuple EMPTY_TUPLE = new AnyTuple(
0054: ARRAY0);
0055:
0056: transient public final static int IS_NEG_INF = 0;
0057: transient public final static int IS_UNDEFINED = 1;
0058: transient public final static int IS_NULL = 2;
0059: transient public final static int IS_BOOLEAN = 3;
0060: transient public final static int IS_INT = 4;
0061: transient public final static int IS_DOUBLE = 5;
0062: transient public final static int IS_STRING = 6;
0063: transient public final static int IS_BUFFER = 7;
0064: transient public final static int IS_BINARY = 8;
0065: transient public final static int IS_PATTERN = 9;
0066: transient public final static int IS_MAP = 10;
0067: transient public final static int IS_RANGE = 11;
0068: transient public final static int IS_ENUMERATION = 12;
0069: transient public final static int IS_TUPLE = 13;
0070: transient public final static int IS_LIST = 14;
0071: transient public final static int IS_ARRAY = 15;
0072: transient public final static int IS_CLASS = 16;
0073: transient public final static int IS_INF = 17;
0074: transient public final static int IS_REF = 18;
0075:
0076: /**
0077: * Constructs Any containing <code>IS_NULL</code>.
0078: */
0079: public static Any create() {
0080: return NULL;
0081: }
0082:
0083: /**
0084: * Constructs Any containing <code>IS_STRING</code>
0085: * with length == 1 and charAt(0) == ch.
0086: *
0087: * @param string String value
0088: */
0089: public static Any create(char ch) {
0090: return ObjectPool.createChar(ch);
0091: }
0092:
0093: /**
0094: * Constructs Any containing <code>IS_STRING</code>
0095: *
0096: * @param string String value
0097: */
0098: public static Any create(String string) {
0099: return ObjectPool.createString(string);
0100: }
0101:
0102: public static Any create(String[] array) {
0103: if (array == null) {
0104: return NULL;
0105: } else {
0106: return new anvil.core.arrays.AnyStringArray(array);
0107: }
0108: }
0109:
0110: /**
0111: * Constructs Any containing <code>IS_INT</code>
0112: *
0113: * @param integer int value
0114: */
0115: public static Any create(int integer) {
0116: return ObjectPool.createInt(integer);
0117: }
0118:
0119: /**
0120: * Constructs Any containing <code>IS_INT</code>
0121: *
0122: * @param lng long value
0123: */
0124: public static Any create(long lng) {
0125: return ObjectPool.createLong(lng);
0126: }
0127:
0128: /**
0129: * Constructs Any containing <code>IS_INT</code>
0130: *
0131: * @param i java.lang.Integer value
0132: */
0133: public static Any create(Integer integer) {
0134: return ObjectPool.createInt(integer.intValue());
0135: }
0136:
0137: /**
0138: * Constructs Any containing <code>IS_DOUBLE</code>
0139: * @param dbl double value
0140: */
0141: public static Any create(double dbl) {
0142: return new AnyDouble(dbl);
0143: }
0144:
0145: /**
0146: * Constructs Any containing <code>IS_DOUBLE</code>
0147: * @param dbl java.lang.Double value
0148: */
0149: public static Any create(Double dbl) {
0150: return new AnyDouble(dbl);
0151: }
0152:
0153: /**
0154: * Constructs Any containing <code>IS_BOOLEAN</code>
0155: * @param bool boolean value
0156: */
0157: public static Any create(boolean bool) {
0158: return bool ? TRUE : FALSE;
0159: }
0160:
0161: /**
0162: * Constructs Any containing <code>IS_BOOLEAN</code>
0163: * @param bool java.lang.Boolean value
0164: */
0165: public static Any create(Boolean bool) {
0166: return bool.booleanValue() ? TRUE : FALSE;
0167: }
0168:
0169: /**
0170: * Constructs Any with spefified type and value
0171: * @param type type of value
0172: * @param value string presentation of value of given type
0173: */
0174: public static Any create(int type, String value) {
0175: switch (type) {
0176: case IS_BOOLEAN:
0177: return (value.length() <= 4)
0178: && (value.equalsIgnoreCase("true")
0179: || value.equalsIgnoreCase("yes")
0180: || value.equalsIgnoreCase("on") || value
0181: .equals("1")) ? TRUE : FALSE;
0182:
0183: case IS_INT:
0184: try {
0185: return ObjectPool.createLong(Long.parseLong(value));
0186: } catch (NumberFormatException e) {
0187: return ZERO;
0188: }
0189:
0190: case IS_DOUBLE:
0191: try {
0192: return new AnyDouble(Double.valueOf(value)
0193: .doubleValue());
0194: } catch (NumberFormatException e) {
0195: return DOUBLE_ZERO;
0196: }
0197:
0198: case IS_STRING:
0199: return ObjectPool.createString(value);
0200:
0201: default:
0202: return NULL;
0203: }
0204: }
0205:
0206: public static Any create(Object object) {
0207: return ObjectPool.create(object);
0208: }
0209:
0210: /**
0211: * Constructs Any from another Any instance
0212: * @param any Any value
0213: */
0214: public static Any create(Any any) {
0215: if (any != null) {
0216: return any;
0217: } else {
0218: return NULL;
0219: }
0220: }
0221:
0222: /************************************************************************/
0223:
0224: /**
0225: * Constructs Any containing <code>IS_NULL</code>.
0226: */
0227: protected Any() {
0228: }
0229:
0230: /* cloning operations */
0231:
0232: /**
0233: * Returns shallow copy from this any.
0234: *
0235: * @return Shallow copy
0236: */
0237: public Object clone() {
0238: return this ;
0239: }
0240:
0241: /**
0242: * Returns deep copy from this any.
0243: */
0244: public Any copy() {
0245: return this ;
0246: }
0247:
0248: /**
0249: * Returns the logical size of this any.
0250: *
0251: * @return Logical size
0252: */
0253: public int sizeOf() {
0254: return 0;
0255: }
0256:
0257: /* type identity */
0258:
0259: /**
0260: * Returns the type of this Any.
0261: */
0262: public anvil.script.ClassType classOf() {
0263: return __class__;
0264: }
0265:
0266: public Type type() {
0267: return classOf();
0268: }
0269:
0270: /**
0271: * Returns the type of contained value.
0272: *
0273: * @return Type of this any as int.
0274: */
0275: public int typeOf() {
0276: return IS_NULL;
0277: }
0278:
0279: /**
0280: * Returns the classname of contained object
0281: */
0282: public final String classNameOf() {
0283: return classOf().getName();
0284: }
0285:
0286: /**
0287: * Checks if this any is of given type.
0288: *
0289: * @param ofClass Type to check against.
0290: * @return <code>true<code> if this any if of given type.
0291: */
0292: public boolean isInstanceOf(Type ofType) {
0293: return classOf().isInstanceOf(ofType);
0294: }
0295:
0296: /**
0297: * Checks if this any is defined. Only <code>undefined</code>
0298: * returns <code>false</code> for this method.
0299: *
0300: * @return <code>true</code> if this is other than <code>undefined</code>
0301: */
0302: public boolean isDefined() {
0303: return true;
0304: }
0305:
0306: /**
0307: * Checks if this any is <code>undefined</code>.
0308: *
0309: * @return <code>true</code> if this is <code>undefined</code>
0310: */
0311: public boolean isUndefined() {
0312: return false;
0313: }
0314:
0315: /**
0316: * Checks if this any is <code>null</code>.
0317: *
0318: * @return <code>true</code> if this is <code>null</code>
0319: */
0320: public boolean isNull() {
0321: return false;
0322: }
0323:
0324: /**
0325: * Checks if this any is <code>boolean</code>.
0326: *
0327: * @return <code>true</code> if this is <code>boolean</code>
0328: */
0329: public boolean isBoolean() {
0330: return false;
0331: }
0332:
0333: /**
0334: * Checks if this any is <code>int</code>.
0335: *
0336: * @return <code>true</code> if this is <code>int</code>
0337: */
0338: public boolean isInt() {
0339: return false;
0340: }
0341:
0342: /**
0343: * Checks if this any is <code>float</code>. In script the float is
0344: * used, but the implementation uses double.
0345: *
0346: * @return <code>true</code> if this is <code>float</code>
0347: */
0348: public boolean isDouble() {
0349: return false;
0350: }
0351:
0352: public boolean isMutable() {
0353: return false;
0354: }
0355:
0356: public boolean isSequence() {
0357: return false;
0358: }
0359:
0360: /**
0361: * Checks if this any is <code>string</code>.
0362: *
0363: * @return <code>true</code> if this is <code>string</code>
0364: */
0365: public boolean isString() {
0366: return false;
0367: }
0368:
0369: /**
0370: * Checks if this any is <code>binary</code>.
0371: *
0372: * @return <code>true</code> if this is <code>binary</code>
0373: */
0374: public boolean isBinary() {
0375: return false;
0376: }
0377:
0378: /**
0379: * Checks if this any is <code>tuple</code>.
0380: *
0381: * @return <code>true</code> if this is <code>tuple</code>
0382: */
0383: public boolean isTuple() {
0384: return false;
0385: }
0386:
0387: /**
0388: * Checks if this any is <code>list</code>.
0389: *
0390: * @return <code>true</code> if this is <code>list</code>
0391: */
0392: public boolean isList() {
0393: return false;
0394: }
0395:
0396: /**
0397: * Checks if this any is <code>array</code>.
0398: *
0399: * @return <code>true</code> if this is <code>array</code>
0400: */
0401: public boolean isArray() {
0402: return false;
0403: }
0404:
0405: /**
0406: * Checks if this any is <code>class</code>.
0407: *
0408: * @return <code>true</code> if this is <code>class</code>
0409: */
0410: public boolean isClass() {
0411: return false;
0412: }
0413:
0414: /**
0415: * Checks if this any is <code>pattern</code>.
0416: *
0417: * @return <code>true</code> if this is <code>pattern</code>
0418: */
0419: public boolean isPattern() {
0420: return false;
0421: }
0422:
0423: /**
0424: * Checks if this any is <code>range</code>.
0425: *
0426: * @return <code>true</code> if this is <code>range</code>
0427: */
0428: public boolean isRange() {
0429: return false;
0430: }
0431:
0432: /**
0433: * Checks if this any is <code>map</code>.
0434: *
0435: * @return <code>true</code> if this is <code>map</code>
0436: */
0437: public boolean isMap() {
0438: return false;
0439: }
0440:
0441: /**
0442: * Checks if this any is <code>buffer</code>.
0443: *
0444: * @return <code>true</code> if this is <code>buffer</code>
0445: */
0446: public boolean isBuffer() {
0447: return false;
0448: }
0449:
0450: /**
0451: * Checks if this any is <code>enumeration</code>.
0452: *
0453: * @return <code>true</code> if this is <code>enumeration</code>
0454: */
0455: public boolean isEnumeration() {
0456: return false;
0457: }
0458:
0459: public boolean isRef() {
0460: return false;
0461: }
0462:
0463: public void setRef(Any value) {
0464: }
0465:
0466: public Any getRef() {
0467: return this ;
0468: }
0469:
0470: /* conversions */
0471:
0472: /**
0473: * Gets the contained value as <code>java.lang.Object</code>.
0474: *
0475: * @return Value as Object.
0476: */
0477: public Object toObject() {
0478: return null;
0479: }
0480:
0481: /**
0482: * Gets the contained value as <code>int</code>.
0483: *
0484: * @return Value as <code>int</code> or zero if it can't be transformed.
0485: */
0486: public int toInt() {
0487: return 0;
0488: }
0489:
0490: public byte toByte() {
0491: return (byte) toInt();
0492: }
0493:
0494: /**
0495: * Gets the contained value as <code>long</code>.
0496: *
0497: * @return Value as <code>long</code> or zero if it can't be transformed.
0498: */
0499: public long toLong() {
0500: return (long) toInt();
0501: }
0502:
0503: /**
0504: * Gets the contained value as <code>double</code>.
0505: *
0506: * @return Value as <code>double</code> or <code>0.0</code>
0507: * if it can't be transformed.
0508: */
0509: public double toDouble() {
0510: return 0.0;
0511: }
0512:
0513: /**
0514: * Gets the contained value as <code>boolean</code>.
0515: * Integer is considered <code>true</code> if it is different from 0.
0516: * Double is considered <code>true</code> if it is different from 0.0.
0517: * String is considered <code>true</code> if it contains
0518: * <code>"true"</code>, <code>"on"</code>,
0519: * <code>"yes"</code> or <code>"1"</code>.
0520: *
0521: * @return Value as boolean or false if it can't be transformed.
0522: */
0523: public boolean toBoolean() {
0524: return false;
0525: }
0526:
0527: /**
0528: * Gets the contained value as <code>char</code>. Value is converted to
0529: * string and first character is returned.
0530: *
0531: * @return Value as char
0532: */
0533: public char toChar() {
0534: String str = toString();
0535: return (str.length() > 0) ? str.charAt(0) : ' ';
0536: }
0537:
0538: /**
0539: * Converts contained value into <code>String</code>.
0540: *
0541: * @return Value as <code>String</code>.
0542: */
0543: public String toString() {
0544: return "";
0545: }
0546:
0547: public StringBuffer toBuffer() {
0548: return new StringBuffer(toString());
0549: }
0550:
0551: /**
0552: * Converts contained value into value anvil code.
0553: *
0554: * @return Value as anvil code.
0555: */
0556: public String toAnvil() {
0557: java.io.StringWriter writer = new java.io.StringWriter();
0558: try {
0559: toAnvil(writer);
0560: } catch (IOException e) {
0561: }
0562: return writer.toString();
0563: }
0564:
0565: public Writer toAnvil(Writer writer) throws IOException {
0566: writer.write("null");
0567: return writer;
0568: }
0569:
0570: public String toJava() {
0571: java.io.StringWriter writer = new java.io.StringWriter();
0572: try {
0573: toJava(writer);
0574: } catch (IOException e) {
0575: }
0576: return writer.toString();
0577: }
0578:
0579: public Writer toJava(Writer writer) throws IOException {
0580: writer.write("anvil.core.Any.NULL");
0581: return writer;
0582: }
0583:
0584: public anvil.codec.Code toCode(anvil.codec.Code code) {
0585: code.getstatic(code.getPool().addFieldRef("anvil/core/Any",
0586: "NULL", "Lanvil/core/Any;"));
0587: return code;
0588: }
0589:
0590: /**
0591: * Gets the contained vaelue as <code>Array</code>.
0592: *
0593: * @return Value as Array or null if this instance doesn't contain Array.
0594: */
0595: public Array toArray() {
0596: return null;
0597: }
0598:
0599: /**
0600: * Gets the contained value as <code>byte[]</code>.
0601: *
0602: * @return Value as <code>byte[]</code> or <code>null</code> if this instance
0603: * isn't <code>AnyBinary</code>.
0604: */
0605: public byte[] toBinary() {
0606: String s = toString();
0607: if (s != null) {
0608: return anvil.util.Conversions.getBytes(s);
0609: } else {
0610: return null;
0611: }
0612: }
0613:
0614: /**
0615: * Gets the contained value as <code>Any[]</code>.
0616: *
0617: * @return Value as <code>Any[]</code> or <code>null</code> if this instance
0618: * isn't AnyTuple.
0619: */
0620: public Any[] toTuple() {
0621: return null;
0622: }
0623:
0624: public Any[] toList() {
0625: return null;
0626: }
0627:
0628: public AnyClass toClass() {
0629: return null;
0630: }
0631:
0632: public Pattern toPattern() {
0633: return null;
0634: }
0635:
0636: public AnyMap toMap() {
0637: return null;
0638: }
0639:
0640: public AnyRange toRange() {
0641: return null;
0642: }
0643:
0644: /**
0645: * Gets the contained value as <code>AnyTrue</code> or <code>AnyFalse</code>
0646: *
0647: * @return Value as <code>AnyBoolean</code>.
0648: */
0649: public Any toAnyBoolean() {
0650: return toBoolean() ? TRUE : FALSE;
0651: }
0652:
0653: /**
0654: * Gets the contained value as <code>AnyInt</code>.
0655: *
0656: * @return Value as <code>AnyInt</code>.
0657: */
0658: public Any toAnyInt() {
0659: return ObjectPool.createLong(toLong());
0660: }
0661:
0662: /**
0663: * Gets the contained value as <code>AnyDouble</code>.
0664: *
0665: * @return Value as <code>AnyDouble</code>.
0666: */
0667: public Any toAnyDouble() {
0668: return new AnyDouble(toDouble());
0669: }
0670:
0671: /**
0672: * Converts contained value into <code>AnyString</code>.
0673: *
0674: * @return Value as <code>AnyString</code>.
0675: */
0676: public Any toAnyString() {
0677: return new AnyString(toString());
0678: }
0679:
0680: /* arithmetic operations */
0681:
0682: /**
0683: * Concatenated two Any's together. Returned type will be IS_STRING.
0684: *
0685: * @param any Value of add
0686: * @return Calculated value
0687: */
0688: public Any concat(Any any) {
0689: return ObjectPool.createString(toString()
0690: .concat(any.toString()));
0691: }
0692:
0693: /**
0694: * Adds two Any's together.
0695: *
0696: * @param any Value of add
0697: * @return Calculated value
0698: */
0699: public Any add(Any other) {
0700: return UNDEFINED;
0701: }
0702:
0703: /**
0704: * Substract two Any's.
0705: *
0706: * @param any Value of subtract
0707: * @return Calculated value
0708: */
0709: public Any subtract(Any b) {
0710: return UNDEFINED;
0711: }
0712:
0713: /**
0714: * Multiply two Any's. Returned type will be the
0715: * same as of <code>this</code> instance.
0716: * Will only work with integer and double.
0717: *
0718: * @param any Multiplicator
0719: * @return Calculated value
0720: */
0721: public Any multiply(Any b) {
0722: return UNDEFINED;
0723: }
0724:
0725: /**
0726: * Divide two Any's.
0727: *
0728: * @param any Divider
0729: * @return Calculated value
0730: */
0731: public Any divide(Any b) {
0732: return UNDEFINED;
0733: }
0734:
0735: /**
0736: * Calculate the remainder.
0737: *
0738: * @param any Divider for modulus
0739: * @return Calculated value
0740: */
0741: public Any modulo(Any b) {
0742: return UNDEFINED;
0743: }
0744:
0745: /**
0746: * Increase the value by one.
0747: *
0748: * @return Increased value
0749: */
0750: public Any increase() {
0751: return ZERO;
0752: }
0753:
0754: /**
0755: * Decrease the value by one.
0756: *
0757: * @return Decreased value
0758: */
0759: public Any decrease() {
0760: return ZERO;
0761: }
0762:
0763: /**
0764: * Negate the sign.
0765: *
0766: * @return Negated value
0767: */
0768: public Any minus() {
0769: return ZERO;
0770: }
0771:
0772: /**
0773: * Remove the sign.
0774: *
0775: * @return Value, with sign removed
0776: */
0777: public Any plus() {
0778: return ZERO;
0779: }
0780:
0781: /* boolean operations */
0782:
0783: /**
0784: * Logical AND.
0785: *
0786: * @param any Any
0787: * @return Result of AND
0788: */
0789: public Any and(Any any) {
0790: return (toBoolean() && any.toBoolean()) ? TRUE : FALSE;
0791: }
0792:
0793: /**
0794: * Logical OR.
0795: *
0796: * @param any Any
0797: * @return Result of OR
0798: */
0799: public Any or(Any any) {
0800: return (toBoolean() || any.toBoolean()) ? TRUE : FALSE;
0801: }
0802:
0803: /**
0804: * Perform logical negation.
0805: * Will only work with boolean, integer and double.
0806: *
0807: * @return Negated value
0808: */
0809: public Any not() {
0810: return toBoolean() ? FALSE : TRUE;
0811: }
0812:
0813: /**
0814: * Logical AND.
0815: *
0816: * @param any Any
0817: * @return Result of AND
0818: */
0819: public boolean booleanAnd(Any any) {
0820: return (toBoolean() && any.toBoolean());
0821: }
0822:
0823: /**
0824: * Logical OR.
0825: *
0826: * @param any Any
0827: * @return Result of OR
0828: */
0829: public boolean booleanOr(Any any) {
0830: return (toBoolean() || any.toBoolean());
0831: }
0832:
0833: /**
0834: * Perform logical negation.
0835: * Will only work with boolean, integer and double.
0836: *
0837: * @return Negated value
0838: */
0839: public boolean booleanNot() {
0840: return !toBoolean();
0841: }
0842:
0843: /* comparisons */
0844:
0845: /**
0846: * Calculates the hashcode of this Any.
0847: *
0848: * @return Hashcode.
0849: */
0850: public int hashCode() {
0851: return 0;
0852: }
0853:
0854: /**
0855: * Tests for equality.
0856: *
0857: * @param o Object to check. Valid types are
0858: * <code>Boolean</code>, <code>Integer</code>, <code>Double</code>,
0859: * <code>String</code>, <code>Array</code> and <code>Any</code>.
0860: * No conversions are made, so, if the actual type doesn't
0861: * match between two objects <code>false</code> is returned.
0862: *
0863: * @return <code>true</code> if equal, <code>false</code> otherwise.
0864: */
0865: public boolean equals(Object obj) {
0866: return (this == obj);
0867: }
0868:
0869: /**
0870: * Compares two Any's. Will not work with <code>Hashtable</code>.
0871: *
0872: * @param any Value to compare with
0873: * @return -1 if <code>this</code> is less than paramter.
0874: * 0 if equal.
0875: * 1 if <code>this</code> if greater than parameter.
0876: *
0877: */
0878: public final int compareTo(Object obj) {
0879: if (this == obj) {
0880: return 0;
0881: }
0882: if (obj instanceof Any) {
0883: Any other = (Any) obj;
0884: int delta = typeOf() - other.typeOf();
0885: if (delta == 0) {
0886: return compare(other);
0887: } else {
0888: return delta;
0889: }
0890: }
0891: return -1;
0892: }
0893:
0894: protected int compare(Any other) {
0895: return equals(other) ? 0 : 1;
0896: }
0897:
0898: public Any coerce() {
0899: return this ;
0900: }
0901:
0902: /* serialization */
0903:
0904: public void serialize(Serializer serializer) throws IOException {
0905: serializer.write('n');
0906: }
0907:
0908: /* attributes */
0909:
0910: public boolean contains(Any value) {
0911: return false;
0912: }
0913:
0914: public Any getAttribute(Context context, String attribute) {
0915: throw context.AttributeError(classNameOf() + '.' + attribute);
0916: }
0917:
0918: public Any setAttribute(Context context, String attribute, Any value) {
0919: throw context.AttributeError(classNameOf() + '.' + attribute);
0920: }
0921:
0922: public Any checkAttribute(Context context, String attribute) {
0923: return UNDEFINED;
0924: }
0925:
0926: public boolean deleteAttribute(Context context, String attribute) {
0927: throw context.AttributeError(classNameOf() + '.' + attribute);
0928: }
0929:
0930: /* references */
0931:
0932: public Any getReference(Context context, Any index) {
0933: throw context.ReferenceError(classNameOf() + '[' + index + ']');
0934: }
0935:
0936: public Any setReference(Context context, Any index, Any value) {
0937: throw context.ReferenceError(classNameOf() + '[' + index + ']');
0938: }
0939:
0940: public Any setReference(Context context, Any value) {
0941: throw context.ReferenceError(classNameOf() + "[]");
0942: }
0943:
0944: public Any checkReference(Context context, Any index) {
0945: return Any.UNDEFINED;
0946: }
0947:
0948: public boolean deleteReference(Context context, Any index) {
0949: throw context.ReferenceError(classNameOf() + '[' + index + ']');
0950: }
0951:
0952: /* foreach enumeration */
0953:
0954: public BindingEnumeration enumeration() {
0955: return new SingleBindingEnumeration(this );
0956: }
0957:
0958: /* callable emulation */
0959:
0960: public Any execute(Context context, Any[] parameters) {
0961: throw context.CallError(classNameOf());
0962: }
0963:
0964: public Any execute(Context context) {
0965: return execute(context, ARRAY0);
0966: }
0967:
0968: public Any execute(Context context, Any param1) {
0969: return execute(context, new Any[] { param1 });
0970: }
0971:
0972: public Any execute(Context context, Any param1, Any param2) {
0973: return execute(context, new Any[] { param1, param2 });
0974: }
0975:
0976: public Any execute(Context context, Any param1, Any param2,
0977: Any param3) {
0978: return execute(context, new Any[] { param1, param2, param3 });
0979: }
0980:
0981: public Any execute(Context context, Any param1, Any param2,
0982: Any param3, Any param4) {
0983: return execute(context, new Any[] { param1, param2, param3,
0984: param4 });
0985: }
0986:
0987: /* invoke mechanishm */
0988:
0989: public boolean has(String methodName) {
0990: return classOf().getDispatcher(Context.getInstance())
0991: .hasMethod(Register.register(methodName));
0992: }
0993:
0994: public Any invoke(Context context, int methodIndex, Any[] parameters) {
0995: return classOf().getDispatcher(context).invoke(context, this ,
0996: methodIndex, parameters);
0997: }
0998:
0999: public Any invoke(Context context, int methodIndex) {
1000: return classOf().getDispatcher(context).invoke(context, this ,
1001: methodIndex);
1002: }
1003:
1004: public Any invoke(Context context, int methodIndex, Any param1) {
1005: return classOf().getDispatcher(context).invoke(context, this ,
1006: methodIndex, param1);
1007: }
1008:
1009: public Any invoke(Context context, int methodIndex, Any param1,
1010: Any param2) {
1011: return classOf().getDispatcher(context).invoke(context, this ,
1012: methodIndex, param1, param2);
1013: }
1014:
1015: public Any invoke(Context context, int methodIndex, Any param1,
1016: Any param2, Any param3) {
1017: return classOf().getDispatcher(context).invoke(context, this ,
1018: methodIndex, param1, param2, param3);
1019: }
1020:
1021: public Any invoke(Context context, int methodIndex, Any param1,
1022: Any param2, Any param3, Any param4) {
1023: return classOf().getDispatcher(context).invoke(context, this ,
1024: methodIndex, param1, param2, param3, param4);
1025: }
1026:
1027: public Any invoke(Context context, String methodName,
1028: Any[] parameters) {
1029: return invoke(context, Register.register(methodName),
1030: parameters);
1031: }
1032:
1033: public Any invoke(Context context, String methodName) {
1034: return invoke(context, Register.register(methodName));
1035: }
1036:
1037: public Any invoke(Context context, String methodName, Any param1) {
1038: return invoke(context, Register.register(methodName), param1);
1039: }
1040:
1041: public Any invoke(Context context, String methodName, Any param1,
1042: Any param2) {
1043: return invoke(context, Register.register(methodName), param1,
1044: param2);
1045: }
1046:
1047: public Any invoke(Context context, String methodName, Any param1,
1048: Any param2, Any param3) {
1049: return invoke(context, Register.register(methodName), param1,
1050: param2, param3);
1051: }
1052:
1053: public Any invoke(Context context, String methodName, Any param1,
1054: Any param2, Any param3, Any param4) {
1055: return invoke(context, Register.register(methodName), param1,
1056: param2, param3, param4);
1057: }
1058:
1059: public ScriptException nonExistentMethod(Context context,
1060: int methodIndex) {
1061: throw context.NoSuchMethod(classNameOf() + '.'
1062: + Register.getNameOf(methodIndex));
1063: }
1064:
1065: public ScriptException parametersMissing(Context context,
1066: String method) {
1067: throw context.NotEnoughParameters(classNameOf() + '.' + method);
1068: }
1069:
1070: public ScriptException parametersMissing(Context context,
1071: int methodIndex) {
1072: throw context.NotEnoughParameters(classNameOf() + '.'
1073: + Register.getNameOf(methodIndex));
1074: }
1075:
1076: /********* Exposed methods ************/
1077:
1078: /// @method copy
1079: /// Copy (deep copy) this object.
1080: /// @synopsis object copy()
1081: public Any m_copy() {
1082: return copy();
1083: }
1084:
1085: /// @method clone
1086: /// Clone (shallow copy) this object.
1087: /// @synopsis object clone()
1088: public Any m_clone() {
1089: return (Any) clone();
1090: }
1091:
1092: /// @method toBoolean
1093: /// Converts this object to boolean.
1094: /// @synopsis boolean toBoolean()
1095: public Any m_toBoolean() {
1096: return toAnyBoolean();
1097: }
1098:
1099: /// @method toString
1100: /// Converts this object to string.
1101: /// @synopsis string toString()
1102: public Any m_toString() {
1103: return Any.create(toString());
1104: }
1105:
1106: /// @method hashCode
1107: /// Return hashcode for this object.
1108: /// @synopsis int hashCode()
1109: public Any m_hashCode() {
1110: return Any.create(hashCode());
1111: }
1112:
1113: /// @method equals
1114: /// Checks if this object and 'other' equals.
1115: /// @synopsis boolean equals(other)
1116: public static final Object[] p_equals = new Object[] { "object" };
1117:
1118: public Any m_equals(Any other) {
1119: return equals(other) ? TRUE : FALSE;
1120: }
1121:
1122: /// @method compareTo
1123: /// Compares this object and 'other'. Returns -1 if this < other,
1124: /// 0 if this == other, 1 if this > other.
1125: /// @synopsis int compareTo(other)
1126: public static final Object[] p_compareTo = new Object[] { "object" };
1127:
1128: public Any m_compareTo(Any other) {
1129: int result = compareTo(other);
1130: return (result > 0) ? ONE : ((result < 0) ? MINUS_ONE : ZERO);
1131: }
1132:
1133: public static final anvil.script.compiler.NativeClass __class__ = new anvil.script.compiler.NativeClass(
1134: "object", Any.class,
1135: null,
1136: //DOC{{
1137: ""
1138: + " @class object\n"
1139: + " Object is a root of the class hiearchy: every class has\n"
1140: + " a <code>object</code> as a superclass. \n"
1141: + " @method copy\n"
1142: + " Copy (deep copy) this object.\n"
1143: + " @synopsis object copy()\n"
1144: + " @method clone\n"
1145: + " Clone (shallow copy) this object.\n"
1146: + " @synopsis object clone()\n"
1147: + " @method toBoolean\n"
1148: + " Converts this object to boolean.\n"
1149: + " @synopsis boolean toBoolean()\n"
1150: + " @method toString\n"
1151: + " Converts this object to string.\n"
1152: + " @synopsis string toString()\n"
1153: + " @method hashCode\n"
1154: + " Return hashcode for this object.\n"
1155: + " @synopsis int hashCode()\n"
1156: + " @method equals\n"
1157: + " Checks if this object and 'other' equals.\n"
1158: + " @synopsis boolean equals(other)\n"
1159: + " @method compareTo\n"
1160: + " Compares this object and 'other'. Returns -1 if this < other,\n"
1161: + " 0 if this == other, 1 if this > other.\n"
1162: + " @synopsis int compareTo(other)\n"
1163: //}}DOC
1164: );
1165: static {
1166: LangModule.class.getName();
1167: }
1168:
1169: public static class Op {
1170: public static final int EQ = 0;
1171: public static final int NE = 1;
1172: public static final int LT = 2;
1173: public static final int LE = 3;
1174: public static final int GE = 4;
1175: public static final int GT = 5;
1176:
1177: public static final boolean lt(Any a, Any b) {
1178: return test(a, b) < 0;
1179: }
1180:
1181: public static final Any ltA(Any a, Any b) {
1182: return test(a, b) < 0 ? Any.TRUE : Any.FALSE;
1183: }
1184:
1185: public static final boolean le(Any a, Any b) {
1186: return test(a, b) <= 0;
1187: }
1188:
1189: public static final Any leA(Any a, Any b) {
1190: return test(a, b) <= 0 ? Any.TRUE : Any.FALSE;
1191: }
1192:
1193: public static final boolean ge(Any a, Any b) {
1194: return test(a, b) >= 0;
1195: }
1196:
1197: public static final Any geA(Any a, Any b) {
1198: return test(a, b) >= 0 ? Any.TRUE : Any.FALSE;
1199: }
1200:
1201: public static final boolean gt(Any a, Any b) {
1202: return test(a, b) > 0;
1203: }
1204:
1205: public static final Any gtA(Any a, Any b) {
1206: return test(a, b) > 0 ? Any.TRUE : Any.FALSE;
1207: }
1208:
1209: public static final boolean eq(Any a, Any b) {
1210: return test(a, b) == 0;
1211: }
1212:
1213: public static final Any eqA(Any a, Any b) {
1214: return test(a, b) == 0 ? Any.TRUE : Any.FALSE;
1215: }
1216:
1217: public static final boolean ne(Any a, Any b) {
1218: return test(a, b) != 0;
1219: }
1220:
1221: public static final Any neA(Any a, Any b) {
1222: return test(a, b) != 0 ? Any.TRUE : Any.FALSE;
1223: }
1224:
1225: public static final Any testA(Any a, Any b) {
1226: return create(test(a, b));
1227: }
1228:
1229: public static final int test(Any a, Any b) {
1230: if (a == b) {
1231: return 0;
1232: }
1233: //int,double -> double
1234: //double,int -> double
1235: //int,string -> int || double || ERR
1236: //double,string -> double || ERR
1237: //string,int -> int || double || ERR
1238: //string,double -> double || ERR
1239: int typeOfA = a.typeOf();
1240: int typeOfB = b.typeOf();
1241: switch (typeOfA | typeOfB << 5) {
1242: case Any.IS_NULL | Any.IS_UNDEFINED << 5:
1243: case Any.IS_UNDEFINED | Any.IS_NULL << 5:
1244: return 0;
1245:
1246: case Any.IS_INT | Any.IS_DOUBLE << 5:
1247: return a.toAnyDouble().compare(b);
1248:
1249: case Any.IS_DOUBLE | Any.IS_INT << 5:
1250: return a.compare(b);
1251:
1252: case Any.IS_INT | Any.IS_STRING << 5:
1253: b = b.coerce();
1254: switch (b.typeOf()) {
1255: case Any.IS_INT:
1256: return a.compare(b);
1257: case Any.IS_DOUBLE:
1258: return a.toAnyDouble().compare(b);
1259: case Any.IS_STRING:
1260: default:
1261: return -1;
1262: }
1263:
1264: case Any.IS_DOUBLE | Any.IS_STRING << 5:
1265: b = b.coerce();
1266: if (b.typeOf() == Any.IS_STRING) {
1267: return -1;
1268: } else {
1269: return a.compare(b);
1270: }
1271:
1272: case Any.IS_STRING | Any.IS_INT << 5:
1273: a = a.coerce();
1274: if (a.typeOf() == Any.IS_STRING) {
1275: return 1;
1276: } else {
1277: return a.compare(b);
1278: }
1279:
1280: case Any.IS_STRING | Any.IS_DOUBLE << 5:
1281: a = a.coerce();
1282: switch (a.typeOf()) {
1283: case Any.IS_INT:
1284: return a.toAnyDouble().compare(b);
1285: case Any.IS_DOUBLE:
1286: return a.compare(b);
1287: case Any.IS_STRING:
1288: default:
1289: return 1;
1290: }
1291:
1292: default:
1293: if (typeOfA == typeOfB) {
1294: return a.compare(b);
1295: } else {
1296: if (a.isSequence()) {
1297: AnySequence seq = (AnySequence) a;
1298: if (seq.isCompatible(b)) {
1299: return a.compare(b);
1300: }
1301: }
1302: return typeOfA - typeOfB;
1303: }
1304: }
1305: }
1306:
1307: public static final Any add(Any a, Any b) {
1308: int typeOfA = a.typeOf();
1309: int typeOfB = b.typeOf();
1310: switch (typeOfA | typeOfB << 5) {
1311: case Any.IS_INT | Any.IS_UNDEFINED << 5:
1312: case Any.IS_INT | Any.IS_NULL << 5:
1313: return a.add(ZERO);
1314:
1315: case Any.IS_UNDEFINED | Any.IS_INT << 5:
1316: case Any.IS_NULL | Any.IS_INT << 5:
1317: return ZERO.add(b);
1318:
1319: case Any.IS_DOUBLE | Any.IS_UNDEFINED << 5:
1320: case Any.IS_DOUBLE | Any.IS_NULL << 5:
1321: return a.add(DOUBLE_ZERO);
1322:
1323: case Any.IS_UNDEFINED | Any.IS_DOUBLE << 5:
1324: case Any.IS_NULL | Any.IS_DOUBLE << 5:
1325: return DOUBLE_ZERO.add(b);
1326:
1327: case Any.IS_INT | Any.IS_DOUBLE << 5:
1328: return a.toAnyDouble().add(b);
1329:
1330: case Any.IS_DOUBLE | Any.IS_INT << 5:
1331: return a.add(b);
1332:
1333: case Any.IS_INT | Any.IS_STRING << 5:
1334: b = b.coerce();
1335: switch (b.typeOf()) {
1336: case Any.IS_INT:
1337: return a.add(b);
1338: case Any.IS_DOUBLE:
1339: return a.toAnyDouble().add(b);
1340: case Any.IS_STRING:
1341: return a.concat(b);
1342: }
1343: break;
1344:
1345: case Any.IS_DOUBLE | Any.IS_STRING << 5:
1346: b = b.coerce();
1347: if (b.typeOf() == Any.IS_STRING) {
1348: return a.concat(b);
1349: } else {
1350: return a.add(b);
1351: }
1352:
1353: case Any.IS_STRING | Any.IS_INT << 5:
1354: a = a.coerce();
1355: if (a.typeOf() == Any.IS_STRING) {
1356: return a.concat(b);
1357: } else {
1358: return a.add(b);
1359: }
1360:
1361: case Any.IS_STRING | Any.IS_DOUBLE << 5:
1362: a = a.coerce();
1363: switch (a.typeOf()) {
1364: case Any.IS_INT:
1365: return a.toAnyDouble().add(b);
1366: case Any.IS_DOUBLE:
1367: return a.add(b);
1368: case Any.IS_STRING:
1369: return a.concat(b);
1370: }
1371: break;
1372:
1373: default:
1374: if (typeOfA == typeOfB) {
1375: return a.add(b);
1376: } else {
1377: if (a.isSequence()) {
1378: AnySequence seq = (AnySequence) a;
1379: if (seq.isCompatible(b)) {
1380: AnySequence seq2 = seq
1381: .createEmptySequence();
1382: seq2 = seq2.append(seq);
1383: seq2 = seq2.append((AnySequence) b);
1384: return seq2;
1385: }
1386: }
1387: }
1388: }
1389: return UNDEFINED;
1390: }
1391:
1392: public static final Any sub(Any a, Any b) {
1393: int typeOfA = a.typeOf();
1394: int typeOfB = b.typeOf();
1395: switch (typeOfA | typeOfB << 5) {
1396: case Any.IS_INT | Any.IS_UNDEFINED << 5:
1397: case Any.IS_INT | Any.IS_NULL << 5:
1398: return a.subtract(ZERO);
1399:
1400: case Any.IS_UNDEFINED | Any.IS_INT << 5:
1401: case Any.IS_NULL | Any.IS_INT << 5:
1402: return ZERO.subtract(b);
1403:
1404: case Any.IS_DOUBLE | Any.IS_UNDEFINED << 5:
1405: case Any.IS_DOUBLE | Any.IS_NULL << 5:
1406: return a.subtract(DOUBLE_ZERO);
1407:
1408: case Any.IS_UNDEFINED | Any.IS_DOUBLE << 5:
1409: case Any.IS_NULL | Any.IS_DOUBLE << 5:
1410: return DOUBLE_ZERO.subtract(b);
1411:
1412: case Any.IS_INT | Any.IS_DOUBLE << 5:
1413: return a.toAnyDouble().subtract(b);
1414:
1415: case Any.IS_DOUBLE | Any.IS_INT << 5:
1416: return a.subtract(b);
1417:
1418: case Any.IS_INT | Any.IS_STRING << 5:
1419: b = b.coerce();
1420: switch (b.typeOf()) {
1421: case Any.IS_INT:
1422: return a.subtract(b);
1423: case Any.IS_DOUBLE:
1424: return a.toAnyDouble().subtract(b);
1425: case Any.IS_STRING:
1426: return UNDEFINED;
1427: }
1428: return UNDEFINED;
1429:
1430: case Any.IS_DOUBLE | Any.IS_STRING << 5:
1431: b = b.coerce();
1432: if (b.typeOf() == Any.IS_STRING) {
1433: return UNDEFINED;
1434: } else {
1435: return a.subtract(b);
1436: }
1437:
1438: case Any.IS_STRING | Any.IS_INT << 5:
1439: a = a.coerce();
1440: if (a.typeOf() == Any.IS_STRING) {
1441: return UNDEFINED;
1442: } else {
1443: return a.subtract(b);
1444: }
1445:
1446: case Any.IS_STRING | Any.IS_DOUBLE << 5:
1447: a = a.coerce();
1448: switch (a.typeOf()) {
1449: case Any.IS_INT:
1450: return a.toAnyDouble().subtract(b);
1451: case Any.IS_DOUBLE:
1452: return a.subtract(b);
1453: case Any.IS_STRING:
1454: return UNDEFINED;
1455: }
1456: return UNDEFINED;
1457:
1458: default:
1459: if (typeOfA == typeOfB) {
1460: return a.subtract(b);
1461: }
1462: return UNDEFINED;
1463: }
1464: }
1465:
1466: public static final Any mul(Any a, Any b) {
1467: int typeOfA = a.typeOf();
1468: int typeOfB = b.typeOf();
1469: switch (typeOfA | typeOfB << 5) {
1470: case Any.IS_INT | Any.IS_UNDEFINED << 5:
1471: case Any.IS_INT | Any.IS_NULL << 5:
1472: return a.multiply(ZERO);
1473:
1474: case Any.IS_UNDEFINED | Any.IS_INT << 5:
1475: case Any.IS_NULL | Any.IS_INT << 5:
1476: return ZERO.multiply(b);
1477:
1478: case Any.IS_DOUBLE | Any.IS_UNDEFINED << 5:
1479: case Any.IS_DOUBLE | Any.IS_NULL << 5:
1480: return a.multiply(DOUBLE_ZERO);
1481:
1482: case Any.IS_UNDEFINED | Any.IS_DOUBLE << 5:
1483: case Any.IS_NULL | Any.IS_DOUBLE << 5:
1484: return DOUBLE_ZERO.multiply(b);
1485:
1486: case Any.IS_INT | Any.IS_DOUBLE << 5:
1487: return a.toAnyDouble().multiply(b);
1488:
1489: case Any.IS_DOUBLE | Any.IS_INT << 5:
1490: return a.multiply(b);
1491:
1492: case Any.IS_INT | Any.IS_STRING << 5:
1493: b = b.coerce();
1494: switch (b.typeOf()) {
1495: case Any.IS_INT:
1496: return a.multiply(b);
1497: case Any.IS_DOUBLE:
1498: return a.toAnyDouble().multiply(b);
1499: case Any.IS_STRING:
1500: return UNDEFINED;
1501: }
1502: return UNDEFINED;
1503:
1504: case Any.IS_DOUBLE | Any.IS_STRING << 5:
1505: b = b.coerce();
1506: if (b.typeOf() == Any.IS_STRING) {
1507: return UNDEFINED;
1508: } else {
1509: return a.multiply(b);
1510: }
1511:
1512: case Any.IS_STRING | Any.IS_INT << 5:
1513: a = a.coerce();
1514: if (a.typeOf() == Any.IS_STRING) {
1515: return UNDEFINED;
1516: } else {
1517: return a.multiply(b);
1518: }
1519:
1520: case Any.IS_STRING | Any.IS_DOUBLE << 5:
1521: a = a.coerce();
1522: switch (a.typeOf()) {
1523: case Any.IS_INT:
1524: return a.toAnyDouble().multiply(b);
1525: case Any.IS_DOUBLE:
1526: return a.multiply(b);
1527: case Any.IS_STRING:
1528: return UNDEFINED;
1529: }
1530: return UNDEFINED;
1531:
1532: default:
1533: if (typeOfA == typeOfB) {
1534: return a.multiply(b);
1535: }
1536: return UNDEFINED;
1537: }
1538: }
1539:
1540: public static final Any div(Any a, Any b) {
1541: int typeOfA = a.typeOf();
1542: int typeOfB = b.typeOf();
1543: switch (typeOfA | typeOfB << 5) {
1544: case Any.IS_INT | Any.IS_UNDEFINED << 5:
1545: case Any.IS_INT | Any.IS_NULL << 5:
1546: return a.divide(ZERO);
1547:
1548: case Any.IS_UNDEFINED | Any.IS_INT << 5:
1549: case Any.IS_NULL | Any.IS_INT << 5:
1550: return ZERO.divide(b);
1551:
1552: case Any.IS_DOUBLE | Any.IS_UNDEFINED << 5:
1553: case Any.IS_DOUBLE | Any.IS_NULL << 5:
1554: return a.divide(DOUBLE_ZERO);
1555:
1556: case Any.IS_UNDEFINED | Any.IS_DOUBLE << 5:
1557: case Any.IS_NULL | Any.IS_DOUBLE << 5:
1558: return DOUBLE_ZERO.divide(b);
1559:
1560: case Any.IS_INT | Any.IS_DOUBLE << 5:
1561: return a.toAnyDouble().divide(b);
1562:
1563: case Any.IS_DOUBLE | Any.IS_INT << 5:
1564: return a.divide(b);
1565:
1566: case Any.IS_INT | Any.IS_STRING << 5:
1567: b = b.coerce();
1568: switch (b.typeOf()) {
1569: case Any.IS_INT:
1570: return a.divide(b);
1571: case Any.IS_DOUBLE:
1572: return a.toAnyDouble().divide(b);
1573: case Any.IS_STRING:
1574: return UNDEFINED;
1575: }
1576: return UNDEFINED;
1577:
1578: case Any.IS_DOUBLE | Any.IS_STRING << 5:
1579: b = b.coerce();
1580: if (b.typeOf() == Any.IS_STRING) {
1581: return UNDEFINED;
1582: } else {
1583: return a.divide(b);
1584: }
1585:
1586: case Any.IS_STRING | Any.IS_INT << 5:
1587: a = a.coerce();
1588: if (a.typeOf() == Any.IS_STRING) {
1589: return UNDEFINED;
1590: } else {
1591: return a.divide(b);
1592: }
1593:
1594: case Any.IS_STRING | Any.IS_DOUBLE << 5:
1595: a = a.coerce();
1596: switch (a.typeOf()) {
1597: case Any.IS_INT:
1598: return a.toAnyDouble().divide(b);
1599: case Any.IS_DOUBLE:
1600: return a.divide(b);
1601: case Any.IS_STRING:
1602: return UNDEFINED;
1603: }
1604: return UNDEFINED;
1605:
1606: default:
1607: if (typeOfA == typeOfB) {
1608: return a.divide(b);
1609: }
1610: return UNDEFINED;
1611: }
1612: }
1613:
1614: public static final Any mod(Any a, Any b) {
1615: int typeOfA = a.typeOf();
1616: int typeOfB = b.typeOf();
1617: switch (typeOfA | typeOfB << 5) {
1618: case Any.IS_INT | Any.IS_UNDEFINED << 5:
1619: case Any.IS_INT | Any.IS_NULL << 5:
1620: return a.modulo(ZERO);
1621:
1622: case Any.IS_UNDEFINED | Any.IS_INT << 5:
1623: case Any.IS_NULL | Any.IS_INT << 5:
1624: return ZERO.modulo(b);
1625:
1626: case Any.IS_DOUBLE | Any.IS_UNDEFINED << 5:
1627: case Any.IS_DOUBLE | Any.IS_NULL << 5:
1628: return a.modulo(DOUBLE_ZERO);
1629:
1630: case Any.IS_UNDEFINED | Any.IS_DOUBLE << 5:
1631: case Any.IS_NULL | Any.IS_DOUBLE << 5:
1632: return DOUBLE_ZERO.modulo(b);
1633:
1634: case Any.IS_INT | Any.IS_DOUBLE << 5:
1635: return a.toAnyDouble().modulo(b);
1636:
1637: case Any.IS_DOUBLE | Any.IS_INT << 5:
1638: return a.modulo(b);
1639:
1640: case Any.IS_INT | Any.IS_STRING << 5:
1641: b = b.coerce();
1642: switch (b.typeOf()) {
1643: case Any.IS_INT:
1644: return a.modulo(b);
1645: case Any.IS_DOUBLE:
1646: return a.toAnyDouble().modulo(b);
1647: case Any.IS_STRING:
1648: return UNDEFINED;
1649: }
1650: return UNDEFINED;
1651:
1652: case Any.IS_DOUBLE | Any.IS_STRING << 5:
1653: b = b.coerce();
1654: if (b.typeOf() == Any.IS_STRING) {
1655: return UNDEFINED;
1656: } else {
1657: return a.modulo(b);
1658: }
1659:
1660: case Any.IS_STRING | Any.IS_INT << 5:
1661: a = a.coerce();
1662: if (a.typeOf() == Any.IS_STRING) {
1663: return UNDEFINED;
1664: } else {
1665: return a.modulo(b);
1666: }
1667:
1668: case Any.IS_STRING | Any.IS_DOUBLE << 5:
1669: a = a.coerce();
1670: switch (a.typeOf()) {
1671: case Any.IS_INT:
1672: return a.toAnyDouble().modulo(b);
1673: case Any.IS_DOUBLE:
1674: return a.modulo(b);
1675: case Any.IS_STRING:
1676: return UNDEFINED;
1677: }
1678: return UNDEFINED;
1679:
1680: default:
1681: if (typeOfA == typeOfB) {
1682: return a.modulo(b);
1683: }
1684: return UNDEFINED;
1685: }
1686: }
1687:
1688: }
1689:
1690: }
|