Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace Cases with enum Tag and switch statements #99

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions nabl2.terms/src/main/java/mb/nabl2/terms/IApplTerm.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ public interface IApplTerm extends ITerm {

@Override IApplTerm withAttachments(IAttachments value);

@Override default Tag termTag() {
return Tag.IApplTerm;
}
}
4 changes: 4 additions & 0 deletions nabl2.terms/src/main/java/mb/nabl2/terms/IBlobTerm.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ public interface IBlobTerm extends ITerm {
@Override
IBlobTerm withAttachments(IAttachments value);

@Override default Tag termTag() {
return Tag.IBlobTerm;
}

}
7 changes: 7 additions & 0 deletions nabl2.terms/src/main/java/mb/nabl2/terms/IConsTerm.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,11 @@ public interface IConsTerm extends IListTerm {
@Override
IConsTerm withAttachments(IAttachments value);

@Override default ITerm.Tag termTag() {
return ITerm.Tag.IConsTerm;
}

@Override default IListTerm.Tag listTermTag() {
return IListTerm.Tag.IConsTerm;
}
}
4 changes: 4 additions & 0 deletions nabl2.terms/src/main/java/mb/nabl2/terms/IIntTerm.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ public interface IIntTerm extends ITerm {
@Override
IIntTerm withAttachments(IAttachments value);

@Override default Tag termTag() {
return Tag.IIntTerm;
}

}
8 changes: 8 additions & 0 deletions nabl2.terms/src/main/java/mb/nabl2/terms/IListTerm.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,12 @@ default T apply(IListTerm list) throws E {
@Override
IListTerm withAttachments(IAttachments value);

Tag listTermTag();

enum Tag {
IConsTerm,
INilTerm,
ITermVar
}

}
8 changes: 8 additions & 0 deletions nabl2.terms/src/main/java/mb/nabl2/terms/INilTerm.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,12 @@ public interface INilTerm extends IListTerm {
@Override
INilTerm withAttachments(IAttachments value);

@Override default ITerm.Tag termTag() {
return ITerm.Tag.INilTerm;
}

@Override default IListTerm.Tag listTermTag() {
return IListTerm.Tag.INilTerm;
}

}
4 changes: 4 additions & 0 deletions nabl2.terms/src/main/java/mb/nabl2/terms/IStringTerm.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,8 @@ public interface IStringTerm extends ITerm {
@Override
IStringTerm withAttachments(IAttachments value);

@Override default Tag termTag() {
return Tag.IStringTerm;
}

}
20 changes: 16 additions & 4 deletions nabl2.terms/src/main/java/mb/nabl2/terms/ITerm.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ interface Cases<T> {

T caseAppl(IApplTerm appl);

T caseList(IListTerm cons);
T caseList(IListTerm list);

T caseString(IStringTerm string);

T caseInt(IIntTerm integer);

T caseBlob(IBlobTerm integer);
T caseBlob(IBlobTerm blob);

T caseVar(ITermVar var);

Expand All @@ -48,13 +48,13 @@ interface CheckedCases<T, E extends Throwable> {

T caseAppl(IApplTerm appl) throws E;

T caseList(IListTerm cons) throws E;
T caseList(IListTerm list) throws E;

T caseString(IStringTerm string) throws E;

T caseInt(IIntTerm integer) throws E;

T caseBlob(IBlobTerm integer) throws E;
T caseBlob(IBlobTerm blob) throws E;

T caseVar(ITermVar var) throws E;

Expand All @@ -64,4 +64,16 @@ default T caseLock(ITerm term) throws E {

}

Tag termTag();

enum Tag {
IApplTerm,
IConsTerm,
INilTerm,
IStringTerm,
IIntTerm,
IBlobTerm,
ITermVar,
}

}
8 changes: 8 additions & 0 deletions nabl2.terms/src/main/java/mb/nabl2/terms/ITermVar.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,12 @@ public interface ITermVar extends ITerm, IListTerm, Comparable<ITermVar> {
return c;
}

@Override default ITerm.Tag termTag() {
return ITerm.Tag.ITermVar;
}

@Override default IListTerm.Tag listTermTag() {
return IListTerm.Tag.ITermVar;
}

}
16 changes: 14 additions & 2 deletions nabl2.terms/src/main/java/mb/nabl2/terms/ListTerms.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,20 @@ public IListTerm.CheckedCases<T, E> otherwise(final CheckedFunction1<? super ILi
}

public static String toString(IListTerm list) {
return list
.match(cases(cons -> toStringTail(cons.getHead(), cons.getTail()), nil -> "[]", var -> var.toString()));
switch(list.listTermTag()) {
case IConsTerm: {
IConsTerm cons = (IConsTerm) list;
return toStringTail(cons.getHead(), cons.getTail());
}
case INilTerm: {
return "[]";
}
case ITermVar: {
return list.toString();
}
}
// N.B. don't use this in default case branch, instead use IDE to catch non-exhaustive switch statements
throw new RuntimeException("Missing case for IListTerm subclass/tag");
}

private static String toStringTail(ITerm head, IListTerm tail) {
Expand Down
34 changes: 21 additions & 13 deletions nabl2.terms/src/main/java/mb/nabl2/terms/build/AConsTerm.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
import org.immutables.value.Value;
import org.metaborg.util.collection.CapsuleUtil;
import org.metaborg.util.functions.Action1;
import org.metaborg.util.functions.Function2;

import io.usethesource.capsule.Set;
import mb.nabl2.terms.IConsTerm;
import mb.nabl2.terms.IListTerm;
import mb.nabl2.terms.INilTerm;
import mb.nabl2.terms.ITerm;
import mb.nabl2.terms.ITermVar;
import mb.nabl2.terms.ListTerms;

@Value.Immutable(lazyhash = false)
@Serial.Version(value = 42L)
Expand Down Expand Up @@ -94,23 +95,30 @@ abstract class AConsTerm extends AbstractTerm implements IConsTerm {
StringBuilder sb = new StringBuilder();
sb.append("[");
sb.append(getHead());
getTail().match(ListTerms.casesFix(
// @formatter:off
(f,cons) -> {
toString(getTail(), sb);
sb.append("]");
return sb.toString();
}

private static void toString(IListTerm subj, StringBuilder sb) {
switch(subj.listTermTag()) {
case IConsTerm: { IConsTerm cons = (IConsTerm) subj;
sb.append(",");
sb.append(cons.getHead());
return cons.getTail().match(f);
},
(f,nil) -> unit,
(f,var) -> {
toString(cons.getTail(), sb);
break;
}

case INilTerm: {
break;
}

case ITermVar: { ITermVar var = (ITermVar) subj;
sb.append("|");
sb.append(var);
return unit;
break;
}
// @formatter:on
));
sb.append("]");
return sb.toString();
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
import java.util.Iterator;
import java.util.NoSuchElementException;

import org.metaborg.util.functions.Function1;

import mb.nabl2.terms.IConsTerm;
import mb.nabl2.terms.IListTerm;
import mb.nabl2.terms.INilTerm;
import mb.nabl2.terms.ITerm;
import mb.nabl2.terms.ListTerms;
import mb.nabl2.terms.ITermVar;

public class ListTermIterator implements Iterator<ITerm> {

Expand All @@ -16,20 +20,42 @@ public ListTermIterator(IListTerm list) {
}

@Override public boolean hasNext() {
return current.match(ListTerms.cases(cons -> true, nil -> false, var -> {
throw new IllegalStateException("Cannot iterate over a non-ground list.");
}));
IListTerm subj = current;
switch(subj.listTermTag()) {
case IConsTerm: {
return true;
}

case INilTerm: {
return false;
}

case ITermVar: {
throw new IllegalStateException("Cannot iterate over a non-ground list.");
}
}
// N.B. don't use this in default case branch, instead use IDE to catch non-exhaustive switch statements
throw new RuntimeException("Missing case for IListTerm subclass/tag");
}

@Override public ITerm next() {
return current.match(ListTerms.cases(cons -> {
current = cons.getTail();
return cons.getHead();
}, nil -> {
throw new NoSuchElementException();
}, var -> {
throw new IllegalStateException("Cannot iterate over a non-ground list.");
}));
IListTerm subj = current;
switch(subj.listTermTag()) {
case IConsTerm: { IConsTerm cons = (IConsTerm) subj;
current = cons.getTail();
return cons.getHead();
}

case INilTerm: {
throw new NoSuchElementException();
}

case ITermVar: {
throw new IllegalStateException("Cannot iterate over a non-ground list.");
}
}
// N.B. don't use this in default case branch, instead use IDE to catch non-exhaustive switch statements
throw new RuntimeException("Missing case for IListTerm subclass/tag");
}

}
35 changes: 25 additions & 10 deletions nabl2.terms/src/main/java/mb/nabl2/terms/matching/ApplPattern.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@
import com.google.common.collect.ImmutableList;

import io.usethesource.capsule.Set;
import mb.nabl2.terms.IApplTerm;
import mb.nabl2.terms.IAttachments;
import mb.nabl2.terms.IBlobTerm;
import mb.nabl2.terms.IIntTerm;
import mb.nabl2.terms.IListTerm;
import mb.nabl2.terms.IStringTerm;
import mb.nabl2.terms.ITerm;
import mb.nabl2.terms.ITermVar;
import mb.nabl2.terms.Terms;
Expand Down Expand Up @@ -57,22 +62,32 @@ public List<Pattern> getArgs() {

@Override protected boolean matchTerm(ITerm term, ISubstitution.Transient subst, IUnifier.Immutable unifier,
Eqs eqs) {
// @formatter:off
return unifier.findTerm(term).match(Terms.<Boolean>cases()
.appl(applTerm -> {
if(applTerm.getArity() == this.args.size() && applTerm.getOp().equals(op)) {
final ApplPattern pattern = this;
ITerm subj = unifier.findTerm(term);
switch(subj.termTag()) {
case IApplTerm: { IApplTerm applTerm = (IApplTerm) subj;
if(applTerm.getArity() == pattern.args.size() && applTerm.getOp().equals(op)) {
return matchTerms(args, applTerm.getArgs(), subst, unifier, eqs);
} else {
return false;
}
}).var(v -> {
eqs.add(v, this);
}

case ITermVar: { ITermVar v = (ITermVar) subj;
eqs.add(v, pattern);
return true;
}).otherwise(t -> {
}

case IConsTerm:
case INilTerm:
case IStringTerm:
case IIntTerm:
case IBlobTerm: {
return false;
})
);
// @formatter:on
}
}
// N.B. don't use this in default case branch, instead use IDE to catch non-exhaustive switch statements
throw new RuntimeException("Missing case for ITerm subclass/tag");
}

@Override public Pattern apply(IRenaming subst) {
Expand Down
Loading