From c8a00b789671d59589bcb5520c1e9d208bcc27f6 Mon Sep 17 00:00:00 2001 From: bculkin2442 Date: Mon, 11 Apr 2016 21:54:44 -0400 Subject: Work on restructing data. --- BJC-Utils2/src/main/java/bjc/utils/data/IPair.java | 26 +- BJC-Utils2/src/main/java/bjc/utils/data/Pair.java | 21 +- .../java/bjc/utils/data/experimental/IHolder.java | 18 +- .../java/bjc/utils/data/experimental/IPair.java | 84 ++++++ .../java/bjc/utils/data/experimental/Identity.java | 82 +++--- .../java/bjc/utils/data/experimental/Lazy.java | 39 ++- .../java/bjc/utils/data/experimental/LazyPair.java | 317 +++++++++++++++++++++ .../java/bjc/utils/data/experimental/Pair.java | 63 ++++ .../main/java/bjc/utils/data/lazy/LazyHolder.java | 2 +- .../main/java/bjc/utils/data/lazy/LazyPair.java | 21 -- .../main/java/bjc/utils/data/lazy/NewLazyPair.java | 202 +++++++++++++ .../bjc/utils/parserutils/TreeConstructor.java | 16 +- 12 files changed, 762 insertions(+), 129 deletions(-) create mode 100644 BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/data/experimental/Pair.java create mode 100644 BJC-Utils2/src/main/java/bjc/utils/data/lazy/NewLazyPair.java (limited to 'BJC-Utils2/src') diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java index a20ff36..98f425f 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/IPair.java @@ -2,7 +2,6 @@ package bjc.utils.data; import java.util.function.BiConsumer; import java.util.function.BiFunction; -import java.util.function.Function; /** * An interface representing a pair of values @@ -14,26 +13,7 @@ import java.util.function.Function; * @param * The type stored in the right side of the pair */ -public interface IPair { - - /** - * Create a new pair by applying the given functions to the left/right. - * Does not change the internal contents of this pair. - * - * @param - * The new left type of the pair - * @param - * The new right type of the pair - * - * @param leftTransformer - * The function to apply to the left value. - * @param rightTransformer - * The function to apply to the right value. - * @return A new pair containing the two modified values. - */ - public IPair apply(Function leftTransformer, - Function rightTransformer); - +public interface IPair { /** * Apply a function to the two internal values that returns a new pair. * @@ -47,8 +27,8 @@ public interface IPair { * The function to use as a bind * @return The new pair */ - public IPair - bind(BiFunction> binder); + public IPair bind( + BiFunction> binder); /** * Execute an action with the values of this pair. Has no effect on the diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java index 03f2eed..87727be 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/Pair.java @@ -2,7 +2,6 @@ package bjc.utils.data; import java.util.function.BiConsumer; import java.util.function.BiFunction; -import java.util.function.Function; /** * Holds a pair of values of two different types. @@ -47,24 +46,6 @@ public class Pair implements IPair { rightValue = right; } - /* - * (non-Javadoc) - * - * @see bjc.utils.data.IPair#apply(java.util.function.Function, - * java.util.function.Function) - */ - @Override - public IPair apply(Function leftTransformer, - Function rightTransformer) { - if (leftTransformer == null || rightTransformer == null) { - throw new NullPointerException( - "Transformers must be non-null"); - } - - return new Pair<>(leftTransformer.apply(leftValue), - rightTransformer.apply(rightValue)); - } - /* * (non-Javadoc) * @@ -110,7 +91,7 @@ public class Pair implements IPair { } else { rightValueString = "(null)"; } - + return "pair[l=" + leftValueString + ", r=" + rightValueString + "]"; } diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java index 2767897..7d1d7a0 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IHolder.java @@ -15,8 +15,11 @@ import java.util.function.UnaryOperator; public interface IHolder { /** * Bind a function across the value in this container - * @param The type of value in this container - * @param binder The function to bind to the value + * + * @param + * The type of value in this container + * @param binder + * The function to bind to the value * @return A holder from binding the value */ public IHolder bind( @@ -82,4 +85,15 @@ public interface IHolder { */ public UnwrappedType unwrap( Function unwrapper); + + /** + * Replace the held value with a new one + * + * @param newValue + * The value to hold instead + * @return The holder itself + */ + public default IHolder replace(ContainedType newValue) { + return transform((oldValue) -> newValue); + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java new file mode 100644 index 0000000..fb9648e --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/IPair.java @@ -0,0 +1,84 @@ +package bjc.utils.data.experimental; + +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * Represents a pair of values + * + * @author ben + * @param + * The type of the left side of the pair + * @param + * The type of the right side of the pair + * + */ +public interface IPair { + /** + * Bind a function to the left value in this pair + * + * @param + * The type of the bound value + * @param leftBinder + * The function to use to bind + * @return A pair with the left type bound + */ + public IPair bindLeft( + Function> leftBinder); + + /** + * Bind a function to the right value in this pair + * + * @param + * The type of the bound value + * @param rightBinder + * The function to use to bind + * @return A pair with the right type bound + */ + public IPair bindRight( + Function> rightBinder); + + /** + * Bind a function across the values in this pair + * + * @param + * The type of the bound left + * @param + * The type of the bound right + * @param binder + * The function to bind with + * @return The bound pair + */ + public IPair bind( + BiFunction> binder); + + /** + * Merge the two values in this pair into a single value + * + * @param + * The type of the single value + * @param merger + * The function to use for merging + * @return The pair, merged into a single value + */ + public MergedType merge( + BiFunction merger); + + /** + * Get the value on the left side of the pair + * + * @return The value on the left side of the pair + */ + public default LeftType getLeft() { + return merge((leftValue, rightValue) -> leftValue); + } + + /** + * Get the value on the right side of the pair + * + * @return The value on the right side of the pair + */ + public default RightType getRight() { + return merge((leftValue, rightValue) -> rightValue); + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java index 3cf0987..1780f2d 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Identity.java @@ -42,29 +42,32 @@ public class Identity implements IHolder { return binder.apply(heldValue); } + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ @Override - public IHolder map( - Function mapper) { - return new Identity<>(mapper.apply(heldValue)); - } - - @Override - public IHolder transform( - UnaryOperator transformer) { - heldValue = transformer.apply(heldValue); + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (obj == null) { + return false; + } else if (getClass() != obj.getClass()) { + return false; + } - return this; - } + Identity other = (Identity) obj; - @Override - public UnwrappedType unwrap( - Function unwrapper) { - return unwrapper.apply(heldValue); - } + if (heldValue == null) { + if (other.heldValue != null) { + return false; + } + } else if (!heldValue.equals(other.heldValue)) { + return false; + } - @Override - public String toString() { - return "holding[v=" + heldValue + "]"; + return true; } /* @@ -85,31 +88,28 @@ public class Identity implements IHolder { return result; } - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } else if (obj == null) { - return false; - } else if (getClass() != obj.getClass()) { - return false; - } + public IHolder map( + Function mapper) { + return new Identity<>(mapper.apply(heldValue)); + } - Identity other = (Identity) obj; + @Override + public String toString() { + return "holding[v=" + heldValue + "]"; + } - if (heldValue == null) { - if (other.heldValue != null) { - return false; - } - } else if (!heldValue.equals(other.heldValue)) { - return false; - } + @Override + public IHolder transform( + UnaryOperator transformer) { + heldValue = transformer.apply(heldValue); - return true; + return this; + } + + @Override + public UnwrappedType unwrap( + Function unwrapper) { + return unwrapper.apply(heldValue); } } \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java index e919fec..0d6fcef 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Lazy.java @@ -26,8 +26,7 @@ public class Lazy implements IHolder { private boolean holderBound; - private IFunctionalList> actions = - new FunctionalList<>(); + private IFunctionalList> actions = new FunctionalList<>(); public BoundLazy(Supplier> supp, Function> binder) { @@ -38,8 +37,7 @@ public class Lazy implements IHolder { @Override public IHolder bind( Function> bindr) { - IFunctionalList> pendingActions = - new FunctionalList<>(); + IFunctionalList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); @@ -62,8 +60,7 @@ public class Lazy implements IHolder { @Override public IHolder map( Function mapper) { - IFunctionalList> pendingActions = - new FunctionalList<>(); + IFunctionalList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); @@ -101,12 +98,19 @@ public class Lazy implements IHolder { return boundHolder.unwrap(unwrapper); } + @Override + public String toString() { + if (holderBound) { + return boundHolder.toString(); + } + + return "(unmaterialized)"; + } } private Supplier valueSupplier; - private IFunctionalList> actions = - new FunctionalList<>(); + private IFunctionalList> actions = new FunctionalList<>(); private boolean valueMaterialized; @@ -146,8 +150,7 @@ public class Lazy implements IHolder { @Override public IHolder bind( Function> binder) { - IFunctionalList> pendingActions = - new FunctionalList<>(); + IFunctionalList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); @@ -167,8 +170,7 @@ public class Lazy implements IHolder { @Override public IHolder map( Function mapper) { - IFunctionalList> pendingActions = - new FunctionalList<>(); + IFunctionalList> pendingActions = new FunctionalList<>(); actions.forEach(pendingActions::add); @@ -210,4 +212,17 @@ public class Lazy implements IHolder { return unwrapper.apply(heldValue); } + + @Override + public String toString() { + if (valueMaterialized) { + if (actions.isEmpty()) { + return "value[v='" + heldValue + "']"; + } + + return "value[v='" + heldValue + "'] (has pending transforms)"; + } + + return "(unmaterialized)"; + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java new file mode 100644 index 0000000..04a4b61 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/LazyPair.java @@ -0,0 +1,317 @@ +package bjc.utils.data.experimental; + +import java.util.function.BiFunction; +import java.util.function.Function; +import java.util.function.Supplier; + +/** + * A lazy implementation of a pair + * + * @author ben + * + * @param + * The type on the left side of the pair + * @param + * The type on the right side of the pair + */ +public class LazyPair + implements IPair { + private static class HalfBoundLazyPair + implements IPair { + private Supplier oldSupplier; + + private Function> binder; + + private IPair boundPair; + private boolean pairBound; + + public HalfBoundLazyPair(Supplier oldSupp, + Function> bindr) { + oldSupplier = oldSupp; + binder = bindr; + } + + @Override + public IPair bindLeft( + Function> leftBinder) { + Supplier leftSupp = () -> { + IPair newPair = boundPair; + + if (!pairBound) { + newPair = binder.apply(oldSupplier.get()); + } + + return newPair.getLeft(); + }; + + return new HalfBoundLazyPair<>(leftSupp, leftBinder); + } + + @Override + public IPair bindRight( + Function> rightBinder) { + Supplier rightSupp = () -> { + IPair newPair = boundPair; + + if (!pairBound) { + newPair = binder.apply(oldSupplier.get()); + } + + return newPair.getRight(); + }; + + return new HalfBoundLazyPair<>(rightSupp, rightBinder); + } + + @Override + public IPair bind( + BiFunction> bindr) { + IHolder> newPair = new Identity<>( + boundPair); + IHolder newPairMade = new Identity<>(pairBound); + + Supplier leftSupp = () -> { + if (!newPairMade.getValue()) { + newPair.replace(binder.apply(oldSupplier.get())); + newPairMade.replace(true); + } + + return newPair.unwrap((pair) -> pair.getLeft()); + }; + + Supplier rightSupp = () -> { + if (!newPairMade.getValue()) { + newPair.replace(binder.apply(oldSupplier.get())); + newPairMade.replace(true); + } + + return newPair.unwrap((pair) -> pair.getRight()); + }; + + return new BoundLazyPair<>(leftSupp, rightSupp, bindr); + } + + @Override + public MergedType merge( + BiFunction merger) { + if (!pairBound) { + boundPair = binder.apply(oldSupplier.get()); + + pairBound = true; + } + + return boundPair.merge(merger); + } + } + + private static class BoundLazyPair + implements IPair { + private Supplier leftSupplier; + private Supplier rightSupplier; + + private BiFunction> binder; + + private IPair boundPair; + + private boolean pairBound; + + public BoundLazyPair(Supplier leftSupp, + Supplier rightSupp, + BiFunction> bindr) { + leftSupplier = leftSupp; + rightSupplier = rightSupp; + binder = bindr; + } + + @Override + public IPair bindLeft( + Function> leftBinder) { + Supplier leftSupp = () -> { + IPair newPair = boundPair; + + if (!pairBound) { + newPair = binder.apply(leftSupplier.get(), + rightSupplier.get()); + } + + return newPair.getLeft(); + }; + + return new HalfBoundLazyPair<>(leftSupp, leftBinder); + } + + @Override + public IPair bindRight( + Function> rightBinder) { + Supplier rightSupp = () -> { + IPair newPair = boundPair; + + if (!pairBound) { + newPair = binder.apply(leftSupplier.get(), + rightSupplier.get()); + } + + return newPair.getRight(); + }; + + return new HalfBoundLazyPair<>(rightSupp, rightBinder); + } + + @Override + public IPair bind( + BiFunction> bindr) { + IHolder> newPair = new Identity<>( + boundPair); + IHolder newPairMade = new Identity<>(pairBound); + + return new BoundLazyPair<>(() -> { + if (!newPairMade.getValue()) { + newPair.replace(binder.apply(leftSupplier.get(), + rightSupplier.get())); + + newPairMade.replace(false); + } + + return newPair.unwrap((pair) -> pair.getLeft()); + }, () -> { + if (!newPairMade.getValue()) { + newPair.replace(binder.apply(leftSupplier.get(), + rightSupplier.get())); + + newPairMade.replace(false); + } + + return newPair.unwrap((pair) -> pair.getRight()); + }, bindr); + } + + @Override + public MergedType merge( + BiFunction merger) { + if (!pairBound) { + boundPair = binder.apply(leftSupplier.get(), + rightSupplier.get()); + + pairBound = true; + } + + return boundPair.merge(merger); + } + } + + private LeftType leftValue; + private RightType rightValue; + + private Supplier leftSupplier; + private Supplier rightSupplier; + + private boolean leftMaterialized; + private boolean rightMaterialized; + + /** + * Create a new lazy pair, using the set value s + * + * @param leftVal + * The value for the left side of the pair + * @param rightVal + * The value for the right side of the pair + */ + public LazyPair(LeftType leftVal, RightType rightVal) { + leftValue = leftVal; + rightValue = rightVal; + + leftMaterialized = true; + rightMaterialized = true; + } + + /** + * Create a new lazy pair from the given value sources + * + * @param leftSupp + * The source for a value on the left side of the pair + * @param rightSupp + * The source for a value on the right side of the pair + */ + public LazyPair(Supplier leftSupp, + Supplier rightSupp) { + leftSupplier = leftSupp; + rightSupplier = rightSupp; + + leftMaterialized = false; + rightMaterialized = false; + } + + @Override + public IPair bindLeft( + Function> leftBinder) { + Supplier leftSupp = () -> { + if (leftMaterialized) { + return leftValue; + } + + return leftSupplier.get(); + }; + + return new HalfBoundLazyPair<>(leftSupp, leftBinder); + } + + @Override + public IPair bindRight( + Function> rightBinder) { + Supplier rightSupp = () -> { + if (rightMaterialized) { + return rightValue; + } + + return rightSupplier.get(); + }; + + return new HalfBoundLazyPair<>(rightSupp, rightBinder); + } + + @Override + public IPair bind( + BiFunction> binder) { + return new BoundLazyPair<>(leftSupplier, rightSupplier, binder); + } + + @Override + public MergedType merge( + BiFunction merger) { + if (!leftMaterialized) { + leftValue = leftSupplier.get(); + + leftMaterialized = true; + } + + if (!rightMaterialized) { + rightValue = rightSupplier.get(); + + rightMaterialized = true; + } + + return merger.apply(leftValue, rightValue); + } + + @Override + public LeftType getLeft() { + if (!leftMaterialized) { + leftValue = leftSupplier.get(); + + leftMaterialized = true; + } + + return leftValue; + } + + @Override + public RightType getRight() { + if (!rightMaterialized) { + rightValue = rightSupplier.get(); + + rightMaterialized = true; + } + + return rightValue; + } +} diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Pair.java b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Pair.java new file mode 100644 index 0000000..87378d7 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/experimental/Pair.java @@ -0,0 +1,63 @@ +package bjc.utils.data.experimental; + +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * A pair of values, with nothing special about them. + * + * @author ben + * + * @param + * The type of the left value + * @param + * The type of the right value + */ +public class Pair + implements IPair { + private LeftType leftValue; + private RightType rightValue; + + /** + * Create a new pair with both sides set to null + */ + public Pair() { + } + + /** + * Create a new pair with both sides set to the specified values + * + * @param left + * The value of the left side + * @param right + * The value of the right side + */ + public Pair(LeftType left, RightType right) { + leftValue = left; + rightValue = right; + } + + @Override + public IPair bindLeft( + Function> leftBinder) { + return leftBinder.apply(leftValue); + } + + @Override + public IPair bindRight( + Function> rightBinder) { + return rightBinder.apply(rightValue); + } + + @Override + public IPair bind( + BiFunction> binder) { + return binder.apply(leftValue, rightValue); + } + + @Override + public MergedType merge( + BiFunction merger) { + return merger.apply(leftValue, rightValue); + } +} \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java index 85b7493..141d558 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyHolder.java @@ -171,7 +171,7 @@ public class LazyHolder implements IHolder, ILazy { * The value held in the holder */ public LazyHolder(T value) { - heldValue = value; + heldSource = () -> value; } @Override diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyPair.java index 70f5478..dcaeeba 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyPair.java +++ b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/LazyPair.java @@ -2,7 +2,6 @@ package bjc.utils.data.lazy; import java.util.function.BiConsumer; import java.util.function.BiFunction; -import java.util.function.Function; import java.util.function.Supplier; import bjc.utils.data.IHolder; @@ -85,26 +84,6 @@ public class LazyPair implements IPair, ILazy { delegatePair = delegate; } - /* - * (non-Javadoc) - * - * @see bjc.utils.data.IPair#apply(java.util.function.Function, - * java.util.function.Function) - */ - @Override - public IPair apply(Function leftTransform, - Function rightTransform) { - if (leftTransform == null || rightTransform == null) { - throw new NullPointerException("Transforms must be non-null"); - } - - IHolder> newPair = delegatePair - .map((currentPair) -> currentPair.apply(leftTransform, - rightTransform)); - - return new LazyPair<>(newPair, materialized, true); - } - /* * (non-Javadoc) * diff --git a/BJC-Utils2/src/main/java/bjc/utils/data/lazy/NewLazyPair.java b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/NewLazyPair.java new file mode 100644 index 0000000..4bd3832 --- /dev/null +++ b/BJC-Utils2/src/main/java/bjc/utils/data/lazy/NewLazyPair.java @@ -0,0 +1,202 @@ +package bjc.utils.data.lazy; + +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Supplier; + +import bjc.utils.data.GenHolder; +import bjc.utils.data.IPair; +import bjc.utils.funcdata.FunctionalList; +import bjc.utils.funcdata.IFunctionalList; + +/** + * New implementation of lazy pair not delegating to {@link LazyHolder} + * + * @author ben + * @param + * The type on the left side of the pair + * @param + * The type on the right side of the pair + * + */ +public class NewLazyPair implements IPair, ILazy { + private static class BoundLazyPair + implements IPair { + private Supplier oldLeftSupplier; + private Supplier oldRightSupplier; + + private BiFunction> newPairSupplier; + + private IPair newPair; + + private boolean newPairMaterialized; + + public BoundLazyPair(Supplier leftSup, + Supplier rightSup, + BiFunction> binder) { + oldLeftSupplier = leftSup; + oldRightSupplier = rightSup; + + newPairSupplier = binder; + } + + @Override + public IPair bind( + BiFunction> binder) { + // TODO Auto-generated method stub + return null; + } + + @Override + public void doWith(BiConsumer action) { + // TODO Auto-generated method stub + + } + + @Override + public E merge(BiFunction merger) { + if (!newPairMaterialized) { + newPair = newPairSupplier.apply(oldLeftSupplier.get(), + oldRightSupplier.get()); + } + + return newPair.merge(merger); + } + } + + private L leftValue; + private R rightValue; + + private Supplier rightValueSupplier; + private Supplier leftValueSupplier; + + private boolean rightMaterialized; + private boolean leftMaterialized; + + private IFunctionalList> actions; + + /** + * Create a new lazy pair + * + * @param leftVal + * The left value in the pair + * @param rightVal + * The right value in the pair + */ + public NewLazyPair(L leftVal, R rightVal) { + leftValueSupplier = () -> leftVal; + rightValueSupplier = () -> rightVal; + } + + /** + * Create a new lazy pair + * + * @param leftSupplier + * The supplier for the left value in the pair + * @param rightSupplier + * The supplier for the right value in the pair + */ + public NewLazyPair(Supplier leftSupplier, + Supplier rightSupplier) { + leftValueSupplier = leftSupplier; + rightValueSupplier = rightSupplier; + } + + @Override + public void applyPendingActions() { + if (!isMaterialized()) { + throw new UnsupportedOperationException( + "Can only apply actions to materialized values"); + } + + actions.forEach((action) -> { + action.accept(leftValue, rightValue); + }); + + actions = new FunctionalList<>(); + } + + private void applyPossiblyPendingActions(GenHolder hasActions, + IFunctionalList> pendingActions) { + if (hasActions.unwrap((val) -> val) == true) { + pendingActions.forEach((action) -> { + action.accept(leftValue, rightValue); + }); + + hasActions.transform((val) -> false); + } + } + + @Override + public IPair bind( + BiFunction> binder) { + GenHolder hasActions = new GenHolder<>(true); + IFunctionalList> pendingActions = new FunctionalList<>(); + + actions.forEach(pendingActions::add); + + return new BoundLazyPair<>(() -> { + applyPossiblyPendingActions(hasActions, pendingActions); + + return leftValue; + }, () -> { + applyPossiblyPendingActions(hasActions, pendingActions); + + return rightValue; + }, binder); + } + + @Override + public void doWith(BiConsumer action) { + actions.add(action); + } + + @Override + public boolean hasPendingActions() { + return !actions.isEmpty(); + } + + @Override + public boolean isMaterialized() { + if (leftValueSupplier == null) { + if (rightValueSupplier == null) { + return true; + } + + return rightMaterialized; + } + + if (rightValueSupplier == null) { + return leftMaterialized; + } + + return leftMaterialized && rightMaterialized; + } + + @Override + public void materialize() { + if (isMaterialized()) { + throw new UnsupportedOperationException( + "Cannot materialize lazy object twice"); + } + + if (leftValueSupplier != null) { + leftValue = leftValueSupplier.get(); + } + + if (rightValueSupplier != null) { + rightValue = rightValueSupplier.get(); + } + } + + @Override + public E merge(BiFunction merger) { + if (!isMaterialized()) { + materialize(); + } + + applyPendingActions(); + + return merger.apply(leftValue, rightValue); + } +} \ No newline at end of file diff --git a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java index 68ec70e..3252351 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java +++ b/BJC-Utils2/src/main/java/bjc/utils/parserutils/TreeConstructor.java @@ -7,6 +7,7 @@ import java.util.function.Function; import java.util.function.Predicate; import bjc.utils.data.GenHolder; +import bjc.utils.data.IHolder; import bjc.utils.data.IPair; import bjc.utils.data.Pair; import bjc.utils.funcdata.IFunctionalList; @@ -45,8 +46,7 @@ public class TreeConstructor { if (queuedASTs.size() < 2) { throw new IllegalStateException( "Attempted to parse binary operator without enough operands.\n" - + "Problem operator is " - + element + + "Problem operator is " + element + "\nPossible operand is: \n\t" + queuedASTs.peek()); } @@ -63,13 +63,13 @@ public class TreeConstructor { } } - private GenHolder>, AST>> initialState; + private IHolder>, AST>> initialState; private Predicate operatorPredicate; private Predicate isSpecialOperator; private Function>, AST> handleSpecialOperator; public TokenTransformer( - GenHolder>, AST>> initialState, + IHolder>, AST>> initialState, Predicate operatorPredicate, Predicate isSpecialOperator, Function>, AST> handleSpecialOperator) { @@ -93,10 +93,8 @@ public class TreeConstructor { }); initialState.transform((pair) -> { - return pair.apply((Deque> queue) -> { - return queue; - }, (AST currentAST) -> { - return newAST; + return pair.bind((queue, currentAST) -> { + return new Pair<>(queue, newAST); }); }); } @@ -160,7 +158,7 @@ public class TreeConstructor { "Special operator determiner must not be null"); } - GenHolder>, AST>> initialState = new GenHolder<>( + IHolder>, AST>> initialState = new GenHolder<>( new Pair<>(new LinkedList<>(), null)); tokens.forEach( -- cgit v1.2.3