Some maven dependencies were updated and alternative method of building an uberjar was added (currently commented out), since the shade plugin displays a warning for the module-info in ClassGraph.
75 lines
2.3 KiB
Kotlin
75 lines
2.3 KiB
Kotlin
package table
|
|
|
|
import error.CriticalLispException
|
|
import function.FunctionNames
|
|
import function.LispFunction
|
|
import io.github.classgraph.ClassGraph
|
|
|
|
object FunctionTable {
|
|
|
|
private val table = mutableMapOf<String, LispFunction>()
|
|
|
|
private val classGraph = ClassGraph()
|
|
.disableJarScanning()
|
|
.enableClassInfo()
|
|
.enableAnnotationInfo()
|
|
.whitelistPackages("function.builtin")
|
|
|
|
private val allBuiltIns = with(classGraph.scan()) {
|
|
getClassesWithAnnotation(FunctionNames::class.qualifiedName)
|
|
.map { it.loadClass() }
|
|
.filterIsInstance<Class<out LispFunction>>()
|
|
.toSet()
|
|
}
|
|
|
|
init {
|
|
initializeFunctionTable(allBuiltIns)
|
|
}
|
|
|
|
private fun initializeFunctionTable(builtIns: Set<Class<out LispFunction>>) {
|
|
table.clear()
|
|
|
|
for (function in builtIns)
|
|
addBuiltInFunctionToTable(function)
|
|
}
|
|
|
|
private fun addBuiltInFunctionToTable(function: Class<out LispFunction>) {
|
|
val functionNames = function.getAnnotation(FunctionNames::class.java)
|
|
|
|
if (functionNames != null)
|
|
addAllFunctionNamesToTable(function, functionNames.value)
|
|
}
|
|
|
|
private fun addAllFunctionNamesToTable(function: Class<out LispFunction>, names: Array<out String>) {
|
|
for (name in names)
|
|
table[name] = createInstance(function, name)
|
|
}
|
|
|
|
private fun createInstance(function: Class<out LispFunction>, name: String) = try {
|
|
function.getConstructor(String::class.java).newInstance(name)
|
|
} catch (e: Exception) {
|
|
throw LispFunctionInstantiationException(function.name)
|
|
}
|
|
|
|
fun lookupFunction(functionName: String) = table[functionName]
|
|
fun isAlreadyDefined(functionName: String) = table.containsKey(functionName)
|
|
|
|
fun defineFunction(functionName: String, function: LispFunction) {
|
|
table[functionName] = function
|
|
}
|
|
|
|
fun resetFunctionTable() {
|
|
initializeFunctionTable(allBuiltIns)
|
|
}
|
|
|
|
internal fun resetFunctionTable(builtIns: Set<Class<out LispFunction>>) {
|
|
initializeFunctionTable(builtIns)
|
|
}
|
|
|
|
class LispFunctionInstantiationException(private val functionName: String) : CriticalLispException() {
|
|
|
|
override val message: String
|
|
get() = "Could not create an instance of '$functionName'"
|
|
}
|
|
}
|