LuaCatalog.kt
src/jvmMain/kotlin/afield/lang/lua/LuaCatalog.kt · 56 lines
package afield.lang.lua
The signatures and one-line descriptions that completion shows for Lua names, held to a live LuaJIT by LuaCatalogTest.
object LuaCatalog
What completion says about a Lua name: its signature and one line on what it does.
Two catalogs, both resources beside the prelude: lua-stdlib.txt for the Lua 5.1 library and
LuaJIT 2.1's additions (bit, jit, table.move, ...), and lua-field.txt for what Field's
prelude adds (display, line, play, field.*, the methods of a line). Neither is generated
from a header, because Lua's headers say nothing about Lua functions; instead LuaCatalogTest holds
each to a live LuaJIT state in both directions, the way Pd's object list is held to its pinned
sources: a function the state has and the catalog does not fails, and so does a line naming a
function the state no longer has.
object LuaCatalog {
class Entry(val name: String, val signature: String, val doc: String, val fromField: Boolean)
One catalogued function: name as it is reached (string.format, Line.moveTo, print).
private fun read(resource: String, fromField: Boolean): Map<String, Entry> {
val text = LuaCatalog::class.java.getResource(resource)?.readText() ?: return emptyMap()
val out = LinkedHashMap<String, Entry>()
for (raw in text.lines()) {
val line = raw.trim()
if (line.isEmpty() || line.startsWith("#")) continue
val signature = line.substringBefore("|").trim()
val doc = line.substringAfter("|", "").trim()
val name = signature.substringBefore("(").trim()
out[name] = Entry(name, signature, doc, fromField)
}
return out
}
val stdlib: Map<String, Entry> by lazy { read("/afield/lua/lua-stdlib.txt", fromField = false) }
The Lua and LuaJIT library.
val field: Map<String, Entry> by lazy { read("/afield/lua/lua-field.txt", fromField = true) }
What Field's prelude adds.
fun lookup(path: String, name: String): Entry?
The entry for name reached at path ("" for a global, "string", "field", "field.Line").
Field's entry wins where both have one — print goes to the box, not stdout.
fun lookup(path: String, name: String): Entry? {
val key = when (path) {
"" -> name
"field.Line" -> "Line.$name"
else -> "$path.$name"
}
return field[key] ?: stdlib[key]
}
}