Skip to content

Commit

Permalink
Merge branch '__rultor'
Browse files Browse the repository at this point in the history
  • Loading branch information
rultor committed Mar 31, 2024
2 parents d8cd36f + 3e8a0ad commit 9b51532
Show file tree
Hide file tree
Showing 3 changed files with 238 additions and 26 deletions.
196 changes: 185 additions & 11 deletions eo-runtime/src/main/java/EOorg/EOeolang/EOtry.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,11 @@
*/
package EOorg.EOeolang;

import java.util.function.Consumer;
import java.util.function.Function;
import org.eolang.AtVoid;
import org.eolang.Atom;
import org.eolang.Data;
import org.eolang.Dataized;
import org.eolang.PhDefault;
import org.eolang.Phi;
Expand All @@ -44,7 +47,6 @@
@Versionized
@XmirObject(oname = "try")
public final class EOtry extends PhDefault implements Atom {

/**
* Ctor.
* @param sigma Sigma
Expand All @@ -58,16 +60,188 @@ public EOtry(final Phi sigma) {

@Override
public Phi lambda() {
Phi ret = this.take("main");
try {
new Dataized(ret).take();
} catch (final EOerror.ExError ex) {
final Phi ctch = this.take("catch").copy();
ctch.put(0, ex.enclosure());
ret = ctch;
} finally {
new Dataized(this.take("finally")).take();
return new PhTry(this.take("main"), this.take("catch"), this.take("finally"));
}

/**
* Object that knows how to deal with {@link EOorg.EOeolang.EOerror.ExError}.
* @since 0.36.0
*/
private static class PhTry implements Phi {
/**
* Body object.
*/
private final Phi body;

/**
* Catch object.
*/
private final Phi ctch;

/**
* Finally object.
*/
private final Phi last;

/**
* Put function.
*/
private final Consumer<Consumer<Phi>> func;

/**
* Ctor.
* @param body Body object
* @param ctch Catch object
* @param last Finally object
*/
PhTry(final Phi body, final Phi ctch, final Phi last) {
this.body = body;
this.ctch = ctch;
this.last = last;
this.func = new TryExecute(body, ctch);
}

@Override
public byte[] delta() {
return new TryReturn<byte[]>(
this.body, this.ctch, this.last
).apply(Data::delta);
}

@Override
public Phi copy() {
return new PhTry(this.body.copy(), this.ctch.copy(), this.last.copy());
}

@Override
public Phi take(final String name) {
return new TryReturn<Phi>(
this.body, this.ctch, this.last
).apply(phi -> phi.take(name));
}

@Override
public Phi take(final String name, final Phi rho) {
return new TryReturn<Phi>(
this.body, this.ctch, this.last
).apply(phi -> phi.take(name, rho));
}

@Override
public void put(final int pos, final Phi object) {
this.func.accept(phi -> phi.put(pos, object));
}

@Override
public void put(final String name, final Phi object) {
this.func.accept(phi -> phi.put(name, object));
}

@Override
public String locator() {
return new TryReturn<String>(
this.body, this.ctch, this.last
).apply(Phi::locator);
}

@Override
public String forma() {
return new TryReturn<String>(
this.body, this.ctch, this.last
).apply(Phi::forma);
}

@Override
public String φTerm() {
return new TryReturn<String>(
this.body, this.ctch, this.last
).apply(Phi::φTerm);
}
}

/**
* Tries to execute given function and catches {@link EOorg.EOeolang.EOerror.ExError}.
* @since 0.36.0
*/
private static class TryExecute implements Consumer<Consumer<Phi>> {
/**
* Body object.
*/
private final Phi body;

/**
* Catch object.
*/
private final Phi ctch;

/**
* Ctor.
* @param main Body object
* @param ctch Catch object
*/
TryExecute(final Phi main, final Phi ctch) {
this.body = main;
this.ctch = ctch;
}

@Override
public void accept(final Consumer<Phi> func) {
try {
func.accept(this.body);
} catch (final EOerror.ExError ex) {
final Phi caught = this.ctch.copy();
caught.put(0, ex.enclosure());
func.accept(caught);
}
}
}

/**
* Tries to return value from given function and catches {@link EOorg.EOeolang.EOerror.ExError}.
* @param <T> Type of return value.
* @since 0.36.0
*/
private static class TryReturn<T> implements Function<Function<Phi, T>, T> {
/**
* Body object.
*/
private final Phi body;

/**
* Catch object.
*/
private final Phi ctch;

/**
* Finally object.
*/
private final Phi last;

/**
* Ctor.
* @param main Body object
* @param ctch Catch object
* @param last Finally object
*/
TryReturn(final Phi main, final Phi ctch, final Phi last) {
this.body = main;
this.ctch = ctch;
this.last = last;
}

@Override
public T apply(final Function<Phi, T> func) {
T result;
try {
result = func.apply(this.body);
} catch (final EOerror.ExError ex) {
final Phi caught = this.ctch.copy();
caught.put(0, ex.enclosure());
result = func.apply(caught);
} finally {
new Dataized(this.last).take();
}
return result;
}
return ret;
}
}
13 changes: 4 additions & 9 deletions eo-runtime/src/test/eo/org/eolang/try-tests.eo
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@
+version 0.0.0

# Test.
# @todo #2931:30min Enable the tests try-memory-update, try-memory-update-catch. The test were
# disabled because 1) "try" object dataizes body twice 2) implementation of "memory" is wrong.
# Need to fix it and enable the test.
[] > simple-division-by-zero
try > @
[]
Expand Down Expand Up @@ -84,8 +81,8 @@

# Test.
[] > try-memory-update
memory 0 > m
eq. > res
memory.alloc 0 > m
eq. > @
seq
*
m.write 1
Expand All @@ -97,12 +94,11 @@
nop
m.as-int
2
TRUE > @

# Test.
[] > try-memory-update-catch
memory 0 > m
eq. > res
memory.alloc 0 > m
eq. > @
seq
*
m.write 1
Expand All @@ -116,4 +112,3 @@
nop
m
1
TRUE > @
55 changes: 49 additions & 6 deletions eo-runtime/src/test/java/EOorg/EOeolang/EOtryTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import org.eolang.AtComposite;
import org.eolang.AtVoid;
import org.eolang.Attr;
import org.eolang.Data;
import org.eolang.Dataized;
import org.eolang.ExFailure;
Expand Down Expand Up @@ -124,17 +125,59 @@ public void worksWithoutException() {
);
}

@Test
public void doesNotDataizeBodyTwice() {
final Phi trier = new EOtry(Phi.Φ);
final MainWithCounter main = new MainWithCounter();
trier.put(0, main);
trier.put(1, new Catcher(Phi.Φ));
trier.put(2, new EOnop(Phi.Φ));
new Dataized(trier).take();
MatcherAssert.assertThat(
main.count,
Matchers.equalTo(1)
);
}

/**
* Body object with counter.
* @since 0.36.0
*/
private static class MainWithCounter extends PhDefault {
/**
* Counter.
*/
private int count;

/**
* Ctor.
*/
MainWithCounter() {
super(Phi.Φ);
this.add(
Attr.PHI,
new AtComposite(
this,
rho -> {
++this.count;
return new Data.ToPhi(1L);
}
)
);
}
}

/**
* Main.
* @since 1.0
*/
public static class Main extends PhDefault {
private static class Main extends PhDefault {

/**
* Ctor.
* @param sigma Sigma
*/
public Main(final Phi sigma) {
Main(final Phi sigma) {
super(sigma);
this.add(
"φ",
Expand All @@ -152,12 +195,12 @@ public Main(final Phi sigma) {
* Broken.
* @since 1.0
*/
public static class Broken extends PhDefault {
private static class Broken extends PhDefault {
/**
* Ctor.
* @param sigma Sigma.
*/
public Broken(final Phi sigma) {
Broken(final Phi sigma) {
super(sigma);
this.add(
"φ",
Expand All @@ -175,12 +218,12 @@ public Broken(final Phi sigma) {
* Catcher.
* @since 1.0
*/
public static class Catcher extends PhDefault {
private static class Catcher extends PhDefault {
/**
* Ctor.
* @param sigma Sigma
*/
public Catcher(final Phi sigma) {
Catcher(final Phi sigma) {
super(sigma);
this.add("ex", new AtVoid("ex"));
this.add(
Expand Down

1 comment on commit 9b51532

@0pdd
Copy link

@0pdd 0pdd commented on 9b51532 Mar 31, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Puzzle 2931-5e65ee7f disappeared from eo-runtime/src/test/eo/org/eolang/try-tests.eo), that's why I closed #3011. Please, remember that the puzzle was not necessarily removed in this particular commit. Maybe it happened earlier, but we discovered this fact only now.

Please sign in to comment.