52 lines
1.3 KiB
Kotlin
52 lines
1.3 KiB
Kotlin
package function.builtin
|
|
|
|
import function.ArgumentValidator
|
|
import function.FunctionNames
|
|
import function.LispFunction
|
|
import sexpression.Cons
|
|
import sexpression.SExpression
|
|
import sexpression.Symbol
|
|
import table.ExecutionContext
|
|
import table.FunctionTable.lookupFunction
|
|
import table.SymbolTable
|
|
|
|
@FunctionNames("SET")
|
|
class Set(name: String) : LispFunction() {
|
|
|
|
private val argumentValidator = ArgumentValidator(name).apply {
|
|
setExactNumberOfArguments(2)
|
|
setFirstArgumentExpectedType(Symbol::class.java)
|
|
|
|
}
|
|
|
|
override fun call(argumentList: Cons): SExpression {
|
|
argumentValidator.validate(argumentList)
|
|
|
|
val rest = argumentList.rest as Cons
|
|
val symbol = argumentList.first
|
|
val value = rest.first
|
|
|
|
val table = findScopeOfSymbol(symbol)
|
|
table[symbol.toString()] = value
|
|
|
|
return value
|
|
}
|
|
|
|
private fun findScopeOfSymbol(symbol: SExpression): SymbolTable {
|
|
var table: SymbolTable = ExecutionContext.scope
|
|
|
|
while (!isSymbolInTable(symbol, table) && !table.isGlobal())
|
|
table = table.parent!!
|
|
|
|
return table
|
|
}
|
|
|
|
private fun isSymbolInTable(symbol: SExpression, table: SymbolTable) =
|
|
table.contains(symbol.toString())
|
|
|
|
companion object {
|
|
|
|
fun set(argumentList: Cons) = lookupFunction("SET")!!.call(argumentList)
|
|
}
|
|
}
|