Search in sources :

Example 1 with LoopManipulationException

use of com.laytonsmith.core.exceptions.LoopManipulationException in project CommandHelper by EngineHub.

the class Procedure method execute.

/**
 * Executes this procedure, with the arguments that were passed in
 *
 * @param args
 * @param env
 * @param t
 * @return
 */
public Construct execute(List<Construct> args, Environment env, Target t) {
    env.getEnv(GlobalEnv.class).SetVarList(new IVariableList());
    // This is what will become our @arguments var
    CArray arguments = new CArray(Target.UNKNOWN);
    for (String key : originals.keySet()) {
        Construct c = originals.get(key);
        env.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(Auto.TYPE, key, c, Target.UNKNOWN));
        arguments.push(c, t);
    }
    // new Script(null, null);
    Script fakeScript = Script.GenerateScript(tree, env.getEnv(GlobalEnv.class).GetLabel());
    for (int i = 0; i < args.size(); i++) {
        Construct c = args.get(i);
        arguments.set(i, c, t);
        if (varIndex.size() > i) {
            String varname = varIndex.get(i).getVariableName();
            if (c instanceof CNull || InstanceofUtil.isInstanceof(c, varIndex.get(i).getDefinedType()) || varIndex.get(i).getDefinedType().equals(Auto.TYPE)) {
                env.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(varIndex.get(i).getDefinedType(), varname, c, c.getTarget()));
            } else {
                throw new CRECastException("Procedure \"" + name + "\" expects a value of type " + varIndex.get(i).getDefinedType().val() + " in argument " + (i + 1) + ", but" + " a value of type " + c.typeof() + " was found instead.", c.getTarget());
            }
        }
    }
    env.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(CArray.TYPE, "@arguments", arguments, Target.UNKNOWN));
    StackTraceManager stManager = env.getEnv(GlobalEnv.class).GetStackTraceManager();
    stManager.addStackTraceElement(new ConfigRuntimeException.StackTraceElement("proc " + name, getTarget()));
    try {
        if (tree.getData() instanceof CFunction && "sconcat".equals(tree.getData().val())) {
            // compiler proper.
            for (ParseTree child : tree.getChildren()) {
                fakeScript.eval(child, env);
            }
        } else {
            fakeScript.eval(tree, env);
        }
    } catch (FunctionReturnException e) {
        // Normal exit
        stManager.popStackTraceElement();
        Construct ret = e.getReturn();
        if (!InstanceofUtil.isInstanceof(ret, returnType)) {
            throw new CRECastException("Expected procedure \"" + name + "\" to return a value of type " + returnType.val() + " but a value of type " + ret.typeof() + " was returned instead", ret.getTarget());
        }
        return ret;
    } catch (LoopManipulationException ex) {
        // Not exactly normal, but pop anyways
        stManager.popStackTraceElement();
        // a compile error.
        throw ConfigRuntimeException.CreateUncatchableException("Loop manipulation operations (e.g. break() or continue()) cannot" + " bubble up past procedures.", t);
    } catch (ConfigRuntimeException e) {
        if (e instanceof AbstractCREException) {
            ((AbstractCREException) e).freezeStackTraceElements(stManager);
        }
        stManager.popStackTraceElement();
        throw e;
    } catch (Throwable th) {
        // Not sure. Pop, but rethrow
        stManager.popStackTraceElement();
        throw th;
    }
    // Normal exit, but no return.
    stManager.popStackTraceElement();
    // If we got here, then there was no return value. This is fine, but only for returnType void or auto.
    if (!(returnType.equals(Auto.TYPE) || returnType.equals(CVoid.TYPE))) {
        throw new CRECastException("Expecting procedure \"" + name + "\" to return a value of type " + returnType.val() + "," + " but no value was returned.", tree.getTarget());
    }
    return CVoid.VOID;
}
Also used : AbstractCREException(com.laytonsmith.core.exceptions.CRE.AbstractCREException) CRECastException(com.laytonsmith.core.exceptions.CRE.CRECastException) IVariable(com.laytonsmith.core.constructs.IVariable) IVariableList(com.laytonsmith.core.constructs.IVariableList) CArray(com.laytonsmith.core.constructs.CArray) CFunction(com.laytonsmith.core.constructs.CFunction) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) StackTraceManager(com.laytonsmith.core.exceptions.StackTraceManager) Construct(com.laytonsmith.core.constructs.Construct) GlobalEnv(com.laytonsmith.core.environments.GlobalEnv) FunctionReturnException(com.laytonsmith.core.exceptions.FunctionReturnException) LoopManipulationException(com.laytonsmith.core.exceptions.LoopManipulationException) CNull(com.laytonsmith.core.constructs.CNull)

Example 2 with LoopManipulationException

use of com.laytonsmith.core.exceptions.LoopManipulationException in project CommandHelper by EngineHub.

the class CIClosure method execute.

@Override
public void execute(Construct... values) throws ConfigRuntimeException, ProgramFlowManipulationException, FunctionReturnException, CancelCommandException {
    if (node == null) {
        return;
    }
    StackTraceManager stManager = env.getEnv(GlobalEnv.class).GetStackTraceManager();
    stManager.addStackTraceElement(new ConfigRuntimeException.StackTraceElement("<<iclosure>>", getTarget()));
    try {
        Environment environment;
        synchronized (this) {
            boolean prev = env.getEnv(GlobalEnv.class).getCloneVars();
            env.getEnv(GlobalEnv.class).setCloneVars(false);
            environment = env.clone();
            env.getEnv(GlobalEnv.class).setCloneVars(prev);
        }
        environment.getEnv(GlobalEnv.class).setCloneVars(true);
        if (values != null) {
            for (int i = 0; i < names.length; i++) {
                String name = names[i];
                Construct value;
                try {
                    value = values[i];
                } catch (Exception e) {
                    value = defaults[i].clone();
                }
                environment.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(types[i], name, value, getTarget()));
            }
        }
        boolean hasArgumentsParam = false;
        for (String pName : this.names) {
            if (pName.equals("@arguments")) {
                hasArgumentsParam = true;
                break;
            }
        }
        if (!hasArgumentsParam) {
            CArray arguments = new CArray(node.getData().getTarget());
            if (values != null) {
                for (Construct value : values) {
                    arguments.push(value, node.getData().getTarget());
                }
            }
            environment.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(CArray.TYPE, "@arguments", arguments, node.getData().getTarget()));
        }
        ParseTree newNode = new ParseTree(new CFunction("g", getTarget()), node.getFileOptions());
        List<ParseTree> children = new ArrayList<ParseTree>();
        children.add(node);
        newNode.setChildren(children);
        try {
            MethodScriptCompiler.execute(newNode, environment, null, environment.getEnv(GlobalEnv.class).GetScript());
        } catch (LoopManipulationException e) {
            // Not normal, but pop anyways
            stManager.popStackTraceElement();
            // This shouldn't ever happen.
            LoopManipulationException lme = ((LoopManipulationException) e);
            Target t = lme.getTarget();
            ConfigRuntimeException.HandleUncaughtException(ConfigRuntimeException.CreateUncatchableException("A " + lme.getName() + "() bubbled up to the top of" + " a closure, which is unexpected behavior.", t), environment);
        } catch (FunctionReturnException ex) {
            // Normal. Pop element
            stManager.popStackTraceElement();
            // Check the return type of the closure to see if it matches the defined type
            Construct ret = ex.getReturn();
            if (!InstanceofUtil.isInstanceof(ret, returnType)) {
                throw new CRECastException("Expected closure to return a value of type " + returnType.val() + " but a value of type " + ret.typeof() + " was returned instead", ret.getTarget());
            }
            // Now rethrow it
            throw ex;
        } catch (CancelCommandException e) {
            stManager.popStackTraceElement();
        // die()
        } catch (ConfigRuntimeException ex) {
            if (ex instanceof AbstractCREException) {
                ((AbstractCREException) ex).freezeStackTraceElements(stManager);
            }
            throw ex;
        } catch (Throwable t) {
            stManager.popStackTraceElement();
            throw t;
        }
        // If we got here, then there was no return type. This is fine, but only for returnType void or auto.
        if (!(returnType.equals(Auto.TYPE) || returnType.equals(CVoid.TYPE))) {
            throw new CRECastException("Expecting closure to return a value of type " + returnType.val() + "," + " but no value was returned.", node.getTarget());
        }
    } catch (CloneNotSupportedException ex) {
        Logger.getLogger(CClosure.class.getName()).log(Level.SEVERE, null, ex);
    }
}
Also used : ArrayList(java.util.ArrayList) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) CancelCommandException(com.laytonsmith.core.exceptions.CancelCommandException) AbstractCREException(com.laytonsmith.core.exceptions.CRE.AbstractCREException) CRECastException(com.laytonsmith.core.exceptions.CRE.CRECastException) StackTraceManager(com.laytonsmith.core.exceptions.StackTraceManager) CRECastException(com.laytonsmith.core.exceptions.CRE.CRECastException) LoopManipulationException(com.laytonsmith.core.exceptions.LoopManipulationException) ProgramFlowManipulationException(com.laytonsmith.core.exceptions.ProgramFlowManipulationException) AbstractCREException(com.laytonsmith.core.exceptions.CRE.AbstractCREException) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) CancelCommandException(com.laytonsmith.core.exceptions.CancelCommandException) FunctionReturnException(com.laytonsmith.core.exceptions.FunctionReturnException) Environment(com.laytonsmith.core.environments.Environment) GlobalEnv(com.laytonsmith.core.environments.GlobalEnv) FunctionReturnException(com.laytonsmith.core.exceptions.FunctionReturnException) LoopManipulationException(com.laytonsmith.core.exceptions.LoopManipulationException) ParseTree(com.laytonsmith.core.ParseTree)

Example 3 with LoopManipulationException

use of com.laytonsmith.core.exceptions.LoopManipulationException in project CommandHelper by EngineHub.

the class CClosure method execute.

/**
 * Executes the closure, giving it the supplied arguments. {@code values} may be null, which means that no arguments
 * are being sent.
 *
 * LoopManipulationExceptions will never bubble up past this point, because they are never allowed, so they are
 * handled automatically, but other ProgramFlowManipulationExceptions will, . ConfigRuntimeExceptions will also
 * bubble up past this, since an execution mechanism may need to do custom handling.
 *
 * A typical execution will include the following code:
 * <pre>
 * try {
 *	closure.execute();
 * } catch(ConfigRuntimeException e){
 *	ConfigRuntimeException.HandleUncaughtException(e);
 * } catch(ProgramFlowManipulationException e){
 *	// Ignored
 * }
 * </pre>
 *
 * @param values The values to be passed to the closure
 * @throws ConfigRuntimeException If any call inside the closure causes a CRE
 * @throws ProgramFlowManipulationException If any ProgramFlowManipulationException is thrown (other than a
 * LoopManipulationException) within the closure
 * @throws FunctionReturnException If the closure has a return() call in it.
 */
public void execute(Construct... values) throws ConfigRuntimeException, ProgramFlowManipulationException, FunctionReturnException, CancelCommandException {
    if (node == null) {
        return;
    }
    StackTraceManager stManager = env.getEnv(GlobalEnv.class).GetStackTraceManager();
    stManager.addStackTraceElement(new ConfigRuntimeException.StackTraceElement("<<closure>>", getTarget()));
    try {
        Environment environment;
        synchronized (this) {
            environment = env.clone();
        }
        if (values != null) {
            for (int i = 0; i < names.length; i++) {
                String name = names[i];
                Construct value;
                try {
                    value = values[i];
                } catch (Exception e) {
                    value = defaults[i].clone();
                }
                environment.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(types[i], name, value, getTarget()));
            }
        }
        boolean hasArgumentsParam = false;
        for (String pName : this.names) {
            if (pName.equals("@arguments")) {
                hasArgumentsParam = true;
                break;
            }
        }
        if (!hasArgumentsParam) {
            CArray arguments = new CArray(node.getData().getTarget());
            if (values != null) {
                for (Construct value : values) {
                    arguments.push(value, node.getData().getTarget());
                }
            }
            environment.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(CArray.TYPE, "@arguments", arguments, node.getData().getTarget()));
        }
        ParseTree newNode = new ParseTree(new CFunction("g", getTarget()), node.getFileOptions());
        List<ParseTree> children = new ArrayList<ParseTree>();
        children.add(node);
        newNode.setChildren(children);
        try {
            MethodScriptCompiler.execute(newNode, environment, null, environment.getEnv(GlobalEnv.class).GetScript());
        } catch (LoopManipulationException e) {
            // This shouldn't ever happen.
            LoopManipulationException lme = ((LoopManipulationException) e);
            Target t = lme.getTarget();
            ConfigRuntimeException.HandleUncaughtException(ConfigRuntimeException.CreateUncatchableException("A " + lme.getName() + "() bubbled up to the top of" + " a closure, which is unexpected behavior.", t), environment);
        } catch (FunctionReturnException ex) {
            // Check the return type of the closure to see if it matches the defined type
            // Normal execution.
            Construct ret = ex.getReturn();
            if (!InstanceofUtil.isInstanceof(ret, returnType)) {
                throw new CRECastException("Expected closure to return a value of type " + returnType.val() + " but a value of type " + ret.typeof() + " was returned instead", ret.getTarget());
            }
            // Now rethrow it
            throw ex;
        } catch (CancelCommandException e) {
        // die()
        } catch (ConfigRuntimeException ex) {
            if (ex instanceof AbstractCREException) {
                ((AbstractCREException) ex).freezeStackTraceElements(stManager);
            }
            throw ex;
        } catch (Throwable t) {
            // Not sure. Pop and re-throw.
            throw t;
        } finally {
            stManager.popStackTraceElement();
        }
        // If we got here, then there was no return type. This is fine, but only for returnType void or auto.
        if (!(returnType.equals(Auto.TYPE) || returnType.equals(CVoid.TYPE))) {
            throw new CRECastException("Expecting closure to return a value of type " + returnType.val() + "," + " but no value was returned.", node.getTarget());
        }
    } catch (CloneNotSupportedException ex) {
        Logger.getLogger(CClosure.class.getName()).log(Level.SEVERE, null, ex);
    }
}
Also used : ArrayList(java.util.ArrayList) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) CancelCommandException(com.laytonsmith.core.exceptions.CancelCommandException) AbstractCREException(com.laytonsmith.core.exceptions.CRE.AbstractCREException) CRECastException(com.laytonsmith.core.exceptions.CRE.CRECastException) StackTraceManager(com.laytonsmith.core.exceptions.StackTraceManager) CRECastException(com.laytonsmith.core.exceptions.CRE.CRECastException) LoopManipulationException(com.laytonsmith.core.exceptions.LoopManipulationException) ProgramFlowManipulationException(com.laytonsmith.core.exceptions.ProgramFlowManipulationException) AbstractCREException(com.laytonsmith.core.exceptions.CRE.AbstractCREException) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) CancelCommandException(com.laytonsmith.core.exceptions.CancelCommandException) FunctionReturnException(com.laytonsmith.core.exceptions.FunctionReturnException) Environment(com.laytonsmith.core.environments.Environment) GlobalEnv(com.laytonsmith.core.environments.GlobalEnv) FunctionReturnException(com.laytonsmith.core.exceptions.FunctionReturnException) LoopManipulationException(com.laytonsmith.core.exceptions.LoopManipulationException) ParseTree(com.laytonsmith.core.ParseTree)

Aggregations

GlobalEnv (com.laytonsmith.core.environments.GlobalEnv)3 AbstractCREException (com.laytonsmith.core.exceptions.CRE.AbstractCREException)3 CRECastException (com.laytonsmith.core.exceptions.CRE.CRECastException)3 ConfigRuntimeException (com.laytonsmith.core.exceptions.ConfigRuntimeException)3 FunctionReturnException (com.laytonsmith.core.exceptions.FunctionReturnException)3 LoopManipulationException (com.laytonsmith.core.exceptions.LoopManipulationException)3 StackTraceManager (com.laytonsmith.core.exceptions.StackTraceManager)3 ParseTree (com.laytonsmith.core.ParseTree)2 Environment (com.laytonsmith.core.environments.Environment)2 CancelCommandException (com.laytonsmith.core.exceptions.CancelCommandException)2 ProgramFlowManipulationException (com.laytonsmith.core.exceptions.ProgramFlowManipulationException)2 ArrayList (java.util.ArrayList)2 CArray (com.laytonsmith.core.constructs.CArray)1 CFunction (com.laytonsmith.core.constructs.CFunction)1 CNull (com.laytonsmith.core.constructs.CNull)1 Construct (com.laytonsmith.core.constructs.Construct)1 IVariable (com.laytonsmith.core.constructs.IVariable)1 IVariableList (com.laytonsmith.core.constructs.IVariableList)1