Skip to content

Commit 1137d9e

Browse files
committed
Add check for balanced brackets in WhileLoopAnalysis
1 parent a668dce commit 1137d9e

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

src/main/groovy/net/zomis/brainf/analyze/IndexCounters.groovy

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import java.util.stream.Stream
44

55
class IndexCounters {
66
private final Map<Integer, IndexCounter> counters = [:]
7-
private final Stack<IndexCounter> recentCounters = new Stack<>()
7+
private final Deque<IndexCounter> recentCounters = new LinkedList<>()
88

99
Stream<Map.Entry<Integer, IndexCounter>> sorted() {
1010
counters.entrySet().stream().sorted(Comparator.comparingInt({it.key}))
@@ -16,7 +16,7 @@ class IndexCounters {
1616

1717
void begin(IndexCounter counter) {
1818
assert counter : 'Cannot begin on null counter'
19-
recentCounters.push(counter)
19+
recentCounters.addLast(counter)
2020
counter.begin()
2121
}
2222

@@ -25,11 +25,11 @@ class IndexCounters {
2525
}
2626

2727
void finishLast() {
28-
recentCounters.pop().finishLast()
28+
recentCounters.removeLast().finishLast()
2929
}
3030

3131
IndexCounter recent() {
32-
recentCounters.peek()
32+
recentCounters.peekLast()
3333
}
3434

3535
IndexCounter getOrCreate(int i) {

src/main/groovy/net/zomis/brainf/analyze/analyzers/WhileLoopAnalysis.groovy

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class WhileLoopAnalysis implements BrainfuckAnalyzer {
2929
}
3030

3131
private final IndexCounters whileLoopCounts = new IndexCounters()
32+
private int bracketsOpened
33+
private int bracketsClosed
3234

3335
IndexCounters getWhileLoopCounts() {
3436
return this.whileLoopCounts
@@ -39,9 +41,25 @@ class WhileLoopAnalysis implements BrainfuckAnalyzer {
3941
return new CellLoops()
4042
}
4143

44+
@Override
45+
void beforeStart(BrainfuckRunner runner) {
46+
for (int i = 0; i < runner.code.commandCount; i++) {
47+
BrainfuckCommand command = runner.code.getCommandAt(i)
48+
if (command == BrainFCommand.WHILE) {
49+
bracketsOpened++
50+
}
51+
if (command == BrainFCommand.END_WHILE) {
52+
bracketsClosed++
53+
}
54+
}
55+
}
56+
4257
@Override
4358
void print() {
4459
println 'While loops analysis'
60+
if (bracketsOpened != bracketsClosed) {
61+
println "ERROR: Number of starting brackets ($bracketsOpened) mismatch number of ending brackets ($bracketsClosed)"
62+
}
4563
whileLoopCounts.sorted().forEach({entry ->
4664
println "$entry.key $entry.value"
4765
})
@@ -63,7 +81,11 @@ class WhileLoopAnalysis implements BrainfuckAnalyzer {
6381
}
6482

6583
if (command == BrainFCommand.END_WHILE) {
66-
whileLoopCounts.recent().increase()
84+
IndexCounter recent = whileLoopCounts.recent()
85+
if (recent == null) {
86+
return
87+
}
88+
recent.increase()
6789
int startIndex = whileLoopCounts.recent().forIndex
6890
int current = runner.memory.value
6991
if (current == 0) {
@@ -74,4 +96,17 @@ class WhileLoopAnalysis implements BrainfuckAnalyzer {
7496
}
7597
}
7698
}
99+
100+
int getBracketsOpened() {
101+
this.@bracketsOpened
102+
}
103+
104+
int getBracketsClosed() {
105+
this.@bracketsClosed
106+
}
107+
108+
boolean isBracketsMatching() {
109+
this.bracketsClosed == this.bracketsOpened
110+
}
111+
77112
}

src/test/groovy/net/zomis/brainf/BrainTest.groovy

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,20 @@ public class BrainTest extends BrainfuckTest {
117117
assert brain.getOutput() == "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
118118
}
119119

120+
@Test
121+
public void unbalanced1() {
122+
source.addCommands("++[->+<] ]")
123+
analyze(new WhileLoopAnalysis())
124+
assert !analyze.get(WhileLoopAnalysis).bracketsMatching
125+
}
126+
127+
@Test
128+
public void unbalanced2() {
129+
source.addCommands("++ [ [->+<]")
130+
analyze(new WhileLoopAnalysis())
131+
assert !analyze.get(WhileLoopAnalysis).bracketsMatching
132+
}
133+
120134
@Test
121135
public void fizzBuzz() {
122136
source.addCommands(BrainfuckRunner.classLoader.getResource('fizzbuzz.bf').text);

0 commit comments

Comments
 (0)