Convert tokens to kotlin

This commit is contained in:
Mike Cifelli 2018-05-19 13:56:14 -04:00
parent b4cd5f2fe4
commit c5fbab6813
24 changed files with 186 additions and 307 deletions

View File

@ -32,9 +32,9 @@ import function.builtin.predicate.EQUAL
import function.builtin.predicate.GENSYM_EQUAL import function.builtin.predicate.GENSYM_EQUAL
import function.builtin.predicate.LISTP import function.builtin.predicate.LISTP
import function.builtin.predicate.NULL import function.builtin.predicate.NULL
import function.builtin.predicate.NumericEqual
import function.builtin.predicate.NUMERIC_GREATER import function.builtin.predicate.NUMERIC_GREATER
import function.builtin.predicate.NUMERIC_LESS import function.builtin.predicate.NUMERIC_LESS
import function.builtin.predicate.NumericEqual
import function.builtin.special.AND import function.builtin.special.AND
import function.builtin.special.CASE import function.builtin.special.CASE
import function.builtin.special.COND import function.builtin.special.COND
@ -42,9 +42,9 @@ import function.builtin.special.DEFINE_SPECIAL
import function.builtin.special.DEFMACRO import function.builtin.special.DEFMACRO
import function.builtin.special.DEFUN import function.builtin.special.DEFUN
import function.builtin.special.IF import function.builtin.special.IF
import function.builtin.special.Lambda
import function.builtin.special.LET import function.builtin.special.LET
import function.builtin.special.LET_STAR import function.builtin.special.LET_STAR
import function.builtin.special.Lambda
import function.builtin.special.OR import function.builtin.special.OR
import function.builtin.special.PROGN import function.builtin.special.PROGN
import function.builtin.special.QUOTE import function.builtin.special.QUOTE

View File

@ -1,22 +0,0 @@
package token;
import file.FilePosition;
import sexpression.AtSignExpression;
import sexpression.SExpression;
import java.util.function.Supplier;
public class AtSign extends Token {
public AtSign(String text, FilePosition position) {
super(text, position);
}
@Override
public SExpression parseSExpression(Supplier<Token> getNextToken) {
Token nextToken = getNextToken.get();
SExpression argument = nextToken.parseSExpression(getNextToken);
return new AtSignExpression(argument);
}
}

View File

@ -0,0 +1,15 @@
package token
import file.FilePosition
import sexpression.AtSignExpression
import sexpression.SExpression
class AtSign(text: String, position: FilePosition) : Token(text, position) {
override fun parseSExpression(getNextToken: () -> Token): SExpression {
val nextToken = getNextToken()
val argument = nextToken.parseSExpression(getNextToken)
return AtSignExpression(argument)
}
}

View File

@ -1,22 +0,0 @@
package token;
import file.FilePosition;
import sexpression.BackquoteExpression;
import sexpression.SExpression;
import java.util.function.Supplier;
public class Backquote extends Token {
public Backquote(String text, FilePosition position) {
super(text, position);
}
@Override
public SExpression parseSExpression(Supplier<Token> getNextToken) {
Token nextToken = getNextToken.get();
SExpression argument = nextToken.parseSExpression(getNextToken);
return new BackquoteExpression(argument);
}
}

View File

@ -0,0 +1,15 @@
package token
import file.FilePosition
import sexpression.BackquoteExpression
import sexpression.SExpression
class Backquote(text: String, position: FilePosition) : Token(text, position) {
override fun parseSExpression(getNextToken: () -> Token): SExpression {
val nextToken = getNextToken()
val argument = nextToken.parseSExpression(getNextToken)
return BackquoteExpression(argument)
}
}

View File

@ -1,22 +0,0 @@
package token;
import file.FilePosition;
import sexpression.CommaExpression;
import sexpression.SExpression;
import java.util.function.Supplier;
public class Comma extends Token {
public Comma(String text, FilePosition position) {
super(text, position);
}
@Override
public SExpression parseSExpression(Supplier<Token> getNextToken) {
Token nextToken = getNextToken.get();
SExpression argument = nextToken.parseSExpression(getNextToken);
return new CommaExpression(argument);
}
}

View File

@ -0,0 +1,15 @@
package token
import file.FilePosition
import sexpression.CommaExpression
import sexpression.SExpression
class Comma(text: String, position: FilePosition) : Token(text, position) {
override fun parseSExpression(getNextToken: () -> Token): SExpression {
val nextToken = getNextToken()
val argument = nextToken.parseSExpression(getNextToken)
return CommaExpression(argument)
}
}

View File

@ -1,33 +0,0 @@
package token;
import error.LineColumnException;
import file.FilePosition;
import sexpression.SExpression;
import java.util.function.Supplier;
public class Eof extends Token {
public Eof(String text, FilePosition position) {
super(text, position);
}
@Override
public SExpression parseSExpression(Supplier<Token> getNextToken) {
throw new EofEncounteredException(getPosition());
}
public static class EofEncounteredException extends LineColumnException {
private static final long serialVersionUID = 1L;
public EofEncounteredException(FilePosition position) {
super(position);
}
@Override
public String getMessagePrefix() {
return "end-of-file encountered";
}
}
}

View File

@ -0,0 +1,17 @@
package token
import error.LineColumnException
import file.FilePosition
import sexpression.SExpression
class Eof(text: String, position: FilePosition) : Token(text, position) {
override fun parseSExpression(getNextToken: () -> Token): SExpression {
throw EofEncounteredException(position)
}
class EofEncounteredException(position: FilePosition) : LineColumnException(position) {
override val messagePrefix: String
get() = "end-of-file encountered"
}
}

View File

@ -1,19 +0,0 @@
package token;
import file.FilePosition;
import sexpression.SExpression;
import sexpression.Symbol;
import java.util.function.Supplier;
public class Identifier extends Token {
public Identifier(String text, FilePosition position) {
super(text, position);
}
@Override
public SExpression parseSExpression(Supplier<Token> getNextToken) {
return new Symbol(getText());
}
}

View File

@ -0,0 +1,9 @@
package token
import file.FilePosition
import sexpression.Symbol
class Identifier(text: String, position: FilePosition) : Token(text, position) {
override fun parseSExpression(getNextToken: () -> Token) = Symbol(text)
}

View File

@ -1,20 +0,0 @@
package token;
import file.FilePosition;
import sexpression.SExpression;
import java.util.function.Supplier;
public class LeftParenthesis extends Token {
public LeftParenthesis(String text, FilePosition position) {
super(text, position);
}
@Override
public SExpression parseSExpression(Supplier<Token> getNextToken) {
Token nextToken = getNextToken.get();
return nextToken.parseListTail(getNextToken).invoke();
}
}

View File

@ -0,0 +1,13 @@
package token
import file.FilePosition
import sexpression.SExpression
class LeftParenthesis(text: String, position: FilePosition) : Token(text, position) {
override fun parseSExpression(getNextToken: () -> Token): SExpression {
val nextToken = getNextToken()
return nextToken.parseListTail(getNextToken).invoke()
}
}

View File

@ -1,19 +0,0 @@
package token;
import file.FilePosition;
import sexpression.LispNumber;
import sexpression.SExpression;
import java.util.function.Supplier;
public class Number extends Token {
public Number(String text, FilePosition position) {
super(text, position);
}
@Override
public SExpression parseSExpression(Supplier<Token> getNextToken) {
return new LispNumber(getText());
}
}

View File

@ -0,0 +1,9 @@
package token
import file.FilePosition
import sexpression.LispNumber
class Number(text: String, position: FilePosition) : Token(text, position) {
override fun parseSExpression(getNextToken: () -> Token) = LispNumber(text)
}

View File

@ -1,25 +0,0 @@
package token;
import file.FilePosition;
import sexpression.Cons;
import sexpression.SExpression;
import sexpression.Symbol;
import java.util.function.Supplier;
import static sexpression.Nil.NIL;
public class QuoteMark extends Token {
public QuoteMark(String text, FilePosition position) {
super(text, position);
}
@Override
public SExpression parseSExpression(Supplier<Token> getNextToken) {
Token nextToken = getNextToken.get();
SExpression argument = nextToken.parseSExpression(getNextToken);
return new Cons(Symbol.createQuote(), new Cons(argument, NIL));
}
}

View File

@ -0,0 +1,17 @@
package token
import file.FilePosition
import sexpression.Cons
import sexpression.Nil.NIL
import sexpression.SExpression
import sexpression.Symbol
class QuoteMark(text: String, position: FilePosition) : Token(text, position) {
override fun parseSExpression(getNextToken: () -> Token): SExpression {
val nextToken = getNextToken()
val argument = nextToken.parseSExpression(getNextToken)
return Cons(Symbol.createQuote(), Cons(argument, NIL))
}
}

View File

@ -1,19 +0,0 @@
package token;
import file.FilePosition;
import sexpression.LispString;
import sexpression.SExpression;
import java.util.function.Supplier;
public class QuotedString extends Token {
public QuotedString(String text, FilePosition position) {
super(text, position);
}
@Override
public SExpression parseSExpression(Supplier<Token> getNextToken) {
return new LispString(getText());
}
}

View File

@ -0,0 +1,9 @@
package token
import file.FilePosition
import sexpression.LispString
class QuotedString(text: String, position: FilePosition) : Token(text, position) {
override fun parseSExpression(getNextToken: () -> Token) = LispString(text)
}

View File

@ -1,48 +0,0 @@
package token;
import error.LineColumnException;
import file.FilePosition;
import recursion.TailCall;
import sexpression.Cons;
import sexpression.SExpression;
import java.util.function.Supplier;
import static recursion.TailCalls.done;
import static sexpression.Nil.NIL;
public class RightParenthesis extends Token {
public RightParenthesis(String text, FilePosition position) {
super(text, position);
}
@Override
public SExpression parseSExpression(Supplier<Token> getNextToken) {
throw new StartsWithRightParenthesisException(getPosition());
}
@Override
protected TailCall<Cons> parseListTail(Supplier<Token> getNextToken) {
return done(NIL);
}
@Override
protected TailCall<Cons> parseListTailRecursive(Cons start, Cons end, Supplier<Token> getNextToken) {
return done(start);
}
public static class StartsWithRightParenthesisException extends LineColumnException {
private static final long serialVersionUID = 1L;
public StartsWithRightParenthesisException(FilePosition position) {
super(position);
}
@Override
public String getMessagePrefix() {
return "expression begins with ')'";
}
}
}

View File

@ -0,0 +1,29 @@
package token
import error.LineColumnException
import file.FilePosition
import recursion.TailCall
import recursion.TailCalls.done
import sexpression.Cons
import sexpression.Nil.NIL
import sexpression.SExpression
class RightParenthesis(text: String, position: FilePosition) : Token(text, position) {
override fun parseSExpression(getNextToken: () -> Token): SExpression {
throw StartsWithRightParenthesisException(position)
}
override fun parseListTail(getNextToken: () -> Token): TailCall<Cons> {
return done(NIL)
}
override fun parseListTailRecursive(start: Cons, end: Cons, getNextToken: () -> Token): TailCall<Cons> {
return done(start)
}
class StartsWithRightParenthesisException(position: FilePosition) : LineColumnException(position) {
override val messagePrefix: String
get() = "expression begins with ')'"
}
}

View File

@ -1,55 +0,0 @@
package token;
import file.FilePosition;
import recursion.TailCall;
import sexpression.Cons;
import sexpression.SExpression;
import java.util.function.Supplier;
import static recursion.TailCalls.tailCall;
import static sexpression.Nil.NIL;
public abstract class Token {
private String text;
private FilePosition position;
public Token(String text, FilePosition position) {
this.text = text;
this.position = position;
}
public String getText() {
return text;
}
public FilePosition getPosition() {
return position;
}
// --------------------------------------------------------------------------------------------
// s-expression
// ::= NUMBER | IDENTIFIER | STRING | QUOTE_MARK s-expression | LEFT_PAREN list-tail
//
// list-tail
// ::= RIGHT_PAREN | s-expression list-tail
// --------------------------------------------------------------------------------------------
public abstract SExpression parseSExpression(Supplier<Token> getNextToken);
protected TailCall<Cons> parseListTail(Supplier<Token> getNextToken) {
Cons firstCons = new Cons(parseSExpression(getNextToken), NIL);
Token next = getNextToken.get();
return tailCall(() -> next.parseListTailRecursive(firstCons, firstCons, getNextToken));
}
protected TailCall<Cons> parseListTailRecursive(Cons start, Cons end, Supplier<Token> getNextToken) {
Cons newEnd = new Cons(parseSExpression(getNextToken), NIL);
Token next = getNextToken.get();
end.setRest(newEnd);
return tailCall(() -> next.parseListTailRecursive(start, newEnd, getNextToken));
}
}

View File

@ -0,0 +1,36 @@
package token
import file.FilePosition
import recursion.TailCall
import recursion.TailCalls.tailCall
import sexpression.Cons
import sexpression.Nil.NIL
import sexpression.SExpression
abstract class Token(val text: String, val position: FilePosition) {
// --------------------------------------------------------------------------------------------
// s-expression
// ::= NUMBER | IDENTIFIER | STRING | QUOTE_MARK s-expression | LEFT_PAREN list-tail
//
// list-tail
// ::= RIGHT_PAREN | s-expression list-tail
// --------------------------------------------------------------------------------------------
abstract fun parseSExpression(getNextToken: () -> Token): SExpression
open fun parseListTail(getNextToken: () -> Token): TailCall<Cons> {
val firstCons = Cons(parseSExpression(getNextToken), NIL)
val next = getNextToken()
return tailCall { next.parseListTailRecursive(firstCons, firstCons, getNextToken) }
}
protected open fun parseListTailRecursive(start: Cons, end: Cons, getNextToken: () -> Token): TailCall<Cons> {
val newEnd = Cons(parseSExpression(getNextToken), NIL)
val next = getNextToken()
end.rest = newEnd
return tailCall { next.parseListTailRecursive(start, newEnd, getNextToken) }
}
}

View File

@ -1,7 +1,6 @@
package parser package parser
import error.LispException import error.LispException
import error.Severity.ERROR
import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.Assertions.assertThrows import org.junit.jupiter.api.Assertions.assertThrows
import org.junit.jupiter.api.Assertions.fail import org.junit.jupiter.api.Assertions.fail