IO Operators
This commit is contained in:
parent
b9f419a59d
commit
82a8fccf87
22 changed files with 450 additions and 199 deletions
|
@ -1,4 +1,90 @@
|
|||
package repl
|
||||
|
||||
import io.Logger
|
||||
import io.Terminal
|
||||
import parser.ReplParser
|
||||
import prolog.Answer
|
||||
import prolog.Answers
|
||||
|
||||
class Repl {
|
||||
private val io = Terminal()
|
||||
private val parser = ReplParser()
|
||||
|
||||
fun start() {
|
||||
io.say("Prolog REPL. Type '^D' to quit.\n")
|
||||
while (true) {
|
||||
try {
|
||||
printAnswers(query())
|
||||
} catch (e: Exception) {
|
||||
Logger.error("Error parsing REPL: ${e.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun query(): Answers {
|
||||
val queryString = io.prompt("?-", { "" })
|
||||
val query = parser.parse(queryString)
|
||||
return query.satisfy(emptyMap())
|
||||
}
|
||||
|
||||
fun printAnswers(answers: Answers) {
|
||||
val knownCommands = setOf(";", "a", ".", "h")
|
||||
|
||||
if (answers.none()) {
|
||||
io.say("false.")
|
||||
} else {
|
||||
val iterator = answers.iterator()
|
||||
var previous = iterator.next()
|
||||
io.say(prettyPrint(previous))
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
var command = io.prompt("")
|
||||
|
||||
while (command !in knownCommands) {
|
||||
io.say("Unknown action: $command (h for help)\n")
|
||||
command = io.prompt("Action?")
|
||||
}
|
||||
|
||||
when (command) {
|
||||
";" -> previous = iterator.next()
|
||||
"a" -> return
|
||||
"." -> return
|
||||
"h" -> {
|
||||
help()
|
||||
io.say("Action?")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
io.say(prettyPrint(previous))
|
||||
}
|
||||
|
||||
io.say("\n")
|
||||
}
|
||||
|
||||
fun help(): String {
|
||||
io.say("Commands:\n")
|
||||
io.say(" ; find next solution\n")
|
||||
io.say(" a abort\n")
|
||||
io.say(" . end query\n")
|
||||
io.say(" h help\n")
|
||||
return ""
|
||||
}
|
||||
|
||||
fun prettyPrint(result: Answer): String {
|
||||
result.fold(
|
||||
onSuccess = {
|
||||
val subs = result.getOrNull()!!
|
||||
if (subs.isEmpty()) {
|
||||
return "true."
|
||||
}
|
||||
return subs.entries.joinToString(",\n") { "${it.key} = ${it.value}" }
|
||||
},
|
||||
onFailure = {
|
||||
val text = "Failure: ${it.message}"
|
||||
Logger.warn(text)
|
||||
return text
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
Reference in a new issue