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);
}
}
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;
}
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;
}
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
}
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());
}
Aggregations