diff --git a/src/main/java/com/laytonsmith/core/compiler/keywords/SwitchKeyword.java b/src/main/java/com/laytonsmith/core/compiler/keywords/SwitchKeyword.java index 7b4f380bd..745e4576b 100644 --- a/src/main/java/com/laytonsmith/core/compiler/keywords/SwitchKeyword.java +++ b/src/main/java/com/laytonsmith/core/compiler/keywords/SwitchKeyword.java @@ -36,11 +36,15 @@ public int process(TokenStream stream, Environment env, int keywordPosition) int codeStart = -1; { int parenthesisStack = 0; - for(int i = keywordPosition; i < stream.size(); i++) { - Token token = stream.get(i); + for(ListIterator it = stream.listIterator(keywordPosition); it.hasNext(); ) { + int ind = it.nextIndex(); + Token token = it.next(); Token next = null; - if(i + 1 < stream.size()) { - next = stream.get(i + 1); + if(it.hasNext()) { + next = it.next(); + it.previous(); // Switch iteration direction. + it.previous(); // Return to previous element. + it.next(); // Switch iteration direction. } if(token.type == TType.FUNC_START) { parenthesisStack++; @@ -48,7 +52,7 @@ public int process(TokenStream stream, Environment env, int keywordPosition) if(token.type == TType.FUNC_END) { parenthesisStack--; if(parenthesisStack == 0 && next != null && next.type == TType.LCURLY_BRACKET) { - codeStart = i + 1; + codeStart = ind + 1; break; } else if(parenthesisStack == 0) { // Functional usage, do nothing @@ -67,7 +71,7 @@ public int process(TokenStream stream, Environment env, int keywordPosition) // First token should be case or default List newStream = new ArrayList<>(); int codeEnd = -1; - Comparator tokenComparator = (List o1, List o2) -> { + Comparator> tokenComparator = (List o1, List o2) -> { // Order doesn't matter, just needs to be deterministic return o1.toString().compareTo(o2.toString()); }; @@ -81,8 +85,9 @@ public int process(TokenStream stream, Environment env, int keywordPosition) int braceStack = 0; int bracketStack = 0; OUTER: - for(int i = codeStart + 1; i < stream.size(); i++) { - Token t = stream.get(i); + for(ListIterator it = stream.listIterator(codeStart + 1); it.hasNext(); ) { + int i = it.nextIndex(); + Token t = it.next(); if(inCode) { if(null != t.type) { // If we're in code, we need to balance all parenthesis, braces, and brackets, and not parse @@ -155,11 +160,13 @@ public int process(TokenStream stream, Environment env, int keywordPosition) // Ignore these case labels, they are being removed caseLabels = new TreeSet<>(tokenComparator); } - if(i + 1 >= stream.size() || stream.get(i + 1).type != TType.LABEL) { - throw new ConfigCompileException("Expected colon after default keyword", - (i + 1 >= stream.size() ? t.target : stream.get(i + 1).target)); + if(!it.hasNext()) { + throw new ConfigCompileException("Expected colon after default keyword", t.target); + } + Token next = it.next(); + if(next.type != TType.LABEL) { + throw new ConfigCompileException("Expected colon after default keyword", next.target); } - i++; inDefault = true; inCode = true; continue; @@ -217,11 +224,10 @@ public int process(TokenStream stream, Environment env, int keywordPosition) throw new ConfigCompileException("Unsupported type in case clause", t.target); } caseTokens.add(t); - i++; - if(i >= stream.size()) { + if(!it.hasNext()) { throw new ConfigCompileException("Incomplete case clause", t.target); } - t = stream.get(i); + t = it.next(); } caseLabels.add(caseTokens); inCase = false; @@ -249,18 +255,26 @@ public int process(TokenStream stream, Environment env, int keywordPosition) } // Replace code start - 1 with a comma, and then the whole code block with the new tokens, and finally a right // parenthesis. + ListIterator it; if(!newStream.isEmpty()) { - stream.set(codeStart - 1, new Token(TType.COMMA, ",", stream.get(codeStart - 1).target.copy())); + it = stream.listIterator(codeStart - 1); + Token token = it.next(); + it.set(new Token(TType.COMMA, ",", token.target.copy())); + } else { + it = stream.listIterator(codeStart); } for(int i = codeStart; i <= codeEnd; i++) { - stream.remove(codeStart); + it.next(); // Select index codeStart. + it.remove(); // Remove index codeStart. } if(!newStream.isEmpty()) { - stream.add(codeStart, new Token(TType.FUNC_END, ")", Target.UNKNOWN)); + it.add(new Token(TType.FUNC_END, ")", Target.UNKNOWN)); // Add at index codeStart. + it.previous(); // Select index codeStart + 1 <---. + it.previous(); // Select index codeStart <---. + it.next(); // Select index codeStart --->. } - ListIterator it = newStream.listIterator(newStream.size()); - while(it.hasPrevious()) { - stream.add(codeStart, it.previous()); + for(ListIterator it2 = newStream.listIterator(); it2.hasNext(); ) { + it.add(it2.next()); } return keywordPosition; @@ -275,6 +289,4 @@ public String docs() { public Version since() { return MSVersion.V3_3_1; } - - }