Clean up data structure code

This commit is contained in:
Mike Cifelli 2018-07-22 11:30:00 -04:00
parent cb0e8a1d15
commit 8a970b6797
11 changed files with 81 additions and 101 deletions

View File

@ -9,14 +9,13 @@ import java.io.FileInputStream
import java.io.FileNotFoundException import java.io.FileNotFoundException
import java.io.InputStream import java.io.InputStream
import java.io.PrintStream import java.io.PrintStream
import java.util.ArrayList
object LispInterpreterBuilder { object LispInterpreterBuilder {
private var inputName = "" private var inputName = ""
private var isInteractive = true private var isInteractive = true
private var isFileBased = false private var isFileBased = false
private var languageFiles = ArrayList<LanguageFile>() private var languageFiles = mutableListOf<LanguageFile>()
private var inputStream: InputStream? = null private var inputStream: InputStream? = null
private var outputStream: PrintStream? = null private var outputStream: PrintStream? = null
private var errorOutputStream: PrintStream? = null private var errorOutputStream: PrintStream? = null
@ -36,7 +35,7 @@ object LispInterpreterBuilder {
inputName = "" inputName = ""
isInteractive = true isInteractive = true
isFileBased = false isFileBased = false
languageFiles = ArrayList() languageFiles = mutableListOf()
inputStream = null inputStream = null
outputStream = null outputStream = null
errorOutputStream = null errorOutputStream = null
@ -74,7 +73,7 @@ object LispInterpreterBuilder {
fun setLanguageFileNames(vararg languageFiles: String) { fun setLanguageFileNames(vararg languageFiles: String) {
val classLoader = javaClass.classLoader val classLoader = javaClass.classLoader
this.languageFiles = ArrayList() this.languageFiles = mutableListOf()
for (fileName in languageFiles) for (fileName in languageFiles)
this.languageFiles.add(LanguageFile(classLoader.getResourceAsStream(fileName), fileName)) this.languageFiles.add(LanguageFile(classLoader.getResourceAsStream(fileName), fileName))

View File

@ -11,7 +11,6 @@ import util.Characters.NEWLINE
import util.Characters.isIdentifierCharacter import util.Characters.isIdentifierCharacter
import util.Characters.isNumberPrefix import util.Characters.isNumberPrefix
import java.io.InputStream import java.io.InputStream
import java.lang.Character.isWhitespace
/** /**
* Converts a stream of bytes into a stream of Lisp tokens. * Converts a stream of bytes into a stream of Lisp tokens.
@ -28,7 +27,7 @@ class LispScanner(inputStream: InputStream, fileName: String) {
val currentCharacter = c.toChar() val currentCharacter = c.toChar()
positionTracker.incrementColumn() positionTracker.incrementColumn()
if (!isWhitespace(currentCharacter)) if (!currentCharacter.isWhitespace())
return createTokenFromCharacter(currentCharacter) return createTokenFromCharacter(currentCharacter)
else if (currentCharacter == NEWLINE) else if (currentCharacter == NEWLINE)
positionTracker.incrementLine() positionTracker.incrementLine()

View File

@ -50,63 +50,61 @@ import function.builtin.special.PROGN
import function.builtin.special.QUOTE import function.builtin.special.QUOTE
import function.builtin.special.RECUR import function.builtin.special.RECUR
import function.builtin.special.SETQ import function.builtin.special.SETQ
import java.util.HashMap
import java.util.HashSet
object FunctionTable { object FunctionTable {
private var table = HashMap<String, LispFunction>() private val allBuiltIns = setOf(
private val allBuiltIns = HashSet<Class<out LispFunction>>() AND::class.java,
APPEND::class.java,
APPLY::class.java,
ATOM::class.java,
CASE::class.java,
COND::class.java,
CONS::class.java,
DEFINE_SPECIAL::class.java,
DEFMACRO::class.java,
DEFUN::class.java,
DIVIDE::class.java,
EQ::class.java,
EQUAL::class.java,
NumericEqual::class.java,
EVAL::class.java,
Exit::class.java,
FIRST::class.java,
FUNCALL::class.java,
FUSE::class.java,
GENSYM::class.java,
GENSYM_EQUAL::class.java,
NUMERIC_GREATER::class.java,
IF::class.java,
Lambda::class.java,
LENGTH::class.java,
NUMERIC_LESS::class.java,
LET::class.java,
LET_STAR::class.java,
LIST::class.java,
LISTP::class.java,
LOAD::class.java,
MINUS::class.java,
MODULO::class.java,
MULTIPLY::class.java,
NULL::class.java,
OR::class.java,
PLUS::class.java,
PRINT::class.java,
PROGN::class.java,
QUOTE::class.java,
RECUR::class.java,
REMAINDER::class.java,
REST::class.java,
SET::class.java,
SETQ::class.java,
SYMBOL_FUNCTION::class.java,
SYMBOLS::class.java)
private val table = mutableMapOf<String, LispFunction>()
init { init {
allBuiltIns.add(AND::class.java)
allBuiltIns.add(APPEND::class.java)
allBuiltIns.add(APPLY::class.java)
allBuiltIns.add(ATOM::class.java)
allBuiltIns.add(CASE::class.java)
allBuiltIns.add(COND::class.java)
allBuiltIns.add(CONS::class.java)
allBuiltIns.add(DEFINE_SPECIAL::class.java)
allBuiltIns.add(DEFMACRO::class.java)
allBuiltIns.add(DEFUN::class.java)
allBuiltIns.add(DIVIDE::class.java)
allBuiltIns.add(EQ::class.java)
allBuiltIns.add(EQUAL::class.java)
allBuiltIns.add(NumericEqual::class.java)
allBuiltIns.add(EVAL::class.java)
allBuiltIns.add(Exit::class.java)
allBuiltIns.add(FIRST::class.java)
allBuiltIns.add(FUNCALL::class.java)
allBuiltIns.add(FUSE::class.java)
allBuiltIns.add(GENSYM::class.java)
allBuiltIns.add(GENSYM_EQUAL::class.java)
allBuiltIns.add(NUMERIC_GREATER::class.java)
allBuiltIns.add(IF::class.java)
allBuiltIns.add(Lambda::class.java)
allBuiltIns.add(LENGTH::class.java)
allBuiltIns.add(NUMERIC_LESS::class.java)
allBuiltIns.add(LET::class.java)
allBuiltIns.add(LET_STAR::class.java)
allBuiltIns.add(LIST::class.java)
allBuiltIns.add(LISTP::class.java)
allBuiltIns.add(LOAD::class.java)
allBuiltIns.add(MINUS::class.java)
allBuiltIns.add(MODULO::class.java)
allBuiltIns.add(MULTIPLY::class.java)
allBuiltIns.add(NULL::class.java)
allBuiltIns.add(OR::class.java)
allBuiltIns.add(PLUS::class.java)
allBuiltIns.add(PRINT::class.java)
allBuiltIns.add(PROGN::class.java)
allBuiltIns.add(QUOTE::class.java)
allBuiltIns.add(RECUR::class.java)
allBuiltIns.add(REMAINDER::class.java)
allBuiltIns.add(REST::class.java)
allBuiltIns.add(SET::class.java)
allBuiltIns.add(SETQ::class.java)
allBuiltIns.add(SYMBOL_FUNCTION::class.java)
allBuiltIns.add(SYMBOLS::class.java)
initializeFunctionTable(allBuiltIns) initializeFunctionTable(allBuiltIns)
} }

View File

@ -6,13 +6,11 @@ import sexpression.Cons
import sexpression.Nil.NIL import sexpression.Nil.NIL
import sexpression.SExpression import sexpression.SExpression
import sexpression.Symbol import sexpression.Symbol
import java.util.HashMap
import java.util.TreeMap
import kotlin.collections.Map.Entry import kotlin.collections.Map.Entry
open class SymbolTable @JvmOverloads constructor(open val parent: SymbolTable? = NullSymbolTable) : Iterable<SymbolTable> { open class SymbolTable @JvmOverloads constructor(open val parent: SymbolTable? = NullSymbolTable) : Iterable<SymbolTable> {
private val table: HashMap<String, SExpression> = HashMap() private val table = mutableMapOf<String, SExpression>()
override fun iterator(): Iterator<SymbolTable> = SymbolTableIterator(this) override fun iterator(): Iterator<SymbolTable> = SymbolTableIterator(this)
operator fun contains(symbolName: String) = symbolName in table operator fun contains(symbolName: String) = symbolName in table
@ -27,7 +25,7 @@ open class SymbolTable @JvmOverloads constructor(open val parent: SymbolTable? =
fun toList(): Cons { fun toList(): Cons {
var context: Cons = NIL var context: Cons = NIL
for (binding in TreeMap(table).entries) for (binding in table.toSortedMap().entries)
context = append(context, makeList(makeSymbolValuePair(binding))) context = append(context, makeList(makeSymbolValuePair(binding)))
return context return context

View File

@ -1,7 +1,5 @@
package util package util
import java.util.HashSet
object Characters { object Characters {
const val EOF = -1 const val EOF = -1
@ -24,24 +22,21 @@ object Characters {
const val UNICODE_ESCAPE = '\u001B' const val UNICODE_ESCAPE = '\u001B'
const val UNICODE_NULL = '\u0000' const val UNICODE_NULL = '\u0000'
private val illegalIdentifierCharacters = HashSet<Char>() private val illegalIdentifierCharacters =
setOf(AT_SIGN,
BACKQUOTE,
BACKSLASH,
COMMA,
DOUBLE_QUOTE,
HASH,
LEFT_PARENTHESIS,
LEFT_SQUARE_BRACKET,
PERIOD,
RIGHT_PARENTHESIS,
RIGHT_SQUARE_BRACKET,
SEMICOLON,
SINGLE_QUOTE)
init { fun isIdentifierCharacter(c: Char) = !c.isWhitespace() && !illegalIdentifierCharacters.contains(c)
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 isIdentifierCharacter(c: Char) = !Character.isWhitespace(c) && !illegalIdentifierCharacters.contains(c)
fun isNumberPrefix(c: Char) = c == DASH || c == PLUS fun isNumberPrefix(c: Char) = c == DASH || c == PLUS
} }

View File

@ -7,7 +7,6 @@ import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
import java.util.HashSet
@TestInstance(PER_CLASS) @TestInstance(PER_CLASS)
class RuntimeEnvironmentTest { class RuntimeEnvironmentTest {
@ -17,7 +16,7 @@ class RuntimeEnvironmentTest {
private const val TERMINATED_EXCEPTIONALLY = "TERMINATED_EXCEPTIONALLY" private const val TERMINATED_EXCEPTIONALLY = "TERMINATED_EXCEPTIONALLY"
} }
private val indicatorSet: MutableSet<String> = HashSet() private val indicatorSet = mutableSetOf<String>()
@BeforeEach @BeforeEach
fun setUp() { fun setUp() {

View File

@ -10,7 +10,6 @@ import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.PrintStream import java.io.PrintStream
import java.util.HashSet
class ErrorManagerTest { class ErrorManagerTest {
@ -19,7 +18,7 @@ class ErrorManagerTest {
private const val MESSAGE = "message" private const val MESSAGE = "message"
} }
private val indicatorSet: MutableSet<String> = HashSet() private val indicatorSet = mutableSetOf<String>()
private val errorOutputStream: ByteArrayOutputStream = ByteArrayOutputStream() private val errorOutputStream: ByteArrayOutputStream = ByteArrayOutputStream()
private val outputStream: ByteArrayOutputStream = ByteArrayOutputStream() private val outputStream: ByteArrayOutputStream = ByteArrayOutputStream()

View File

@ -9,7 +9,6 @@ import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
import testutil.SymbolAndFunctionCleaner import testutil.SymbolAndFunctionCleaner
import testutil.TestUtilities.evaluateString import testutil.TestUtilities.evaluateString
import java.util.HashSet
@TestInstance(PER_CLASS) @TestInstance(PER_CLASS)
class ExitTest : SymbolAndFunctionCleaner() { class ExitTest : SymbolAndFunctionCleaner() {
@ -18,7 +17,7 @@ class ExitTest : SymbolAndFunctionCleaner() {
private const val TERMINATED = "terminated" private const val TERMINATED = "terminated"
} }
private var indicatorSet = HashSet<String>() private val indicatorSet = mutableSetOf<String>()
private fun assertTerminated() { private fun assertTerminated() {
assertThat(indicatorSet.contains(TERMINATED)).isTrue() assertThat(indicatorSet.contains(TERMINATED)).isTrue()

View File

@ -11,7 +11,6 @@ import org.junit.Test
import testutil.TestUtilities.createInputStreamFromString import testutil.TestUtilities.createInputStreamFromString
import java.io.ByteArrayOutputStream import java.io.ByteArrayOutputStream
import java.io.PrintStream import java.io.PrintStream
import java.util.HashSet
class LispInterpreterTest { class LispInterpreterTest {
@ -20,9 +19,9 @@ class LispInterpreterTest {
private val FILE = LispInterpreterTest::class.java.getResource("file.lisp").file private val FILE = LispInterpreterTest::class.java.getResource("file.lisp").file
} }
private var indicatorSet = HashSet<String>() private val indicatorSet = mutableSetOf<String>()
private var outputStream = ByteArrayOutputStream() private val outputStream = ByteArrayOutputStream()
private var errorOutputStream = ByteArrayOutputStream() private val errorOutputStream = ByteArrayOutputStream()
private fun setCommonFeatures() { private fun setCommonFeatures() {
LispInterpreterBuilder.setOutput(PrintStream(outputStream)) LispInterpreterBuilder.setOutput(PrintStream(outputStream))

View File

@ -20,7 +20,6 @@ import token.QuotedString
import token.RightParenthesis import token.RightParenthesis
import token.Token import token.Token
import token.TokenFactory.BadCharacterException import token.TokenFactory.BadCharacterException
import java.util.ArrayList
class LispScannerTypeTest { class LispScannerTypeTest {
@ -38,7 +37,7 @@ class LispScannerTypeTest {
@Before @Before
fun setUp() { fun setUp() {
expectedTypes = ArrayList() expectedTypes = mutableListOf()
} }
@Test @Test

View File

@ -20,7 +20,6 @@ import table.FunctionTable.defineFunction
import table.FunctionTable.isAlreadyDefined import table.FunctionTable.isAlreadyDefined
import table.FunctionTable.lookupFunction import table.FunctionTable.lookupFunction
import table.FunctionTable.resetFunctionTable import table.FunctionTable.resetFunctionTable
import java.util.HashSet
@TestInstance(PER_CLASS) @TestInstance(PER_CLASS)
class FunctionTableTest { class FunctionTableTest {
@ -101,8 +100,7 @@ class FunctionTableTest {
@Test @Test
fun `reset function table with custom built-ins`() { fun `reset function table with custom built-ins`() {
val goodBuiltIns = HashSet<Class<out LispFunction>>() val goodBuiltIns = setOf(GoodFunction::class.java)
goodBuiltIns.add(GoodFunction::class.java)
resetFunctionTable(goodBuiltIns) resetFunctionTable(goodBuiltIns)
@ -112,8 +110,7 @@ class FunctionTableTest {
@Test @Test
fun `unable to initialize a built-in function`() { fun `unable to initialize a built-in function`() {
val badBuiltIns = HashSet<Class<out LispFunction>>() val badBuiltIns = setOf(BadFunction::class.java)
badBuiltIns.add(BadFunction::class.java)
assertThrows(LispFunctionInstantiationException::class.java) { resetFunctionTable(badBuiltIns) } assertThrows(LispFunctionInstantiationException::class.java) { resetFunctionTable(badBuiltIns) }
} }
@ -128,8 +125,7 @@ class FunctionTableTest {
@Test @Test
fun `built-in without a name doesn't throw an exception`() { fun `built-in without a name doesn't throw an exception`() {
val namelessBuiltins = HashSet<Class<out LispFunction>>() val namelessBuiltins = setOf(UglyFunction::class.java)
namelessBuiltins.add(UglyFunction::class.java)
resetFunctionTable(namelessBuiltins) resetFunctionTable(namelessBuiltins)