transcendental-lisp/src/main/kotlin/sexpression/Cons.kt

39 lines
1.2 KiB
Kotlin

package sexpression
import recursion.MutualTailCall
import recursion.MutualTailCalls.terminalValue
import recursion.MutualTailCalls.recursiveCall
@DisplayName("list")
open class Cons(open var first: SExpression, open var rest: SExpression) : SExpression(), Iterable<Cons> {
override val isCons = true
override fun toString(): String {
return toStringTailRecursive(StringBuilder("(")).invoke()
}
private fun toStringTailRecursive(leadingString: StringBuilder): MutualTailCall<String> {
leadingString.append(first.toString())
if (rest.isNull)
return terminalValue(leadingString.append(")").toString())
else if (rest.isCons) {
return recursiveCall { (rest as Cons).toStringTailRecursive(leadingString.append(" ")) }
}
return terminalValue(leadingString.append(" . $rest)").toString())
}
override fun iterator(): Iterator<Cons> = ConsIterator(this)
private class ConsIterator(start: Cons) : Iterator<Cons> {
private var current: SExpression = start
override fun hasNext() = current.isCons
override fun next() = (current as Cons).apply { current = rest }
}
}