Clean up data structure code
This commit is contained in:
		
							parent
							
								
									cb0e8a1d15
								
							
						
					
					
						commit
						8a970b6797
					
				@ -9,14 +9,13 @@ import java.io.FileInputStream
 | 
			
		||||
import java.io.FileNotFoundException
 | 
			
		||||
import java.io.InputStream
 | 
			
		||||
import java.io.PrintStream
 | 
			
		||||
import java.util.ArrayList
 | 
			
		||||
 | 
			
		||||
object LispInterpreterBuilder {
 | 
			
		||||
 | 
			
		||||
    private var inputName = ""
 | 
			
		||||
    private var isInteractive = true
 | 
			
		||||
    private var isFileBased = false
 | 
			
		||||
    private var languageFiles = ArrayList<LanguageFile>()
 | 
			
		||||
    private var languageFiles = mutableListOf<LanguageFile>()
 | 
			
		||||
    private var inputStream: InputStream? = null
 | 
			
		||||
    private var outputStream: PrintStream? = null
 | 
			
		||||
    private var errorOutputStream: PrintStream? = null
 | 
			
		||||
@ -36,7 +35,7 @@ object LispInterpreterBuilder {
 | 
			
		||||
        inputName = ""
 | 
			
		||||
        isInteractive = true
 | 
			
		||||
        isFileBased = false
 | 
			
		||||
        languageFiles = ArrayList()
 | 
			
		||||
        languageFiles = mutableListOf()
 | 
			
		||||
        inputStream = null
 | 
			
		||||
        outputStream = null
 | 
			
		||||
        errorOutputStream = null
 | 
			
		||||
@ -74,7 +73,7 @@ object LispInterpreterBuilder {
 | 
			
		||||
 | 
			
		||||
    fun setLanguageFileNames(vararg languageFiles: String) {
 | 
			
		||||
        val classLoader = javaClass.classLoader
 | 
			
		||||
        this.languageFiles = ArrayList()
 | 
			
		||||
        this.languageFiles = mutableListOf()
 | 
			
		||||
 | 
			
		||||
        for (fileName in languageFiles)
 | 
			
		||||
            this.languageFiles.add(LanguageFile(classLoader.getResourceAsStream(fileName), fileName))
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,6 @@ import util.Characters.NEWLINE
 | 
			
		||||
import util.Characters.isIdentifierCharacter
 | 
			
		||||
import util.Characters.isNumberPrefix
 | 
			
		||||
import java.io.InputStream
 | 
			
		||||
import java.lang.Character.isWhitespace
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 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()
 | 
			
		||||
                positionTracker.incrementColumn()
 | 
			
		||||
 | 
			
		||||
                if (!isWhitespace(currentCharacter))
 | 
			
		||||
                if (!currentCharacter.isWhitespace())
 | 
			
		||||
                    return createTokenFromCharacter(currentCharacter)
 | 
			
		||||
                else if (currentCharacter == NEWLINE)
 | 
			
		||||
                    positionTracker.incrementLine()
 | 
			
		||||
 | 
			
		||||
@ -50,63 +50,61 @@ import function.builtin.special.PROGN
 | 
			
		||||
import function.builtin.special.QUOTE
 | 
			
		||||
import function.builtin.special.RECUR
 | 
			
		||||
import function.builtin.special.SETQ
 | 
			
		||||
import java.util.HashMap
 | 
			
		||||
import java.util.HashSet
 | 
			
		||||
 | 
			
		||||
object FunctionTable {
 | 
			
		||||
 | 
			
		||||
    private var table = HashMap<String, LispFunction>()
 | 
			
		||||
    private val allBuiltIns = HashSet<Class<out LispFunction>>()
 | 
			
		||||
    private val allBuiltIns = setOf(
 | 
			
		||||
            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 {
 | 
			
		||||
        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)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -6,13 +6,11 @@ import sexpression.Cons
 | 
			
		||||
import sexpression.Nil.NIL
 | 
			
		||||
import sexpression.SExpression
 | 
			
		||||
import sexpression.Symbol
 | 
			
		||||
import java.util.HashMap
 | 
			
		||||
import java.util.TreeMap
 | 
			
		||||
import kotlin.collections.Map.Entry
 | 
			
		||||
 | 
			
		||||
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)
 | 
			
		||||
    operator fun contains(symbolName: String) = symbolName in table
 | 
			
		||||
@ -27,7 +25,7 @@ open class SymbolTable @JvmOverloads constructor(open val parent: SymbolTable? =
 | 
			
		||||
    fun toList(): Cons {
 | 
			
		||||
        var context: Cons = NIL
 | 
			
		||||
 | 
			
		||||
        for (binding in TreeMap(table).entries)
 | 
			
		||||
        for (binding in table.toSortedMap().entries)
 | 
			
		||||
            context = append(context, makeList(makeSymbolValuePair(binding)))
 | 
			
		||||
 | 
			
		||||
        return context
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,5 @@
 | 
			
		||||
package util
 | 
			
		||||
 | 
			
		||||
import java.util.HashSet
 | 
			
		||||
 | 
			
		||||
object Characters {
 | 
			
		||||
 | 
			
		||||
    const val EOF = -1
 | 
			
		||||
@ -24,24 +22,21 @@ object Characters {
 | 
			
		||||
    const val UNICODE_ESCAPE = '\u001B'
 | 
			
		||||
    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 {
 | 
			
		||||
        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 isIdentifierCharacter(c: Char) = !c.isWhitespace() && !illegalIdentifierCharacters.contains(c)
 | 
			
		||||
    fun isNumberPrefix(c: Char) = c == DASH || c == PLUS
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,7 +7,6 @@ import org.junit.jupiter.api.BeforeEach
 | 
			
		||||
import org.junit.jupiter.api.Test
 | 
			
		||||
import org.junit.jupiter.api.TestInstance
 | 
			
		||||
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
 | 
			
		||||
import java.util.HashSet
 | 
			
		||||
 | 
			
		||||
@TestInstance(PER_CLASS)
 | 
			
		||||
class RuntimeEnvironmentTest {
 | 
			
		||||
@ -17,7 +16,7 @@ class RuntimeEnvironmentTest {
 | 
			
		||||
        private const val TERMINATED_EXCEPTIONALLY = "TERMINATED_EXCEPTIONALLY"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val indicatorSet: MutableSet<String> = HashSet()
 | 
			
		||||
    private val indicatorSet = mutableSetOf<String>()
 | 
			
		||||
 | 
			
		||||
    @BeforeEach
 | 
			
		||||
    fun setUp() {
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,6 @@ import org.junit.jupiter.api.BeforeEach
 | 
			
		||||
import org.junit.jupiter.api.Test
 | 
			
		||||
import java.io.ByteArrayOutputStream
 | 
			
		||||
import java.io.PrintStream
 | 
			
		||||
import java.util.HashSet
 | 
			
		||||
 | 
			
		||||
class ErrorManagerTest {
 | 
			
		||||
 | 
			
		||||
@ -19,7 +18,7 @@ class ErrorManagerTest {
 | 
			
		||||
        private const val MESSAGE = "message"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val indicatorSet: MutableSet<String> = HashSet()
 | 
			
		||||
    private val indicatorSet = mutableSetOf<String>()
 | 
			
		||||
    private val errorOutputStream: ByteArrayOutputStream = ByteArrayOutputStream()
 | 
			
		||||
    private val outputStream: ByteArrayOutputStream = ByteArrayOutputStream()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,6 @@ import org.junit.jupiter.api.TestInstance
 | 
			
		||||
import org.junit.jupiter.api.TestInstance.Lifecycle.PER_CLASS
 | 
			
		||||
import testutil.SymbolAndFunctionCleaner
 | 
			
		||||
import testutil.TestUtilities.evaluateString
 | 
			
		||||
import java.util.HashSet
 | 
			
		||||
 | 
			
		||||
@TestInstance(PER_CLASS)
 | 
			
		||||
class ExitTest : SymbolAndFunctionCleaner() {
 | 
			
		||||
@ -18,7 +17,7 @@ class ExitTest : SymbolAndFunctionCleaner() {
 | 
			
		||||
        private const val TERMINATED = "terminated"
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private var indicatorSet = HashSet<String>()
 | 
			
		||||
    private val indicatorSet = mutableSetOf<String>()
 | 
			
		||||
 | 
			
		||||
    private fun assertTerminated() {
 | 
			
		||||
        assertThat(indicatorSet.contains(TERMINATED)).isTrue()
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,6 @@ import org.junit.Test
 | 
			
		||||
import testutil.TestUtilities.createInputStreamFromString
 | 
			
		||||
import java.io.ByteArrayOutputStream
 | 
			
		||||
import java.io.PrintStream
 | 
			
		||||
import java.util.HashSet
 | 
			
		||||
 | 
			
		||||
class LispInterpreterTest {
 | 
			
		||||
 | 
			
		||||
@ -20,9 +19,9 @@ class LispInterpreterTest {
 | 
			
		||||
        private val FILE = LispInterpreterTest::class.java.getResource("file.lisp").file
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private var indicatorSet = HashSet<String>()
 | 
			
		||||
    private var outputStream = ByteArrayOutputStream()
 | 
			
		||||
    private var errorOutputStream = ByteArrayOutputStream()
 | 
			
		||||
    private val indicatorSet = mutableSetOf<String>()
 | 
			
		||||
    private val outputStream = ByteArrayOutputStream()
 | 
			
		||||
    private val errorOutputStream = ByteArrayOutputStream()
 | 
			
		||||
 | 
			
		||||
    private fun setCommonFeatures() {
 | 
			
		||||
        LispInterpreterBuilder.setOutput(PrintStream(outputStream))
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,6 @@ import token.QuotedString
 | 
			
		||||
import token.RightParenthesis
 | 
			
		||||
import token.Token
 | 
			
		||||
import token.TokenFactory.BadCharacterException
 | 
			
		||||
import java.util.ArrayList
 | 
			
		||||
 | 
			
		||||
class LispScannerTypeTest {
 | 
			
		||||
 | 
			
		||||
@ -38,7 +37,7 @@ class LispScannerTypeTest {
 | 
			
		||||
 | 
			
		||||
    @Before
 | 
			
		||||
    fun setUp() {
 | 
			
		||||
        expectedTypes = ArrayList()
 | 
			
		||||
        expectedTypes = mutableListOf()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
 | 
			
		||||
@ -20,7 +20,6 @@ import table.FunctionTable.defineFunction
 | 
			
		||||
import table.FunctionTable.isAlreadyDefined
 | 
			
		||||
import table.FunctionTable.lookupFunction
 | 
			
		||||
import table.FunctionTable.resetFunctionTable
 | 
			
		||||
import java.util.HashSet
 | 
			
		||||
 | 
			
		||||
@TestInstance(PER_CLASS)
 | 
			
		||||
class FunctionTableTest {
 | 
			
		||||
@ -101,8 +100,7 @@ class FunctionTableTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `reset function table with custom built-ins`() {
 | 
			
		||||
        val goodBuiltIns = HashSet<Class<out LispFunction>>()
 | 
			
		||||
        goodBuiltIns.add(GoodFunction::class.java)
 | 
			
		||||
        val goodBuiltIns = setOf(GoodFunction::class.java)
 | 
			
		||||
 | 
			
		||||
        resetFunctionTable(goodBuiltIns)
 | 
			
		||||
 | 
			
		||||
@ -112,8 +110,7 @@ class FunctionTableTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `unable to initialize a built-in function`() {
 | 
			
		||||
        val badBuiltIns = HashSet<Class<out LispFunction>>()
 | 
			
		||||
        badBuiltIns.add(BadFunction::class.java)
 | 
			
		||||
        val badBuiltIns = setOf(BadFunction::class.java)
 | 
			
		||||
 | 
			
		||||
        assertThrows(LispFunctionInstantiationException::class.java) { resetFunctionTable(badBuiltIns) }
 | 
			
		||||
    }
 | 
			
		||||
@ -128,8 +125,7 @@ class FunctionTableTest {
 | 
			
		||||
 | 
			
		||||
    @Test
 | 
			
		||||
    fun `built-in without a name doesn't throw an exception`() {
 | 
			
		||||
        val namelessBuiltins = HashSet<Class<out LispFunction>>()
 | 
			
		||||
        namelessBuiltins.add(UglyFunction::class.java)
 | 
			
		||||
        val namelessBuiltins = setOf(UglyFunction::class.java)
 | 
			
		||||
 | 
			
		||||
        resetFunctionTable(namelessBuiltins)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user