Add ability to read large lists

This commit is contained in:
Mike Cifelli 2017-11-19 10:53:21 -05:00
parent a9c13610a2
commit 1fbc74f3ac
5 changed files with 40 additions and 12 deletions

View File

@ -1,4 +1,4 @@
|TranscendentalLisp.Recursion||17:56:26 Sat, Nov 18, 2017| |TranscendentalLisp.Recursion||10:47:58 Sun, Nov 19, 2017|
|TranscendentalLisp||16:15:14 Fri, Mar 17, 2017| |TranscendentalLisp||16:15:14 Fri, Mar 17, 2017|
|TranscendentalLisp.Macros||10:10:15 Mon, Mar 13, 2017| |TranscendentalLisp.Macros||10:10:15 Mon, Mar 13, 2017|
|TranscendentalLisp.MacroTests||10:07:00 Mon, Mar 13, 2017| |TranscendentalLisp.MacroTests||10:07:00 Mon, Mar 13, 2017|

View File

@ -4,8 +4,9 @@ Test
Test recursion capabilities of various functions. Test recursion capabilities of various functions.
| script | lisp interpreter fixture | | script | lisp interpreter fixture |
| show | evaluate text | (load "lisp/random/big-list.lisp") |
| show | evaluate text | (load "lisp/random/list-builder.lisp") | | show | evaluate text | (load "lisp/random/list-builder.lisp") |
| check | evaluate text | (setq big-list (list-doubler '(1 1 1 1 1 1 1 1) 11)) | =~/1\)$/ | | check | evaluate text | big-list | =~/1\)$/ |
| check | evaluate text | (length big-list) | 16384 | | check | evaluate text | (length big-list) | 16384 |
| check | evaluate text | (length (apply 'list big-list)) | 16384 | | check | evaluate text | (length (apply 'list big-list)) | 16384 |
| check | evaluate text | (apply '/ big-list) | 1 | | check | evaluate text | (apply '/ big-list) | 1 |

File diff suppressed because one or more lines are too long

View File

@ -1,11 +1,13 @@
package token; package token;
import static sexpression.Nil.NIL; import static recursion.TailCalls.done;
import java.util.function.Supplier; import java.util.function.Supplier;
import error.LineColumnException; import error.LineColumnException;
import file.FilePosition; import file.FilePosition;
import recursion.TailCall;
import sexpression.Cons;
import sexpression.SExpression; import sexpression.SExpression;
public class RightParenthesis extends Token { public class RightParenthesis extends Token {
@ -20,8 +22,8 @@ public class RightParenthesis extends Token {
} }
@Override @Override
public SExpression parseSExpressionTail(Supplier<Token> getNextToken) { public TailCall<SExpression> parseListBackwards(Cons accumulator, Supplier<Token> getNextToken) {
return NIL; return done(accumulator);
} }
public static class StartsWithRightParenthesisException extends LineColumnException { public static class StartsWithRightParenthesisException extends LineColumnException {

View File

@ -1,8 +1,13 @@
package token; package token;
import static recursion.TailCalls.done;
import static recursion.TailCalls.tailCall;
import static sexpression.Nil.NIL;
import java.util.function.Supplier; import java.util.function.Supplier;
import file.FilePosition; import file.FilePosition;
import recursion.TailCall;
import sexpression.Cons; import sexpression.Cons;
import sexpression.SExpression; import sexpression.SExpression;
@ -24,19 +29,38 @@ public abstract class Token {
return position; return position;
} }
// s-expression ::= NUMBER | IDENTIFIER | STRING | QUOTE_MARK s-expression | LEFT_PAREN // --------------------------------------------------------------------------------------------
// s-expression
// ::= NUMBER | IDENTIFIER | STRING | QUOTE_MARK s-expression | LEFT_PAREN s-expression-tail
//
// s-expression-tail // s-expression-tail
// s-expression-tail ::= RIGHT_PAREN | s-expression s-expression-tail // ::= RIGHT_PAREN | s-expression s-expression-tail
// --------------------------------------------------------------------------------------------
public abstract SExpression parseSExpression(Supplier<Token> getNextToken); public abstract SExpression parseSExpression(Supplier<Token> getNextToken);
public SExpression parseSExpressionTail(Supplier<Token> getNextToken) { public SExpression parseSExpressionTail(Supplier<Token> getNextToken) {
SExpression first = parseSExpression(getNextToken); Cons list = (Cons) parseListBackwards(NIL, getNextToken).invoke();
Token nextToken = getNextToken.get(); return reverse(NIL, list).invoke();
SExpression rest = nextToken.parseSExpressionTail(getNextToken); }
return new Cons(first, rest); public TailCall<SExpression> parseListBackwards(Cons accumulator, Supplier<Token> getNextToken) {
Cons nextAccumulator = new Cons(parseSExpression(getNextToken), accumulator);
Token next = getNextToken.get();
return tailCall(() -> next.parseListBackwards(nextAccumulator, getNextToken));
}
// TODO - refactor into a built in function?
private TailCall<SExpression> reverse(Cons accumulator, Cons list) {
if (list.isNull())
return done(accumulator);
Cons nextAccumulator = new Cons(list.getFirst(), accumulator);
Cons rest = (Cons) list.getRest();
return tailCall(() -> reverse(nextAccumulator, rest));
} }
} }