| JavaDoq: Objective.java |
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 }
| JavaDoq: Objective.java |