Search in sources :

Example 11 with ParseTree

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

the class MethodScriptStaticCompiler method go.

private static void go(ParseTree node, StringBuilder b, api.Platforms platform) throws ConfigCompileException {
    if (node.hasChildren()) {
        FunctionBase f = FunctionList.getFunction(node.getData(), platform);
        if (!(f instanceof CompiledFunction)) {
            throw new ConfigCompileException("The function " + f.getName() + " is unknown in this platform.", node.getData().getTarget());
        }
        CompiledFunction cf = (CompiledFunction) f;
        List<String> children = new ArrayList<String>();
        for (ParseTree baby : node.getChildren()) {
            StringBuilder bb = new StringBuilder();
            go(baby, bb, platform);
            children.add(bb.toString());
        }
        b.append(cf.compile(node.getData().getTarget(), children.toArray(new String[children.size()])));
    } else {
        if (platform.getResolver() == null) {
            b.append(node.getData().val());
        } else {
            b.append(platform.getResolver().outputConstant(node.getData()));
        }
    }
}
Also used : CompiledFunction(com.laytonsmith.core.functions.CompiledFunction) FunctionBase(com.laytonsmith.core.functions.FunctionBase) ArrayList(java.util.ArrayList) ConfigCompileException(com.laytonsmith.core.exceptions.ConfigCompileException) ParseTree(com.laytonsmith.core.ParseTree)

Example 12 with ParseTree

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

the class CommandHelperInterpreterListener method execute.

public void execute(String script, final MCPlayer p) throws ConfigCompileException, ConfigCompileGroupException {
    TokenStream stream = MethodScriptCompiler.lex(script, new File("Interpreter"), true);
    ParseTree tree = MethodScriptCompiler.compile(stream);
    interpreterMode.remove(p.getName());
    GlobalEnv gEnv = new GlobalEnv(plugin.executionQueue, plugin.profiler, plugin.persistenceNetwork, CommandHelperFileLocations.getDefault().getConfigDirectory(), plugin.profiles, new TaskManager());
    gEnv.SetDynamicScriptingMode(true);
    CommandHelperEnvironment cEnv = new CommandHelperEnvironment();
    cEnv.SetPlayer(p);
    Environment env = Environment.createEnvironment(gEnv, cEnv);
    try {
        MethodScriptCompiler.registerAutoIncludes(env, null);
        MethodScriptCompiler.execute(tree, env, new MethodScriptComplete() {

            @Override
            public void done(String output) {
                output = output.trim();
                if (output.isEmpty()) {
                    Static.SendMessage(p, ":");
                } else {
                    if (output.startsWith("/")) {
                        // Run the command
                        Static.SendMessage(p, ":" + MCChatColor.YELLOW + output);
                        p.chat(output);
                    } else {
                        // output the results
                        Static.SendMessage(p, ":" + MCChatColor.GREEN + output);
                    }
                }
                interpreterMode.add(p.getName());
            }
        }, null);
    } catch (CancelCommandException e) {
        interpreterMode.add(p.getName());
    } catch (ConfigRuntimeException e) {
        ConfigRuntimeException.HandleUncaughtException(e, env);
        Static.SendMessage(p, MCChatColor.RED + e.toString());
        interpreterMode.add(p.getName());
    } catch (Exception e) {
        Static.SendMessage(p, MCChatColor.RED + e.toString());
        Logger.getLogger(CommandHelperInterpreterListener.class.getName()).log(Level.SEVERE, null, e);
        interpreterMode.add(p.getName());
    }
}
Also used : TokenStream(com.laytonsmith.core.compiler.TokenStream) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) CancelCommandException(com.laytonsmith.core.exceptions.CancelCommandException) ConfigCompileException(com.laytonsmith.core.exceptions.ConfigCompileException) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) ConfigCompileGroupException(com.laytonsmith.core.exceptions.ConfigCompileGroupException) MethodScriptComplete(com.laytonsmith.core.MethodScriptComplete) TaskManager(com.laytonsmith.core.taskmanager.TaskManager) CancelCommandException(com.laytonsmith.core.exceptions.CancelCommandException) CommandHelperEnvironment(com.laytonsmith.core.environments.CommandHelperEnvironment) Environment(com.laytonsmith.core.environments.Environment) CommandHelperEnvironment(com.laytonsmith.core.environments.CommandHelperEnvironment) GlobalEnv(com.laytonsmith.core.environments.GlobalEnv) File(java.io.File) ParseTree(com.laytonsmith.core.ParseTree)

Example 13 with ParseTree

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

the class Interpreter method execute.

/**
 * This executes an entire script. The cmdline_prompt_event is first triggered (if used) and if the event is
 * cancelled, nothing happens.
 *
 * @param script
 * @param args
 * @param fromFile
 * @throws ConfigCompileException
 * @throws IOException
 */
public void execute(String script, List<String> args, File fromFile) throws ConfigCompileException, IOException, ConfigCompileGroupException {
    CmdlineEvents.cmdline_prompt_input.CmdlinePromptInput input = new CmdlineEvents.cmdline_prompt_input.CmdlinePromptInput(script, inShellMode);
    EventUtils.TriggerListener(Driver.CMDLINE_PROMPT_INPUT, "cmdline_prompt_input", input);
    if (input.isCancelled()) {
        return;
    }
    ctrlCcount = 0;
    if ("exit".equals(script)) {
        if (inShellMode) {
            inShellMode = false;
            return;
        }
        pl(YELLOW + "Use exit() if you wish to exit.");
        return;
    }
    if ("help".equals(script)) {
        pl(getHelpMsg());
        return;
    }
    if (fromFile == null) {
        fromFile = new File("Interpreter");
    }
    boolean localShellMode = false;
    if (!inShellMode && script.startsWith("$$")) {
        localShellMode = true;
        script = script.substring(2);
    }
    if (inShellMode || localShellMode) {
        // Wrap this in shell_adv
        if (doBuiltin(script)) {
            return;
        }
        List<String> shellArgs = StringUtils.ArgParser(script);
        List<String> escapedArgs = new ArrayList<>();
        for (String arg : shellArgs) {
            escapedArgs.add(new CString(arg, Target.UNKNOWN).getQuote());
        }
        script = "shell_adv(" + "array(" + StringUtils.Join(escapedArgs, ",") + ")," + "array(" + "'stdout':closure(@l){sys_out(@l);}," + "'stderr':closure(@l){sys_err(@l);})" + ");";
    }
    isExecuting = true;
    ProfilePoint compile = env.getEnv(GlobalEnv.class).GetProfiler().start("Compilation", LogLevel.VERBOSE);
    final ParseTree tree;
    try {
        TokenStream stream = MethodScriptCompiler.lex(script, fromFile, true);
        tree = MethodScriptCompiler.compile(stream);
    } finally {
        compile.stop();
    }
    // Environment env = Environment.createEnvironment(this.env.getEnv(GlobalEnv.class));
    final List<Variable> vars = new ArrayList<>();
    if (args != null) {
        // Build the @arguments variable, the $ vars, and $ itself. Note that
        // we have special handling for $0, that is the script name, like bash.
        // However, it doesn't get added to either $ or @arguments, due to the
        // uncommon use of it.
        StringBuilder finalArgument = new StringBuilder();
        CArray arguments = new CArray(Target.UNKNOWN);
        {
            // Set the $0 argument
            Variable v = new Variable("$0", "", Target.UNKNOWN);
            v.setVal(fromFile.toString());
            v.setDefault(fromFile.toString());
            vars.add(v);
        }
        for (int i = 0; i < args.size(); i++) {
            String arg = args.get(i);
            if (i > 0) {
                finalArgument.append(" ");
            }
            Variable v = new Variable("$" + Integer.toString(i + 1), "", Target.UNKNOWN);
            v.setVal(new CString(arg, Target.UNKNOWN));
            v.setDefault(arg);
            vars.add(v);
            finalArgument.append(arg);
            arguments.push(new CString(arg, Target.UNKNOWN), Target.UNKNOWN);
        }
        Variable v = new Variable("$", "", false, true, Target.UNKNOWN);
        v.setVal(new CString(finalArgument.toString(), Target.UNKNOWN));
        v.setDefault(finalArgument.toString());
        vars.add(v);
        env.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(CArray.TYPE, "@arguments", arguments, Target.UNKNOWN));
    }
    try {
        ProfilePoint p = this.env.getEnv(GlobalEnv.class).GetProfiler().start("Interpreter Script", LogLevel.ERROR);
        try {
            final MutableObject<Throwable> wasThrown = new MutableObject<>();
            scriptThread = new Thread(new Runnable() {

                @Override
                public void run() {
                    try {
                        MethodScriptCompiler.execute(tree, env, new MethodScriptComplete() {

                            @Override
                            public void done(String output) {
                                if (System.console() != null && !"".equals(output.trim())) {
                                    StreamUtils.GetSystemOut().println(output);
                                }
                            }
                        }, null, vars);
                    } catch (CancelCommandException e) {
                    // Nothing, though we could have been Ctrl+C cancelled, so we need to reset
                    // the interrupt flag. But we do that unconditionally below, in the finally,
                    // in the other thread.
                    } catch (ConfigRuntimeException e) {
                        ConfigRuntimeException.HandleUncaughtException(e, env);
                        // No need for the full stack trace
                        if (System.console() == null) {
                            System.exit(1);
                        }
                    } catch (NoClassDefFoundError e) {
                        StreamUtils.GetSystemErr().println(RED + Main.getNoClassDefFoundErrorMessage(e) + reset());
                        StreamUtils.GetSystemErr().println("Since you're running from standalone interpreter mode, this is not a fatal error, but one of the functions you just used required" + " an actual backing engine that isn't currently loaded. (It still might fail even if you load the engine though.) You simply won't be" + " able to use that function here.");
                        if (System.console() == null) {
                            System.exit(1);
                        }
                    } catch (InvalidEnvironmentException ex) {
                        StreamUtils.GetSystemErr().println(RED + ex.getMessage() + " " + ex.getData() + "() cannot be used in this context.");
                        if (System.console() == null) {
                            System.exit(1);
                        }
                    } catch (RuntimeException e) {
                        pl(RED + e.toString());
                        e.printStackTrace(StreamUtils.GetSystemErr());
                        if (System.console() == null) {
                            System.exit(1);
                        }
                    }
                }
            }, "MethodScript-Main");
            scriptThread.start();
            try {
                scriptThread.join();
            } catch (InterruptedException ex) {
            // 
            }
        } finally {
            p.stop();
        }
    } finally {
        env.getEnv(GlobalEnv.class).SetInterrupt(false);
        isExecuting = false;
    }
}
Also used : TokenStream(com.laytonsmith.core.compiler.TokenStream) InvalidEnvironmentException(com.laytonsmith.core.environments.InvalidEnvironmentException) IVariable(com.laytonsmith.core.constructs.IVariable) Variable(com.laytonsmith.core.constructs.Variable) IVariable(com.laytonsmith.core.constructs.IVariable) ArrayList(java.util.ArrayList) CArray(com.laytonsmith.core.constructs.CArray) CString(com.laytonsmith.core.constructs.CString) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) CString(com.laytonsmith.core.constructs.CString) CmdlineEvents(com.laytonsmith.core.events.drivers.CmdlineEvents) ConfigRuntimeException(com.laytonsmith.core.exceptions.ConfigRuntimeException) CancelCommandException(com.laytonsmith.core.exceptions.CancelCommandException) MutableObject(com.laytonsmith.PureUtilities.Common.MutableObject) ProfilePoint(com.laytonsmith.core.profiler.ProfilePoint) ProfilePoint(com.laytonsmith.core.profiler.ProfilePoint) MethodScriptComplete(com.laytonsmith.core.MethodScriptComplete) GlobalEnv(com.laytonsmith.core.environments.GlobalEnv) File(java.io.File) ParseTree(com.laytonsmith.core.ParseTree)

Example 14 with ParseTree

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

Example 15 with ParseTree

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

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