Skip to content

ForthDocsSupport.kt

src/jvmMain/kotlin/afield/tools/docs/ForthDocsSupport.kt · 43 lines

package afield.tools.docs

import afield.document.graph.Box
import afield.lang.forth.ForthInterpreter
import afield.geometry.path.FLine
import afield.ui.visualization.lines
import afield.ui.visualization.h

fun Box.renderForthDocsSnippet(source: String)

fun Box.renderForthDocsSnippet(source: String) {
    val forth = ForthInterpreter()
    val stdout = StringBuilder()
    var hadDisplay = false

    forth.onOutput = { text ->
        print(text)
        stdout.append(text)
    }
    forth.onDisplay = { channel, content ->
        hadDisplay = true
        display(channel, content?.toString() ?: "")
    }

    val diagnostics = forth.eval(source)
    if (diagnostics.isNotEmpty()) {
        val message = diagnostics.joinToString("\n") { diag ->
            val prefix = if (diag.line >= 0) "line ${diag.line + 1}: " else ""
            prefix + diag.message
        }
        throw IllegalStateException(message)
    }

    val forthLines = forth.stack.filterIsInstance<FLine>()
    if (forthLines.isNotEmpty()) {
        lines(forthLines, channel = "lines", w = 460.0, h = 320.0, fitToSize = true)
    } else if (!hadDisplay && stdout.isNotBlank()) {
        display("stdout", stdout.toString())
    } else if (!hadDisplay && forth.stack.isNotEmpty()) {
        display("stack", forth.stack.toList().h)
    } else if (!hadDisplay) {
        display("status", "<em>ok</em>")
    }
}