diff --git a/src/main/java/com/sk89q/worldedit/expression/lexer/Lexer.java b/src/main/java/com/sk89q/worldedit/expression/lexer/Lexer.java index 21a6b163d..007ec5eb2 100644 --- a/src/main/java/com/sk89q/worldedit/expression/lexer/Lexer.java +++ b/src/main/java/com/sk89q/worldedit/expression/lexer/Lexer.java @@ -105,6 +105,8 @@ public class Lexer { characterTokens.add('{'); characterTokens.add('}'); characterTokens.add(';'); + characterTokens.add('?'); + characterTokens.add(':'); } private static final Set keywords = new HashSet(Arrays.asList("if", "else", "while", "do", "for", "break", "continue", "return")); diff --git a/src/main/java/com/sk89q/worldedit/expression/parser/ParserProcessors.java b/src/main/java/com/sk89q/worldedit/expression/parser/ParserProcessors.java index 74d535265..d4f4c5ba2 100644 --- a/src/main/java/com/sk89q/worldedit/expression/parser/ParserProcessors.java +++ b/src/main/java/com/sk89q/worldedit/expression/parser/ParserProcessors.java @@ -28,6 +28,7 @@ import java.util.Map; import com.sk89q.worldedit.expression.Identifiable; import com.sk89q.worldedit.expression.lexer.tokens.OperatorToken; import com.sk89q.worldedit.expression.lexer.tokens.Token; +import com.sk89q.worldedit.expression.runtime.Conditional; import com.sk89q.worldedit.expression.runtime.RValue; import com.sk89q.worldedit.expression.runtime.Operators; @@ -235,7 +236,61 @@ public final class ParserProcessors { } private static RValue processTernaryOps(LinkedList input) throws ParserException { - return processBinaryOpsLA(input, binaryOpMapsLA.length - 1); + LinkedList lhs = new LinkedList(); + LinkedList mhs = new LinkedList(); + LinkedList rhs = new LinkedList(); + + int partsFound = 0; + int conditionalsFound = 0; + + for (Identifiable identifiable : input) { + final char character = identifiable.id(); + switch (character) { + case '?': + ++conditionalsFound; + break; + case ':': + --conditionalsFound; + break; + } + + if (conditionalsFound < 0) { + throw new ParserException(identifiable.getPosition(), "Unexpected ':'"); + } + + switch (partsFound) { + case 0: + if (character == '?') { + System.out.println("question mark found"); + partsFound = 1; + } else { + lhs.addLast(identifiable); + } + break; + + case 1: + if (conditionalsFound == 0 && character == ':') { + System.out.println("matching colon found"); + partsFound = 2; + } else { + mhs.addLast(identifiable); + } + break; + + case 2: + rhs.addLast(identifiable); + } + } + + if (partsFound < 2) { + return processBinaryOpsLA(input, binaryOpMapsLA.length - 1); + } + + RValue lhsInvokable = processBinaryOpsLA(lhs, binaryOpMapsLA.length - 1); + RValue mhsInvokable = processTernaryOps(mhs); + RValue rhsInvokable = processTernaryOps(rhs); + + return new Conditional(input.get(lhs.size()).getPosition(), lhsInvokable, mhsInvokable, rhsInvokable); } private static RValue processUnaryOps(LinkedList input) throws ParserException { diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Conditional.java b/src/main/java/com/sk89q/worldedit/expression/runtime/Conditional.java index b7a5a02c5..c6c7d1c7c 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Conditional.java +++ b/src/main/java/com/sk89q/worldedit/expression/runtime/Conditional.java @@ -55,8 +55,10 @@ public class Conditional extends Node { public String toString() { if (falsePart == null) { return "if (" + condition + ") { " + truePart + " }"; - } else { + } else if (truePart instanceof Sequence || falsePart instanceof Sequence) { return "if (" + condition + ") { " + truePart + " } else { " + falsePart + " }"; + } else { + return "(" + condition + ") ? (" + truePart + ") : (" + falsePart + ")"; } }