diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Sequence.java b/src/main/java/com/sk89q/worldedit/expression/runtime/Sequence.java index bdf9615b8..2dfc50306 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Sequence.java +++ b/src/main/java/com/sk89q/worldedit/expression/runtime/Sequence.java @@ -28,7 +28,7 @@ import java.util.List; * @author TomyLobo */ public class Sequence extends Node { - private final RValue[] sequence; + final RValue[] sequence; public Sequence(int position, RValue... sequence) { super(position); @@ -67,7 +67,7 @@ public class Sequence extends Node { @Override public RValue optimize() throws EvaluationException { - List newSequence = new ArrayList(); + final List newSequence = new ArrayList(); RValue droppedLast = null; for (RValue invokable : sequence) { diff --git a/src/main/java/com/sk89q/worldedit/expression/runtime/Switch.java b/src/main/java/com/sk89q/worldedit/expression/runtime/Switch.java index 30714b375..4cea9ae55 100644 --- a/src/main/java/com/sk89q/worldedit/expression/runtime/Switch.java +++ b/src/main/java/com/sk89q/worldedit/expression/runtime/Switch.java @@ -1,26 +1,59 @@ +// $Id$ +/* + * WorldEdit + * Copyright (C) 2010, 2011 sk89q + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . +*/ + package com.sk89q.worldedit.expression.runtime; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; +/** + * A switch/case construct. + * + * @author TomyLobo + */ public class Switch extends Node implements RValue { private final RValue parameter; - private final Map valueMap = new HashMap(); + private final Map valueMap; private final RValue[] caseStatements; private final RValue defaultCase; public Switch(int position, RValue parameter, List values, List caseStatements, RValue defaultCase) { - super(position); - this.parameter = parameter; + this(position, parameter, invertList(values), caseStatements, defaultCase); - assert(values.size() == caseStatements.size()); + } + private static Map invertList(List values) { + Map valueMap = new HashMap(); for (int i = 0; i < values.size(); ++i) { valueMap.put(values.get(i), i); } + return valueMap; + } + private Switch(int position, RValue parameter, Map valueMap, List caseStatements, RValue defaultCase) { + super(position); + + this.parameter = parameter; + this.valueMap = valueMap; this.caseStatements = caseStatements.toArray(new RValue[caseStatements.size()]); this.defaultCase = defaultCase; } @@ -82,4 +115,34 @@ public class Switch extends Node implements RValue { return sb.toString(); } + + @Override + public RValue optimize() throws EvaluationException { + final List newSequence = new ArrayList(); + final Map newValueMap = new HashMap(); + + Map backMap = new HashMap(); + for (Entry entry : valueMap.entrySet()) { + backMap.put(entry.getValue(), entry.getKey()); + } + + for (int i = 0; i < caseStatements.length; ++i) { + final RValue invokable = caseStatements[i].optimize(); + + final Double caseValue = backMap.get(i); + if (caseValue != null) { + newValueMap.put(caseValue, newSequence.size()); + } + + if (invokable instanceof Sequence) { + for (RValue subInvokable : ((Sequence) invokable).sequence) { + newSequence.add(subInvokable); + } + } else { + newSequence.add(invokable); + } + } + + return new Switch(getPosition(), parameter.optimize(), newValueMap, newSequence, defaultCase.optimize()); + } }