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.Macros||10:10:15 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.
| script | lisp interpreter fixture |
| show | evaluate text | (load "lisp/random/big-list.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 (apply 'list big-list)) | 16384 |
| 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;
import static sexpression.Nil.NIL;
import static recursion.TailCalls.done;
import java.util.function.Supplier;
import error.LineColumnException;
import file.FilePosition;
import recursion.TailCall;
import sexpression.Cons;
import sexpression.SExpression;
public class RightParenthesis extends Token {
@ -20,8 +22,8 @@ public class RightParenthesis extends Token {
}
@Override
public SExpression parseSExpressionTail(Supplier<Token> getNextToken) {
return NIL;
public TailCall<SExpression> parseListBackwards(Cons accumulator, Supplier<Token> getNextToken) {
return done(accumulator);
}
public static class StartsWithRightParenthesisException extends LineColumnException {

View File

@ -1,8 +1,13 @@
package token;
import static recursion.TailCalls.done;
import static recursion.TailCalls.tailCall;
import static sexpression.Nil.NIL;
import java.util.function.Supplier;
import file.FilePosition;
import recursion.TailCall;
import sexpression.Cons;
import sexpression.SExpression;
@ -24,19 +29,38 @@ public abstract class Token {
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 ::= RIGHT_PAREN | s-expression s-expression-tail
// ::= RIGHT_PAREN | s-expression s-expression-tail
// --------------------------------------------------------------------------------------------
public abstract SExpression parseSExpression(Supplier<Token> getNextToken);
public SExpression parseSExpressionTail(Supplier<Token> getNextToken) {
SExpression first = parseSExpression(getNextToken);
Cons list = (Cons) parseListBackwards(NIL, getNextToken).invoke();
Token nextToken = getNextToken.get();
SExpression rest = nextToken.parseSExpressionTail(getNextToken);
return reverse(NIL, list).invoke();
}
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));
}
}