M src/main/java/nl/grauw/glass/Scope.java +17 -3
@@ 124,10 124,10 @@ public class Scope implements Context {
}
public String serializeSymbols() {
- return serializeSymbols("");
+ return serializeSymbols("", new SingleLinkedList<Scope>(this, null));
}
- public String serializeSymbols(String namePrefix) {
+ public String serializeSymbols(String namePrefix, SingleLinkedList<Scope> breadcrumbs) {
StringBuilder builder = new StringBuilder();
TreeMap<String, Expression> sortedMap = new TreeMap<>(symbols);
for (Map.Entry<String, Expression> entry : sortedMap.entrySet()) {
@@ 143,7 143,9 @@ public class Scope implements Context {
if (value.is(Type.CONTEXT)) {
try {
Scope context = (Scope)value.getContext();
- builder.append(context.serializeSymbols(name + "."));
+ if (!breadcrumbs.contains(context)) {
+ builder.append(context.serializeSymbols(name + ".", new SingleLinkedList<Scope>(context, breadcrumbs)));
+ }
} catch (EvaluationException e) {
// ignore
}
@@ 156,4 158,16 @@ public class Scope implements Context {
return serializeSymbols();
}
+ private static class SingleLinkedList<T> {
+ private T head;
+ private SingleLinkedList<T> tail;
+ public SingleLinkedList(T head, SingleLinkedList<T> tail) {
+ this.head = head;
+ this.tail = tail;
+ }
+ public boolean contains(T value) {
+ return value == head || (tail != null && tail.contains(value));
+ }
+ }
+
}
M src/test/java/nl/grauw/glass/SymbolsTest.java +20 -0
@@ 210,6 210,26 @@ public class SymbolsTest extends TestBas
);
}
+ @Test
+ public void testCycle() {
+ assertIterableEquals(
+ s(
+ "Test: equ 1H",
+ "Test.x: equ 7H",
+ "Test.y: equ 1H",
+ "Test.z: equ 2H"
+ ),
+ symbols(
+ " nop",
+ "Test: PROC",
+ "x: equ 7",
+ "y: equ Test",
+ " nop",
+ "z: ENDP"
+ )
+ );
+ }
+
@TempDir
static Path temporaryDirectory;