Search in sources :

Example 1 with ArrayAccess

use of com.laytonsmith.core.natives.interfaces.ArrayAccess in project CommandHelper by EngineHub.

the class Math method doIncrementDecrement.

/**
 * If we have the case {@code @array[0]++}, we have to increment it as though it were a variable, so we have to do
 * that with execs. This method consolidates the code to do so.
 *
 * @return
 */
protected static Construct doIncrementDecrement(ParseTree[] nodes, Script parent, Environment env, Target t, Function func, boolean pre, boolean inc) {
    if (nodes[0].getData() instanceof CFunction) {
        Function f;
        try {
            f = ((CFunction) nodes[0].getData()).getFunction();
        } catch (ConfigCompileException ex) {
            // This can't really happen, as the compiler would have already caught this
            throw new Error(ex);
        }
        if (f.getName().equals(new ArrayHandling.array_get().getName())) {
            // Ok, so, this is it, we're in charge here.
            long temp;
            long newVal;
            // First, pull out the current value. We're gonna do this manually though, and we will actually
            // skip the whole array_get execution.
            ParseTree eval = nodes[0];
            Construct array = parent.seval(eval.getChildAt(0), env);
            Construct index = parent.seval(eval.getChildAt(1), env);
            Construct cdelta = new CInt(1, t);
            if (nodes.length == 2) {
                cdelta = parent.seval(nodes[1], env);
            }
            long delta = Static.getInt(cdelta, t);
            // First, error check, then get the old value, and store it in temp.
            if (!(array instanceof CArray) && !(array instanceof ArrayAccess)) {
                // Let's just evaluate this like normal with array_get, so it will
                // throw the appropriate exception.
                new ArrayHandling.array_get().exec(t, env, array, index);
                throw ConfigRuntimeException.CreateUncatchableException("Shouldn't have gotten here. Please report this error, and how you got here.", t);
            } else if (!(array instanceof CArray)) {
                // own exception.
                throw new CRECastException("Cannot increment/decrement a non-array array" + " accessed value. (The value passed in was \"" + array.val() + "\")", t);
            } else {
                // Ok, we're good. Data types should all be correct.
                CArray myArray = ((CArray) array);
                Construct value = myArray.get(index, t);
                if (value instanceof CInt || value instanceof CDouble) {
                    temp = Static.getInt(value, t);
                    if (inc) {
                        newVal = temp + delta;
                    } else {
                        newVal = temp - delta;
                    }
                    new ArrayHandling.array_set().exec(t, env, array, index, new CInt(newVal, t));
                } else {
                    throw new CRECastException("Cannot increment/decrement a non numeric value.", t);
                }
            }
            long valueToReturn;
            if (pre) {
                valueToReturn = newVal;
            } else {
                valueToReturn = temp;
            }
            return new CInt(valueToReturn, t);
        }
    }
    Construct[] args = new Construct[nodes.length];
    for (int i = 0; i < args.length; i++) {
        args[i] = parent.eval(nodes[i], env);
    }
    return func.exec(t, env, args);
}
Also used : CRECastException(com.laytonsmith.core.exceptions.CRE.CRECastException) CArray(com.laytonsmith.core.constructs.CArray) CFunction(com.laytonsmith.core.constructs.CFunction) CDouble(com.laytonsmith.core.constructs.CDouble) ConfigCompileException(com.laytonsmith.core.exceptions.ConfigCompileException) CFunction(com.laytonsmith.core.constructs.CFunction) ArrayAccess(com.laytonsmith.core.natives.interfaces.ArrayAccess) CInt(com.laytonsmith.core.constructs.CInt) Construct(com.laytonsmith.core.constructs.Construct) ParseTree(com.laytonsmith.core.ParseTree)

Aggregations

ParseTree (com.laytonsmith.core.ParseTree)1 CArray (com.laytonsmith.core.constructs.CArray)1 CDouble (com.laytonsmith.core.constructs.CDouble)1 CFunction (com.laytonsmith.core.constructs.CFunction)1 CInt (com.laytonsmith.core.constructs.CInt)1 Construct (com.laytonsmith.core.constructs.Construct)1 CRECastException (com.laytonsmith.core.exceptions.CRE.CRECastException)1 ConfigCompileException (com.laytonsmith.core.exceptions.ConfigCompileException)1 ArrayAccess (com.laytonsmith.core.natives.interfaces.ArrayAccess)1