Add ability to read large lists
This commit is contained in:
parent
a9c13610a2
commit
1fbc74f3ac
|
@ -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|
|
||||
|
|
|
@ -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
|
@ -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 {
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue