transcendental-lisp/src/main/kotlin/table/SymbolTable.kt
2018-03-23 18:12:47 -04:00

62 lines
1.8 KiB
Kotlin

package table
import function.builtin.cons.APPEND.append
import function.builtin.cons.LIST.makeList
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> {
val isGlobal: Boolean
get() = parent === NullSymbolTable
private val table: HashMap<String, SExpression> = HashMap()
private val sortedBindings: Set<Entry<String, SExpression>>
get() = TreeMap(table).entries
override fun iterator(): Iterator<SymbolTable> = SymbolTableIterator(this)
operator fun contains(symbolName: String) = table.containsKey(symbolName)
operator fun get(symbolName: String) = table[symbolName]
operator fun set(symbolName: String, value: SExpression) {
table[symbolName] = value
}
fun toList(): Cons {
var context: Cons = NIL
for (binding in sortedBindings)
context = append(context, makeList(makeSymbolValuePair(binding)))
return context
}
private fun makeSymbolValuePair(binding: Entry<String, SExpression>) =
Cons(Symbol(binding.key), makeList(binding.value))
object NullSymbolTable : SymbolTable(null) {
override val parent: SymbolTable
get() = this
}
private class SymbolTableIterator(private var symbolTable: SymbolTable) : AbstractIterator<SymbolTable>() {
override fun computeNext() {
when (symbolTable) {
is NullSymbolTable -> done()
else -> {
setNext(symbolTable)
symbolTable = symbolTable.parent ?: NullSymbolTable
}
}
}
}
}