diff --git a/src/main/java/com/sk89q/worldedit/EditSession.java b/src/main/java/com/sk89q/worldedit/EditSession.java index e7eeea9f1..d0da26c17 100644 --- a/src/main/java/com/sk89q/worldedit/EditSession.java +++ b/src/main/java/com/sk89q/worldedit/EditSession.java @@ -2635,8 +2635,8 @@ public class EditSession { final Expression expression = Expression.compile(expressionString, "x", "y", "z", "type", "data"); expression.optimize(); - final RValue typeVariable = expression.getVariable("type"); - final RValue dataVariable = expression.getVariable("data"); + final RValue typeVariable = expression.getVariable("type", false); + final RValue dataVariable = expression.getVariable("data", false); final ArbitraryShape shape = new ArbitraryShape(region) { @Override @@ -2663,9 +2663,9 @@ public class EditSession { final Expression expression = Expression.compile(expressionString, "x", "y", "z"); expression.optimize(); - final RValue x = expression.getVariable("x"); - final RValue y = expression.getVariable("y"); - final RValue z = expression.getVariable("z"); + final RValue x = expression.getVariable("x", false); + final RValue y = expression.getVariable("y", false); + final RValue z = expression.getVariable("z", false); Vector zero2 = zero.add(0.5, 0.5, 0.5); diff --git a/src/main/java/com/sk89q/worldedit/expression/Expression.java b/src/main/java/com/sk89q/worldedit/expression/Expression.java index fbcb3685e..5ee202544 100644 --- a/src/main/java/com/sk89q/worldedit/expression/Expression.java +++ b/src/main/java/com/sk89q/worldedit/expression/Expression.java @@ -84,7 +84,7 @@ public class Expression { variables.put(variableName, new Variable(0)); } - root = Parser.parse(tokens, variables); + root = Parser.parse(tokens, this); } public double evaluate(double... values) throws EvaluationException { @@ -114,7 +114,12 @@ public class Expression { return root.toString(); } - public RValue getVariable(String name) { - return variables.get(name); + public RValue getVariable(String name, boolean create) { + RValue variable = variables.get(name); + if (variable == null && create) { + variables.put(name, variable = new Variable(0)); + } + + return variable; } } diff --git a/src/main/java/com/sk89q/worldedit/expression/parser/Parser.java b/src/main/java/com/sk89q/worldedit/expression/parser/Parser.java index aa698c25e..17a74a0a1 100644 --- a/src/main/java/com/sk89q/worldedit/expression/parser/Parser.java +++ b/src/main/java/com/sk89q/worldedit/expression/parser/Parser.java @@ -22,8 +22,7 @@ package com.sk89q.worldedit.expression.parser; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; -import java.util.Map; - +import com.sk89q.worldedit.expression.Expression; import com.sk89q.worldedit.expression.Identifiable; import com.sk89q.worldedit.expression.lexer.tokens.IdentifierToken; import com.sk89q.worldedit.expression.lexer.tokens.KeywordToken; @@ -40,7 +39,6 @@ import com.sk89q.worldedit.expression.runtime.RValue; import com.sk89q.worldedit.expression.runtime.Return; import com.sk89q.worldedit.expression.runtime.Sequence; import com.sk89q.worldedit.expression.runtime.SimpleFor; -import com.sk89q.worldedit.expression.runtime.Variable; import com.sk89q.worldedit.expression.runtime.While; /** @@ -68,15 +66,15 @@ public class Parser { private final List tokens; private int position = 0; - private Map variables; + private Expression expression; - private Parser(List tokens, Map variables) { + private Parser(List tokens, Expression expression) { this.tokens = tokens; - this.variables = variables; + this.expression = expression; } - public static final RValue parse(List tokens, Map variables) throws ParserException { - return new Parser(tokens, variables).parse(); + public static final RValue parse(List tokens, Expression expression) throws ParserException { + return new Parser(tokens, expression).parse(); } private RValue parse() throws ParserException { @@ -176,9 +174,7 @@ public class Parser { throw new ParserException(variableToken.getPosition(), "Expected identifier"); } - // In theory, I should have to create non-existant variables here. - // However, the java-for parsing attempt further up already takes care of that :) - RValue variable = variables.get(((IdentifierToken) variableToken).value); + RValue variable = expression.getVariable(((IdentifierToken) variableToken).value, true); if (!(variable instanceof LValue)) { throw new ParserException(variableToken.getPosition(), "Expected variable"); } @@ -286,14 +282,11 @@ public class Parser { if (next.id() == '(') { halfProcessed.add(parseFunctionCall(identifierToken)); } else { - RValue variable = variables.get(identifierToken.value); + // Ugly hack to make temporary variables work while not sacrificing error reporting. + final boolean isSimpleAssignment = next instanceof OperatorToken && ((OperatorToken) next).operator.equals("="); + RValue variable = expression.getVariable(identifierToken.value, isSimpleAssignment); if (variable == null) { - if (next instanceof OperatorToken && ((OperatorToken) next).operator.equals("=")) { - // Ugly hack to make temporary variables work while not sacrificing error reporting. - variables.put(identifierToken.value, variable = new Variable(0)); - } else { - throw new ParserException(current.getPosition(), "Variable '" + identifierToken.value + "' not found"); - } + throw new ParserException(current.getPosition(), "Variable '" + identifierToken.value + "' not found"); } halfProcessed.add(variable); } diff --git a/src/test/java/com/sk89q/worldedit/expression/ExpressionTest.java b/src/test/java/com/sk89q/worldedit/expression/ExpressionTest.java index 00e2a8046..19651c924 100644 --- a/src/test/java/com/sk89q/worldedit/expression/ExpressionTest.java +++ b/src/test/java/com/sk89q/worldedit/expression/ExpressionTest.java @@ -65,9 +65,9 @@ public class ExpressionTest { public void testAssign() throws ExpressionException { Expression foo = compile("{a=x} b=y; c=z", "x", "y", "z", "a", "b", "c"); foo.evaluate(2, 3, 5); - assertEquals(2, foo.getVariable("a").getValue(), 0); - assertEquals(3, foo.getVariable("b").getValue(), 0); - assertEquals(5, foo.getVariable("c").getValue(), 0); + assertEquals(2, foo.getVariable("a", false).getValue(), 0); + assertEquals(3, foo.getVariable("b", false).getValue(), 0); + assertEquals(5, foo.getVariable("c", false).getValue(), 0); } @Test @@ -78,13 +78,13 @@ public class ExpressionTest { // test 'dangling else' final Expression expression1 = compile("if (1) if (0) x=4; else y=5;", "x", "y"); expression1.evaluate(1, 2); - assertEquals(1, expression1.getVariable("x").getValue(), 0); - assertEquals(5, expression1.getVariable("y").getValue(), 0); + assertEquals(1, expression1.getVariable("x", false).getValue(), 0); + assertEquals(5, expression1.getVariable("y", false).getValue(), 0); // test if the if construct is correctly recognized as a statement final Expression expression2 = compile("if (0) if (1) x=5; y=4;", "x", "y"); expression2.evaluate(1, 2); - assertEquals(4, expression2.getVariable("y").getValue(), 0); + assertEquals(4, expression2.getVariable("y", false).getValue(), 0); } @Test