From 16de6fb37cf025e84b5f92865f5aeed624ee33b6 Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Thu, 15 Feb 2024 13:14:04 +0300 Subject: [PATCH 01/16] #2836: --- .../src/main/java/EOorg/EOeolang/EOcage.java | 84 ++++++++++++++++++- .../src/test/eo/org/eolang/cage-tests.eo | 39 +++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java index a55384274d..33e320c8ce 100644 --- a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java +++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java @@ -33,6 +33,7 @@ import org.eolang.Atom; import org.eolang.Attr; import org.eolang.Data; +import org.eolang.ExFailure; import org.eolang.PhDefault; import org.eolang.Phi; import org.eolang.Versionized; @@ -62,7 +63,7 @@ public EOcage(final Phi sigma) { @Override public Phi lambda() { - return this.attr("enclosure").get(); + return new PhTracedEnclosure(this.attr("enclosure").get(), this.hashCode()); } /** @@ -108,4 +109,85 @@ public Phi lambda() { return new Data.ToPhi(true); } } + + + + public static final class PhTracedEnclosure implements Phi { + final Phi enclosure; + final int cage; + + public PhTracedEnclosure(final Phi enclosure, final int cage) { + this.enclosure = enclosure; + this.cage = cage; + } + + @Override + public Phi copy() { + return this.enclosure.copy(); + } + + @Override + public Attr attr(int pos) { + return new AtTracedEnclosure(enclosure.attr(pos).get(), cage); + } + + @Override + public Attr attr(String name) { + return new AtTracedEnclosure(enclosure.attr(name).get(), cage); + } + + @Override + public String locator() { + return enclosure.locator(); + } + + @Override + public String forma() { + return enclosure.forma(); + } + + @Override + public String φTerm() { + return this.getClass() + " -> " + enclosure.forma(); + } + } + + public static class AtTracedEnclosure implements Attr { + + Phi enclosure; + int cage; + + public AtTracedEnclosure(Phi enclosure, int cage) { + this.enclosure = enclosure; + this.cage = cage; + } + + @Override + public Attr copy(Phi self) { + return new AtTracedEnclosure(enclosure, cage); + } + + @Override + public Phi get() { + System.out.println("cage = " + cage + ", enclosure = " + this.enclosure.hashCode() + " = " + this.enclosure.forma() + ", " + this.enclosure.toString()); + if (cage == this.enclosure.hashCode()) { + throw new ExFailure("Cage stackoverflow"); + } + if (enclosure instanceof Data) { + return enclosure; + } + return new PhTracedEnclosure(enclosure, cage); + } + + @Override + public void put(Phi phi) { + this.enclosure = phi; + this.cage = 0; + } + + @Override + public String φTerm() { + return this.enclosure.φTerm(); + } + } } diff --git a/eo-runtime/src/test/eo/org/eolang/cage-tests.eo b/eo-runtime/src/test/eo/org/eolang/cage-tests.eo index e81ed88dd2..25d9dc2381 100644 --- a/eo-runtime/src/test/eo/org/eolang/cage-tests.eo +++ b/eo-runtime/src/test/eo/org/eolang/cage-tests.eo @@ -200,3 +200,42 @@ nop cge.eq 10 TRUE + +# Test +[] > example-stack-overflow + cage > cge + plus. + 1 + 1 + seq > @ + * + cge.write + plus. + cge + 2 + cge + TRUE + +# Test +[] > not-stack-overflow + # Fibonacci. + [n] > fibo + if. > @ + n.lt 2 + 1 + times. + fibo (n.minus 1) + cage > cge + if. + TRUE + 0 + 0 + seq > @ + * + cge.write + if. + cge.lt 2 + cge + cge + cge + TRUE From bf4a3e834397385f01a3f8e017fff68c2507359f Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Thu, 15 Feb 2024 17:34:42 +0300 Subject: [PATCH 02/16] #2836: System of decorators works --- .../src/test/eo/org/eolang/cage-tests.eo | 23 +++++-------------- .../test/java/EOorg/EOeolang/EOcageTest.java | 21 ++++++++++++++--- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/eo-runtime/src/test/eo/org/eolang/cage-tests.eo b/eo-runtime/src/test/eo/org/eolang/cage-tests.eo index 25d9dc2381..8edc561907 100644 --- a/eo-runtime/src/test/eo/org/eolang/cage-tests.eo +++ b/eo-runtime/src/test/eo/org/eolang/cage-tests.eo @@ -207,7 +207,8 @@ plus. 1 1 - seq > @ + nop > @ + seq > ret * cge.write plus. @@ -218,24 +219,12 @@ # Test [] > not-stack-overflow - # Fibonacci. - [n] > fibo - if. > @ - n.lt 2 - 1 - times. - fibo (n.minus 1) cage > cge - if. - TRUE - 0 - 0 - seq > @ + 0.plus 0 + nop > @ + seq > ret * cge.write - if. - cge.lt 2 - cge - cge + 0.plus cge cge TRUE diff --git a/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java b/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java index 2e2f18b91d..62642c8e77 100644 --- a/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java +++ b/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java @@ -164,24 +164,39 @@ void overwritesCagedObject() { ); } + @Test + void evaluatesLazilySimple() { + final Phi first = new EOcage(Phi.Φ); + EOcageTest.writeTo(first, new Data.ToPhi(3L)); + EOcageTest.writeTo(first, new Data.ToPhi(1L)); + MatcherAssert.assertThat( + new Dataized(first).take(Long.class), + Matchers.equalTo(1L) + ); + } + @Test void evaluatesLazily() { final Phi first = new EOcage(Phi.Φ); EOcageTest.writeTo(first, new Data.ToPhi(3L)); final Phi second = new EOcage(Phi.Φ); EOcageTest.writeTo(second, new Data.ToPhi(5L)); - final Phi cage = new EOcage(Phi.Φ); + final Phi sum = new EOcage(Phi.Φ); EOcageTest.writeTo( - cage, + sum, new PhWith( new PhCopy(new PhMethod(first, "plus")), 0, second ) ); EOcageTest.writeTo(first, new Data.ToPhi(1L)); + MatcherAssert.assertThat( + new Dataized(first).take(Long.class), + Matchers.equalTo(1L) + ); EOcageTest.writeTo(second, new Data.ToPhi(9L)); MatcherAssert.assertThat( - new Dataized(cage).take(Long.class), + new Dataized(sum).take(Long.class), Matchers.equalTo(10L) ); } From 866adb7ce21ea5ead2ec0fc22bf9a7b91409422c Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Thu, 15 Feb 2024 17:34:50 +0300 Subject: [PATCH 03/16] #2836: System of decorators works --- .../src/main/java/EOorg/EOeolang/EOcage.java | 53 ++++++++++++++----- .../src/main/java/org/eolang/PhDefault.java | 1 + 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java index 33e320c8ce..b89854fe82 100644 --- a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java +++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java @@ -40,6 +40,10 @@ import org.eolang.Volatile; import org.eolang.XmirObject; +import java.util.HashSet; +import java.util.Objects; +import java.util.Set; + /** * CAGE. * @@ -63,6 +67,7 @@ public EOcage(final Phi sigma) { @Override public Phi lambda() { + System.out.println("EOcage::lambda"); return new PhTracedEnclosure(this.attr("enclosure").get(), this.hashCode()); } @@ -103,6 +108,7 @@ private static final class Write extends PhDefault implements Atom { @Override public Phi lambda() { + System.out.println("write"); this.attr("σ").get().attr("enclosure").put( this.attr("x").get() ); @@ -110,11 +116,10 @@ public Phi lambda() { } } - - public static final class PhTracedEnclosure implements Phi { final Phi enclosure; final int cage; + private static final Set cages_dataizing = new HashSet<>(); public PhTracedEnclosure(final Phi enclosure, final int cage) { this.enclosure = enclosure; @@ -123,17 +128,30 @@ public PhTracedEnclosure(final Phi enclosure, final int cage) { @Override public Phi copy() { - return this.enclosure.copy(); + System.out.println("PhTracedEnclosure::copy"); + return new PhTracedEnclosure(this.enclosure, cage); } @Override public Attr attr(int pos) { - return new AtTracedEnclosure(enclosure.attr(pos).get(), cage); + return new AtTracedEnclosure(enclosure.attr(pos), cage); } @Override public Attr attr(String name) { - return new AtTracedEnclosure(enclosure.attr(name).get(), cage); + if (cages_dataizing.contains(cage)) { + throw new RuntimeException("the cage is already dataizing"); + //System.out.println("ABOBA"); + } + cages_dataizing.add(cage); + if (this.enclosure.hashCode() == this.cage) { + System.out.println("ABOBA"); + } + System.out.printf("start PhTracedEnclosure::attr(\"%s\"), enclosure = %d, cage = %d\n", name, enclosure.hashCode(), cage); + final Attr ret = new AtTracedEnclosure(enclosure.attr(name), cage); + System.out.printf("finish PhTracedEnclosure::attr(\"%s\")\n", name); + cages_dataizing.remove(cage); + return enclosure.attr(name); } @Override @@ -150,38 +168,45 @@ public String forma() { public String φTerm() { return this.getClass() + " -> " + enclosure.forma(); } + + @Override + public int hashCode() { + return enclosure.hashCode(); + } } public static class AtTracedEnclosure implements Attr { - Phi enclosure; + Attr enclosure; int cage; - public AtTracedEnclosure(Phi enclosure, int cage) { + public AtTracedEnclosure(final Attr enclosure, final int cage) { this.enclosure = enclosure; this.cage = cage; } @Override - public Attr copy(Phi self) { - return new AtTracedEnclosure(enclosure, cage); + public Attr copy(final Phi self) { + return this.enclosure.copy(self); } @Override public Phi get() { - System.out.println("cage = " + cage + ", enclosure = " + this.enclosure.hashCode() + " = " + this.enclosure.forma() + ", " + this.enclosure.toString()); + //System.out.println("cage = " + cage + ", enclosure = " + this.enclosure.hashCode() + " = " + this.enclosure.forma() + ", " + this.enclosure.toString()); if (cage == this.enclosure.hashCode()) { throw new ExFailure("Cage stackoverflow"); } - if (enclosure instanceof Data) { - return enclosure; + Phi ret = enclosure.get(); + if (!(ret instanceof Data)) { + ret = new PhTracedEnclosure(enclosure.get(), cage); } - return new PhTracedEnclosure(enclosure, cage); + return ret; } @Override public void put(Phi phi) { - this.enclosure = phi; + System.out.println("AtTracedEnclosure::put"); + this.enclosure.put(phi); this.cage = 0; } diff --git a/eo-runtime/src/main/java/org/eolang/PhDefault.java b/eo-runtime/src/main/java/org/eolang/PhDefault.java index b2daa7111e..04f6231549 100644 --- a/eo-runtime/src/main/java/org/eolang/PhDefault.java +++ b/eo-runtime/src/main/java/org/eolang/PhDefault.java @@ -246,6 +246,7 @@ public final Attr attr(final String name) { if (attr == null) { final Phi found; if (this instanceof Atom) { + //System.out.println("PhDefault::attr, branch this instanceof Atom"); found = this.cached.get(name, new AtomSafe((Atom) this)::lambda).attr(name).get(); found.attr("ρ").put(this); attr = new AtSimple(found); From 6e03ff6bced2b2e448c487006108db21aa293bec Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Fri, 16 Feb 2024 01:24:47 +0300 Subject: [PATCH 04/16] #2836: Cleaning it --- .../src/main/java/EOorg/EOeolang/EOcage.java | 106 ++++++++---------- .../src/test/eo/org/eolang/cage-tests.eo | 41 +++---- .../test/java/EOorg/EOeolang/EOcageTest.java | 11 ++ 3 files changed, 71 insertions(+), 87 deletions(-) diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java index b89854fe82..778fe91f13 100644 --- a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java +++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java @@ -27,6 +27,9 @@ */ package EOorg.EOeolang; +import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Supplier; +import java.util.Set; import org.eolang.AtAtom; import org.eolang.AtCage; import org.eolang.AtFree; @@ -40,10 +43,6 @@ import org.eolang.Volatile; import org.eolang.XmirObject; -import java.util.HashSet; -import java.util.Objects; -import java.util.Set; - /** * CAGE. * @@ -67,7 +66,6 @@ public EOcage(final Phi sigma) { @Override public Phi lambda() { - System.out.println("EOcage::lambda"); return new PhTracedEnclosure(this.attr("enclosure").get(), this.hashCode()); } @@ -108,7 +106,6 @@ private static final class Write extends PhDefault implements Atom { @Override public Phi lambda() { - System.out.println("write"); this.attr("σ").get().attr("enclosure").put( this.attr("x").get() ); @@ -116,42 +113,53 @@ public Phi lambda() { } } - public static final class PhTracedEnclosure implements Phi { + /** + * Class to trace if the cage got into recursion during the dataization. + * @since 0.36 + */ + private static final class PhTracedEnclosure implements Phi { + + /** + * Cages that are currently dataizing. If one cage is datazing and + * it needs to be dataized inside current dataizing, the cage will be here, + */ + private static final Set DATAIZING_CAGES = + new ConcurrentHashMap().keySet(); + + /** + * Enclosure. + */ final Phi enclosure; + + /** + * Vertex of cage where the {@link PhTracedEnclosure#enclosure} + * was retrieved. + */ final int cage; - private static final Set cages_dataizing = new HashSet<>(); - public PhTracedEnclosure(final Phi enclosure, final int cage) { + /** + * Ctor. + * @param enclosure Enclosure. + * @param cage Vertex of source cage. + */ + PhTracedEnclosure(final Phi enclosure, final int cage) { this.enclosure = enclosure; this.cage = cage; } @Override public Phi copy() { - System.out.println("PhTracedEnclosure::copy"); return new PhTracedEnclosure(this.enclosure, cage); } @Override public Attr attr(int pos) { - return new AtTracedEnclosure(enclosure.attr(pos), cage); + return this.getAttrSafely(() -> enclosure.attr(pos)); } @Override public Attr attr(String name) { - if (cages_dataizing.contains(cage)) { - throw new RuntimeException("the cage is already dataizing"); - //System.out.println("ABOBA"); - } - cages_dataizing.add(cage); - if (this.enclosure.hashCode() == this.cage) { - System.out.println("ABOBA"); - } - System.out.printf("start PhTracedEnclosure::attr(\"%s\"), enclosure = %d, cage = %d\n", name, enclosure.hashCode(), cage); - final Attr ret = new AtTracedEnclosure(enclosure.attr(name), cage); - System.out.printf("finish PhTracedEnclosure::attr(\"%s\")\n", name); - cages_dataizing.remove(cage); - return enclosure.attr(name); + return this.getAttrSafely(() -> enclosure.attr(name)); } @Override @@ -166,53 +174,27 @@ public String forma() { @Override public String φTerm() { - return this.getClass() + " -> " + enclosure.forma(); + return enclosure.φTerm(); } @Override public int hashCode() { return enclosure.hashCode(); } - } - - public static class AtTracedEnclosure implements Attr { - Attr enclosure; - int cage; - - public AtTracedEnclosure(final Attr enclosure, final int cage) { - this.enclosure = enclosure; - this.cage = cage; - } - - @Override - public Attr copy(final Phi self) { - return this.enclosure.copy(self); - } - - @Override - public Phi get() { - //System.out.println("cage = " + cage + ", enclosure = " + this.enclosure.hashCode() + " = " + this.enclosure.forma() + ", " + this.enclosure.toString()); - if (cage == this.enclosure.hashCode()) { - throw new ExFailure("Cage stackoverflow"); - } - Phi ret = enclosure.get(); - if (!(ret instanceof Data)) { - ret = new PhTracedEnclosure(enclosure.get(), cage); + /** + * Get attribute tracing cages. + * @param supplier Ordinary way to get attribute. + * @return The {@link Attr} if there is no StackOverflow case. + */ + private Attr getAttrSafely(final Supplier supplier) { + if (DATAIZING_CAGES.contains(cage)) { + throw new ExFailure("The cage %s is already dataizing", this.cage); } + DATAIZING_CAGES.add(cage); + final Attr ret = supplier.get(); + DATAIZING_CAGES.remove(cage); return ret; } - - @Override - public void put(Phi phi) { - System.out.println("AtTracedEnclosure::put"); - this.enclosure.put(phi); - this.cage = 0; - } - - @Override - public String φTerm() { - return this.enclosure.φTerm(); - } } } diff --git a/eo-runtime/src/test/eo/org/eolang/cage-tests.eo b/eo-runtime/src/test/eo/org/eolang/cage-tests.eo index 8edc561907..13d265e129 100644 --- a/eo-runtime/src/test/eo/org/eolang/cage-tests.eo +++ b/eo-runtime/src/test/eo/org/eolang/cage-tests.eo @@ -201,30 +201,21 @@ cge.eq 10 TRUE -# Test -[] > example-stack-overflow +# Check that cage stack leads to error. Just prints the error +# message if passes. +[] > catches-stack-overflow cage > cge - plus. - 1 - 1 - nop > @ - seq > ret - * - cge.write - plus. + 0.plus + try > @ + [] + seq > @ + * + cge.write + 0.plus cge cge - 2 - cge - TRUE - -# Test -[] > not-stack-overflow - cage > cge - 0.plus 0 - nop > @ - seq > ret - * - cge.write - 0.plus cge - cge - TRUE + FALSE + [stack-overflow-message] + QQ.io.stdout > @ + stack-overflow-message + [] + FALSE > @ diff --git a/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java b/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java index 62642c8e77..bfd3c2e445 100644 --- a/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java +++ b/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java @@ -30,6 +30,7 @@ import org.eolang.AtFree; import org.eolang.Data; import org.eolang.Dataized; +import org.eolang.ExAbstract; import org.eolang.PhCopy; import org.eolang.PhDefault; import org.eolang.PhMethod; @@ -270,6 +271,16 @@ void writesBoundedCopyOfTheSameBase() { ); } + @Test + void throwsExceptionIfRecursion() { + final Phi cage = new EOcage(Phi.Φ); + writeTo(cage, cage); + Assertions.assertThrows( + ExAbstract.class, + new Dataized(cage)::take + ); + } + private static void writeTo(final Phi cage, final Phi obj) { new Dataized( new PhWith( From f6df06b215f460681c8a54e1235d4562e2ee7e4c Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Fri, 16 Feb 2024 01:39:59 +0300 Subject: [PATCH 05/16] #2836: Cleaning it --- .../src/main/java/EOorg/EOeolang/EOcage.java | 46 ++++++++++--------- .../src/main/java/org/eolang/PhDefault.java | 1 - 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java index 778fe91f13..5a3e61c57d 100644 --- a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java +++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java @@ -27,9 +27,9 @@ */ package EOorg.EOeolang; -import java.util.concurrent.ConcurrentHashMap; -import java.util.function.Supplier; +import java.util.HashSet; import java.util.Set; +import java.util.function.Supplier; import org.eolang.AtAtom; import org.eolang.AtCage; import org.eolang.AtFree; @@ -123,19 +123,18 @@ private static final class PhTracedEnclosure implements Phi { * Cages that are currently dataizing. If one cage is datazing and * it needs to be dataized inside current dataizing, the cage will be here, */ - private static final Set DATAIZING_CAGES = - new ConcurrentHashMap().keySet(); + private static final Set DATAIZING_CAGES = new HashSet<>(); /** * Enclosure. */ - final Phi enclosure; + private final Phi enclosure; /** * Vertex of cage where the {@link PhTracedEnclosure#enclosure} * was retrieved. */ - final int cage; + private final int cage; /** * Ctor. @@ -149,37 +148,42 @@ private static final class PhTracedEnclosure implements Phi { @Override public Phi copy() { - return new PhTracedEnclosure(this.enclosure, cage); + return new PhTracedEnclosure(this.enclosure, this.cage); } @Override - public Attr attr(int pos) { - return this.getAttrSafely(() -> enclosure.attr(pos)); + public String locator() { + return this.enclosure.locator(); } @Override - public Attr attr(String name) { - return this.getAttrSafely(() -> enclosure.attr(name)); + public String forma() { + return this.enclosure.forma(); } @Override - public String locator() { - return enclosure.locator(); + public String φTerm() { + return this.enclosure.φTerm(); } @Override - public String forma() { - return enclosure.forma(); + public Attr attr(final int pos) { + return this.getAttrSafely(() -> this.enclosure.attr(pos)); } @Override - public String φTerm() { - return enclosure.φTerm(); + public Attr attr(final String name) { + return this.getAttrSafely(() -> this.enclosure.attr(name)); } @Override public int hashCode() { - return enclosure.hashCode(); + return this.enclosure.hashCode(); + } + + @Override + public boolean equals(final Object obj) { + return obj instanceof Phi && this.hashCode() == obj.hashCode(); } /** @@ -188,12 +192,12 @@ public int hashCode() { * @return The {@link Attr} if there is no StackOverflow case. */ private Attr getAttrSafely(final Supplier supplier) { - if (DATAIZING_CAGES.contains(cage)) { + if (EOcage.PhTracedEnclosure.DATAIZING_CAGES.contains(this.cage)) { throw new ExFailure("The cage %s is already dataizing", this.cage); } - DATAIZING_CAGES.add(cage); + EOcage.PhTracedEnclosure.DATAIZING_CAGES.add(this.cage); final Attr ret = supplier.get(); - DATAIZING_CAGES.remove(cage); + EOcage.PhTracedEnclosure.DATAIZING_CAGES.remove(this.cage); return ret; } } diff --git a/eo-runtime/src/main/java/org/eolang/PhDefault.java b/eo-runtime/src/main/java/org/eolang/PhDefault.java index 04f6231549..b2daa7111e 100644 --- a/eo-runtime/src/main/java/org/eolang/PhDefault.java +++ b/eo-runtime/src/main/java/org/eolang/PhDefault.java @@ -246,7 +246,6 @@ public final Attr attr(final String name) { if (attr == null) { final Phi found; if (this instanceof Atom) { - //System.out.println("PhDefault::attr, branch this instanceof Atom"); found = this.cached.get(name, new AtomSafe((Atom) this)::lambda).attr(name).get(); found.attr("ρ").put(this); attr = new AtSimple(found); From a4bd0e6c2e5dfd8e378cb7b23f6f0ba4e1c8d3b6 Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Fri, 16 Feb 2024 01:48:45 +0300 Subject: [PATCH 06/16] #2836: Added todo --- eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java index 5a3e61c57d..7a3604fe42 100644 --- a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java +++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java @@ -116,6 +116,9 @@ public Phi lambda() { /** * Class to trace if the cage got into recursion during the dataization. * @since 0.36 + * @todo #2836: 60min Add a new parameter of recursion depth. This parameter + * should be set by user via pom.xml. We can make DATAIZING_CAGES a + * ConsurrentHashMap which will add thread safety to the class. */ private static final class PhTracedEnclosure implements Phi { From d8afc2be14fbdf9f78b863a53ef503e30ca8abc1 Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Fri, 16 Feb 2024 01:51:07 +0300 Subject: [PATCH 07/16] #2836: Edited todo --- eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java index 7a3604fe42..b6c8f3317c 100644 --- a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java +++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java @@ -116,7 +116,7 @@ public Phi lambda() { /** * Class to trace if the cage got into recursion during the dataization. * @since 0.36 - * @todo #2836: 60min Add a new parameter of recursion depth. This parameter + * @todo #2836:60min Add a new parameter of recursion depth. This parameter * should be set by user via pom.xml. We can make DATAIZING_CAGES a * ConsurrentHashMap which will add thread safety to the class. */ From c2342a6e2094f033ed9f418d3817b1bcd0b19454 Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Fri, 16 Feb 2024 02:15:05 +0300 Subject: [PATCH 08/16] #2836: Clean it again --- .../src/test/java/EOorg/EOeolang/EOcageTest.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java b/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java index bfd3c2e445..a89dc3be23 100644 --- a/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java +++ b/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java @@ -165,17 +165,6 @@ void overwritesCagedObject() { ); } - @Test - void evaluatesLazilySimple() { - final Phi first = new EOcage(Phi.Φ); - EOcageTest.writeTo(first, new Data.ToPhi(3L)); - EOcageTest.writeTo(first, new Data.ToPhi(1L)); - MatcherAssert.assertThat( - new Dataized(first).take(Long.class), - Matchers.equalTo(1L) - ); - } - @Test void evaluatesLazily() { final Phi first = new EOcage(Phi.Φ); @@ -191,10 +180,6 @@ void evaluatesLazily() { ) ); EOcageTest.writeTo(first, new Data.ToPhi(1L)); - MatcherAssert.assertThat( - new Dataized(first).take(Long.class), - Matchers.equalTo(1L) - ); EOcageTest.writeTo(second, new Data.ToPhi(9L)); MatcherAssert.assertThat( new Dataized(sum).take(Long.class), From 253f3d9cc11a60917476847ca28ea19b3f8c5ff3 Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Mon, 19 Feb 2024 12:42:57 +0300 Subject: [PATCH 09/16] #2836: Edited copy method --- eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java index b6c8f3317c..141fba76c6 100644 --- a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java +++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java @@ -151,7 +151,7 @@ private static final class PhTracedEnclosure implements Phi { @Override public Phi copy() { - return new PhTracedEnclosure(this.enclosure, this.cage); + return new PhTracedEnclosure(this.enclosure.copy(), this.cage); } @Override From f776569edf4ac9e67a9b56d0f28cb65be1f6ab26 Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Mon, 19 Feb 2024 13:41:48 +0300 Subject: [PATCH 10/16] #2836: Added todo --- eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java | 5 ++++- eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java index 141fba76c6..8755bae928 100644 --- a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java +++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java @@ -118,7 +118,10 @@ public Phi lambda() { * @since 0.36 * @todo #2836:60min Add a new parameter of recursion depth. This parameter * should be set by user via pom.xml. We can make DATAIZING_CAGES a - * ConsurrentHashMap which will add thread safety to the class. + * Map and count how many times the cage was met. + * @todo #2836: 60min Make the class thread safe. It has private static + * field which can be accessed from differ thread and is not thread safe. + * Needs to synchronize this field. */ private static final class PhTracedEnclosure implements Phi { diff --git a/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java b/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java index a89dc3be23..9985f425ed 100644 --- a/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java +++ b/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java @@ -262,7 +262,8 @@ void throwsExceptionIfRecursion() { writeTo(cage, cage); Assertions.assertThrows( ExAbstract.class, - new Dataized(cage)::take + new Dataized(cage)::take, + "Throws exception if recursion happened" ); } From 45b9d87aa0346e6626d5883ec41a3864733ac6d8 Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Mon, 19 Feb 2024 13:45:50 +0300 Subject: [PATCH 11/16] #2836: Edited todo --- eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java index 8755bae928..2abc3be57e 100644 --- a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java +++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java @@ -119,7 +119,7 @@ public Phi lambda() { * @todo #2836:60min Add a new parameter of recursion depth. This parameter * should be set by user via pom.xml. We can make DATAIZING_CAGES a * Map and count how many times the cage was met. - * @todo #2836: 60min Make the class thread safe. It has private static + * @todo #2836:60min Make the class thread safe. It has private static * field which can be accessed from differ thread and is not thread safe. * Needs to synchronize this field. */ From 0bf9d0d802769b530b0e51c82373b91e4016f437 Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Mon, 19 Feb 2024 14:18:52 +0300 Subject: [PATCH 12/16] #2836: Edited doc --- eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java index 2abc3be57e..1f4a3ea04c 100644 --- a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java +++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java @@ -127,7 +127,7 @@ private static final class PhTracedEnclosure implements Phi { /** * Cages that are currently dataizing. If one cage is datazing and - * it needs to be dataized inside current dataizing, the cage will be here, + * it needs to be dataized inside current dataizing, the cage will be here. */ private static final Set DATAIZING_CAGES = new HashSet<>(); From 7c54043aaa61985b3baed2f8372a89aab825c458 Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Mon, 19 Feb 2024 15:57:50 +0300 Subject: [PATCH 13/16] #2836: Edited assert message --- eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java b/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java index 9985f425ed..2bac2c0d6d 100644 --- a/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java +++ b/eo-runtime/src/test/java/EOorg/EOeolang/EOcageTest.java @@ -263,7 +263,7 @@ void throwsExceptionIfRecursion() { Assertions.assertThrows( ExAbstract.class, new Dataized(cage)::take, - "Throws exception if recursion happened" + "We expect the exception to be thrown since we have recursion here" ); } From a69876edc4fd1e2dd45da7181701c90c0e42a97f Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Wed, 21 Feb 2024 17:15:18 +0300 Subject: [PATCH 14/16] #2836: private final class TracingWhileGetting --- .../src/main/java/EOorg/EOeolang/EOcage.java | 95 +----------- .../java/org/eolang/PhTracedEnclosure.java | 146 ++++++++++++++++++ 2 files changed, 147 insertions(+), 94 deletions(-) create mode 100644 eo-runtime/src/main/java/org/eolang/PhTracedEnclosure.java diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java index 1f4a3ea04c..ee5e744f89 100644 --- a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java +++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java @@ -38,6 +38,7 @@ import org.eolang.Data; import org.eolang.ExFailure; import org.eolang.PhDefault; +import org.eolang.PhTracedEnclosure; import org.eolang.Phi; import org.eolang.Versionized; import org.eolang.Volatile; @@ -113,98 +114,4 @@ public Phi lambda() { } } - /** - * Class to trace if the cage got into recursion during the dataization. - * @since 0.36 - * @todo #2836:60min Add a new parameter of recursion depth. This parameter - * should be set by user via pom.xml. We can make DATAIZING_CAGES a - * Map and count how many times the cage was met. - * @todo #2836:60min Make the class thread safe. It has private static - * field which can be accessed from differ thread and is not thread safe. - * Needs to synchronize this field. - */ - private static final class PhTracedEnclosure implements Phi { - - /** - * Cages that are currently dataizing. If one cage is datazing and - * it needs to be dataized inside current dataizing, the cage will be here. - */ - private static final Set DATAIZING_CAGES = new HashSet<>(); - - /** - * Enclosure. - */ - private final Phi enclosure; - - /** - * Vertex of cage where the {@link PhTracedEnclosure#enclosure} - * was retrieved. - */ - private final int cage; - - /** - * Ctor. - * @param enclosure Enclosure. - * @param cage Vertex of source cage. - */ - PhTracedEnclosure(final Phi enclosure, final int cage) { - this.enclosure = enclosure; - this.cage = cage; - } - - @Override - public Phi copy() { - return new PhTracedEnclosure(this.enclosure.copy(), this.cage); - } - - @Override - public String locator() { - return this.enclosure.locator(); - } - - @Override - public String forma() { - return this.enclosure.forma(); - } - - @Override - public String φTerm() { - return this.enclosure.φTerm(); - } - - @Override - public Attr attr(final int pos) { - return this.getAttrSafely(() -> this.enclosure.attr(pos)); - } - - @Override - public Attr attr(final String name) { - return this.getAttrSafely(() -> this.enclosure.attr(name)); - } - - @Override - public int hashCode() { - return this.enclosure.hashCode(); - } - - @Override - public boolean equals(final Object obj) { - return obj instanceof Phi && this.hashCode() == obj.hashCode(); - } - - /** - * Get attribute tracing cages. - * @param supplier Ordinary way to get attribute. - * @return The {@link Attr} if there is no StackOverflow case. - */ - private Attr getAttrSafely(final Supplier supplier) { - if (EOcage.PhTracedEnclosure.DATAIZING_CAGES.contains(this.cage)) { - throw new ExFailure("The cage %s is already dataizing", this.cage); - } - EOcage.PhTracedEnclosure.DATAIZING_CAGES.add(this.cage); - final Attr ret = supplier.get(); - EOcage.PhTracedEnclosure.DATAIZING_CAGES.remove(this.cage); - return ret; - } - } } diff --git a/eo-runtime/src/main/java/org/eolang/PhTracedEnclosure.java b/eo-runtime/src/main/java/org/eolang/PhTracedEnclosure.java new file mode 100644 index 0000000000..674803fb68 --- /dev/null +++ b/eo-runtime/src/main/java/org/eolang/PhTracedEnclosure.java @@ -0,0 +1,146 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2024 Objectionary.com + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package org.eolang; + +import java.util.HashSet; +import java.util.Set; +import java.util.function.Supplier; + +/** + * Class to trace if the cage got into recursion during the dataization. + * @since 0.36 + * @todo #2836:60min Add a new parameter of recursion depth. This parameter + * should be set by user via pom.xml. We can make DATAIZING_CAGES a + * Map and count how many times the cage was met. + * @todo #2836:60min Make the class thread safe. It has private static + * field which can be accessed from differ thread and is not thread safe. + * Needs to synchronize this field. + */ +public final class PhTracedEnclosure implements Phi { + + /** + * Cages that are currently dataizing. If one cage is datazing and + * it needs to be dataized inside current dataizing, the cage will be here. + */ + private static final Set DATAIZING_CAGES = new HashSet<>(); + + /** + * Enclosure. + */ + private final Phi enclosure; + + /** + * Vertex of cage where the {@link PhTracedEnclosure#enclosure} + * was retrieved. + */ + private final int cage; + + /** + * Ctor. + * @param enclosure Enclosure. + * @param cage Vertex of source cage. + */ + public PhTracedEnclosure(final Phi enclosure, final int cage) { + this.enclosure = enclosure; + this.cage = cage; + } + + @Override + public Phi copy() { + return new PhTracedEnclosure(this.enclosure.copy(), this.cage); + } + + @Override + public String locator() { + return this.enclosure.locator(); + } + + @Override + public String forma() { + return this.enclosure.forma(); + } + + @Override + public String φTerm() { + return this.enclosure.φTerm(); + } + + @Override + public Attr attr(final int pos) { + return new PhTracedEnclosure.TracingWhileGetting( + () -> this.enclosure.attr(pos) + ).get(); + } + + @Override + public Attr attr(final String name) { + return new PhTracedEnclosure.TracingWhileGetting( + () -> this.enclosure.attr(name) + ).get(); + } + + @Override + public int hashCode() { + return this.enclosure.hashCode(); + } + + @Override + public boolean equals(final Object obj) { + return obj instanceof Phi && this.hashCode() == obj.hashCode(); + } + + /** + * Supplier that traces the cage while gets. + * @since 0.36 + */ + private final class TracingWhileGetting implements Supplier { + + /** + * Supplies the {@link Attr}. + */ + private final Supplier attr; + + /** + * Ctor. + * @param attr Supplier of the {@link Attr}. + */ + private TracingWhileGetting(final Supplier attr) { + this.attr = attr; + } + + @Override + public Attr get() { + if (PhTracedEnclosure.DATAIZING_CAGES.contains(PhTracedEnclosure.this.cage)) { + throw new ExFailure( + "The cage %s is already dataizing", + PhTracedEnclosure.this.cage + ); + } + PhTracedEnclosure.DATAIZING_CAGES.add(PhTracedEnclosure.this.cage); + final Attr ret = this.attr.get(); + PhTracedEnclosure.DATAIZING_CAGES.remove(PhTracedEnclosure.this.cage); + return ret; + } + } +} From cb57445c66a7fc34f9ef5e2434f46526668b69c0 Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Wed, 21 Feb 2024 17:21:01 +0300 Subject: [PATCH 15/16] #2836: unused imports --- eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java index ee5e744f89..3a7d841d6b 100644 --- a/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java +++ b/eo-runtime/src/main/java/EOorg/EOeolang/EOcage.java @@ -27,16 +27,12 @@ */ package EOorg.EOeolang; -import java.util.HashSet; -import java.util.Set; -import java.util.function.Supplier; import org.eolang.AtAtom; import org.eolang.AtCage; import org.eolang.AtFree; import org.eolang.Atom; import org.eolang.Attr; import org.eolang.Data; -import org.eolang.ExFailure; import org.eolang.PhDefault; import org.eolang.PhTracedEnclosure; import org.eolang.Phi; From a25498b7de3e5426be6de08749f8595462e356e9 Mon Sep 17 00:00:00 2001 From: levBagryansky <28lev11@gmail.com> Date: Wed, 21 Feb 2024 17:23:14 +0300 Subject: [PATCH 16/16] #2836: Versionized --- eo-runtime/src/main/java/org/eolang/PhTracedEnclosure.java | 1 + 1 file changed, 1 insertion(+) diff --git a/eo-runtime/src/main/java/org/eolang/PhTracedEnclosure.java b/eo-runtime/src/main/java/org/eolang/PhTracedEnclosure.java index 674803fb68..cd96fd4436 100644 --- a/eo-runtime/src/main/java/org/eolang/PhTracedEnclosure.java +++ b/eo-runtime/src/main/java/org/eolang/PhTracedEnclosure.java @@ -37,6 +37,7 @@ * field which can be accessed from differ thread and is not thread safe. * Needs to synchronize this field. */ +@Versionized public final class PhTracedEnclosure implements Phi { /**