Skip to content

Commit

Permalink
#162: Converted token.TokenRef's lookup() method to be tail call recu…
Browse files Browse the repository at this point in the history
…rsive.
  • Loading branch information
jvdb committed Jun 5, 2017
1 parent 37ed720 commit 4a1d6b2
Showing 1 changed file with 9 additions and 10 deletions.
19 changes: 9 additions & 10 deletions core/src/main/java/io/parsingdata/metal/token/TokenRef.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import io.parsingdata.metal.SafeTrampoline;
import io.parsingdata.metal.data.Environment;
import io.parsingdata.metal.data.ImmutableList;
import io.parsingdata.metal.data.ParseItem;
import io.parsingdata.metal.encoding.Encoding;

Expand Down Expand Up @@ -63,22 +64,20 @@ public TokenRef(final String name, final String referenceName, final Encoding en

@Override
protected Optional<Environment> parseImpl(final String scope, final Environment environment, final Encoding encoding) throws IOException {
return lookup(environment.order, referenceName).computeResult().parse(scope, environment, encoding);
return lookup(ImmutableList.create(environment.order), referenceName).computeResult().parse(scope, environment, encoding);
}

private SafeTrampoline<Token> lookup(final ParseItem item, final String referenceName) {
if (item.getDefinition().name.equals(referenceName)) {
return complete(item::getDefinition);
}
if (!item.isGraph() || item.asGraph().isEmpty()) { return complete(() -> LOOKUP_FAILED); }
final Token headResult = lookup(item.asGraph().head, referenceName).computeResult();
if (headResult != LOOKUP_FAILED) { return complete(() -> headResult); }
return intermediate(() -> lookup(item.asGraph().tail, referenceName));
private SafeTrampoline<Token> lookup(final ImmutableList<ParseItem> items, final String referenceName) {
if (items.isEmpty()) { return complete(() -> LOOKUP_FAILED); }
final ParseItem item = items.head;
if (item.getDefinition().name.equals(referenceName)) { return complete(item::getDefinition); }
if (item.isGraph() && !item.asGraph().isEmpty()) { return intermediate(() -> lookup(items.tail.add(item.asGraph().tail).add(item.asGraph().head), referenceName)); }
return intermediate(() -> lookup(items.tail, referenceName));
}

@Override
public Token getCanonical(final Environment environment) {
return lookup(environment.order, referenceName).computeResult();
return lookup(ImmutableList.create(environment.order), referenceName).computeResult();
}

@Override
Expand Down

0 comments on commit 4a1d6b2

Please sign in to comment.