IO Operators

This commit is contained in:
Tibo De Peuter 2025-04-27 20:11:15 +02:00
parent b9f419a59d
commit 82a8fccf87
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
22 changed files with 450 additions and 199 deletions

View file

@ -1,5 +1,8 @@
package prolog.builtins
import io.Logger
import io.Terminal
import parser.ReplParser
import prolog.Answers
import prolog.Substitutions
import prolog.ast.logic.Satisfiable
@ -7,13 +10,60 @@ import prolog.ast.terms.Atom
import prolog.ast.terms.Operator
import prolog.ast.terms.Term
import prolog.logic.applySubstitution
import prolog.logic.unifyLazy
/**
* Write [Term] to the current output, using brackets and operators where appropriate.
*/
class Write(private val term: Term) : Operator(Atom("write"), null, term), Satisfiable {
override fun satisfy(subs: Substitutions): Answers {
val t = applySubstitution(term, subs)
println(t.toString())
Terminal().say(t.toString())
return sequenceOf(Result.success(emptyMap()))
}
}
}
/**
* Write a newline character to the current output stream.
*/
object Nl : Atom("nl"), Satisfiable {
override fun satisfy(subs: Substitutions): Answers {
Terminal().say("\n")
return sequenceOf(Result.success(emptyMap()))
}
}
/**
* Read the next Prolog term from the current input stream and unify it with [Term].
*
* On reaching end-of-file, [Term] is unified with the [Atom] `end_of_file`.
*/
class Read(private val term: Term) : Operator(Atom("read"), null, term), Satisfiable {
private val io = Terminal()
private val parser = ReplParser()
private fun readTerm(): Term {
val input = io.readLine()
Logger.debug("Read input: $input")
return when (input) {
"end_of_file" -> Atom("end_of_file")
else -> {
val out = parser.parse(input).query
Logger.debug("Parsed input: $out")
out as? Term ?: throw IllegalArgumentException("Expected a term, but got: $out")
}
}
}
override fun satisfy(subs: Substitutions): Answers = sequence {
val t1 = applySubstitution(term, subs)
val t2 = readTerm()
Logger.debug("Read term: $t2")
yieldAll(unifyLazy(t1, t2, subs))
}
}