Convert tokens to kotlin
This commit is contained in:
parent
b4cd5f2fe4
commit
c5fbab6813
|
@ -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
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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))
|
||||||
|
}
|
||||||
|
}
|
|
@ -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());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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)
|
||||||
|
}
|
|
@ -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 ')'";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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 ')'"
|
||||||
|
}
|
||||||
|
}
|
|
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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) }
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue