Skip to content

Commit 5e5ec87

Browse files
authored
Merge pull request #22 from JaredDavis22/main
Enrich access to evaluator's variables
2 parents 2875c17 + afd40a1 commit 5e5ec87

5 files changed

Lines changed: 159 additions & 3 deletions

File tree

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</parent>
1111

1212
<artifactId>parsington</artifactId>
13-
<version>3.1.1-SNAPSHOT</version>
13+
<version>3.2.0-SNAPSHOT</version>
1414

1515
<name>Parsington: The SciJava Expression Parser</name>
1616
<description>A general-purpose mathematical expression parser, which converts infix expression strings into postfix queues and/or syntax trees.</description>

src/main/java/org/scijava/parsington/eval/AbstractEvaluator.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
package org.scijava.parsington.eval;
3232

33+
import java.util.Collections;
3334
import java.util.HashMap;
3435
import java.util.Map;
3536

@@ -79,6 +80,11 @@ public Object get(final String name) {
7980
return new Unresolved(name);
8081
}
8182

83+
@Override
84+
public Map<String, Object> getAll() {
85+
return Collections.unmodifiableMap(vars);
86+
}
87+
8288
@Override
8389
public void set(final String name, final Object value) {
8490
vars.put(name, value);
@@ -89,4 +95,14 @@ public void setAll(final Map<? extends String, ? extends Object> map) {
8995
vars.putAll(map);
9096
}
9197

98+
@Override
99+
public Object remove(final String name) {
100+
return vars.remove(name);
101+
}
102+
103+
@Override
104+
public void clear() {
105+
vars.clear();
106+
}
107+
92108
}

src/main/java/org/scijava/parsington/eval/Evaluator.java

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,13 @@ default Object get(final Variable v) {
167167
return get(v.getToken());
168168
}
169169

170+
/**
171+
* Gets a map of all variable names and values.
172+
*
173+
* @return A map from variable names to variable values.
174+
*/
175+
Map<String, Object> getAll();
176+
170177
/**
171178
* Sets the value of a variable.
172179
*
@@ -184,4 +191,19 @@ default void set(final Variable v, final Object value) {
184191
*/
185192
void setAll(Map<? extends String, ? extends Object> map);
186193

194+
/**
195+
* Removes the named variable.
196+
*
197+
* @param name The name of the variable whose value you want to remove.
198+
* @return The previous variables value associated with name,
199+
* or null if the name did not exist.
200+
*/
201+
Object remove(String name);
202+
203+
/**
204+
* Clears all the variables.
205+
*
206+
*/
207+
void clear();
208+
187209
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* #%L
3+
* Parsington: the SciJava mathematical expression parser.
4+
* %%
5+
* Copyright (C) 2015 - 2026 Board of Regents of the University of
6+
* Wisconsin-Madison.
7+
* %%
8+
* Redistribution and use in source and binary forms, with or without
9+
* modification, are permitted provided that the following conditions are met:
10+
*
11+
* 1. Redistributions of source code must retain the above copyright notice,
12+
* this list of conditions and the following disclaimer.
13+
* 2. Redistributions in binary form must reproduce the above copyright notice,
14+
* this list of conditions and the following disclaimer in the documentation
15+
* and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
21+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27+
* POSSIBILITY OF SUCH DAMAGE.
28+
* #L%
29+
*/
30+
31+
package org.scijava.parsington.eval;
32+
33+
import static org.junit.jupiter.api.Assertions.assertEquals;
34+
import static org.junit.jupiter.api.Assertions.assertNull;
35+
import static org.junit.jupiter.api.Assertions.assertThrows;
36+
import static org.junit.jupiter.api.Assertions.assertTrue;
37+
38+
import java.util.HashMap;
39+
import java.util.Map;
40+
41+
import org.junit.jupiter.api.Test;
42+
import org.scijava.parsington.AbstractTest;
43+
44+
/**
45+
* Abstract base class for testing {@link Evaluator} implementations.
46+
*
47+
* @author Curtis Rueden
48+
*/
49+
public abstract class AbstractEvaluatorTest extends AbstractTest {
50+
51+
public abstract Evaluator createEvaluator();
52+
53+
/**
54+
* Tests {@link Evaluator#get(String)} and
55+
* {@link Evaluator#set(String, Object)}.
56+
*/
57+
@Test
58+
public void testGetSet() {
59+
final Evaluator e = createEvaluator();
60+
// In strict mode (the default), getting an unset variable throws.
61+
assertThrows(IllegalArgumentException.class, () -> e.get("x"));
62+
e.set("x", 42);
63+
assertEquals(42, e.get("x"));
64+
e.set("x", "hello");
65+
assertEquals("hello", e.get("x"));
66+
}
67+
68+
/** Tests {@link Evaluator#remove(String)}. */
69+
@Test
70+
public void testRemove() {
71+
final Evaluator e = createEvaluator();
72+
// Removing an absent variable returns null.
73+
assertNull(e.remove("x"));
74+
e.set("x", 99);
75+
assertEquals(99, e.remove("x"));
76+
// Variable is gone after removal.
77+
assertThrows(IllegalArgumentException.class, () -> e.get("x"));
78+
}
79+
80+
/** Tests {@link Evaluator#clear()}. */
81+
@Test
82+
public void testClear() {
83+
final Evaluator e = createEvaluator();
84+
e.set("a", 1);
85+
e.set("b", 2);
86+
e.clear();
87+
assertEquals(new HashMap<>(), e.getAll());
88+
assertThrows(IllegalArgumentException.class, () -> e.get("a"));
89+
assertThrows(IllegalArgumentException.class, () -> e.get("b"));
90+
}
91+
92+
/** Tests {@link Evaluator#getAll()} and {@link Evaluator#setAll(Map)}. */
93+
@Test
94+
public void testGetAllSetAll() {
95+
final Evaluator e = createEvaluator();
96+
assertEquals(new HashMap<>(), e.getAll());
97+
98+
final Map<String, Object> vars = new HashMap<>();
99+
vars.put("a", 1);
100+
vars.put("b", "two");
101+
vars.put("c", 3.0);
102+
e.setAll(vars);
103+
104+
assertEquals(vars, e.getAll());
105+
106+
// Verify individual get still works after setAll.
107+
assertEquals(1, e.get("a"));
108+
assertEquals("two", e.get("b"));
109+
assertEquals(3.0, e.get("c"));
110+
111+
// Verify variables created at evaluation are accessible and correct.
112+
e.evaluate("d=a+c");
113+
assertTrue(e.getAll().containsKey("d"));
114+
final Object dVal = e.get("d");
115+
assertEquals(4.0, dVal);
116+
assertEquals(dVal, e.getAll().get("d"));
117+
}
118+
}

src/test/java/org/scijava/parsington/eval/AbstractStandardEvaluatorTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,12 @@
4545

4646
import org.junit.jupiter.api.BeforeEach;
4747
import org.junit.jupiter.api.Test;
48-
import org.scijava.parsington.AbstractTest;
4948
import org.scijava.parsington.Operators;
5049
import org.scijava.parsington.SyntaxTree;
5150
import org.scijava.parsington.Variable;
5251

5352
/** Abstract base class for testing {@link StandardEvaluator} implementations. */
54-
public abstract class AbstractStandardEvaluatorTest extends AbstractTest {
53+
public abstract class AbstractStandardEvaluatorTest extends AbstractEvaluatorTest {
5554

5655
protected StandardEvaluator e;
5756

@@ -60,6 +59,7 @@ public void setUp() {
6059
e = createEvaluator();
6160
}
6261

62+
@Override
6363
public abstract StandardEvaluator createEvaluator();
6464

6565
/** Tests {@link Evaluator#evaluate(String)}. */

0 commit comments

Comments
 (0)