39 lines
1.2 KiB
Kotlin
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 }
|
|
}
|
|
}
|