Refactor list parsing code
This commit is contained in:
parent
a8d8d6696c
commit
f3923cadc0
|
@ -15,7 +15,7 @@ public class LeftParenthesis extends Token {
|
||||||
public SExpression parseSExpression(Supplier<Token> getNextToken) {
|
public SExpression parseSExpression(Supplier<Token> getNextToken) {
|
||||||
Token nextToken = getNextToken.get();
|
Token nextToken = getNextToken.get();
|
||||||
|
|
||||||
return nextToken.parseSExpressionTail(getNextToken);
|
return nextToken.parseListTail(getNextToken).invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package token;
|
package token;
|
||||||
|
|
||||||
import static recursion.TailCalls.done;
|
import static recursion.TailCalls.done;
|
||||||
|
import static sexpression.Nil.NIL;
|
||||||
|
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
@ -22,8 +23,13 @@ public class RightParenthesis extends Token {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TailCall<Cons> parseListBackwards(Cons accumulator, Supplier<Token> getNextToken) {
|
protected TailCall<Cons> parseListTail(Supplier<Token> getNextToken) {
|
||||||
return done(accumulator);
|
return done(NIL);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TailCall<Cons> parseListTailRecursive(Cons start, Cons end, Supplier<Token> getNextToken) {
|
||||||
|
return done(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class StartsWithRightParenthesisException extends LineColumnException {
|
public static class StartsWithRightParenthesisException extends LineColumnException {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package token;
|
package token;
|
||||||
|
|
||||||
import static recursion.TailCalls.done;
|
|
||||||
import static recursion.TailCalls.tailCall;
|
import static recursion.TailCalls.tailCall;
|
||||||
import static sexpression.Nil.NIL;
|
import static sexpression.Nil.NIL;
|
||||||
|
|
||||||
|
@ -31,36 +30,27 @@ public abstract class Token {
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
// s-expression
|
// s-expression
|
||||||
// ::= NUMBER | IDENTIFIER | STRING | QUOTE_MARK s-expression | LEFT_PAREN s-expression-tail
|
// ::= NUMBER | IDENTIFIER | STRING | QUOTE_MARK s-expression | LEFT_PAREN list-tail
|
||||||
//
|
//
|
||||||
// s-expression-tail
|
// list-tail
|
||||||
// ::= RIGHT_PAREN | s-expression s-expression-tail
|
// ::= RIGHT_PAREN | s-expression list-tail
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
public abstract SExpression parseSExpression(Supplier<Token> getNextToken);
|
public abstract SExpression parseSExpression(Supplier<Token> getNextToken);
|
||||||
|
|
||||||
public SExpression parseSExpressionTail(Supplier<Token> getNextToken) {
|
protected TailCall<Cons> parseListTail(Supplier<Token> getNextToken) {
|
||||||
Cons backwardsList = parseListBackwards(NIL, getNextToken).invoke();
|
Cons firstCons = new Cons(parseSExpression(getNextToken), NIL);
|
||||||
|
|
||||||
return reverse(NIL, backwardsList).invoke();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TailCall<Cons> parseListBackwards(Cons accumulator, Supplier<Token> getNextToken) {
|
|
||||||
Cons nextAccumulator = new Cons(parseSExpression(getNextToken), accumulator);
|
|
||||||
Token next = getNextToken.get();
|
Token next = getNextToken.get();
|
||||||
|
|
||||||
return tailCall(() -> next.parseListBackwards(nextAccumulator, getNextToken));
|
return tailCall(() -> next.parseListTailRecursive(firstCons, firstCons, getNextToken));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO - refactor into a built in function?
|
protected TailCall<Cons> parseListTailRecursive(Cons start, Cons end, Supplier<Token> getNextToken) {
|
||||||
private TailCall<SExpression> reverse(Cons accumulator, Cons list) {
|
Cons newEnd = new Cons(parseSExpression(getNextToken), NIL);
|
||||||
if (list.isNull())
|
Token next = getNextToken.get();
|
||||||
return done(accumulator);
|
end.setRest(newEnd);
|
||||||
|
|
||||||
Cons nextAccumulator = new Cons(list.getFirst(), accumulator);
|
return tailCall(() -> next.parseListTailRecursive(start, newEnd, getNextToken));
|
||||||
Cons rest = (Cons) list.getRest();
|
|
||||||
|
|
||||||
return tailCall(() -> reverse(nextAccumulator, rest));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue