From 79bb4e26aafff7ff8132291ab28696d15716c0f6 Mon Sep 17 00:00:00 2001 From: boxbeam Date: Sun, 4 Feb 2024 19:53:15 -0500 Subject: [PATCH] Make variables no longer hold a reference to their expression --- src/redempt/crunch/CompiledExpression.java | 8 ++++---- src/redempt/crunch/ExpressionParser.java | 9 +++------ src/redempt/crunch/ShuntingYard.java | 2 +- src/redempt/crunch/Variable.java | 10 ++++------ src/redempt/crunch/functional/ExpressionEnv.java | 2 +- src/redempt/crunch/functional/FunctionCall.java | 4 ++-- src/redempt/crunch/token/BinaryOperation.java | 4 ++-- src/redempt/crunch/token/Constant.java | 2 +- src/redempt/crunch/token/LazyVariable.java | 2 +- src/redempt/crunch/token/LiteralValue.java | 2 +- src/redempt/crunch/token/UnaryOperation.java | 4 ++-- src/redempt/crunch/token/Value.java | 2 +- test/redempt/crunch/test/CrunchTest.java | 7 +++++++ 13 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/redempt/crunch/CompiledExpression.java b/src/redempt/crunch/CompiledExpression.java index 13aef1c..ef6efff 100644 --- a/src/redempt/crunch/CompiledExpression.java +++ b/src/redempt/crunch/CompiledExpression.java @@ -55,7 +55,7 @@ public int getVariableCount() { */ public double evaluate(double... values) { setVariableValues(values); - return value.getValue(); + return value.getValue(this.variableValues); } /** @@ -64,7 +64,7 @@ public double evaluate(double... values) { */ public double evaluate() { checkArgCount(0); - return value.getValue(); + return value.getValue(this.variableValues); } /** @@ -78,7 +78,7 @@ public double evaluate(double first) { variableValues = new double[1]; } variableValues[0] = first; - return value.getValue(); + return value.getValue(this.variableValues); } /** @@ -94,7 +94,7 @@ public double evaluate(double first, double second) { } variableValues[0] = first; variableValues[1] = second; - return value.getValue(); + return value.getValue(this.variableValues); } private void checkArgCount(int args) { diff --git a/src/redempt/crunch/ExpressionParser.java b/src/redempt/crunch/ExpressionParser.java index bf69689..b6f7ec7 100644 --- a/src/redempt/crunch/ExpressionParser.java +++ b/src/redempt/crunch/ExpressionParser.java @@ -112,7 +112,7 @@ private Value parseNestedExpression() { private Value parseAnonymousVariable() { expectChar('$'); - double value = parseLiteral().getValue(); + double value = parseLiteral().getValue(new double[0]); if (value % 1 != 0) { error("Decimal variable indices are not allowed"); } @@ -121,7 +121,7 @@ private Value parseAnonymousVariable() { } int index = (int) value - 1; maxVarIndex = Math.max(index, maxVarIndex); - return new Variable(expression, index); + return new Variable(index); } private Value parseTerm() { @@ -154,9 +154,6 @@ private Value parseTerm() { if (term == null) { error("Expected value"); } - if (term instanceof Variable) { - ((Variable) term).expression = expression; - } return term; } @@ -179,7 +176,7 @@ private Value parseLeadingOperation(Token token) { UnaryOperator op = (UnaryOperator) token; Value term = parseTerm(); if (op.isPure() && term.getType() == TokenType.LITERAL_VALUE) { - return new LiteralValue(op.getOperation().applyAsDouble(term.getValue())); + return new LiteralValue(op.getOperation().applyAsDouble(term.getValue(new double[0]))); } return new UnaryOperation(op, term); case FUNCTION: diff --git a/src/redempt/crunch/ShuntingYard.java b/src/redempt/crunch/ShuntingYard.java index 06ce567..40c4fbd 100644 --- a/src/redempt/crunch/ShuntingYard.java +++ b/src/redempt/crunch/ShuntingYard.java @@ -26,7 +26,7 @@ private void createOperation() { Value right = stack.removeLast(); Value left = stack.removeLast(); if (right.getType() == TokenType.LITERAL_VALUE && left.getType() == TokenType.LITERAL_VALUE) { - stack.add(new LiteralValue(op.getOperation().applyAsDouble(left.getValue(), right.getValue()))); + stack.add(new LiteralValue(op.getOperation().applyAsDouble(left.getValue(new double[0]), right.getValue(new double[0])))); } else { stack.add(new BinaryOperation(op, left, right)); } diff --git a/src/redempt/crunch/Variable.java b/src/redempt/crunch/Variable.java index 68a8da3..a71eada 100644 --- a/src/redempt/crunch/Variable.java +++ b/src/redempt/crunch/Variable.java @@ -6,10 +6,8 @@ public class Variable implements Value { private final int index; - protected CompiledExpression expression; - public Variable(CompiledExpression expression, int index) { - this.expression = expression; + public Variable(int index) { this.index = index; } @@ -18,8 +16,8 @@ public int getIndex() { } @Override - public double getValue() { - return expression.variableValues[index]; + public double getValue(double[] variableValues) { + return variableValues[index]; } @Override @@ -32,7 +30,7 @@ public String toString() { } public Variable getClone() { - return new Variable(expression, index); + return new Variable(index); } } diff --git a/src/redempt/crunch/functional/ExpressionEnv.java b/src/redempt/crunch/functional/ExpressionEnv.java index c0920db..79a95e1 100644 --- a/src/redempt/crunch/functional/ExpressionEnv.java +++ b/src/redempt/crunch/functional/ExpressionEnv.java @@ -97,7 +97,7 @@ public ExpressionEnv setVariableNames(String... names) { varCount = names.length; for (int i = 0; i < names.length; i++) { checkName(names[i]); - values.set(names[i], new Variable(null, i)); + values.set(names[i], new Variable(i)); } return this; } diff --git a/src/redempt/crunch/functional/FunctionCall.java b/src/redempt/crunch/functional/FunctionCall.java index 3b40d85..5621d71 100644 --- a/src/redempt/crunch/functional/FunctionCall.java +++ b/src/redempt/crunch/functional/FunctionCall.java @@ -25,9 +25,9 @@ public TokenType getType() { } @Override - public double getValue() { + public double getValue(double[] variableValues) { for (int i = 0; i < values.length; i++) { - numbers[i] = values[i].getValue(); + numbers[i] = values[i].getValue(variableValues); } return function.call(numbers); } diff --git a/src/redempt/crunch/token/BinaryOperation.java b/src/redempt/crunch/token/BinaryOperation.java index 8f55f05..d3412f7 100644 --- a/src/redempt/crunch/token/BinaryOperation.java +++ b/src/redempt/crunch/token/BinaryOperation.java @@ -21,8 +21,8 @@ public Value[] getValues() { } @Override - public double getValue() { - return operator.getOperation().applyAsDouble(first.getValue(), second.getValue()); + public double getValue(double[] variableValues) { + return operator.getOperation().applyAsDouble(first.getValue(variableValues), second.getValue(variableValues)); } @Override diff --git a/src/redempt/crunch/token/Constant.java b/src/redempt/crunch/token/Constant.java index 3d81647..fa1d058 100644 --- a/src/redempt/crunch/token/Constant.java +++ b/src/redempt/crunch/token/Constant.java @@ -25,7 +25,7 @@ public TokenType getType() { } @Override - public double getValue() { + public double getValue(double[] variableValues) { return value; } diff --git a/src/redempt/crunch/token/LazyVariable.java b/src/redempt/crunch/token/LazyVariable.java index 1267241..6c9369d 100644 --- a/src/redempt/crunch/token/LazyVariable.java +++ b/src/redempt/crunch/token/LazyVariable.java @@ -18,7 +18,7 @@ public TokenType getType() { } @Override - public double getValue() { + public double getValue(double[] variableValues) { return supplier.getAsDouble(); } diff --git a/src/redempt/crunch/token/LiteralValue.java b/src/redempt/crunch/token/LiteralValue.java index f262f3d..4164649 100644 --- a/src/redempt/crunch/token/LiteralValue.java +++ b/src/redempt/crunch/token/LiteralValue.java @@ -14,7 +14,7 @@ public TokenType getType() { } @Override - public double getValue() { + public double getValue(double[] variableValues) { return value; } diff --git a/src/redempt/crunch/token/UnaryOperation.java b/src/redempt/crunch/token/UnaryOperation.java index 49b9a6c..dc4aa05 100644 --- a/src/redempt/crunch/token/UnaryOperation.java +++ b/src/redempt/crunch/token/UnaryOperation.java @@ -18,8 +18,8 @@ public Value getChild() { } @Override - public double getValue() { - return operator.getOperation().applyAsDouble(first.getValue()); + public double getValue(double[] variableValues) { + return operator.getOperation().applyAsDouble(first.getValue(variableValues)); } @Override diff --git a/src/redempt/crunch/token/Value.java b/src/redempt/crunch/token/Value.java index fa6d3b9..fdc3bd5 100644 --- a/src/redempt/crunch/token/Value.java +++ b/src/redempt/crunch/token/Value.java @@ -6,7 +6,7 @@ */ public interface Value extends Token, Cloneable { - double getValue(); + double getValue(double[] variableValues); Value getClone(); } diff --git a/test/redempt/crunch/test/CrunchTest.java b/test/redempt/crunch/test/CrunchTest.java index 9f4f7ab..f8c271f 100644 --- a/test/redempt/crunch/test/CrunchTest.java +++ b/test/redempt/crunch/test/CrunchTest.java @@ -136,4 +136,11 @@ void largeExpressionWithCustomFunctionTest() { assertEquals(83080, compiled.evaluate()); } + @Test + void cloneTest() { + CompiledExpression expr = Crunch.compileExpression("$1"); + assertEquals(1, expr.evaluate(1)); + assertEquals(2, expr.clone().evaluate(2)); + } + }