0001 
0002 /*
0003  *  Descripter 1.0 - Java Script Engines
0004  *  Copyright (C) 2010-2015  Jianjun Liu (J.J.Liu)
0005  *  
0006  *  This program is free software: you can redistribute it and/or modify
0007  *  it under the terms of the GNU Affero General Public License as published by
0008  *  the Free Software Foundation, either version 3 of the License, or
0009  *  (at your option) any later version.
0010  *  
0011  *  This program is distributed in the hope that it will be useful,
0012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014  *  GNU Affero General Public License for more details.
0015  *  
0016  *  You should have received a copy of the GNU Affero General Public License
0017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0018  */
0019 
0020 package org.descripter.js.api;
0021 
0022 import java.lang.reflect.Method;
0023 
0024 import org.descripter.js.api.core.CObject;
0025 import org.descripter.js.api.core.CString;
0026 
0027 /**
0028  * <p>An abstract base class to represent JavaScript objective contexts.</p>
0029  * 
0030  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.descripter.org" target="_blank">http://www.descripter.org</a>
0031  * @since Descripter 1.0
0032  */
0033 public abstract class Objective<W extends Objective<?>> extends Context<Key, Object, W>
0034 {
0035     /**
0036      * <p>Constructs an {@link Objective} {@link Context} of this type.</p>
0037      * @param with The containing {@link Objective} {@link Context}.
0038      * @since Descripter 1.0
0039      */
0040     protected Objective(W with) {
0041         super(with);
0042     }
0043 
0044     /**
0045      * <p>Gets a string member of this {@link Objective} {@link Context}.</p>
0046      * @param key The name {@link Key} of the member.
0047      * @return The string value of the member specified by the {@link Key}.
0048      * @since Descripter 1.0
0049      */
0050     public String getString(Key key) {
0051         return (String)get(key);
0052     }
0053 
0054     /**
0055      * <p>Gets a number member of this {@link Objective} {@link Context}.</p>
0056      * @param key The name {@link Key} of the member.
0057      * @return The number value of the member specified by the {@link Key}.
0058      * @since Descripter 1.0
0059      */
0060     public Number getNumber(Key key) {
0061         return (Number)get(key);
0062     }
0063 
0064     /**
0065      * <p>Gets a name {@link Key} from this {@link Objective} {@link Context}.</p>
0066      * @param name The name for the {@link Key} to get.
0067      * @return The {@link Key} that has the specified name.
0068      * @since Descripter 1.0
0069      */
0070     public Key key(String name) {
0071         return Key.get(this, name);
0072     }
0073 
0074     /**
0075      * <p>Sets the value associated with the specified key.</p>
0076      * @param key A {@link Key} to set the value
0077      * @param val The value to set
0078      * @throws RuntimeException if the current context is read-only.
0079      * @since Descripter 1.0
0080      */
0081     @Override
0082     public void put(Key key, Object val) {
0083         super.put(key, evaluate(val));
0084     }
0085 
0086     /**
0087      * <p>Sets the value associated with the specified key and returns the current 
0088      * {@link Objective} {@link Context}.</p>
0089      * @param k A {@link Key} to set the value
0090      * @param o The value to set
0091      * @return The current {@link Objective} {@link Context}
0092      * @throws RuntimeException if the current context is read-only.
0093      * @since Descripter 1.0
0094      */
0095     public Objective<W> set(Key k, Object o) {
0096         put(k, o);
0097         return this;
0098     }
0099 
0100     /**
0101      * <p>Sets the value associated with the specified index and returns the current 
0102      * {@link Objective} {@link Context}.</p>
0103      * @param i An index to set the value
0104      * @param o The value to set
0105      * @return The current {@link Objective} {@link Context}
0106      * @throws RuntimeException if the current context is read-only.
0107      * @since Descripter 1.0
0108      */
0109     public Objective<W> set(Integer i, Object o) {
0110         return set(key(i.toString()), o);
0111     }
0112 
0113     /**
0114      * <p>Returns the value associated with the specified index.</p>
0115      * @param i An index to lookup
0116      * @return The value associated with the specified index or <tt>null</tt> for none.
0117      * @since Descripter 1.0
0118      */
0119     public Object get(Integer i) {
0120         return get(key(i.toString()));
0121     }
0122 
0123     /**
0124      * <p>Tells if the specified index is visible from the current context.</p>
0125      * @param i An index to test
0126      * @return <tt>true</tt> if the index is visible from the current context; <tt>false</tt>, otherwise.
0127      * @since Descripter 1.0
0128      */
0129     public boolean has(Integer i) {
0130         return has(key(i.toString()));
0131     }
0132 
0133     /**
0134      * <p>Hides the specified index from the current context if it is visible.</p>
0135      * <p>Note that this method does nothing if the index is not visible.</p>
0136      * @param i An index to remove
0137      * @throws RuntimeException if the current context is read-only.
0138      * @since Descripter 1.0
0139      */
0140     public void hide(Integer i) {
0141         hide(key(i.toString()));
0142     }
0143 
0144     /**
0145      * <p>Sets the value associated with the specified index.</p>
0146      * @param i An index to set the value
0147      * @param v The value to set
0148      * @throws RuntimeException if the current context is read-only.
0149      * @since Descripter 1.0
0150      */
0151     public void put(Integer i, Object v) {
0152         put(key(i.toString()), evaluate(v));
0153     }
0154 
0155     /**
0156      * <p>Returns a {@link Var} specified by a given index.</p>
0157      * @param i The index of the {@link Var} to get
0158      * @return The {@link Var} specified by the index
0159      * @since Descripter 1.0
0160      */
0161     public final Var var(Integer i) {
0162         return new Var(this, key(i.toString()));
0163     }
0164 
0165     /**
0166      * <p>Returns a {@link Var} specified by a given {@link Key}.</p>
0167      * @param k The {@link Key} of the {@link Var} to get
0168      * @return The {@link Var} specified by the {@link Key}
0169      * @since Descripter 1.0
0170      */
0171     public final Var var(Key k) {
0172         return new Var(this, k);
0173     }
0174 
0175     /**
0176      * <p>Evaluates the argument.</p>
0177      * <p>If the argument is not an instance of {@link Value}, this method simply returns the argument itself. 
0178      * Otherwise, it calls the {@link Value#evaluate()} method at the argument and returns the result.</p>
0179      * @param o The object argument to evaluate
0180      * @return The evaluation result or the argument itself
0181      * @since Descripter 1.0
0182      */
0183     public static final Object evaluate(Object o) {
0184         return o instanceof Value ? ((Value)o).evaluate() : o;
0185     }
0186 
0187     /**
0188      * <p>Returns the primitive value associated with the argument, if there is one. </p>
0189      * <p>This method first evaluates the argument. If the evaluation is not an instance of {@link CObject}, 
0190      * it simply returns the evaluation of the argument. Otherwise, it calls the {@link CObject#valueOf()} method at 
0191      * the evaluation and returns the result.</p>
0192      * @param o The object argument to get value of
0193      * @return The value of the object argument
0194      * @since Descripter 1.0
0195      */
0196     public static final Object valueOf(Object o) {
0197         o = evaluate(o);
0198         return o instanceof CObject ? ((CObject)o).valueOf() : o;
0199     }
0200 
0201     /**
0202      * <p>Logically evaluates an object argument.</p>
0203      * @param o The object argument to get boolean value of
0204      * @return The boolean value of the argument
0205      * @since Descripter 1.0
0206      */
0207     public static final boolean bool(Object o) {
0208         o = valueOf(o);
0209         return o instanceof Boolean ? (Boolean)o :
0210                o instanceof String ? ((String)o).length() > 0 :
0211                o instanceof Character ? ((Character)o).charValue() > 0 :
0212                o instanceof Number ? ((Number)o).doubleValue() != 0D : o != null;
0213     }
0214 
0215     /**
0216      * <p>Numerically evaluates an object argument.</p>
0217      * @param o The object argument to get number value of
0218      * @return The number value of the argument
0219      * @since Descripter 1.0
0220      */
0221     public static final Number toNumber(Object o) {
0222         o = valueOf(o);
0223         return o == null ? 0 :
0224             o instanceof Character ? (int)((Character)o).charValue() :
0225             o instanceof Boolean ? ((Boolean)o ? 1 : 0) :
0226             o instanceof String && ((String)o).length() < 1 ? 0 : (Number)o;
0227     }
0228 
0229     /**
0230      * <p>Gets the integer value of an object.</p>
0231      * @param o The object to get integer value of
0232      * @return The integer value of the object
0233      * @since Descripter 1.0
0234      */
0235     public static final int intValue(Object o) {
0236         return toNumber(o).intValue();
0237     }
0238 
0239     /**
0240      * <p>Gets the double value of an object.</p>
0241      * @param o The object to get double value of
0242      * @return The double value of the object
0243      * @since Descripter 1.0
0244      */
0245     public static final double doubleValue(Object o) {
0246         return toNumber(o).doubleValue();
0247     }
0248 
0249     /**
0250      * <p>Gets the string value of an object.</p>
0251      * @param o The object to get string value of
0252      * @return The string value of the object
0253      * @since Descripter 1.0
0254      */
0255     public static final String toString(Object o) {
0256         return o == null ? "undefined" : o.toString();
0257     }
0258 
0259     /**
0260      * <p>The id for the type of <tt>undefined</tt>.</p>
0261      * @since Descripter 1.0
0262      */
0263     public final static int UNDEFINED = 0;
0264     /**
0265      * <p>The id for the type of <tt>function</tt>.</p>
0266      * @since Descripter 1.0
0267      */
0268     public final static int FUNCTION  = 1;
0269     /**
0270      * <p>The id for the type of <tt>object</tt>.</p>
0271      * @since Descripter 1.0
0272      */
0273     public final static int OBJECT    = 2;
0274     /**
0275      * <p>The id for the type of <tt>string</tt>.</p>
0276      * @since Descripter 1.0
0277      */
0278     public final static int STRING    = 3;
0279     /**
0280      * <p>The id for the type of <tt>number</tt>.</p>
0281      * @since Descripter 1.0
0282      */
0283     public final static int NUMBER    = 4;
0284     /**
0285      * <p>The id for the type of <tt>boolean</tt>.</p>
0286      * @since Descripter 1.0
0287      */
0288     public final static int BOOLEAN   = 5;
0289     /**
0290      * <p>The id for the type of <tt>unknown</tt>.</p>
0291      * @since Descripter 1.0
0292      */
0293     public final static int UNKNOWN   = 6;
0294 
0295     /**
0296      * <p>Returns the type id of an object value.</p>
0297      * @param o An object value
0298      * @return The type id of the object value
0299      * @since Descripter 1.0
0300      */
0301     public static final int typeOf(Object o) {
0302         o = evaluate(o);
0303         if (o instanceof Function) {
0304             return FUNCTION;
0305         } else if (o instanceof CObject) {
0306             return OBJECT;
0307         } else if (o instanceof String) {
0308             return STRING;
0309         } else if (o instanceof Number) {
0310             return NUMBER;
0311         } else if (o instanceof Boolean) {
0312             return BOOLEAN;
0313         } else if (o instanceof Method) {
0314             return FUNCTION;
0315         } else if (o instanceof Character) {
0316             return NUMBER;
0317         } else if (o == null) {
0318             return UNDEFINED;
0319         } else {
0320             return UNKNOWN;
0321         }
0322     }
0323 
0324     /**
0325      * <p>Returns a string indicating the data-type of the argument.</p>
0326      * <p>Emulating the JavaScript <tt>typeof</tt> operator and <tt>typeof()</tt> 
0327      * function, this invocation evaluates to "number", "string", or "boolean" if the  
0328      * argument is a number, string, or boolean value. It evaluates to "object" for objects 
0329      * and arrays. It evaluates to "function" for function instance and to "undefined" if 
0330      * the argument is undefined.</p>
0331      * @param o Any value or object.
0332      * @return A string indicating the data-type of the argument.
0333      * @since Descripter 1.0
0334      */
0335     public static final String typeof(Object o) {
0336         switch (typeOf(o)) {
0337             case UNDEFINED:
0338                 return "undefined";
0339             case OBJECT:
0340                 return "object";
0341             case FUNCTION:
0342                 return "function";
0343             case BOOLEAN:
0344                 return "boolean";
0345             case NUMBER:
0346                 return "number";
0347             case STRING:
0348                 return "string";
0349             default:
0350                 return "unknown";
0351         }
0352     }
0353 
0354     /**
0355      * <p>Performs unary negation, resembling the unary minus operator in JavaScript.</p>
0356      * <p>This operation converts a positive value to an equivalently negative value, and 
0357      * vice versa. If the operand is not a number, it attempts to convert it to one.</p>
0358      * @param a Any numeric value.
0359      * @return The negation of the numeric value.
0360      * @since Descripter 1.0
0361      */
0362     public static final double neg(Object a) {
0363         return - doubleValue(a);
0364     }
0365 
0366     /**
0367      * <p>Adds numeric operands, resembling the addition operator in JavaScript.</p>
0368      * @param a A numeric value.
0369      * @param b A numeric value.
0370      * @return The sum of the values.
0371      * @since Descripter 1.0
0372      */
0373     public static final double add(Number a, Number b) {
0374         return doubleValue(a) + doubleValue(b);
0375     }
0376 
0377     /**
0378      * <p>Adds numeric operands or concatenates string operands, resembling the addition 
0379      * operator in JavaScript.</p>
0380      * <p>If one operand is a string, the other is converted to a string, and the two 
0381      * strings are then concatenated. Object operands are converted to numbers or strings 
0382      * that can be added or concatenated. The conversion is performed by {@link #valueOf(Object)}  
0383      * method and/or the {@link #toString(Object)} method on the object.</p>
0384      * @param a A value or object.
0385      * @param b A value or object.
0386      * @return The sum or concatenation of the values.
0387      * @since Descripter 1.0
0388      */
0389     public static final Object add(Object a, Object b) {
0390         a = valueOf(a);
0391         b = valueOf(b);
0392         if (typeOf(a) == NUMBER && typeOf(b) == NUMBER) {
0393             return add((Number)a, (Number)b);
0394         } else {
0395             return toString(a).concat(toString(b));
0396         }
0397     }
0398 
0399     /**
0400      * <p>Subtracts the second operand from the first operand, resembling the subtraction operator in JavaScript.</p>
0401      * <p>If used with non-numeric operands, this operation attempts to convert them to numbers.</p>
0402      * @param a Any numeric value.
0403      * @param b Any numeric value.
0404      * @return The difference between the operands.
0405      * @since Descripter 1.0
0406      */
0407     public static final double sub(Object a, Object b) {
0408         return doubleValue(a) - doubleValue(b);
0409     }
0410 
0411     /**
0412      * <p>Multiplies the two operands, resembling the multiplication operator in JavaScript.</p>
0413      * <p>If used with non-numeric operands, this operation attempts to convert them to numbers.</p>
0414      * @param a Any numeric value.
0415      * @param b Any numeric value.
0416      * @return The product of the two operands.
0417      * @since Descripter 1.0
0418      */
0419     public static final double mul(Object a, Object b) {
0420         return doubleValue(a) * doubleValue(b);
0421     }
0422 
0423     /**
0424      * <p>Computes the first operand modulo the second operand, resembling the modulo 
0425      * operator in JavaScript.</p>
0426      * <p>The operation returns the remainder when the first operand is divided by the 
0427      * second operand a certain number of times. If used with non-numeric operands, the 
0428      * operation attempts to convert them to numbers. The sign of the result is the same 
0429      * as the sign of the first operand.</p>
0430      * <p>This operation is typically used with integer operands, it also works for 
0431      * floating-point values.</p>
0432      * @param a Any numeric value.
0433      * @param b Any numeric value.
0434      * @return The remainder.
0435      * @since Descripter 1.0
0436      */
0437     public static final double mod(Object a, Object b) {
0438         return doubleValue(a) % doubleValue(b);
0439     }
0440 
0441     /**
0442      * <p>Divides the first operand by the second, resembling the division operator 
0443      * in JavaScript.</p>
0444      * <p>Used with non-numeric operands, this operation attempts to convert them to 
0445      * numbers. If you are used to programming languages that distinguish between integer 
0446      * and floating-point numbers, you might expect to get an integer result when you 
0447      * divide one integer by another. In JavaScript, however, all numbers are floating-point, 
0448      * so all division operations have floating-point results. Division by zero yields positive 
0449      * or negative infinity, while <tt>0/0</tt> evaluates to <tt>NaN</tt>.</p>
0450      * @param a Any numeric value.
0451      * @param b Any numeric value.
0452      * @return The quotient of the two operands.
0453      * @since Descripter 1.0
0454      */
0455     public static final double div(Object a, Object b) {
0456         return doubleValue(a) / doubleValue(b);
0457     }
0458 
0459     /**
0460      * <p>Bitwise-NOT operation, resembling that of JavaScript, operates by reversing all 
0461      * bits in the operand.</p>
0462      * <p>Because of the way signed integers are represented in JavaScript, applying this 
0463      * operation to a value is equivalent to changing its sign and subtracting 1.</p>
0464      * <p>Despite the fact that all numbers in JavaScript are floating-point numbers, the bitwise 
0465      * operation requires numeric operands that have integer values. It operate on the integer 
0466      * operands using a 32-bit integer representation instead of the equivalent floating-point 
0467      * representation.</p>
0468      * <p>If this bitwise operation is used with operands that are not integers or are too 
0469      * large to fit in a 32-bit integer representation, it simply coerces the operands to 
0470      * 32-bit integers by dropping any fractional part of the operand or any bits beyond 
0471      * the 32nd.</p>
0472      * @param o A numeric value.
0473      * @return The bitwise-NOT of the operand.
0474      * @since Descripter 1.0
0475      */
0476     public static int not(Object o) {
0477         return ~intValue(o);
0478     }
0479 
0480     /**
0481      * <p>Bitwise-AND operation, resembling that of JavaScript, performs a boolean AND 
0482      * operation on each bit of the integer arguments. A bit is set in the result only if 
0483      * the corresponding bit is set in both operands.</p>
0484      * <p>Despite the fact that all numbers in JavaScript are floating-point numbers, the bitwise 
0485      * operation requires numeric operands that have integer values. It operate on the integer 
0486      * operands using a 32-bit integer representation instead of the equivalent floating-point 
0487      * representation.</p>
0488      * <p>If this bitwise operation is used with operands that are not integers or are too 
0489      * large to fit in a 32-bit integer representation, it simply coerces the operands to 
0490      * 32-bit integers by dropping any fractional part of the operand or any bits beyond 
0491      * the 32nd.</p>
0492      * @param a A numeric value.
0493      * @param b A numeric value.
0494      * @return The bitwise-AND of the two operands.
0495      * @since Descripter 1.0
0496      */
0497     public static int and(Object a, Object b) {
0498         return intValue(a) & intValue(b);
0499     }
0500 
0501     /**
0502      * <p>Bitwise-OR operation, resembling that of JavaScript, performs a boolean OR operation 
0503      * on each bit of the integer arguments. A bit is set in the result if the corresponding 
0504      * bit is set in one or both of the operands.</p>
0505      * <p>Despite the fact that all numbers in JavaScript are floating-point numbers, the bitwise 
0506      * operation requires numeric operands that have integer values. It operate on the integer 
0507      * operands using a 32-bit integer representation instead of the equivalent floating-point 
0508      * representation.</p>
0509      * <p>If this bitwise operation is used with operands that are not integers or are too 
0510      * large to fit in a 32-bit integer representation, it simply coerces the operands to 
0511      * 32-bit integers by dropping any fractional part of the operand or any bits beyond 
0512      * the 32nd.</p>
0513      * @param a A numeric value.
0514      * @param b A numeric value.
0515      * @return The bitwise-OR of the two operands.
0516      * @since Descripter 1.0
0517      */
0518     public static int or(Object a, Object b) {
0519         return intValue(a) | intValue(b);
0520     }
0521 
0522     /**
0523      * <p>Bitwise-XOR operation, resembling that of JavaScript, performs a boolean exclusive 
0524      * OR operation on each bit of the integer arguments. Exclusive OR means that either 
0525      * operand one is <tt>true</tt> or operand two is <tt>true</tt>, but not both. A bit is 
0526      * set in this operation's result if a corresponding bit is set in one (but not both) 
0527      * of the two operands.</p>
0528      * <p>Despite the fact that all numbers in JavaScript are floating-point numbers, the bitwise 
0529      * operation requires numeric operands that have integer values. It operate on the integer 
0530      * operands using a 32-bit integer representation instead of the equivalent floating-point 
0531      * representation.</p>
0532      * <p>If this bitwise operation is used with operands that are not integers or are too 
0533      * large to fit in a 32-bit integer representation, it simply coerces the operands to 
0534      * 32-bit integers by dropping any fractional part of the operand or any bits beyond 
0535      * the 32nd.</p>
0536      * @param a A numeric value.
0537      * @param b A numeric value.
0538      * @return The bitwise-exclusive-OR of the two operands.
0539      * @since Descripter 1.0
0540      */
0541     public static int xor(Object a, Object b) {
0542         return intValue(a) ^ intValue(b);
0543     }
0544 
0545     /**
0546      * <p>Shift-left operation, resembling that of JavaScript, moves all bits in the first 
0547      * operand to the left by the number of places specified in the second operand, which 
0548      * should be an integer between 0 and 31.</p>
0549      * <p>A zero is used for the new first bit, and the value of the 32nd bit is lost. 
0550      * Shifting a value left by one position is equivalent to multiplying by 2, shifting 
0551      * two positions is equivalent to multiplying by 4, etc.</p>
0552      * <p>Despite the fact that all numbers in JavaScript are floating-point numbers, the bitwise 
0553      * operation requires numeric operands that have integer values. It operate on the integer 
0554      * operands using a 32-bit integer representation instead of the equivalent floating-point 
0555      * representation.</p>
0556      * <p>If this bitwise operation is used with operands that are not integers or are too 
0557      * large to fit in a 32-bit integer representation, it simply coerces the operands to 
0558      * 32-bit integers by dropping any fractional part of the operand or any bits beyond 
0559      * the 32nd. The shift operation requires a right-side operand between 0 and 31. After 
0560      * converting this operand to a 32-bit integer, it drops any bits beyond the 5th, which 
0561      * yields a number in the appropriate range.</p>
0562      * @param a A numeric value.
0563      * @param b The number of bits to shift.
0564      * @return The shifted integer number.
0565      * @since Descripter 1.0
0566      */
0567     public static int shl(Object a, Object b) {
0568         return intValue(a) << intValue(b);
0569     }
0570 
0571     /**
0572      * <p>Shift-right operation, resembling that of JavaScript, moves all bits in the first 
0573      * operand to the right by the number of places specified in the second operand (an 
0574      * integer between 0 and 31). Bits that are shifted off the right are lost. The bits 
0575      * filled in on the left depend on the sign bit of the original operand, in order to 
0576      * preserve the sign of the result. If the first operand is positive, the result has 
0577      * zeros placed in the high bits; if the first operand is negative, the result has ones 
0578      * placed in the high bits.</p>
0579      * <p>Shifting a value right one place is equivalent to dividing by 2 (discarding the 
0580      * remainder), shifting right two places is equivalent to integer division by 4, and 
0581      * so on.</p>
0582      * <p>Despite the fact that all numbers in JavaScript are floating-point numbers, the bitwise 
0583      * operation requires numeric operands that have integer values. It operate on the integer 
0584      * operands using a 32-bit integer representation instead of the equivalent floating-point 
0585      * representation.</p>
0586      * <p>If this bitwise operation is used with operands that are not integers or are too 
0587      * large to fit in a 32-bit integer representation, it simply coerces the operands to 
0588      * 32-bit integers by dropping any fractional part of the operand or any bits beyond 
0589      * the 32nd. The shift operation requires a right-side operand between 0 and 31. After 
0590      * converting this operand to a 32-bit integer, it drops any bits beyond the 5th, which 
0591      * yields a number in the appropriate range.</p>
0592      * @param a A numeric value.
0593      * @param b The number of bits to shift.
0594      * @return The shifted integer number.
0595      * @since Descripter 1.0
0596      */
0597     public static int shr(Object a, Object b) {
0598         return intValue(a) >> intValue(b);
0599     }
0600 
0601     /**
0602      * <p>Shift-right-unsigned operation, resembling that of JavaScript, moves all bits in 
0603      * the first operand to the right by the number of places specified in the second 
0604      * operand (an integer between 0 and 31). Bits that are shifted off the right are lost. 
0605      * The result has zeros placed in the high bits.</p>
0606      * <p>This operation is just like {@link #shr(Object, Object)}, except that the bits shifted 
0607      * in on the left are always zero, regardless of the sign of the first operand.</p>
0608      * <p>Shifting a value right one place is equivalent to dividing by 2 (discarding the 
0609      * remainder), shifting right two places is equivalent to integer division by 4, and 
0610      * so on.</p>
0611      * <p>Despite the fact that all numbers in JavaScript are floating-point numbers, the bitwise 
0612      * operation requires numeric operands that have integer values. It operate on the integer 
0613      * operands using a 32-bit integer representation instead of the equivalent floating-point 
0614      * representation.</p>
0615      * <p>If this bitwise operation is used with operands that are not integers or are too 
0616      * large to fit in a 32-bit integer representation, it simply coerces the operands to 
0617      * 32-bit integers by dropping any fractional part of the operand or any bits beyond 
0618      * the 32nd. The shift operation requires a right-side operand between 0 and 31. After 
0619      * converting this operand to a 32-bit integer, it drops any bits beyond the 5th, which 
0620      * yields a number in the appropriate range.</p>
0621      * @param a A numeric value.
0622      * @param b The number of bits to shift.
0623      * @return The shifted integer number.
0624      * @since Descripter 1.0
0625      */
0626     public static int shru(Object a, Object b) {
0627         return intValue(a) >>> intValue(b);
0628     }
0629 
0630     /**
0631      * <p>Bitwise-AND operation, resembling that of JavaScript, performs a boolean AND 
0632      * operation on each bit of the integer arguments. A bit is set in the result only if 
0633      * the corresponding bit is set in both operands.</p>
0634      * <p>Despite the fact that all numbers in JavaScript are floating-point numbers, the bitwise 
0635      * operation requires numeric operands that have integer values. It operate on the integer 
0636      * operands using a 32-bit integer representation instead of the equivalent floating-point 
0637      * representation.</p>
0638      * <p>If this bitwise operation is used with operands that are not integers or are too 
0639      * large to fit in a 32-bit integer representation, it simply coerces the operands to 
0640      * 32-bit integers by dropping any fractional part of the operand or any bits beyond 
0641      * the 32nd.</p>
0642      * @param a A numeric value.
0643      * @param b A numeric value.
0644      * @return The bitwise-AND of the two operands.
0645      * @since Descripter 1.0
0646      */
0647     public static boolean band(Object a, Object b) {
0648         return bool(a) && bool(b);
0649     }
0650 
0651     /**
0652      * <p>Bitwise-OR operation, resembling that of JavaScript, performs a boolean OR operation 
0653      * on each bit of the integer arguments. A bit is set in the result if the corresponding 
0654      * bit is set in one or both of the operands.</p>
0655      * <p>Despite the fact that all numbers in JavaScript are floating-point numbers, the bitwise 
0656      * operation requires numeric operands that have integer values. It operate on the integer 
0657      * operands using a 32-bit integer representation instead of the equivalent floating-point 
0658      * representation.</p>
0659      * <p>If this bitwise operation is used with operands that are not integers or are too 
0660      * large to fit in a 32-bit integer representation, it simply coerces the operands to 
0661      * 32-bit integers by dropping any fractional part of the operand or any bits beyond 
0662      * the 32nd.</p>
0663      * @param a A numeric value.
0664      * @param b A numeric value.
0665      * @return The bitwise-OR of the two operands.
0666      * @since Descripter 1.0
0667      */
0668     public static boolean bor(Object a, Object b) {
0669         return bool(a) || bool(b);
0670     }
0671 
0672     /**
0673      * <p>Inverts the boolean value of its operand, resembling the logical NOT operator 
0674      * in JavaScript.</p>
0675      * <p>This operation converts its operand to a boolean value using the following rules 
0676      * if necessary before inverting the converted value.</p>
0677      * <ul>
0678      * <li>If a number is used where a boolean value is expected, the number is converted 
0679      * to <tt>true</tt> unless the number is 0 or NaN, which are converted to <tt>false</tt>.</li>
0680      * <li>If a string is used where a boolean value is expected, it is converted to <tt>true</tt> 
0681      * except for the empty string, which is converted to <tt>false</tt>.</li>
0682      * <li><tt>null</tt> and the undefined value convert to <tt>false</tt>, and any 
0683      * non-null object, array, or function converts to <tt>true</tt>.
0684      * </ul>
0685      * <p>You can convert any value <tt>x</tt> to its equivalent boolean value by applying 
0686      * this operation twice: <tt>bnot(bnot(x))</tt></p>
0687      * @param o A value or object.
0688      * @return The inverted boolean value.
0689      * @since Descripter 1.0
0690      */
0691     public static boolean bnot(Object o) {
0692         return !bool(o);
0693     }
0694 
0695     /**
0696      * <p>Less-than operation, resembling that of JavaScript, evaluates to <tt>true</tt> if 
0697      * the first operand is less than the second operand; otherwise it evaluates to 
0698      * <tt>false</tt>.</p>
0699      * <p>The operands of this operation may be of any type. Comparison can be performed 
0700      * only on numbers and strings, however, so operands that are not numbers or strings 
0701      * are converted. Comparison and conversion occur as follows:</p>
0702      * <ul>
0703      * <li>If both operands are numbers, or if both convert to numbers, they are compared 
0704      * numerically.</li>
0705      * <li>If both operands are strings or convert to strings, they are compared as 
0706      * strings.</li>
0707      * <li>If one operand is or converts to a string, and one is or converts to a number, 
0708      * the operation attempts to convert the string to a number and performs a numerical 
0709      * comparison. If the string does not represent a number, it converts to <tt>NaN</tt>, 
0710      * and the comparison is <tt>false</tt>. In JavaScript 1.1, the string-to-number 
0711      * conversion causes an error instead of yielding <tt>NaN</tt>.</li>
0712      * <li>If an object can be converted to either a number or a string, JavaScript performs 
0713      * the numerical conversion. This means, for example, that Date objects are compared 
0714      * numerically, and it is meaningful to compare two dates to see whether one is earlier 
0715      * than the other.</li>
0716      * <li>If the operands of the comparison operations cannot both be successfully converted 
0717      * to numbers or to strings, these operations always return <tt>false</tt>.</li>
0718      * <li>If either operand is or converts to <tt>NaN</tt>, the comparison operation always 
0719      * yields <tt>false</tt>.</li>
0720      * </ul>
0721      * <p>Keep in mind that string comparison is done on a strict character-by-character 
0722      * basis using the numerical value of each character from the Unicode encoding. Although 
0723      * in some cases the Unicode standard allows equivalent strings to be encoded using 
0724      * different sequences of characters, the JavaScript comparison operations do not 
0725      * detect these encoding differences; they assume that all strings are expressed in 
0726      * normalized form. Note in particular that string comparison is case-sensitive, and 
0727      * in the Unicode encoding (at least for the ASCII subset), all capital letters are 
0728      * "less than" all lowercase letters. This rule can cause confusing results if you do 
0729      * not expect it.</p>
0730      * <p>For a more robust string-comparison algorithm, see the {@link CString#localeCompare(Object)} 
0731      * method, which also takes locale-specific definitions of alphabetical order into account. 
0732      * For case-insensitive comparisons, you must first convert the strings to all lowercase or 
0733      * all uppercase using {@link CString#toLowerCase()} or {@link CString#toUpperCase()}.</p>
0734      * <p>The less-than-or-equal and greater-than-or-equal operations do not rely on the 
0735      * equality or identity operations for determining whether two values are "equal." 
0736      * Instead, the less-than-or-equal operator is simply defined as "not greater than", 
0737      * and the greater-than-or-equal operator is defined as "not less than". The one 
0738      * exception occurs when either operand is (or converts to) <tt>NaN</tt>, in which case 
0739      * all comparison operations return <tt>false</tt>.</p>
0740      * @param a A value or object.
0741      * @param b A value or object.
0742      * @return <tt>true</tt> if the first operand is less than the second operand; 
0743      * otherwise <tt>false</tt>.
0744      * @since Descripter 1.0
0745      */
0746     public static boolean lt(Object a, Object b) {
0747         return sub(a, b) < 0;
0748     }
0749 
0750     /**
0751      * <p>Less-than-or-equal operation, resembling that of JavaScript, evaluates to 
0752      * <tt>true</tt> if the first operand is less than or equal to the second operand; 
0753      * otherwise it evaluates to <tt>false</tt>.</p>
0754      * <p>The operands of this operation may be of any type. Comparison can be performed 
0755      * only on numbers and strings, however, so operands that are not numbers or strings 
0756      * are converted. Comparison and conversion occur as follows:</p>
0757      * <ul>
0758      * <li>If both operands are numbers, or if both convert to numbers, they are compared 
0759      * numerically.</li>
0760      * <li>If both operands are strings or convert to strings, they are compared as 
0761      * strings.</li>
0762      * <li>If one operand is or converts to a string, and one is or converts to a number, 
0763      * the operation attempts to convert the string to a number and performs a numerical 
0764      * comparison. If the string does not represent a number, it converts to <tt>NaN</tt>, 
0765      * and the comparison is <tt>false</tt>. In JavaScript 1.1, the string-to-number 
0766      * conversion causes an error instead of yielding <tt>NaN</tt>.</li>
0767      * <li>If an object can be converted to either a number or a string, JavaScript performs 
0768      * the numerical conversion. This means, for example, that Date objects are compared 
0769      * numerically, and it is meaningful to compare two dates to see whether one is earlier 
0770      * than the other.</li>
0771      * <li>If the operands of the comparison operations cannot both be successfully converted 
0772      * to numbers or to strings, these operations always return <tt>false</tt>.</li>
0773      * <li>If either operand is or converts to <tt>NaN</tt>, the comparison operation always 
0774      * yields <tt>false</tt>.</li>
0775      * </ul>
0776      * <p>Keep in mind that string comparison is done on a strict character-by-character 
0777      * basis using the numerical value of each character from the Unicode encoding. Although 
0778      * in some cases the Unicode standard allows equivalent strings to be encoded using 
0779      * different sequences of characters, the JavaScript comparison operations do not 
0780      * detect these encoding differences; they assume that all strings are expressed in 
0781      * normalized form. Note in particular that string comparison is case-sensitive, and 
0782      * in the Unicode encoding (at least for the ASCII subset), all capital letters are 
0783      * "less than" all lowercase letters. This rule can cause confusing results if you do 
0784      * not expect it.</p>
0785      * <p>For a more robust string-comparison algorithm, see the {@link CString#localeCompare(Object)} 
0786      * method, which also takes locale-specific definitions of alphabetical order into account. 
0787      * For case-insensitive comparisons, you must first convert the strings to all lowercase or 
0788      * all uppercase using {@link CString#toLowerCase()} or {@link CString#toUpperCase()}.</p>
0789      * <p>The less-than-or-equal and greater-than-or-equal operations do not rely on the 
0790      * equality or identity operations for determining whether two values are "equal." 
0791      * Instead, the less-than-or-equal operator is simply defined as "not greater than", 
0792      * and the greater-than-or-equal operator is defined as "not less than". The one 
0793      * exception occurs when either operand is (or converts to) <tt>NaN</tt>, in which case 
0794      * all comparison operations return <tt>false</tt>.</p>
0795      * @param a A value or object.
0796      * @param b A value or object.
0797      * @return <tt>true</tt> if the first operand is less than or equal to the second operand; 
0798      * otherwise <tt>false</tt>.
0799      * @since Descripter 1.0
0800      */
0801     public static boolean lte(Object a, Object b) {
0802         return sub(a, b) <= 0;
0803     }
0804 
0805     /**
0806      * <p>Greater-than operation, resembling that of JavaScript, evaluates to <tt>true</tt> if 
0807      * the first operand is greater than the second operand; otherwise it evaluates to 
0808      * <tt>false</tt>.</p>
0809      * <p>The operands of this operation may be of any type. Comparison can be performed 
0810      * only on numbers and strings, however, so operands that are not numbers or strings 
0811      * are converted. Comparison and conversion occur as follows:</p>
0812      * <ul>
0813      * <li>If both operands are numbers, or if both convert to numbers, they are compared 
0814      * numerically.</li>
0815      * <li>If both operands are strings or convert to strings, they are compared as 
0816      * strings.</li>
0817      * <li>If one operand is or converts to a string, and one is or converts to a number, 
0818      * the operation attempts to convert the string to a number and performs a numerical 
0819      * comparison. If the string does not represent a number, it converts to <tt>NaN</tt>, 
0820      * and the comparison is <tt>false</tt>. In JavaScript 1.1, the string-to-number 
0821      * conversion causes an error instead of yielding <tt>NaN</tt>.</li>
0822      * <li>If an object can be converted to either a number or a string, JavaScript performs 
0823      * the numerical conversion. This means, for example, that Date objects are compared 
0824      * numerically, and it is meaningful to compare two dates to see whether one is earlier 
0825      * than the other.</li>
0826      * <li>If the operands of the comparison operations cannot both be successfully converted 
0827      * to numbers or to strings, these operations always return <tt>false</tt>.</li>
0828      * <li>If either operand is or converts to <tt>NaN</tt>, the comparison operation always 
0829      * yields <tt>false</tt>.</li>
0830      * </ul>
0831      * <p>Keep in mind that string comparison is done on a strict character-by-character 
0832      * basis using the numerical value of each character from the Unicode encoding. Although 
0833      * in some cases the Unicode standard allows equivalent strings to be encoded using 
0834      * different sequences of characters, the JavaScript comparison operations do not 
0835      * detect these encoding differences; they assume that all strings are expressed in 
0836      * normalized form. Note in particular that string comparison is case-sensitive, and 
0837      * in the Unicode encoding (at least for the ASCII subset), all capital letters are 
0838      * "less than" all lowercase letters. This rule can cause confusing results if you do 
0839      * not expect it.</p>
0840      * <p>For a more robust string-comparison algorithm, see the {@link CString#localeCompare(Object)} 
0841      * method, which also takes locale-specific definitions of alphabetical order into account. 
0842      * For case-insensitive comparisons, you must first convert the strings to all lowercase or 
0843      * all uppercase using {@link CString#toLowerCase()} or {@link CString#toUpperCase()}.</p>
0844      * <p>The less-than-or-equal and greater-than-or-equal operations do not rely on the 
0845      * equality or identity operations for determining whether two values are "equal." 
0846      * Instead, the less-than-or-equal operator is simply defined as "not greater than", 
0847      * and the greater-than-or-equal operator is defined as "not less than". The one 
0848      * exception occurs when either operand is (or converts to) <tt>NaN</tt>, in which case 
0849      * all comparison operations return <tt>false</tt>.</p>
0850      * @param a A value or object.
0851      * @param b A value or object.
0852      * @return <tt>true</tt> if the first operand is greater than the second operand; 
0853      * otherwise <tt>false</tt>.
0854      * @since Descripter 1.0
0855      */
0856     public static boolean gt(Object a, Object b) {
0857         return sub(a, b) > 0;
0858     }
0859 
0860     /**
0861      * <p>Greater-than-or-equal operation, resembling that of JavaScript, evaluates to 
0862      * <tt>true</tt> if the first operand is greater than or equal to the second operand; 
0863      * otherwise it evaluates to <tt>false</tt>.</p>
0864      * <p>The operands of this operation may be of any type. Comparison can be performed 
0865      * only on numbers and strings, however, so operands that are not numbers or strings 
0866      * are converted. Comparison and conversion occur as follows:</p>
0867      * <ul>
0868      * <li>If both operands are numbers, or if both convert to numbers, they are compared 
0869      * numerically.</li>
0870      * <li>If both operands are strings or convert to strings, they are compared as 
0871      * strings.</li>
0872      * <li>If one operand is or converts to a string, and one is or converts to a number, 
0873      * the operation attempts to convert the string to a number and performs a numerical 
0874      * comparison. If the string does not represent a number, it converts to <tt>NaN</tt>, 
0875      * and the comparison is <tt>false</tt>. In JavaScript 1.1, the string-to-number 
0876      * conversion causes an error instead of yielding <tt>NaN</tt>.</li>
0877      * <li>If an object can be converted to either a number or a string, JavaScript performs 
0878      * the numerical conversion. This means, for example, that Date objects are compared 
0879      * numerically, and it is meaningful to compare two dates to see whether one is earlier 
0880      * than the other.</li>
0881      * <li>If the operands of the comparison operations cannot both be successfully converted 
0882      * to numbers or to strings, these operations always return <tt>false</tt>.</li>
0883      * <li>If either operand is or converts to <tt>NaN</tt>, the comparison operation always 
0884      * yields <tt>false</tt>.</li>
0885      * </ul>
0886      * <p>Keep in mind that string comparison is done on a strict character-by-character 
0887      * basis using the numerical value of each character from the Unicode encoding. Although 
0888      * in some cases the Unicode standard allows equivalent strings to be encoded using 
0889      * different sequences of characters, the JavaScript comparison operations do not 
0890      * detect these encoding differences; they assume that all strings are expressed in 
0891      * normalized form. Note in particular that string comparison is case-sensitive, and 
0892      * in the Unicode encoding (at least for the ASCII subset), all capital letters are 
0893      * "less than" all lowercase letters. This rule can cause confusing results if you do 
0894      * not expect it.</p>
0895      * <p>For a more robust string-comparison algorithm, see the {@link CString#localeCompare(Object)} 
0896      * method, which also takes locale-specific definitions of alphabetical order into account. 
0897      * For case-insensitive comparisons, you must first convert the strings to all lowercase or 
0898      * all uppercase using {@link CString#toLowerCase()} or {@link CString#toUpperCase()}.</p>
0899      * <p>The less-than-or-equal and greater-than-or-equal operations do not rely on the 
0900      * equality or identity operations for determining whether two values are "equal." 
0901      * Instead, the less-than-or-equal operator is simply defined as "not greater than", 
0902      * and the greater-than-or-equal operator is defined as "not less than". The one 
0903      * exception occurs when either operand is (or converts to) <tt>NaN</tt>, in which case 
0904      * all comparison operations return <tt>false</tt>.</p>
0905      * @param a A value or object.
0906      * @param b A value or object.
0907      * @return <tt>true</tt> if the first operand is greater than or equal to the second operand; 
0908      * otherwise <tt>false</tt>.
0909      * @since Descripter 1.0
0910      */
0911     public static boolean gte(Object a, Object b) {
0912         return sub(a, b) >= 0;
0913     }
0914 
0915     /**
0916      * <p>Checks whether the two operands are "equal" using a more relaxed definition of 
0917      * sameness that allows type conversions, resembling the equality operator in 
0918      * JavaScript.</p>
0919      * <p>The equality and identity operations check whether two values are the same, using 
0920      * two different definitions of sameness. Both operations accept operands of any type, 
0921      * and both return <tt>true</tt> if their operands are the same and <tt>false</tt> 
0922      * if they are different. The identity operation checks whether its two operands are 
0923      * "identical" using a strict definition of sameness. The equality operation checks 
0924      * whether its two operands are "equal" using a more relaxed definition of sameness 
0925      * that allows type conversions.</p>
0926      * <p>The identity operation is standardized by ECMAScript v3 and implemented in 
0927      * JavaScript 1.3 and later. Be sure you understand the differences between the 
0928      * assignment, equality, and identity operations, and be careful to use the correct one 
0929      * when coding! Although it is tempting to call all three operations "equals," it may 
0930      * help to reduce confusion if you read "gets or is assigned" for assignment operation, 
0931      * "is equal to" for equality operation, and "is identical to" for identity operation.</p>
0932      * <p>In JavaScript, numbers, strings, and boolean values are compared by value. In this 
0933      * case, two separate values are involved, and the equality and identity operations 
0934      * check that these two values are identical. This means that two variables are equal 
0935      * or identical only if they contain the same value. For example, two strings are equal 
0936      * only if they each contain exactly the same characters.</p>
0937      * <p>On the other hand, objects, arrays, and functions are compared by reference. This 
0938      * means that two variables are equal only if they refer to the same object. Two 
0939      * separate arrays are never equal or identical, even if they contain equal or identical 
0940      * elements. Two variables that contain references to objects, arrays, or functions are 
0941      * equal only if they refer to the same object, array, or function. If you want to test 
0942      * that two distinct objects contain the same properties or that two distinct arrays 
0943      * contain the same elements, you'll have to check the properties or elements individually 
0944      * for equality or identity. And, if any of the properties or elements are themselves 
0945      * objects or arrays, you'll have to decide how deep you want the comparison to go.</p>
0946      * <p>The following rules determine whether two values are equal according to the 
0947      * equality operation:
0948      * <ul>
0949      * <li>If the two values have the same type, test them for identity. If the values are 
0950      * identical, they are equal; if they are not identical, they are not equal.</li>
0951      * <li>If the two values do not have the same type, they may still be equal. Use the 
0952      * following rules and type conversions to check for equality:</li>
0953      * <ul>
0954      * <li>If one value is null and the other is undefined, they are equal.</li>
0955      * <li>If one value is a number and the other is a string, convert the string to a 
0956      * number and try the comparison again, using the converted value.</li>
0957      * <li>If either value is <tt>true</tt>, convert it to 1 and try the comparison 
0958      * again. If either value is <tt>false</tt>, convert it to 0 and try the comparison 
0959      * again.</li>
0960      * <li>If one value is an object and the other is a number or string, convert the 
0961      * object to a primitive and try the comparison again. An object is converted to a 
0962      * primitive value by either its <tt>toString()</tt> method or its <tt>valueOf()</tt> 
0963      * method. The built-in classes of core JavaScript attempt <tt>valueOf()</tt> 
0964      * conversion before <tt>toString()</tt> conversion, except for the Date class, 
0965      * which performs <tt>toString()</tt> conversion. Objects that are not part of core 
0966      * JavaScript may convert themselves to primitive values in an implementation-defined 
0967      * way.</li>
0968      * <li>Any other combinations of values are not equal.</li>
0969      * </ul>
0970      * </ul>
0971      * @param a Any value or object.
0972      * @param b Any value or object.
0973      * @return <tt>true</tt> if the first operand equals the second; <tt>false</tt>, 
0974      * otherwise;
0975      * @since Descripter 1.0
0976      */
0977     public static boolean eq(Object a, Object b) {
0978         return valueOf(a).equals(valueOf(b));
0979     }
0980 
0981     /**
0982      * <p>Checks whether the two operands are "identical" using a strict definition of 
0983      * sameness, resembling the identity operator in JavaScript.</p>
0984      * <p>The equality and identity operations check whether two values are the same, using 
0985      * two different definitions of sameness. Both operations accept operands of any type, 
0986      * and both return <tt>true</tt> if their operands are the same and <tt>false</tt> 
0987      * if they are different. The identity operation checks whether its two operands are 
0988      * "identical" using a strict definition of sameness. The equality operation checks 
0989      * whether its two operands are "equal" using a more relaxed definition of sameness 
0990      * that allows type conversions.</p>
0991      * <p>The identity operation is standardized by ECMAScript v3 and implemented in 
0992      * JavaScript 1.3 and later. Be sure you understand the differences between the 
0993      * assignment, equality, and identity operations, and be careful to use the correct one 
0994      * when coding! Although it is tempting to call all three operations "equals," it may 
0995      * help to reduce confusion if you read "gets or is assigned" for assignment operation, 
0996      * "is equal to" for equality operation, and "is identical to" for identity operation.</p>
0997      * <p>In JavaScript, numbers, strings, and boolean values are compared by value. In this 
0998      * case, two separate values are involved, and the equality and identity operations 
0999      * check that these two values are identical. This means that two variables are equal 
1000      * or identical only if they contain the same value. For example, two strings are equal 
1001      * only if they each contain exactly the same characters.</p>
1002      * <p>On the other hand, objects, arrays, and functions are compared by reference. This 
1003      * means that two variables are equal only if they refer to the same object. Two 
1004      * separate arrays are never equal or identical, even if they contain equal or identical 
1005      * elements. Two variables that contain references to objects, arrays, or functions are 
1006      * equal only if they refer to the same object, array, or function. If you want to test 
1007      * that two distinct objects contain the same properties or that two distinct arrays 
1008      * contain the same elements, you'll have to check the properties or elements individually 
1009      * for equality or identity. And, if any of the properties or elements are themselves 
1010      * objects or arrays, you'll have to decide how deep you want the comparison to go.</p>
1011      * <p>The following rules determine whether two values are identical according to the identity operation:
1012      * <ul>
1013      * <li>If the two values have different types, they are not identical.</li>
1014      * <li>If both values are numbers and have the same value, they are identical, unless 
1015      * either or both values are <tt>NaN</tt>, in which case they are not identical. 
1016      * The <tt>NaN</tt> value is never identical to any other value, including itself! 
1017      * To check whether a value is <tt>NaN</tt>, use the global {@link Core#isNaN(Script, Object[])} 
1018      * function.</li>
1019      * <li>If both values are strings and contain exactly the same characters in the same 
1020      * positions, they are identical. If the strings differ in length or content, they are 
1021      * not identical. Note that in some cases, the Unicode standard allows more than one 
1022      * way to encode the same string. For efficiency, however, JavaScript's string 
1023      * comparison compares strictly on a character-by-character basis, and it assumes that 
1024      * all strings have been converted to a "normalized form" before they are compared. 
1025      * See the {@link CString#localeCompare(Object)} for another way to compare strings.</li>
1026      * <li>If both values are the boolean value <tt>true</tt> or both are the boolean 
1027      * value <tt>false</tt>, they are identical.</li>
1028      * <li>If both values refer to the same object, array, or function, they are identical. 
1029      * If they refer to different objects (or arrays or functions) they are not identical, 
1030      * even if both objects have identical properties or both arrays have identical elements.</li>
1031      * <li>If both values are null or both values are undefined, they are identical.</li>
1032      * </ul>
1033      * @param a Any value or object.
1034      * @param b Any value or object.
1035      * @return <tt>true</tt> if the first operand is identical to the second; 
1036      * <tt>false</tt>, otherwise;
1037      * @since Descripter 1.0
1038      */
1039     public static boolean eqs(Object a, Object b) {
1040         return evaluate(a).equals(evaluate(b));
1041     }
1042 
1043     /**
1044      * <p>Comma operation, resembling the comma operator of JavaScript, evaluates the 
1045      * first operand, evaluates the second operand, and then returns the value of the 
1046      * second operand.</p>
1047      * <p>In JavaScript, this strange operator is useful only in a few limited circumstances, 
1048      * primarily when you need to evaluate several independent expressions with side effects 
1049      * in a situation where only a single expression is allowed. In practice, the comma 
1050      * operator is really used only in conjunction with the <tt>for</tt> loop statement.</p>
1051      * @param args An array of arguments.
1052      * @return The last operand.
1053      * @since Descripter 1.0
1054      */
1055     public static Object comma(Object...args) {
1056         Object v = null;
1057         if (args != null) {
1058             for (Object o : args) {
1059                 v = evaluate(o);
1060             }
1061         }
1062         return v;
1063     }
1064 }