Convert util classes to kotlin

This commit is contained in:
Mike Cifelli 2018-03-24 11:43:22 -04:00
parent d74e472780
commit b2989809eb
15 changed files with 98 additions and 178 deletions

View File

@ -10,6 +10,7 @@ import parser.LispParser;
import sexpression.Cons; import sexpression.Cons;
import sexpression.LispString; import sexpression.LispString;
import sexpression.SExpression; import sexpression.SExpression;
import util.Path;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -19,7 +20,6 @@ import static function.builtin.EVAL.eval;
import static java.text.MessageFormat.format; import static java.text.MessageFormat.format;
import static sexpression.Nil.NIL; import static sexpression.Nil.NIL;
import static sexpression.Symbol.T; import static sexpression.Symbol.T;
import static util.Path.getPathPrefix;
@FunctionNames({ "LOAD" }) @FunctionNames({ "LOAD" })
public class LOAD extends LispFunction { public class LOAD extends LispFunction {
@ -80,7 +80,7 @@ public class LOAD extends LispFunction {
} }
private boolean isSuccessfulEvaluationWithPathPrefix(String prefixedFileName, LispParser parser) { private boolean isSuccessfulEvaluationWithPathPrefix(String prefixedFileName, LispParser parser) {
pathPrefixes.push(getPathPrefix(prefixedFileName)); pathPrefixes.push(Path.INSTANCE.getPathPrefix(prefixedFileName));
boolean isSuccessful = isSuccessfulEvaluation(parser); boolean isSuccessful = isSuccessfulEvaluation(parser);
pathPrefixes.pop(); pathPrefixes.pop();

View File

@ -4,6 +4,7 @@ import environment.RuntimeEnvironment;
import error.CriticalLispException; import error.CriticalLispException;
import error.ErrorManager; import error.ErrorManager;
import interpreter.LispInterpreter.LanguageFile; import interpreter.LispInterpreter.LanguageFile;
import util.Path;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
@ -13,8 +14,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import static util.Path.getPathPrefix;
public class LispInterpreterBuilderImpl implements LispInterpreterBuilder { public class LispInterpreterBuilderImpl implements LispInterpreterBuilder {
private static LispInterpreterBuilder uniqueInstance = new LispInterpreterBuilderImpl(); private static LispInterpreterBuilder uniqueInstance = new LispInterpreterBuilderImpl();
@ -162,7 +161,7 @@ public class LispInterpreterBuilderImpl implements LispInterpreterBuilder {
private void configurePath() { private void configurePath() {
if (isFileBased) if (isFileBased)
environment.setPath(getPathPrefix(inputName)); environment.setPath(Path.INSTANCE.getPathPrefix(inputName));
else else
environment.setPath(""); environment.setPath("");
} }

View File

@ -1,15 +1,10 @@
package scanner; package scanner;
import stream.SafeInputStream; import stream.SafeInputStream;
import util.Characters;
import java.io.InputStream; import java.io.InputStream;
import static util.Characters.BACKSLASH;
import static util.Characters.DOUBLE_QUOTE;
import static util.Characters.EOF;
import static util.Characters.NEWLINE;
import static util.Characters.SEMICOLON;
/** /**
* Removes Lisp comments from an input stream. * Removes Lisp comments from an input stream.
*/ */
@ -57,11 +52,11 @@ public class LispCommentRemovingInputStream implements LispInputStream {
} }
private boolean haveEncounteredStringBoundary() { private boolean haveEncounteredStringBoundary() {
return (previousCharacter != BACKSLASH) && (currentCharacter == DOUBLE_QUOTE); return (previousCharacter != Characters.BACKSLASH) && (currentCharacter == Characters.DOUBLE_QUOTE);
} }
private boolean haveEnteredComment() { private boolean haveEnteredComment() {
return (currentCharacter == SEMICOLON) && (!isInQuotedString); return (currentCharacter == Characters.SEMICOLON) && (!isInQuotedString);
} }
private void consumeAllBytesInComment() { private void consumeAllBytesInComment() {
@ -70,7 +65,7 @@ public class LispCommentRemovingInputStream implements LispInputStream {
} }
private boolean stillInComment() { private boolean stillInComment() {
return (currentCharacter != NEWLINE) && (currentCharacter != EOF); return (currentCharacter != Characters.NEWLINE) && (currentCharacter != Characters.EOF);
} }
@Override @Override

View File

@ -13,12 +13,6 @@ import java.util.function.Function;
import static java.lang.Character.isDigit; import static java.lang.Character.isDigit;
import static java.lang.Character.isWhitespace; import static java.lang.Character.isWhitespace;
import static util.Characters.BACKSLASH;
import static util.Characters.DOUBLE_QUOTE;
import static util.Characters.EOF;
import static util.Characters.NEWLINE;
import static util.Characters.isLegalIdentifierCharacter;
import static util.Characters.isNumberPrefix;
/** /**
* Converts a stream of bytes into a stream of Lisp tokens. * Converts a stream of bytes into a stream of Lisp tokens.
@ -36,13 +30,13 @@ public class LispScanner {
} }
public Token getNextToken() { public Token getNextToken() {
for (int c = inputStream.read(); c != EOF; c = inputStream.read()) { for (int c = inputStream.read(); c != Characters.EOF; c = inputStream.read()) {
char currentCharacter = (char) c; char currentCharacter = (char) c;
positionTracker.incrementColumn(); positionTracker.incrementColumn();
if (!isWhitespace(currentCharacter)) if (!isWhitespace(currentCharacter))
return createTokenFromCharacter(currentCharacter); return createTokenFromCharacter(currentCharacter);
else if (currentCharacter == NEWLINE) else if (currentCharacter == Characters.NEWLINE)
positionTracker.incrementLine(); positionTracker.incrementLine();
} }
@ -59,13 +53,13 @@ public class LispScanner {
private String retrieveTokenText(char firstCharacter) { private String retrieveTokenText(char firstCharacter) {
String tokenText = "" + firstCharacter; String tokenText = "" + firstCharacter;
if (firstCharacter == DOUBLE_QUOTE) if (firstCharacter == Characters.DOUBLE_QUOTE)
tokenText = retrieveStringTokenText(firstCharacter); tokenText = retrieveStringTokenText(firstCharacter);
else if (isNumberPrefix(firstCharacter)) else if (Characters.INSTANCE.isNumberPrefix(firstCharacter))
tokenText = retrieveNumberOrIdentifierTokenText(firstCharacter); tokenText = retrieveNumberOrIdentifierTokenText(firstCharacter);
else if (isDigit(firstCharacter)) else if (isDigit(firstCharacter))
tokenText = retrieveNumberTokenText(firstCharacter); tokenText = retrieveNumberTokenText(firstCharacter);
else if (isLegalIdentifierCharacter(firstCharacter)) else if (Characters.INSTANCE.isLegalIdentifierCharacter(firstCharacter))
tokenText = retrieveIdentifierTokenText(firstCharacter); tokenText = retrieveIdentifierTokenText(firstCharacter);
return tokenText; return tokenText;
@ -73,7 +67,7 @@ public class LispScanner {
private String retrieveStringTokenText(char firstDoubleQuote) { private String retrieveStringTokenText(char firstDoubleQuote) {
ComplexTokenTextRetriever retriever = new ComplexTokenTextRetriever(firstDoubleQuote, ComplexTokenTextRetriever retriever = new ComplexTokenTextRetriever(firstDoubleQuote,
Characters::isLegalStringCharacter); Characters.INSTANCE::isLegalStringCharacter);
return retriever.retrieveToken(); return retriever.retrieveToken();
} }
@ -96,7 +90,7 @@ public class LispScanner {
private String retrieveIdentifierTokenText(char firstCharacter) { private String retrieveIdentifierTokenText(char firstCharacter) {
ComplexTokenTextRetriever retriever = new ComplexTokenTextRetriever(firstCharacter, ComplexTokenTextRetriever retriever = new ComplexTokenTextRetriever(firstCharacter,
Characters::isLegalIdentifierCharacter); Characters.INSTANCE::isLegalIdentifierCharacter);
return retriever.retrieveToken(); return retriever.retrieveToken();
} }
@ -122,7 +116,7 @@ public class LispScanner {
public String retrieveToken() { public String retrieveToken() {
text.append(firstCharacter); text.append(firstCharacter);
for (int c = inputStream.read(); c != EOF; c = inputStream.read()) { for (int c = inputStream.read(); c != Characters.EOF; c = inputStream.read()) {
currentCharacter = (char) c; currentCharacter = (char) c;
if (!isPartOfToken.apply(currentCharacter)) { if (!isPartOfToken.apply(currentCharacter)) {
@ -146,7 +140,7 @@ public class LispScanner {
text.append(currentCharacter); text.append(currentCharacter);
positionTracker.incrementColumn(); positionTracker.incrementColumn();
if (currentCharacter == NEWLINE) if (currentCharacter == Characters.NEWLINE)
positionTracker.incrementLine(); positionTracker.incrementLine();
} }
@ -155,11 +149,12 @@ public class LispScanner {
} }
private boolean isStringToken() { private boolean isStringToken() {
return firstCharacter == DOUBLE_QUOTE; return firstCharacter == Characters.DOUBLE_QUOTE;
} }
private boolean isTerminatingDoubleQuote() { private boolean isTerminatingDoubleQuote() {
return (currentCharacter == DOUBLE_QUOTE) && (previousCharacter != BACKSLASH); return (currentCharacter == Characters.DOUBLE_QUOTE) &&
(previousCharacter != Characters.BACKSLASH);
} }
private String terminateTokenWithEof() { private String terminateTokenWithEof() {

View File

@ -56,7 +56,7 @@ import java.util.HashSet
object FunctionTable { object FunctionTable {
private var table: MutableMap<String, LispFunction> = HashMap() private var table = HashMap<String, LispFunction>()
private val allBuiltIns = HashSet<Class<out LispFunction>>() private val allBuiltIns = HashSet<Class<out LispFunction>>()
init { init {
@ -154,6 +154,6 @@ object FunctionTable {
class LispFunctionInstantiationException(private val functionName: String) : CriticalLispException() { class LispFunctionInstantiationException(private val functionName: String) : CriticalLispException() {
override val message: String override val message: String
get() = format("Could not create an instance of ''{0}''", functionName) get() = "Could not create an instance of '$functionName'"
} }
} }

View File

@ -1,16 +1,14 @@
package terminal; package terminal;
import stream.SafeInputStream; import stream.SafeInputStream;
import util.Characters;
import static java.lang.Character.isDigit; import static java.lang.Character.isDigit;
import static util.Characters.EOF;
import static util.Characters.LEFT_SQUARE_BRACKET;
import static util.Characters.UNICODE_ESCAPE;
class ControlSequenceHandler { class ControlSequenceHandler {
public static final boolean isEscape(char c) { public static final boolean isEscape(char c) {
return c == UNICODE_ESCAPE; return c == Characters.UNICODE_ESCAPE;
} }
private ControlSequenceLookup controlSequenceLookup; private ControlSequenceLookup controlSequenceLookup;
@ -42,11 +40,11 @@ class ControlSequenceHandler {
} }
private boolean isCharacter() { private boolean isCharacter() {
return currentCharacter != EOF; return currentCharacter != Characters.EOF;
} }
private boolean isLeftBracket() { private boolean isLeftBracket() {
return (char) currentCharacter == LEFT_SQUARE_BRACKET; return (char) currentCharacter == Characters.LEFT_SQUARE_BRACKET;
} }
private void readCode() { private void readCode() {

View File

@ -7,6 +7,7 @@ import com.googlecode.lanterna.input.KeyType;
import com.googlecode.lanterna.terminal.IOSafeTerminal; import com.googlecode.lanterna.terminal.IOSafeTerminal;
import stream.SafeInputStream; import stream.SafeInputStream;
import stream.SafeOutputStream; import stream.SafeOutputStream;
import util.Characters;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@ -21,12 +22,10 @@ import static com.googlecode.lanterna.input.KeyType.Character;
import static com.googlecode.lanterna.input.KeyType.Delete; import static com.googlecode.lanterna.input.KeyType.Delete;
import static com.googlecode.lanterna.input.KeyType.Enter; import static com.googlecode.lanterna.input.KeyType.Enter;
import static terminal.ControlSequenceHandler.isEscape; import static terminal.ControlSequenceHandler.isEscape;
import static util.Characters.EOF;
import static util.Characters.UNICODE_NULL;
public class LispTerminal { public class LispTerminal {
public static final char END_OF_SEGMENT = UNICODE_NULL; public static final char END_OF_SEGMENT = Characters.UNICODE_NULL;
private IOSafeTerminal terminal; private IOSafeTerminal terminal;
private SafeOutputStream inputWriter; private SafeOutputStream inputWriter;
@ -397,7 +396,7 @@ public class LispTerminal {
} }
private void writeOutput() { private void writeOutput() {
for (int c = outputReader.read(); c != EOF; c = outputReader.read()) for (int c = outputReader.read(); c != Characters.EOF; c = outputReader.read())
processOutput((char) c); processOutput((char) c);
terminal.flush(); terminal.flush();
@ -431,7 +430,7 @@ public class LispTerminal {
private synchronized void putOutputToTerminal() { private synchronized void putOutputToTerminal() {
SafeInputStream input = convertOutputToStream(); SafeInputStream input = convertOutputToStream();
for (int c = input.read(); c != EOF; c = input.read()) for (int c = input.read(); c != Characters.EOF; c = input.read())
if (isEscape((char) c)) if (isEscape((char) c))
applyControlSequence(input); applyControlSequence(input);
else else

View File

@ -1,17 +1,9 @@
package token; package token;
import file.FilePosition; import file.FilePosition;
import util.Characters;
import static java.lang.Character.isDigit; import static java.lang.Character.isDigit;
import static util.Characters.AT_SIGN;
import static util.Characters.BACKQUOTE;
import static util.Characters.COMMA;
import static util.Characters.DOUBLE_QUOTE;
import static util.Characters.LEFT_PARENTHESIS;
import static util.Characters.RIGHT_PARENTHESIS;
import static util.Characters.SINGLE_QUOTE;
import static util.Characters.isLegalIdentifierCharacter;
import static util.Characters.isNumberPrefix;
public class TokenFactoryImpl implements TokenFactory { public class TokenFactoryImpl implements TokenFactory {
@ -23,24 +15,24 @@ public class TokenFactoryImpl implements TokenFactory {
char firstCharacter = text.charAt(0); char firstCharacter = text.charAt(0);
switch (firstCharacter) { switch (firstCharacter) {
case LEFT_PARENTHESIS: case Characters.LEFT_PARENTHESIS:
return new LeftParenthesis(text, position); return new LeftParenthesis(text, position);
case RIGHT_PARENTHESIS: case Characters.RIGHT_PARENTHESIS:
return new RightParenthesis(text, position); return new RightParenthesis(text, position);
case SINGLE_QUOTE: case Characters.SINGLE_QUOTE:
return new QuoteMark(text, position); return new QuoteMark(text, position);
case DOUBLE_QUOTE: case Characters.DOUBLE_QUOTE:
return new QuotedString(text, position); return new QuotedString(text, position);
case BACKQUOTE: case Characters.BACKQUOTE:
return new Backquote(text, position); return new Backquote(text, position);
case AT_SIGN: case Characters.AT_SIGN:
return new AtSign(text, position); return new AtSign(text, position);
case COMMA: case Characters.COMMA:
return new Comma(text, position); return new Comma(text, position);
default: default:
if (isNumeric(firstCharacter, text)) if (isNumeric(firstCharacter, text))
return new Number(text, position); return new Number(text, position);
else if (isLegalIdentifierCharacter(firstCharacter)) else if (Characters.INSTANCE.isLegalIdentifierCharacter(firstCharacter))
return new Identifier(text, position); return new Identifier(text, position);
} }
@ -52,7 +44,7 @@ public class TokenFactoryImpl implements TokenFactory {
} }
private boolean isPrefixedNumeric(char firstCharacter, String text) { private boolean isPrefixedNumeric(char firstCharacter, String text) {
return isNumberPrefix(firstCharacter) && isNextCharacterDigit(text); return Characters.INSTANCE.isNumberPrefix(firstCharacter) && isNextCharacterDigit(text);
} }
private boolean isNextCharacterDigit(String text) { private boolean isNextCharacterDigit(String text) {

View File

@ -1,60 +0,0 @@
package util;
import java.util.HashSet;
import java.util.Set;
public final class Characters {
private Characters() {}
public static final int EOF = -1;
public static final char AT_SIGN = '@';
public static final char BACKQUOTE = '`';
public static final char BACKSLASH = '\\';
public static final char COMMA = ',';
public static final char DASH = '-';
public static final char DOUBLE_QUOTE = '\"';
public static final char HASH = '#';
public static final char LEFT_PARENTHESIS = '(';
public static final char LEFT_SQUARE_BRACKET = '[';
public static final char NEWLINE = '\n';
public static final char PERIOD = '.';
public static final char PLUS = '+';
public static final char RIGHT_PARENTHESIS = ')';
public static final char RIGHT_SQUARE_BRACKET = ']';
public static final char SEMICOLON = ';';
public static final char SINGLE_QUOTE = '\'';
public static final char UNICODE_ESCAPE = '\u001B';
public static final char UNICODE_NULL = '\u0000';
public static final Set<Character> illegalIdentifierCharacters = new HashSet<>();
static {
illegalIdentifierCharacters.add(AT_SIGN);
illegalIdentifierCharacters.add(BACKQUOTE);
illegalIdentifierCharacters.add(BACKSLASH);
illegalIdentifierCharacters.add(COMMA);
illegalIdentifierCharacters.add(DOUBLE_QUOTE);
illegalIdentifierCharacters.add(HASH);
illegalIdentifierCharacters.add(LEFT_PARENTHESIS);
illegalIdentifierCharacters.add(LEFT_SQUARE_BRACKET);
illegalIdentifierCharacters.add(PERIOD);
illegalIdentifierCharacters.add(RIGHT_PARENTHESIS);
illegalIdentifierCharacters.add(RIGHT_SQUARE_BRACKET);
illegalIdentifierCharacters.add(SEMICOLON);
illegalIdentifierCharacters.add(SINGLE_QUOTE);
}
public static boolean isLegalIdentifierCharacter(char c) {
return (!Character.isWhitespace(c)) && (!illegalIdentifierCharacters.contains(c));
}
public static boolean isLegalStringCharacter(char c) {
return true;
}
public static boolean isNumberPrefix(char c) {
return c == DASH || c == PLUS;
}
}

View File

@ -0,0 +1,48 @@
package util
import java.util.HashSet
object Characters {
const val EOF = -1
const val AT_SIGN = '@'
const val BACKQUOTE = '`'
const val BACKSLASH = '\\'
const val COMMA = ','
const val DASH = '-'
const val DOUBLE_QUOTE = '\"'
const val HASH = '#'
const val LEFT_PARENTHESIS = '('
const val LEFT_SQUARE_BRACKET = '['
const val NEWLINE = '\n'
const val PERIOD = '.'
const val PLUS = '+'
const val RIGHT_PARENTHESIS = ')'
const val RIGHT_SQUARE_BRACKET = ']'
const val SEMICOLON = ';'
const val SINGLE_QUOTE = '\''
const val UNICODE_ESCAPE = '\u001B'
const val UNICODE_NULL = '\u0000'
private val illegalIdentifierCharacters = HashSet<Char>()
init {
illegalIdentifierCharacters.add(AT_SIGN)
illegalIdentifierCharacters.add(BACKQUOTE)
illegalIdentifierCharacters.add(BACKSLASH)
illegalIdentifierCharacters.add(COMMA)
illegalIdentifierCharacters.add(DOUBLE_QUOTE)
illegalIdentifierCharacters.add(HASH)
illegalIdentifierCharacters.add(LEFT_PARENTHESIS)
illegalIdentifierCharacters.add(LEFT_SQUARE_BRACKET)
illegalIdentifierCharacters.add(PERIOD)
illegalIdentifierCharacters.add(RIGHT_PARENTHESIS)
illegalIdentifierCharacters.add(RIGHT_SQUARE_BRACKET)
illegalIdentifierCharacters.add(SEMICOLON)
illegalIdentifierCharacters.add(SINGLE_QUOTE)
}
fun isLegalIdentifierCharacter(c: Char) = !Character.isWhitespace(c) && !illegalIdentifierCharacters.contains(c)
fun isLegalStringCharacter(c: Char) = true
fun isNumberPrefix(c: Char) = c == DASH || c == PLUS
}

View File

@ -1,12 +0,0 @@
package util;
import java.io.File;
public final class Path {
private Path() {}
public static String getPathPrefix(String fileName) {
return fileName.substring(0, fileName.lastIndexOf(File.separator) + 1);
}
}

View File

@ -0,0 +1,8 @@
package util
import java.io.File
object Path {
fun getPathPrefix(fileName: String) = fileName.substring(0, fileName.lastIndexOf(File.separator) + 1)
}

View File

@ -6,6 +6,7 @@ import interpreter.LispInterpreterBuilder;
import interpreter.LispInterpreterBuilderImpl; import interpreter.LispInterpreterBuilderImpl;
import table.ExecutionContext; import table.ExecutionContext;
import table.FunctionTable; import table.FunctionTable;
import util.Path;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
@ -14,7 +15,6 @@ import java.io.FileNotFoundException;
import java.io.PrintStream; import java.io.PrintStream;
import static application.LispMain.LANGUAGE_FILE_NAMES; import static application.LispMain.LANGUAGE_FILE_NAMES;
import static util.Path.getPathPrefix;
public class LispInterpreterFixture { public class LispInterpreterFixture {
@ -63,7 +63,7 @@ public class LispInterpreterFixture {
public String evaluateFile(String inputFile) throws FileNotFoundException { public String evaluateFile(String inputFile) throws FileNotFoundException {
environment.setInputName(inputFile); environment.setInputName(inputFile);
environment.setInput(new FileInputStream(inputFile)); environment.setInput(new FileInputStream(inputFile));
environment.setPath(getPathPrefix(inputFile)); environment.setPath(Path.INSTANCE.getPathPrefix(inputFile));
return evaluate(); return evaluate();
} }

View File

@ -1,21 +0,0 @@
package util;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
public class CharactersTest {
@Test
public void constructorIsPrivate() throws Exception {
Constructor<Characters> constructor = Characters.class.getDeclaredConstructor();
assertThat(Modifier.isPrivate(constructor.getModifiers()), is(true));
constructor.setAccessible(true);
constructor.newInstance();
}
}

View File

@ -1,21 +0,0 @@
package util;
import org.junit.Test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
public class PathTest {
@Test
public void constructorIsPrivate() throws Exception {
Constructor<Path> constructor = Path.class.getDeclaredConstructor();
assertThat(Modifier.isPrivate(constructor.getModifiers()), is(true));
constructor.setAccessible(true);
constructor.newInstance();
}
}