Search in sources :

Example 16 with ParseTree

use of com.laytonsmith.core.ParseTree 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)

Example 17 with ParseTree

use of com.laytonsmith.core.ParseTree in project CommandHelper by EngineHub.

the class CompilerObject method pushNode.

private void pushNode(CFunction node) {
    ParseTree n = new ParseTree(node, stream.getFileOptions());
    pointer.addChild(n);
    nodes.push(n);
    pointer = n;
}
Also used : ParseTree(com.laytonsmith.core.ParseTree)

Example 18 with ParseTree

use of com.laytonsmith.core.ParseTree in project CommandHelper by EngineHub.

the class NewMethodScriptCompiler method compile.

/**
 * TODO: Need a platform resolver here?
 *
 * @param tokenStream
 * @param compilerEnvironment
 * @return
 * @throws ConfigCompileException
 */
public static ParseTree compile(TokenStream tokenStream, Environment compilerEnvironment) throws ConfigCompileException {
    ParseTree root = new ParseTree(new CFunction("__autoconcat__", Target.UNKNOWN), tokenStream.getFileOptions());
    new CompilerObject(tokenStream).compile(root, compilerEnvironment);
    link(root, compilerEnvironment);
    return root;
}
Also used : CFunction(com.laytonsmith.core.constructs.CFunction) ParseTree(com.laytonsmith.core.ParseTree)

Example 19 with ParseTree

use of com.laytonsmith.core.ParseTree in project CommandHelper by EngineHub.

the class NewMethodScriptCompiler method link.

private static void link(ParseTree root, Environment compilerEnvirontment) throws ConfigCompileException {
    // Before we actually link, we need to optimize our branch functions, that is,
    // currently just if. However, at this point, we also need to optimize __autoconcat__.
    // so we know what the tree actually looks like. Also, we want to first group all our auto includes
    // together, along with our actual tree.
    ParseTree master = new ParseTree(new CFunction("__autoconcat__", Target.UNKNOWN), root.getFileOptions());
    for (ParseTree include : compilerEnvirontment.getEnv(CompilerEnvironment.class).getIncludes()) {
        master.addChild(include);
    }
    master.addChild(root);
    OptimizerObject optimizer = new OptimizerObject(root, compilerEnvirontment);
    optimizer.optimize();
// root is now optimized
}
Also used : CFunction(com.laytonsmith.core.constructs.CFunction) ParseTree(com.laytonsmith.core.ParseTree)

Example 20 with ParseTree

use of com.laytonsmith.core.ParseTree in project CommandHelper by EngineHub.

the class NewMethodScriptCompiler method main.

public static void main(String[] args) throws ConfigCompileException {
    CompilerEnvironment env = new CompilerEnvironment();
    env.setConstant("v.n", "value");
    TokenStream stream = lex("<! strict; > @var", null, true);
    StreamUtils.GetSystemOut().println(stream + "\n");
    // StreamUtils.GetSystemOut().println(preprocess(stream).toString());
    ParseTree tree = compile(stream, Environment.createEnvironment(env));
    StreamUtils.GetSystemOut().println(tree.toStringVerbose());
}
Also used : ParseTree(com.laytonsmith.core.ParseTree)

Aggregations

ParseTree (com.laytonsmith.core.ParseTree)30 CFunction (com.laytonsmith.core.constructs.CFunction)16 ConfigCompileException (com.laytonsmith.core.exceptions.ConfigCompileException)16 CString (com.laytonsmith.core.constructs.CString)5 Target (com.laytonsmith.core.constructs.Target)5 GlobalEnv (com.laytonsmith.core.environments.GlobalEnv)5 ArrayList (java.util.ArrayList)5 CArray (com.laytonsmith.core.constructs.CArray)4 Construct (com.laytonsmith.core.constructs.Construct)4 CancelCommandException (com.laytonsmith.core.exceptions.CancelCommandException)4 ConfigRuntimeException (com.laytonsmith.core.exceptions.ConfigRuntimeException)4 CKeyword (com.laytonsmith.core.constructs.CKeyword)3 IVariable (com.laytonsmith.core.constructs.IVariable)3 Variable (com.laytonsmith.core.constructs.Variable)3 Environment (com.laytonsmith.core.environments.Environment)3 CRECastException (com.laytonsmith.core.exceptions.CRE.CRECastException)3 ConfigCompileGroupException (com.laytonsmith.core.exceptions.ConfigCompileGroupException)3 FunctionReturnException (com.laytonsmith.core.exceptions.FunctionReturnException)3 MethodScriptComplete (com.laytonsmith.core.MethodScriptComplete)2 TokenStream (com.laytonsmith.core.compiler.TokenStream)2