Refactor list parsing code

This commit is contained in:
Mike Cifelli 2017-11-19 13:44:58 -05:00
parent a8d8d6696c
commit f3923cadc0
3 changed files with 20 additions and 24 deletions

View File

@ -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();
} }
} }

View File

@ -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 {

View File

@ -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));
} }
} }