Skip to content

Commit

Permalink
#70: Converted the initial argument to the various Fold ValueExpressi…
Browse files Browse the repository at this point in the history
…ons to SingleValueExpression.
  • Loading branch information
jvdb committed Feb 11, 2019
1 parent b74a111 commit d7543b4
Show file tree
Hide file tree
Showing 6 changed files with 15 additions and 37 deletions.
6 changes: 3 additions & 3 deletions core/src/main/java/io/parsingdata/metal/Shorthand.java
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,11 @@ private Shorthand() {}
public static ValueExpression elvis(final ValueExpression left, final ValueExpression right) { return new Elvis(left, right); }
public static SingleValueExpression count(final ValueExpression operand) { return new Count(operand); }
public static ValueExpression foldLeft(final ValueExpression values, final BinaryOperator<ValueExpression> reducer) { return new FoldLeft(values, reducer, null); }
public static ValueExpression foldLeft(final ValueExpression values, final BinaryOperator<ValueExpression> reducer, final ValueExpression initial) { return new FoldLeft(values, reducer, initial); }
public static ValueExpression foldLeft(final ValueExpression values, final BinaryOperator<ValueExpression> reducer, final SingleValueExpression initial) { return new FoldLeft(values, reducer, initial); }
public static ValueExpression foldRight(final ValueExpression values, final BinaryOperator<ValueExpression> reducer) { return new FoldRight(values, reducer, null); }
public static ValueExpression foldRight(final ValueExpression values, final BinaryOperator<ValueExpression> reducer, final ValueExpression initial) { return new FoldRight(values, reducer, initial); }
public static ValueExpression foldRight(final ValueExpression values, final BinaryOperator<ValueExpression> reducer, final SingleValueExpression initial) { return new FoldRight(values, reducer, initial); }
public static ValueExpression fold(final ValueExpression values, final BinaryOperator<ValueExpression> reducer) { return foldRight(values, reducer); }
public static ValueExpression fold(final ValueExpression values, final BinaryOperator<ValueExpression> reducer, final ValueExpression initial) { return foldRight(values, reducer, initial); }
public static ValueExpression fold(final ValueExpression values, final BinaryOperator<ValueExpression> reducer, final SingleValueExpression initial) { return foldRight(values, reducer, initial); }
public static ValueExpression rev(final ValueExpression values) { return new Reverse(values); }
public static ValueExpression exp(final ValueExpression base, final SingleValueExpression count) { return new Expand(base, count); }
public static BinaryValueExpression mapLeft(final BiFunction<ValueExpression, ValueExpression, BinaryValueExpression> func, final ValueExpression left, final ValueExpression rightExpand) { return func.apply(left, exp(rightExpand, count(left))); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static io.parsingdata.metal.expression.value.NotAValue.NOT_A_VALUE;

import java.util.Objects;
import java.util.Optional;
import java.util.function.BinaryOperator;

import io.parsingdata.metal.Trampoline;
Expand All @@ -36,8 +37,8 @@
* <p>
* Fold has three operands: <code>values</code> (a {@link ValueExpression}),
* <code>reducer</code> (a {@link BinaryOperator}) and <code>initial</code> (a
* {@link ValueExpression}). First <code>initial</code> is evaluated. If it
* does not return a single value, the final result is an empty list. Next,
* {@link SingleValueExpression}). First <code>initial</code> is evaluated. If it
* does not return a valid value, the final result is an empty list. Next,
* <code>values</code> is evaluated and its result is passed to the abstract
* {@link #prepareValues(ImmutableList)} method. The returned list is prefixed
* by the value returned by evaluating <code>initial</code>. On this list, the
Expand All @@ -48,28 +49,28 @@ public abstract class Fold implements ValueExpression {

public final ValueExpression values;
public final BinaryOperator<ValueExpression> reducer;
public final ValueExpression initial;
public final SingleValueExpression initial;

public Fold(final ValueExpression values, final BinaryOperator<ValueExpression> reducer, final ValueExpression initial) {
public Fold(final ValueExpression values, final BinaryOperator<ValueExpression> reducer, final SingleValueExpression initial) {
this.values = checkNotNull(values, "values");
this.reducer = checkNotNull(reducer, "reducer");
this.initial = initial;
}

@Override
public ImmutableList<Value> eval(final ParseState parseState, final Encoding encoding) {
final ImmutableList<Value> initialList = initial != null ? initial.eval(parseState, encoding) : new ImmutableList<>();
if (initialList.size > 1 || (!initialList.isEmpty() && initialList.head.equals(NOT_A_VALUE))) {
final Optional<Value> initialValue = initial != null ? initial.evalSingle(parseState, encoding) : Optional.empty();
if (initialValue.isPresent() && initialValue.get().equals(NOT_A_VALUE)) {
return ImmutableList.create(NOT_A_VALUE);
}
final ImmutableList<Value> unpreparedValues = this.values.eval(parseState, encoding);
if (unpreparedValues.isEmpty()) {
return initialList;
return initialValue.map(ImmutableList::create).orElseGet(ImmutableList::new);
}
if (containsNotAValue(unpreparedValues).computeResult()) {
return ImmutableList.create(NOT_A_VALUE);
}
final ImmutableList<Value> valueList = prepareValues(unpreparedValues).add(initialList);
final ImmutableList<Value> valueList = initialValue.map(value -> prepareValues(unpreparedValues).add(value)).orElseGet(() -> prepareValues(unpreparedValues));
return ImmutableList.create(fold(parseState, encoding, reducer, valueList.head, valueList.tail).computeResult());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
*/
public class FoldLeft extends Fold {

public FoldLeft(final ValueExpression values, final BinaryOperator<ValueExpression> reducer, final ValueExpression initial) {
public FoldLeft(final ValueExpression values, final BinaryOperator<ValueExpression> reducer, final SingleValueExpression initial) {
super(values, reducer, initial);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
*/
public class FoldRight extends Fold {

public FoldRight(final ValueExpression values, final BinaryOperator<ValueExpression> reducer, final ValueExpression initial) {
public FoldRight(final ValueExpression values, final BinaryOperator<ValueExpression> reducer, final SingleValueExpression initial) {
super(values, reducer, initial);
}

Expand Down
2 changes: 1 addition & 1 deletion core/src/test/java/io/parsingdata/metal/ToStringTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ private Token t() {
}

private ValueExpression v() {
return fold(foldLeft(foldRight(rev(bytes(neg(add(div(mod(mul(sub(cat(last(ref(n()))), first(nth(exp(ref(n()), con(NOT_A_VALUE)), con(1)))), sub(CURRENT_ITERATION, con(1))), cat(ref(n()), ref(t()))), add(SELF, add(offset(ref(n())), add(CURRENT_OFFSET, count(ref(n())))))), elvis(ref(n()), ref(n())))))), Shorthand::add, ref(n())), Shorthand::add), Shorthand::add, ref(n()));
return fold(foldLeft(foldRight(rev(bytes(neg(add(div(mod(mul(sub(cat(last(ref(n()))), first(nth(exp(ref(n()), con(NOT_A_VALUE)), con(1)))), sub(CURRENT_ITERATION, con(1))), cat(ref(n()), ref(t()))), add(SELF, add(offset(ref(n())), add(CURRENT_OFFSET, count(ref(n())))))), elvis(ref(n()), ref(n())))))), Shorthand::add, last(ref(n()))), Shorthand::add), Shorthand::add, last(ref(n())));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,29 +83,6 @@ public void inputContainsEmptyInTail() {
assertEquals(NOT_A_VALUE, foldRight((parseState, encoding) -> ImmutableList.create(NOT_A_VALUE).add(new CoreValue(createFromBytes(new byte[] { 1, 2 }), enc())), Shorthand::add).eval(stream(0), enc()).head);
}

@Test
public void multipleInits() {
final Optional<ParseState> parseResult =
seq(
def("init", 1),
def("init", 1),
def("toFold", 1),
def("toFold", 1),
cho(
def("folded", 1, eq(foldLeft(ref("toFold"), Shorthand::add, ref("init")))),
def("folded", 1, eq(foldRight(ref("toFold"), Shorthand::add, ref("init"))))
)
).parse(env(stream(1, 2, 1, 2, 3)));
assertFalse(parseResult.isPresent());
}

@Test
public void twoInits() {
final ImmutableList<Value> result = fold(exp(con(1), con(2)), Shorthand::add, exp(con(1), con(2))).eval(EMPTY_PARSE_STATE, DEFAULT_ENCODING);
assertEquals(1, result.size);
assertEquals(NOT_A_VALUE, result.head);
}

@Test
public void notAValueInit() {
final ImmutableList<Value> result = fold(exp(con(1), con(2)), Shorthand::add, con(NOT_A_VALUE)).eval(EMPTY_PARSE_STATE, DEFAULT_ENCODING);
Expand Down

0 comments on commit d7543b4

Please sign in to comment.