Skip to content

Commit 8dc005d

Browse files
committed
support & (and) operator, and | (or) operator.
1 parent 991e15c commit 8dc005d

3 files changed

Lines changed: 234 additions & 2 deletions

File tree

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2020 Cufy
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.jamplate.logic;
17+
18+
import org.jamplate.memory.Memory;
19+
20+
import java.util.Objects;
21+
22+
/**
23+
* A logic evaluates to {@code true} if both two logics evaluates to {@code true}.
24+
*
25+
* @author LSafer
26+
* @version 0.0.4
27+
* @since 0.0.4 ~2020.09.22
28+
*/
29+
public class And implements Logic {
30+
/**
31+
* The logic in the left.
32+
*
33+
* @since 0.0.4 ~2020.09.22
34+
*/
35+
protected final Logic left;
36+
/**
37+
* The logic in the right.
38+
*
39+
* @since 0.0.4 ~2020.09.22
40+
*/
41+
protected final Logic right;
42+
43+
/**
44+
* Construct a new {@code and} statement.
45+
*
46+
* @param left the left logic in the {@code and} statement.
47+
* @param right the right logic in the {@code and} statement.
48+
* @throws NullPointerException if the given {@code left} or {@code right} is null.
49+
* @since 0.0.4 ~2020.09.22
50+
*/
51+
public And(Logic left, Logic right) {
52+
Objects.requireNonNull(left, "left");
53+
Objects.requireNonNull(right, "right");
54+
this.left = left;
55+
this.right = right;
56+
}
57+
58+
@Override
59+
public String evaluate(Memory memory) {
60+
Objects.requireNonNull(memory, "memory");
61+
return this.left.evaluateBoolean(memory) &&
62+
this.right.evaluateBoolean(memory) ?
63+
"true" :
64+
"false";
65+
}
66+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 2020 Cufy
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.jamplate.logic;
17+
18+
import org.jamplate.memory.Memory;
19+
20+
import java.util.Objects;
21+
22+
/**
23+
* A logic evaluates to {@code true} if ether two logics evaluates to {@code true}.
24+
*
25+
* @author LSafer
26+
* @version 0.0.4
27+
* @since 0.0.4 ~2020.09.22
28+
*/
29+
public class Or implements Logic {
30+
/**
31+
* The logic in the left.
32+
*
33+
* @since 0.0.4 ~2020.09.22
34+
*/
35+
protected final Logic left;
36+
/**
37+
* The logic in the right.
38+
*
39+
* @since 0.0.4 ~2020.09.22
40+
*/
41+
protected final Logic right;
42+
43+
/**
44+
* Construct a new {@code or} statement.
45+
*
46+
* @param left the left logic in the {@code or} statement.
47+
* @param right the right logic in the {@code or} statement.
48+
* @throws NullPointerException if the given {@code left} or {@code right} is null.
49+
* @since 0.0.4 ~2020.09.22
50+
*/
51+
public Or(Logic left, Logic right) {
52+
Objects.requireNonNull(left, "left");
53+
Objects.requireNonNull(right, "right");
54+
this.left = left;
55+
this.right = right;
56+
}
57+
58+
@Override
59+
public String evaluate(Memory memory) {
60+
Objects.requireNonNull(memory, "memory");
61+
return this.left.evaluateBoolean(memory) ||
62+
this.right.evaluateBoolean(memory) ?
63+
"true" :
64+
"false";
65+
}
66+
}

src/main/java/org/jamplate/parser/LogicParser.java

Lines changed: 102 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
* The default jamplate parser that parses {@link String}s into {@link Logic}s.
2727
*
2828
* @author LSafer
29-
* @version 0.0.3
29+
* @version 0.0.4
3030
* @since 0.0.1 ~2020.09.19
3131
*/
3232
public class LogicParser implements PollParser<Logic> {
@@ -65,7 +65,7 @@ public class LogicParser implements PollParser<Logic> {
6565
*
6666
* @since 0.0.1 ~2020.09.19
6767
*/
68-
protected final Pattern PATTERN_WHITESPACES = Pattern.compile("(\\s+)|(==)|(!(?!=))");
68+
protected final Pattern PATTERN_WHITESPACES = Pattern.compile("(\\s+)|[|]|[&]|(!=)|(==)|(!(?!=))");
6969

7070
@Override
7171
public Logic link(List poll) {
@@ -101,6 +101,8 @@ public void parse(List poll) {
101101

102102
//clear all negations, equations
103103
this.parseNegations(poll);
104+
this.parseAnds(poll);
105+
this.parseOrs(poll);
104106
this.parseEquations(poll);
105107
}
106108

@@ -110,6 +112,55 @@ public List poll(String string) {
110112
return new ArrayList(Collections.singleton(string));
111113
}
112114

115+
/**
116+
* Parse any possible {@link And}s in the given {@code poll}. After calling this method, no and
117+
* statement in a {@link String} should remain in the given {@code poll}.
118+
* <p>
119+
* Clear these before calling this method:
120+
* <ul>
121+
* <li>{@link #processParenthesis(List)}</li>
122+
* <li>{@link #parseConstants(List)}</li>
123+
* <li>{@link #parseReferences(List)}</li>
124+
* <li>{@link #processWhitespaces(List)}</li>
125+
* <li>{@link #parseNegations(List)}</li>
126+
* <li>any statement that could be before or next to a and</li>
127+
* </ul>
128+
*
129+
* @param poll the poll to parse any and in it.
130+
* @throws NullPointerException if the given {@code poll} is null.
131+
* @throws ParseException if any parse exception occurs; if an and has no element before
132+
* or after it; if an element before or after an and has not been
133+
* resolved into a {@link Logic}.
134+
* @since 0.0.1 ~2020.09.19
135+
*/
136+
protected void parseAnds(List poll) {
137+
Objects.requireNonNull(poll, "poll");
138+
139+
ListIterator iterator = poll.listIterator();
140+
while (iterator.hasNext()) {
141+
Object next = iterator.next();
142+
143+
if (next instanceof String) {
144+
String string = (String) next;
145+
146+
if (string.equals("&"))
147+
try {
148+
iterator.remove();
149+
Logic rightLogic = (Logic) iterator.next();
150+
iterator.remove();
151+
Logic leftLogic = (Logic) iterator.previous();
152+
iterator.remove();
153+
154+
Logic logic = new And(leftLogic, rightLogic);
155+
156+
iterator.add(logic);
157+
} catch (NoSuchElementException | ClassCastException e) {
158+
throw new ParseException("Invalid And", e);
159+
}
160+
}
161+
}
162+
}
163+
113164
/**
114165
* Parse any possible {@link Constant}s in the given {@code poll}. After calling this method, no
115166
* constant statement in a {@link String} should remain in the given {@code poll}.
@@ -258,6 +309,55 @@ protected void parseNegations(List poll) {
258309
}
259310
}
260311

312+
/**
313+
* Parse any possible {@link Or}s in the given {@code poll}. After calling this method, no or
314+
* statement in a {@link String} should remain in the given {@code poll}.
315+
* <p>
316+
* Clear these before calling this method:
317+
* <ul>
318+
* <li>{@link #processParenthesis(List)}</li>
319+
* <li>{@link #parseConstants(List)}</li>
320+
* <li>{@link #parseReferences(List)}</li>
321+
* <li>{@link #processWhitespaces(List)}</li>
322+
* <li>{@link #parseNegations(List)}</li>
323+
* <li>any statement that could be before or next to an or</li>
324+
* </ul>
325+
*
326+
* @param poll the poll to parse any or in it.
327+
* @throws NullPointerException if the given {@code poll} is null.
328+
* @throws ParseException if any parse exception occurs; if an or has no element before or
329+
* after it; if an element before or after an or has not been
330+
* resolved into a {@link Logic}.
331+
* @since 0.0.1 ~2020.09.19
332+
*/
333+
protected void parseOrs(List poll) {
334+
Objects.requireNonNull(poll, "poll");
335+
336+
ListIterator iterator = poll.listIterator();
337+
while (iterator.hasNext()) {
338+
Object next = iterator.next();
339+
340+
if (next instanceof String) {
341+
String string = (String) next;
342+
343+
if (string.equals("|"))
344+
try {
345+
iterator.remove();
346+
Logic rightLogic = (Logic) iterator.next();
347+
iterator.remove();
348+
Logic leftLogic = (Logic) iterator.previous();
349+
iterator.remove();
350+
351+
Logic logic = new Or(leftLogic, rightLogic);
352+
353+
iterator.add(logic);
354+
} catch (NoSuchElementException | ClassCastException e) {
355+
throw new ParseException("Invalid Equation", e);
356+
}
357+
}
358+
}
359+
}
360+
261361
/**
262362
* Parse any possible {@link Reference} in the given {@code poll}. After calling this method, no
263363
* reference statement in a {@link String} should remain in the given {@code poll}.

0 commit comments

Comments
 (0)