Skip to content

Commit 8d02ed2

Browse files
committed
Extract WhileLoopAnalysis for issue #22
1 parent 4c36e02 commit 8d02ed2

File tree

4 files changed

+87
-43
lines changed

4 files changed

+87
-43
lines changed

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

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -101,11 +101,6 @@ class Brainalyze implements BrainfuckListener {
101101
println 'Code instructions per command'
102102
printCommands(codeCommands)
103103
println()
104-
println 'While loops analysis'
105-
whileLoopCounts.sorted().forEach({entry ->
106-
println "$entry.key $entry.value"
107-
})
108-
println()
109104
if (this.memoryIndexBelowZero) {
110105
println 'WARNING: Memory index goes below zero'
111106
}
@@ -170,39 +165,12 @@ class Brainalyze implements BrainfuckListener {
170165
if (command == BrainFCommand.WRITE) {
171166
cell.prints.add(codeIndex)
172167
}
173-
174-
if (command == BrainFCommand.WHILE) {
175-
IndexCounter counter = whileLoopCounts.getOrCreate(runner.code.commandIndex)
176-
int current = runner.memory.value
177-
if (current == 0) {
178-
counter.add(0)
179-
} else {
180-
whileLoopCounts.begin(counter)
181-
cell.whileLoopStart.add(codeIndex)
182-
}
183-
}
184-
185-
if (command == BrainFCommand.END_WHILE) {
186-
whileLoopCounts.recent().increase()
187-
int startIndex = whileLoopCounts.recent().forIndex
188-
int current = runner.memory.value
189-
if (current == 0) {
190-
whileLoopCounts.finishLast()
191-
cell.whileLoopEnd.add(startIndex)
192-
} else {
193-
cell.whileLoopContinue.add(startIndex)
194-
}
195-
}
196168
}
197169

198170
@Override
199171
void afterPerform(BrainfuckRunner runner, BrainfuckCommand command) {
200172
}
201173

202-
IndexCounters getWhileLoopCounts() {
203-
return this.whileLoopCounts
204-
}
205-
206174
int getActionsForCommand(BrainFCommand command) {
207175
this.actionsPerCommand[command.ordinal()]
208176
}

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

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,6 @@ class MemoryCell {
2020

2121
private final Map<Class<?>, Object> analysis = [:]
2222

23-
IndexCounter whileLoopStart = new IndexCounter('loop-begin')
24-
IndexCounter whileLoopContinue = new IndexCounter('loop-continue')
25-
IndexCounter whileLoopEnd = new IndexCounter('loop-end')
26-
2723
MemoryCell(int index) {
2824
this.index = index
2925
}
@@ -34,6 +30,9 @@ class MemoryCell {
3430
obj = analyzer.createMemoryData()
3531
analysis.put(clazz, obj)
3632
}
33+
if (!obj) {
34+
throw new IllegalStateException("Analyzer $analyzer does not create a memory data object of $clazz")
35+
}
3736
return (T) obj;
3837
}
3938

@@ -61,8 +60,7 @@ class MemoryCell {
6160
Stream<CellTagger> taggers = this.analysis.values().stream()
6261
.filter({it instanceof CellTagger})
6362
.map({it as CellTagger})
64-
Stream<CellTagger> oldTaggers = Stream.of(prints, userInputs,
65-
whileLoopStart, whileLoopContinue, whileLoopEnd)
63+
Stream<CellTagger> oldTaggers = Stream.of(prints, userInputs)
6664
Stream.concat(taggers, oldTaggers)
6765
.flatMap({it.tags(loopNames)})
6866
.sorted()
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package net.zomis.brainf.analyze.analyzers
2+
3+
import net.zomis.brainf.analyze.BrainfuckAnalyzer
4+
import net.zomis.brainf.analyze.CellTagger
5+
import net.zomis.brainf.analyze.IndexCounter
6+
import net.zomis.brainf.analyze.IndexCounters
7+
import net.zomis.brainf.analyze.MemoryCell
8+
import net.zomis.brainf.model.BrainfuckCommand
9+
import net.zomis.brainf.model.BrainfuckRunner
10+
import net.zomis.brainf.model.classic.BrainFCommand
11+
12+
import java.util.function.Function
13+
import java.util.stream.Stream
14+
15+
class WhileLoopAnalysis implements BrainfuckAnalyzer {
16+
17+
public static class CellLoops implements CellTagger {
18+
IndexCounter whileLoopStart = new IndexCounter('loop-begin')
19+
IndexCounter whileLoopContinue = new IndexCounter('loop-continue')
20+
IndexCounter whileLoopEnd = new IndexCounter('loop-end')
21+
22+
@Override
23+
Stream<String> tags(Function<Integer, String> indexToStringFunction) {
24+
Stream.of(whileLoopStart, whileLoopContinue, whileLoopEnd)
25+
.flatMap({it.tags(indexToStringFunction)})
26+
}
27+
28+
String toString() { 'CellLoops ' }
29+
}
30+
31+
private final IndexCounters whileLoopCounts = new IndexCounters()
32+
33+
IndexCounters getWhileLoopCounts() {
34+
return this.whileLoopCounts
35+
}
36+
37+
@Override
38+
Object createMemoryData() {
39+
return new CellLoops()
40+
}
41+
42+
@Override
43+
void print() {
44+
println()
45+
println 'While loops analysis'
46+
whileLoopCounts.sorted().forEach({entry ->
47+
println "$entry.key $entry.value"
48+
})
49+
}
50+
51+
@Override
52+
void beforePerform(MemoryCell cell, BrainfuckRunner runner, BrainfuckCommand command) {
53+
int codeIndex = runner.code.commandIndex
54+
if (command == BrainFCommand.WHILE) {
55+
IndexCounter counter = whileLoopCounts.getOrCreate(runner.code.commandIndex)
56+
int current = runner.memory.value
57+
if (current == 0) {
58+
counter.add(0)
59+
} else {
60+
whileLoopCounts.begin(counter)
61+
cell.data(this, CellLoops).whileLoopStart.add(codeIndex)
62+
}
63+
}
64+
65+
if (command == BrainFCommand.END_WHILE) {
66+
whileLoopCounts.recent().increase()
67+
int startIndex = whileLoopCounts.recent().forIndex
68+
int current = runner.memory.value
69+
if (current == 0) {
70+
whileLoopCounts.finishLast()
71+
cell.data(this, CellLoops).whileLoopEnd.add(startIndex)
72+
} else {
73+
cell.data(this, CellLoops).whileLoopContinue.add(startIndex)
74+
}
75+
}
76+
}
77+
}

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

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import net.zomis.brainf.analyze.IndexCounters
44
import net.zomis.brainf.analyze.MemoryCell
55
import net.zomis.brainf.analyze.analyzers.MemoryValues
66
import net.zomis.brainf.analyze.analyzers.ReadWriteAnalysis
7+
import net.zomis.brainf.analyze.analyzers.WhileLoopAnalysis
78
import net.zomis.brainf.model.BrainF
89
import net.zomis.brainf.model.classic.BrainFCommand
910
import net.zomis.brainf.model.BrainfuckMemory
@@ -50,7 +51,7 @@ public class BrainTest extends BrainfuckTest {
5051
]
5152
'''
5253
source.addCommands(commands)
53-
analyze()
54+
analyze(new WhileLoopAnalysis())
5455
analyze.print()
5556
println context.getLoopNames()
5657
cellTagsContains(analyze.cell(0), 'before')
@@ -89,8 +90,8 @@ public class BrainTest extends BrainfuckTest {
8990
@Test
9091
public void analyzeLoops() {
9192
source.addCommands("++[ > +++++[>+>+++<<-]>[>+<-]<[+-+-]> +++ << -]");
92-
analyze()
93-
IndexCounters counts = analyze.getWhileLoopCounts();
93+
analyze(new WhileLoopAnalysis())
94+
IndexCounters counts = analyze.get(WhileLoopAnalysis).getWhileLoopCounts()
9495
assert counts.size() == 4
9596
assert counts[2] == [2]
9697
assert counts[11] == [5, 5]
@@ -101,8 +102,8 @@ public class BrainTest extends BrainfuckTest {
101102
@Test
102103
public void loopOnce() {
103104
source.addCommands("+[-]");
104-
analyze()
105-
IndexCounters counts = analyze.getWhileLoopCounts();
105+
analyze(new WhileLoopAnalysis())
106+
IndexCounters counts = analyze.get(WhileLoopAnalysis).getWhileLoopCounts();
106107
assert counts.size() == 1
107108
assert counts[1] == [1]
108109
}

0 commit comments

Comments
 (0)