use of com.laytonsmith.core.constructs.Construct in project CommandHelper by EngineHub.
the class CompilerObject method compile0.
void compile0() throws ConfigCompileException {
Token t = consume();
if (t.type == TType.NEWLINE) {
return;
}
if (t.type == TType.CONST_START) {
StringBuilder constName = new StringBuilder();
while ((t = consume()).type != TType.RCURLY_BRACKET) {
if (t.type != TType.BARE_STRING && t.type != TType.CONCAT) {
throw new ConfigCompileException("Constant names may only contain names and dots.", t.getTarget());
}
constName.append(t.val());
}
Construct constant = env.getConstant(constName.toString());
if (constant == null) {
throw new ConfigCompileException("Expected the constant ${" + constName.toString() + "} to be provided in the compilation options, but it wasn't.", t.getTarget());
}
t = new Token(TType.STRING, constant.val(), constant.getTarget());
}
if (t.type == TType.BARE_STRING && peek().type == TType.FUNC_START) {
consume();
CFunction f = new CFunction(t.val(), t.getTarget());
functionLines.add(peek().getTarget());
pushNode(f);
return;
}
if (t.type == TType.FUNC_END || t.type == TType.COMMA) {
if (autoConcatCounter > 0) {
autoConcatCounter--;
popNode(t.getTarget());
}
}
if (t.type == TType.COMMA) {
return;
}
if (t.type == TType.FUNC_END) {
// We're done with this child, so push it up
popNode(t.getTarget());
functionLines.pop();
return;
}
if (t.type == TType.LSQUARE_BRACKET) {
CFunction f = new CFunction("__cbracket__", Target.UNKNOWN);
pushNode(f);
bracketCounter++;
bracketLines.push(t.getTarget());
return;
}
if (t.type == TType.RSQUARE_BRACKET) {
if (bracketCounter == 0) {
throw new ConfigCompileException("Unexpected right bracket. (Did you have too many right square brackets (]) in your code?)", t.getTarget());
}
bracketCounter--;
bracketLines.pop();
popNode(t.getTarget());
return;
}
if (t.type == TType.LCURLY_BRACKET) {
CFunction f = new CFunction("__cbrace__", Target.UNKNOWN);
pushNode(f);
braceCounter++;
braceLines.push(t.getTarget());
return;
}
if (t.type == TType.RCURLY_BRACKET) {
if (braceCounter == 0) {
throw new ConfigCompileException("Unexpected right brace. (Did you have too many right braces (}) in your code?)", t.getTarget());
}
braceCounter--;
braceLines.pop();
popNode(t.getTarget());
return;
}
// If the next token ISN'T a ) , } ] we need to autoconcat this
if (peek().type != TType.FUNC_END && peek().type != TType.COMMA && peek().type != TType.RCURLY_BRACKET && peek().type != TType.RSQUARE_BRACKET) {
// ... unless we're already in an autoconcat
if (!(pointer.getData() instanceof CFunction && ((CFunction) pointer.getData()).val().equals("__autoconcat__"))) {
CFunction f = new CFunction("__autoconcat__", Target.UNKNOWN);
pushNode(f);
autoConcatCounter++;
}
}
if (t.type == TType.BARE_STRING && peek().type == TType.LABEL) {
consume();
pointer.addChild(new ParseTree(new CLabel(new CString(t.val(), t.getTarget())), stream.getFileOptions()));
return;
}
if (t.type.isIdentifier()) {
// If it's an atomic, put it in a construct and parse tree, then add it
pointer.addChild(new ParseTree(resolveIdentifier(t), stream.getFileOptions()));
return;
}
if (t.type.isSymbol()) {
pointer.addChild(new ParseTree(new CSymbol(t.val(), t.type, t.getTarget()), stream.getFileOptions()));
return;
}
// Now we have to check ahead for commas and other division parameters.
}
use of com.laytonsmith.core.constructs.Construct in project CommandHelper by EngineHub.
the class NewMethodScriptCompiler method preprocess.
public static List<NewScript> preprocess(TokenStream tokenStream, Environment compilerEnvironment) throws ConfigCompileException {
List<NewScript> scripts = new ArrayList<NewScript>();
// We need to split the command definition and the pure mscript parts. First,
// we split on newlines, those are each going to be our alias definitions
List<List<Token>> commands = new ArrayList<List<Token>>();
List<Token> working = new ArrayList<Token>();
for (int i = 0; i < tokenStream.size(); i++) {
Token t = tokenStream.get(i);
if (t.type == Token.TType.NEWLINE) {
commands.add(working);
working = new ArrayList<Token>();
continue;
}
working.add(t);
}
// Now they are split into individual aliases
for (List<Token> stream : commands) {
// We need to make constructs from the left, and compile the right
// Compiling the right can be simply passed off to the compile
// function, but we need to parse the left ourselves
// We *should* only have (bare) strings, numbers, brackets on the left
List<Token> left = new ArrayList<Token>();
TokenStream right = new TokenStream(new ArrayList<Token>(), tokenStream.getFileOptions());
boolean inLeft = true;
boolean hasLabel = false;
for (Token t : stream) {
if (t.type == Token.TType.ALIAS_END) {
inLeft = false;
continue;
}
if (t.type == TType.LABEL) {
hasLabel = true;
}
if (inLeft) {
left.add(t);
} else {
right.add(t);
}
}
ParseTree cright = compile(right, compilerEnvironment);
List<Construct> cleft = new ArrayList<Construct>();
boolean atFinalVar = false;
boolean atOptionalVars = false;
boolean pastLabel = false;
String label = "";
try {
for (int i = 0; i < left.size(); i++) {
Token t = left.get(i);
if (hasLabel && !pastLabel) {
if (t.type == TType.LABEL) {
pastLabel = true;
continue;
}
label += t.val();
continue;
}
if (atFinalVar) {
throw new ConfigCompileException("The final var must be the last declaration in the alias", t.getTarget());
}
if (t.type == TType.LSQUARE_BRACKET) {
Token tname = left.get(i + 1);
atOptionalVars = true;
if (tname.val().equals("$")) {
atFinalVar = true;
}
if (tname.type != TType.VARIABLE && tname.type != TType.FINAL_VAR) {
throw new ConfigCompileException("Expecting a variable, but found " + tname.val(), tname.getTarget());
}
i++;
Token next = left.get(i + 1);
if (next.type != TType.OPT_VAR_ASSIGN && next.type != TType.RSQUARE_BRACKET) {
throw new ConfigCompileException("Expecting either a variable assignment or right square bracket, but found " + next.val(), next.getTarget());
}
i++;
String defaultVal = "";
if (next.type == TType.OPT_VAR_ASSIGN) {
// We have an assignment here
Token val = left.get(i + 1);
i++;
defaultVal = val.val();
next = left.get(i + 1);
}
if (next.type != TType.RSQUARE_BRACKET) {
throw new ConfigCompileException("Expecting a right square bracket, but found " + next.val() + " instead. (Did you forget to quote a multi word string?)", next.getTarget());
}
i++;
Variable v = new Variable(tname.val(), defaultVal, true, (tname.val().equals("$")), tname.getTarget());
cleft.add(v);
continue;
}
if (t.type == TType.VARIABLE || t.type == TType.FINAL_VAR) {
// Required variable
if (atOptionalVars) {
throw new ConfigCompileException("Only optional variables may come after the first optional variable", t.getTarget());
}
if (t.val().equals("$")) {
atFinalVar = true;
}
Variable v = new Variable(t.val(), "", false, t.val().equals("$"), t.getTarget());
cleft.add(v);
continue;
}
cleft.add(tokenToConstruct(t));
}
} catch (IndexOutOfBoundsException e) {
throw new ConfigCompileException("Expecting more tokens, but reached end of alias signature before tokens were resolved.", left.get(0).getTarget());
}
if (!cleft.isEmpty()) {
link(cright, compilerEnvironment);
scripts.add(new NewScript(cleft, cright, label));
}
}
return scripts;
}
use of com.laytonsmith.core.constructs.Construct in project CommandHelper by EngineHub.
the class BoundEvent method manual_trigger.
/**
* Used to manually trigger an event, the underlying event is set to null.
*
* @param event
* @throws EventException
*/
public void manual_trigger(CArray event) throws EventException {
try {
Environment env = originalEnv.clone();
env.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(CArray.TYPE, eventObjName, event, Target.UNKNOWN));
Map<String, Construct> map = new HashMap<>();
for (String key : event.stringKeySet()) {
map.put(key, event.get(key, Target.UNKNOWN));
}
ActiveEvent activeEvent = new ActiveEvent(null);
activeEvent.setParsedEvent(map);
activeEvent.setBoundEvent(this);
env.getEnv(GlobalEnv.class).SetEvent(activeEvent);
this.execute(env, activeEvent);
} catch (CloneNotSupportedException ex) {
Logger.getLogger(BoundEvent.class.getName()).log(Level.SEVERE, null, ex);
}
}
use of com.laytonsmith.core.constructs.Construct in project CommandHelper by EngineHub.
the class BoundEvent method trigger.
/**
* When the event actually occurs, this should be run, after translating the original event object (of whatever type
* it may be) into a standard map, which contains the event object data. It is converted into a CArray here, and
* then the script is executed with the driver's execute function.
*
* @param activeEvent
*/
public void trigger(ActiveEvent activeEvent) throws EventException {
try {
// GenericTree<Construct> root = new GenericTree<Construct>();
// root.setRoot(tree);
Environment env = originalEnv.clone();
CArray ca = CArray.GetAssociativeArray(Target.UNKNOWN);
for (Map.Entry<String, Construct> entry : activeEvent.parsedEvent.entrySet()) {
ca.set(new CString(entry.getKey(), Target.UNKNOWN), entry.getValue(), Target.UNKNOWN);
}
env.getEnv(GlobalEnv.class).GetVarList().set(new IVariable(CArray.TYPE, eventObjName, ca, Target.UNKNOWN));
env.getEnv(GlobalEnv.class).SetEvent(activeEvent);
activeEvent.addHistory("Triggering bound event: " + this);
try {
ProfilePoint p = env.getEnv(GlobalEnv.class).GetProfiler().start("Executing event handler for " + this.getEventName() + " defined at " + this.getTarget(), LogLevel.ERROR);
try {
this.execute(env, activeEvent);
} finally {
p.stop();
}
} catch (ConfigRuntimeException e) {
// We don't know how to handle this, but we need to set the env,
// then pass it up the chain
e.setEnv(env);
throw e;
}
} catch (CloneNotSupportedException ex) {
Logger.getLogger(BoundEvent.class.getName()).log(Level.SEVERE, null, ex);
}
}
use of com.laytonsmith.core.constructs.Construct in project CommandHelper by EngineHub.
the class ObjectGenerator method item.
/**
* Gets an MCItemStack from a given item "object". Supports both the old and new formats currently
*
* @param i
* @param t
* @return An abstract item stack
*/
public MCItemStack item(Construct i, Target t) {
if (i instanceof CNull) {
return EmptyItem();
}
if (!(i instanceof CArray)) {
throw new CREFormatException("Expected an array!", t);
}
CArray item = (CArray) i;
MCMaterial mat;
int data = 0;
int qty = 1;
if (item.containsKey("qty")) {
qty = Static.getInt32(item.get("qty", t), t);
if (qty <= 0) {
return EmptyItem();
}
}
if (item.containsKey("name")) {
mat = StaticLayer.GetConvertor().GetMaterial(item.get("name", t).val());
} else if (item.containsKey("type")) {
Construct type = item.get("type", t);
if (type instanceof CString) {
int seperatorIndex = type.val().indexOf(':');
if (seperatorIndex != -1) {
try {
data = Integer.parseInt(type.val().substring(seperatorIndex + 1));
} catch (NumberFormatException e) {
throw new CRERangeException("The item data \"" + type.val().substring(seperatorIndex + 1) + "\" is not a valid integer.", t);
}
type = new CString(type.val().substring(0, seperatorIndex), t);
}
}
mat = StaticLayer.GetConvertor().getMaterial(Static.getInt32(type, t));
} else {
throw new CREFormatException("Could not find item name!", t);
}
if (mat == null) {
throw new CRENotFoundException("A material could not be found based on the given name.", t);
}
if (mat.getType() == 0) {
return EmptyItem();
}
if (item.containsKey("data")) {
data = Static.getInt32(item.get("data", t), t);
}
MCItemMeta meta = null;
if (item.containsKey("meta")) {
meta = itemMeta(item.get("meta", t), mat, t);
}
// Create itemstack
MCItemStack ret = StaticLayer.GetItemStack(mat, data, qty);
if (meta != null) {
ret.setItemMeta(meta);
}
// Fallback to enchants in item array if not in meta
if (item.containsKey("enchants")) {
try {
Map<MCEnchantment, Integer> enchants = enchants((CArray) item.get("enchants", t), t);
for (Map.Entry<MCEnchantment, Integer> entry : enchants.entrySet()) {
ret.addUnsafeEnchantment(entry.getKey(), entry.getValue());
}
} catch (ClassCastException ex) {
throw new CREFormatException("Enchants must be an array of enchantment arrays.", t);
}
}
return ret;
}
Aggregations