Skip to content

Commit

Permalink
#187: Eliminate use of nulls.
Browse files Browse the repository at this point in the history
Started with the Shorthands.
  • Loading branch information
mvanaken committed Jul 11, 2017
1 parent 24d911c commit 32ff6c6
Show file tree
Hide file tree
Showing 17 changed files with 107 additions and 50 deletions.
69 changes: 35 additions & 34 deletions core/src/main/java/io/parsingdata/metal/Shorthand.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public class ParseGraph implements ParseItem {
public final Token definition;
public final long size;

public static final Token NONE = new Token("NONE", null) {
public static final Token NONE = new Token("NONE", Encoding.DEFAULT) {
@Override protected Optional<Environment> parseImpl(final String scope, final Environment environment, final Encoding encoding) throws IOException { throw new IllegalStateException("This placeholder may not be invoked."); }
@Override public String toString() { return "None"; }
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@

public class Encoding {

public static final Encoding DEFAULT = new Encoding();

public static final Sign DEFAULT_SIGNED = Sign.UNSIGNED;
public static final Charset DEFAULT_CHARSET = StandardCharsets.US_ASCII;
public static final ByteOrder DEFAULT_BYTE_ORDER = ByteOrder.BIG_ENDIAN;
Expand Down Expand Up @@ -54,6 +56,10 @@ public Encoding(final Sign sign, final Charset charset, final ByteOrder byteOrde
this.byteOrder = byteOrder;
}

public boolean isDefault() {
return equals(DEFAULT);
}

@Override
public String toString() {
return getClass().getSimpleName() + "(" + sign + "," + charset + "," + byteOrder + ")";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,23 @@
*/
public abstract class ComparisonExpression implements Expression {

private static final ValueExpression DEFAULT_VALUE_EXPRESSION = (graph, encoding) -> ImmutableList.create(graph.current().map(identity()));

public final ValueExpression value;
public final ValueExpression predicate;

public ComparisonExpression(final ValueExpression value, final ValueExpression predicate) {
this.value = value;
this.value = checkNotNull(value, "value");
this.predicate = checkNotNull(predicate, "predicate");
}

public ComparisonExpression(final ValueExpression predicate) {
this(DEFAULT_VALUE_EXPRESSION, predicate);
}

@Override
public boolean eval(final ParseGraph graph, final Encoding encoding) {
final ImmutableList<Optional<Value>> values = value == null ? ImmutableList.create(graph.current().map(identity())) : value.eval(graph, encoding);
final ImmutableList<Optional<Value>> values = value.eval(graph, encoding);
if (values.isEmpty()) { return false; }
final ImmutableList<Optional<Value>> predicates = predicate.eval(graph, encoding);
if (values.size != predicates.size) { return false; }
Expand All @@ -77,7 +83,7 @@ private SafeTrampoline<Boolean> compare(final ImmutableList<Optional<Value>> cur

@Override
public String toString() {
return getClass().getSimpleName() + "(" + (value == null ? "" : value + ",") + predicate + ")";
return getClass().getSimpleName() + "(" + (value.equals(DEFAULT_VALUE_EXPRESSION) ? "" : value + ",") + predicate + ")";
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ public Eq(final ValueExpression value, final ValueExpression predicate) {
super(value, predicate);
}

public Eq(final ValueExpression predicate) {
super(predicate);
}

@Override
public boolean compare(final Value left, final Value right) {
final byte[] leftBytes = left.getValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public EqNum(final ValueExpression value, final ValueExpression predicate) {
super(value, predicate);
}

public EqNum(final ValueExpression predicate) {
super(predicate);
}

@Override
public boolean compare(final Value left, final Value right) {
return left.asNumeric().compareTo(right.asNumeric()) == 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public EqStr(final ValueExpression value, final ValueExpression predicate) {
super(value, predicate);
}

public EqStr(final ValueExpression predicate) {
super(predicate);
}

@Override
public boolean compare(final Value left, final Value right) {
return left.asString().equals(right.asString());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ public GtNum(final ValueExpression value, final ValueExpression predicate) {
super(value, predicate);
}

public GtNum(final ValueExpression predicate) {
super(predicate);
}

@Override
public boolean compare(final Value left, final Value right) {
return left.asNumeric().compareTo(right.asNumeric()) > 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ public LtNum(final ValueExpression value, final ValueExpression predicate) {
super(value, predicate);
}

public LtNum(final ValueExpression predicate) {
super(predicate);
}

@Override
public boolean compare(final Value left, final Value right) {
return left.asNumeric().compareTo(right.asNumeric()) < 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ public abstract class Fold implements ValueExpression {
public final BinaryOperator<ValueExpression> reducer;
public final ValueExpression initial;

public Fold(final ValueExpression values, final BinaryOperator<ValueExpression> reducer) {
this(values, reducer, (graph, encoding) -> new ImmutableList<>());
}

public Fold(final ValueExpression values, final BinaryOperator<ValueExpression> reducer, final ValueExpression initial) {
this.values = checkNotNull(values, "values");
this.reducer = checkNotNull(reducer, "reducer");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public FoldLeft(final ValueExpression values, final BinaryOperator<ValueExpressi
super(values, reducer, initial);
}

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

@Override
protected ImmutableList<Optional<Value>> prepareValues(final ImmutableList<Optional<Value>> values) {
return reverse(values);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ public FoldRight(final ValueExpression values, final BinaryOperator<ValueExpress
super(values, reducer, initial);
}

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

@Override
protected ImmutableList<Optional<Value>> prepareValues(final ImmutableList<Optional<Value>> values) {
return values;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,31 +51,35 @@ public class Ref<T> implements ValueExpression {
public final Predicate<ParseValue> predicate;
public final ValueExpression limit;

private Ref(final T reference, final Predicate<ParseValue> predicate) {
this(reference, predicate, null);
}

private Ref(final T reference, final Predicate<ParseValue> predicate, final ValueExpression limit) {
this.reference = checkNotNull(reference, "reference");
this.predicate = checkNotNull(predicate, "predicate");
this.limit = limit;
}

public static class NameRef extends Ref<String> {
public NameRef(final String reference) { this(reference, null); }
public NameRef(final String reference) { super(reference, (value) -> value.matches(reference)); }
public NameRef(final String reference, final ValueExpression limit) { super(reference, (value) -> value.matches(reference), limit); }
}

public static class DefinitionRef extends Ref<Token> {
public DefinitionRef(final Token reference) { this(reference, null); }
public DefinitionRef(final Token reference) { super(reference, (value) -> value.definition.equals(reference)); }
public DefinitionRef(final Token reference, final ValueExpression limit) { super(reference, (value) -> value.definition.equals(reference), limit); }
}

@Override
public ImmutableList<Optional<Value>> eval(final ParseGraph graph, final Encoding encoding) {
if (limit == null) { return evalImpl(graph, NO_LIMIT); }
ImmutableList<Optional<Value>> evaluatedLimit = limit.eval(graph, encoding);
if (limit == null) { return evalImpl(graph, predicate, NO_LIMIT);}
final ImmutableList<Optional<Value>> evaluatedLimit = limit.eval(graph, encoding);
if (evaluatedLimit.size != 1 || !evaluatedLimit.head.isPresent()) { throw new IllegalArgumentException("Limit must evaluate to a single non-empty value."); }
return evalImpl(graph, evaluatedLimit.head.get().asNumeric().intValue());
return evalImpl(graph, predicate, evaluatedLimit.head.get().asNumeric().intValue());
}

private ImmutableList<Optional<Value>> evalImpl(final ParseGraph graph, final int limit) {
private static ImmutableList<Optional<Value>> evalImpl(final ParseGraph graph, final Predicate<ParseValue> predicate, final int limit) {
return wrap(getAllValues(graph, predicate, limit), new ImmutableList<Optional<Value>>()).computeResult();
}

Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/io/parsingdata/metal/token/Token.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ public abstract class Token {

protected Token(final String name, final Encoding encoding) {
this.name = checkNotNull(name, "name");
this.encoding = encoding;
this.encoding = checkNotNull(encoding, "encoding");
}

public Optional<Environment> parse(final String scope, final Environment environment, final Encoding encoding) throws IOException {
final Encoding activeEncoding = this.encoding != null ? this.encoding : encoding;
final Encoding activeEncoding = this.encoding.isDefault() ? encoding : this.encoding;
final Optional<Environment> result = parseImpl(makeScope(checkNotNull(scope, "scope")), checkNotNull(environment, "environment"), activeEncoding);
environment.callbacks.handle(this, environment, result);
return result;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
*/
public class TokenRef extends Token {

private static final Token LOOKUP_FAILED = new Token("LOOKUP_FAILED", null) {
private static final Token LOOKUP_FAILED = new Token("LOOKUP_FAILED", Encoding.DEFAULT) {
@Override
protected Optional<Environment> parseImpl(final String scope, final Environment environment, final Encoding encoding) throws IOException {
return failure();
Expand Down
12 changes: 10 additions & 2 deletions core/src/test/java/io/parsingdata/metal/ArgumentsTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static org.junit.Assert.fail;

import static io.parsingdata.metal.Shorthand.con;
import static io.parsingdata.metal.encoding.Encoding.DEFAULT;

import java.io.IOException;
import java.lang.reflect.Constructor;
Expand All @@ -43,6 +44,7 @@
import io.parsingdata.metal.expression.logical.And;
import io.parsingdata.metal.expression.logical.Not;
import io.parsingdata.metal.expression.value.Cat;
import io.parsingdata.metal.expression.value.Fold;
import io.parsingdata.metal.expression.value.FoldLeft;
import io.parsingdata.metal.expression.value.FoldRight;
import io.parsingdata.metal.expression.value.ValueExpression;
Expand Down Expand Up @@ -73,7 +75,7 @@ public class ArgumentsTest {
final private static ValueExpression VALID_VE = con(1);
final private static BinaryOperator<ValueExpression> VALID_REDUCER = (left, right) -> null;
final private static Expression VALID_E = new Expression() { @Override public boolean eval(final ParseGraph graph, final Encoding encoding) { return false; }};
final private static Token VALID_T = new Token("", null) { @Override protected Optional<Environment> parseImpl(final String scope, final Environment environment, final Encoding encoding) throws IOException { return null; } };
final private static Token VALID_T = new Token("", DEFAULT) { @Override protected Optional<Environment> parseImpl(final String scope, final Environment environment, final Encoding encoding) throws IOException { return null; } };

private final Class<?> _class;
private final Object[] _arguments;
Expand Down Expand Up @@ -147,7 +149,13 @@ public ArgumentsTest(final Class<?> argumentsClass, final Object[] arguments) {
@Test
public void runConstructor() throws Throwable {
final Constructor<?>[] constructors = _class.getConstructors();
assertEquals(1, constructors.length);
if (_class.equals(Eq.class) || _class.getSuperclass().equals(Fold.class)) {
assertEquals(2, constructors.length);
}
else {
assertEquals(1, constructors.length);
}

try {
constructors[0].newInstance(_arguments);
fail("Should have thrown an IllegalArgumentException.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class TokenTest {

@Rule
public ExpectedException thrown = ExpectedException.none();
private final Token token = new Token("", null) {
private final Token token = new Token("", Encoding.DEFAULT) {
@Override
protected Optional<Environment> parseImpl(String scope, Environment environment, Encoding encoding) throws IOException {
return null;
Expand Down

0 comments on commit 32ff6c6

Please sign in to comment.