use of com.laytonsmith.core.ParseTree in project CommandHelper by EngineHub.
the class InstanceofKeyword method process.
@Override
public int process(List<ParseTree> list, int keywordPosition) throws ConfigCompileException {
if (list.get(keywordPosition).getData() instanceof CFunction) {
// It's not a keyword, it's a function
return keywordPosition;
}
if (keywordPosition == 0) {
throw new ConfigCompileException("Expected value to proceed \"instanceof\" keyword, but no identifiers were found.", list.get(keywordPosition).getTarget());
}
if (list.size() <= keywordPosition + 1) {
throw new ConfigCompileException("Expected type to follow \"instanceof\" keyword, but no type was found.", list.get(keywordPosition).getTarget());
}
ParseTree node = new ParseTree(new CFunction(INSTANCEOF, list.get(keywordPosition).getTarget()), list.get(keywordPosition).getFileOptions());
node.addChild(list.get(keywordPosition - 1));
node.addChild(list.get(keywordPosition + 1));
// Overwrite the LHS
list.set(keywordPosition - 1, node);
// Remove the keyword
list.remove(keywordPosition);
// Remove the RHS
list.remove(keywordPosition);
return keywordPosition;
}
use of com.laytonsmith.core.ParseTree in project CommandHelper by EngineHub.
the class ProcKeyword method process.
@Override
public int process(List<ParseTree> list, int keywordPosition) throws ConfigCompileException {
if (list.get(keywordPosition).getData() instanceof CKeyword) {
// It's a lone keyword, so we expect some function to follow, which is the proc name + variables
if (list.get(keywordPosition + 1).getData() instanceof CFunction) {
ParseTree proc = new ParseTree(new CFunction(PROC, list.get(keywordPosition).getTarget()), list.get(keywordPosition).getFileOptions());
proc.addChild(new ParseTree(new CString(list.get(keywordPosition + 1).getData().val(), list.get(keywordPosition + 1).getTarget()), list.get(keywordPosition + 1).getFileOptions()));
// Grab the functions children, and put them on the stack
for (ParseTree child : list.get(keywordPosition + 1).getChildren()) {
proc.addChild(child);
}
if (list.size() > keywordPosition + 2) {
validateCodeBlock(list.get(keywordPosition + 2), "Expected braces to follow proc definition");
proc.addChild(getArgumentOrNull(list.get(keywordPosition + 2)));
} else {
throw new ConfigCompileException("Expected braces to follow proc definition", list.get(keywordPosition + 1).getTarget());
}
// Remove the keyword
list.remove(keywordPosition);
// Remove the function definition
list.remove(keywordPosition);
// Remove the cbrace
list.remove(keywordPosition);
// Add in the new proc definition
list.add(keywordPosition, proc);
} else {
throw new ConfigCompileException("Unexpected use of \"proc\" keyword", list.get(keywordPosition).getTarget());
}
} else if (nodeIsProcFunction(list.get(keywordPosition))) {
// It's the functional usage, possibly followed by a cbrace. If so, pull the cbrace in, and that's it
if (list.size() > keywordPosition + 1) {
if (isValidCodeBlock(list.get(keywordPosition + 1))) {
list.get(keywordPosition).addChild(getArgumentOrNull(list.get(keywordPosition + 1)));
list.remove(keywordPosition + 1);
}
}
} else {
// Random keyword in the middle of nowhere
throw new ConfigCompileException("Unexpected use of \"proc\" keyword", list.get(keywordPosition).getTarget());
}
return keywordPosition;
}
use of com.laytonsmith.core.ParseTree in project CommandHelper by EngineHub.
the class IClosureKeyword method process.
@Override
public int process(List<ParseTree> list, int keywordPosition) throws ConfigCompileException {
try {
if (list.get(keywordPosition).getData() instanceof CFunction) {
// It's a function, so do the old processing
SimpleBlockKeywordFunction.doProcess(this.getKeywordName(), null, true, list, keywordPosition);
// easiest if we do the conversion here.
try {
if (list.get(keywordPosition - 1).getData() instanceof CClassType) {
ParseTree type = list.remove(keywordPosition - 1);
List<ParseTree> children = list.get(keywordPosition - 1).getChildren();
children.add(0, type);
list.get(keywordPosition - 1).setChildren(children);
return keywordPosition - 1;
}
} catch (IndexOutOfBoundsException ex) {
// Ignore, it's not a typed closure
}
return keywordPosition;
} else {
// Else it's standalone, so this should be treated as the closure ClassType
list.set(keywordPosition, new ParseTree(CIClosure.TYPE, list.get(keywordPosition).getFileOptions()));
return keywordPosition;
}
} catch (IndexOutOfBoundsException ex) {
throw new ConfigCompileException("Unexpected \"iclosure\" reference", list.get(keywordPosition).getTarget());
}
}
use of com.laytonsmith.core.ParseTree in project CommandHelper by EngineHub.
the class CompositeFunction method exec.
@Override
public Construct exec(Target t, Environment environment, Construct... args) throws ConfigRuntimeException {
ParseTree tree;
if (!cachedScripts.containsKey(this.getClass())) {
try {
String script = script();
tree = MethodScriptCompiler.compile(MethodScriptCompiler.lex(script, null, true)).getChildAt(0);
} catch (ConfigCompileException | ConfigCompileGroupException ex) {
// This is really bad.
throw new Error(ex);
}
if (cacheCompile()) {
cachedScripts.put(this.getClass(), tree);
}
} else {
tree = cachedScripts.get(this.getClass());
}
GlobalEnv env = environment.getEnv(GlobalEnv.class);
IVariableList oldVariables = env.GetVarList();
IVariableList newVariables = new IVariableList();
newVariables.set(new IVariable(CClassType.get("array"), "@arguments", new CArray(t, args.length, args), t));
env.SetVarList(newVariables);
Construct ret = CVoid.VOID;
try {
env.GetScript().eval(tree, environment);
} catch (FunctionReturnException ex) {
ret = ex.getReturn();
}
env.SetVarList(oldVariables);
return ret;
}
use of com.laytonsmith.core.ParseTree in project CommandHelper by EngineHub.
the class IncludeCache method get.
public static ParseTree get(File file, Target t) {
CHLog.GetLogger().Log(TAG, LogLevel.DEBUG, "Loading " + file, t);
if (cache.containsKey(file)) {
CHLog.GetLogger().Log(TAG, LogLevel.INFO, "Returning " + file + " from cache", t);
return cache.get(file);
}
CHLog.GetLogger().Log(TAG, LogLevel.VERBOSE, "Cache does not already contain file. Compiling and caching.", t);
// We have to pull the file from the FS, and compile it.
if (!Security.CheckSecurity(file)) {
throw new CRESecurityException("The script cannot access " + file + " due to restrictions imposed by the base-dir setting.", t);
}
CHLog.GetLogger().Log(TAG, LogLevel.VERBOSE, "Security check passed", t);
try {
String s = new ZipReader(file).getFileContents();
ParseTree tree = MethodScriptCompiler.compile(MethodScriptCompiler.lex(s, file, true));
CHLog.GetLogger().Log(TAG, LogLevel.VERBOSE, "Compilation succeeded, adding to cache.", t);
IncludeCache.add(file, tree);
return tree;
} catch (ConfigCompileException ex) {
throw new CREIncludeException("There was a compile error when trying to include the script at " + file + "\n" + ex.getMessage() + " :: " + file.getName() + ":" + ex.getLineNum(), t);
} catch (ConfigCompileGroupException ex) {
StringBuilder b = new StringBuilder();
b.append("There were compile errors when trying to include the script at ").append(file).append("\n");
for (ConfigCompileException e : ex.getList()) {
b.append(e.getMessage()).append(" :: ").append(e.getFile().getName()).append(":").append(e.getLineNum());
}
throw new CREIncludeException(b.toString(), t);
} catch (IOException ex) {
throw new CREIOException("The script at " + file + " could not be found or read in.", t);
}
}
Aggregations