62 lines
1.8 KiB
Kotlin
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
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|