diff --git a/src/token/LeftParenthesis.java b/src/token/LeftParenthesis.java index b3fc350..1f27542 100644 --- a/src/token/LeftParenthesis.java +++ b/src/token/LeftParenthesis.java @@ -15,7 +15,7 @@ public class LeftParenthesis extends Token { public SExpression parseSExpression(Supplier getNextToken) { Token nextToken = getNextToken.get(); - return nextToken.parseSExpressionTail(getNextToken); + return nextToken.parseListTail(getNextToken).invoke(); } } diff --git a/src/token/RightParenthesis.java b/src/token/RightParenthesis.java index 8c15054..e76b9d6 100644 --- a/src/token/RightParenthesis.java +++ b/src/token/RightParenthesis.java @@ -1,6 +1,7 @@ package token; import static recursion.TailCalls.done; +import static sexpression.Nil.NIL; import java.util.function.Supplier; @@ -22,8 +23,13 @@ public class RightParenthesis extends Token { } @Override - public TailCall parseListBackwards(Cons accumulator, Supplier getNextToken) { - return done(accumulator); + protected TailCall parseListTail(Supplier getNextToken) { + return done(NIL); + } + + @Override + protected TailCall parseListTailRecursive(Cons start, Cons end, Supplier getNextToken) { + return done(start); } public static class StartsWithRightParenthesisException extends LineColumnException { diff --git a/src/token/Token.java b/src/token/Token.java index 2eb9aa0..14e479f 100644 --- a/src/token/Token.java +++ b/src/token/Token.java @@ -1,6 +1,5 @@ package token; -import static recursion.TailCalls.done; import static recursion.TailCalls.tailCall; import static sexpression.Nil.NIL; @@ -31,36 +30,27 @@ public abstract class Token { // -------------------------------------------------------------------------------------------- // 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 - // ::= RIGHT_PAREN | s-expression s-expression-tail + // list-tail + // ::= RIGHT_PAREN | s-expression list-tail // -------------------------------------------------------------------------------------------- public abstract SExpression parseSExpression(Supplier getNextToken); - public SExpression parseSExpressionTail(Supplier getNextToken) { - Cons backwardsList = parseListBackwards(NIL, getNextToken).invoke(); - - return reverse(NIL, backwardsList).invoke(); - } - - public TailCall parseListBackwards(Cons accumulator, Supplier getNextToken) { - Cons nextAccumulator = new Cons(parseSExpression(getNextToken), accumulator); + protected TailCall parseListTail(Supplier getNextToken) { + Cons firstCons = new Cons(parseSExpression(getNextToken), NIL); Token next = getNextToken.get(); - return tailCall(() -> next.parseListBackwards(nextAccumulator, getNextToken)); + return tailCall(() -> next.parseListTailRecursive(firstCons, firstCons, getNextToken)); } - // TODO - refactor into a built in function? - private TailCall reverse(Cons accumulator, Cons list) { - if (list.isNull()) - return done(accumulator); + protected TailCall parseListTailRecursive(Cons start, Cons end, Supplier getNextToken) { + Cons newEnd = new Cons(parseSExpression(getNextToken), NIL); + Token next = getNextToken.get(); + end.setRest(newEnd); - Cons nextAccumulator = new Cons(list.getFirst(), accumulator); - Cons rest = (Cons) list.getRest(); - - return tailCall(() -> reverse(nextAccumulator, rest)); + return tailCall(() -> next.parseListTailRecursive(start, newEnd, getNextToken)); } }