# SPDX-FileCopyrightText: ☭ Emery Hemingway # SPDX-License-Identifier: Unlicense ## This was all Tony's idea, except for the silly name. import std/[asyncdispatch, os, terminal] import preserves import syndicate, syndicate/[durings, relays] import illwill proc exitProc() {.noconv.} = illwillDeinit() showCursor() quit QuitSuccess setControlCHook(exitProc) proc parsePattern(pr: Assertion): Pattern = let dropSigil = initRecord("lit", "_".toSymbol(Cap)) grabSigil = initRecord("lit", "?".toSymbol(Cap)) var pr = grab(pr).toPreserve(Cap) apply(pr) do (pr: var Assertion): if pr == dropSigil: pr = initRecord[Cap]("_") elif pr == grabSigil: pr = initRecord("bind", initRecord[Cap]("_")) doAssert result.fromPreserve(pr) proc inputPattern: Pattern = var args = commandLineParams() if args.len != 1: quit "expected a single pattern argument" else: var input = pop args if input == "": quit "expected Preserves Pattern on stdin" else: var pr: Assertion try: pr = decodePreserves(input, Cap) except ValueError: discard try: pr = parsePreserves(input, Cap) except ValueError: discard if pr.isFalse: quit "failed to parse Preserves argument" result = parsePattern(pr) type TermEntity {.final.} = ref object of Entity pattern: Pattern value: Assertion method publish(te: TermEntity; turn: var Turn; v: AssertionRef; h: Handle) = te.value = v.value var termBuf = newTerminalBuffer(terminalWidth(), terminalHeight()) var y = 1 termBuf.write(1, y, $te.pattern, styleBright) inc(y) termBuf.drawHorizLine(0, termBuf.width(), y) inc(y) termBuf.write(0, y, $h, styleBright) for i, e in te.value.sequence: inc(y) termBuf.write(1, y, $e) termBuf.display() method retract(te: TermEntity; turn: var Turn; h: Handle) = var termBuf = newTerminalBuffer(terminalWidth(), terminalHeight()) var y = 1 termBuf.write(1, y, $te.pattern, styleDim) inc y termBuf.drawHorizLine(0, termBuf.width(), y, true) inc(y) termBuf.write(0, y, $h, styleBright) if te.value.isSequence: for i, e in te.value.sequence: inc(y) termBuf.write(1, y, $e) else: inc(y) termBuf.write(1, y, $te.value) termBuf.display() type DumpEntity {.final.} = ref object of Entity discard method publish(dump: DumpEntity; turn: var Turn; ass: AssertionRef; h: Handle) = stdout.writeLine($ass.value) stdout.flushFile() method message*(dump: DumpEntity; turn: var Turn; ass: AssertionRef) = stdout.writeLine($ass.value) stdout.flushFile() proc exit {.noconv.} = illwillDeinit() showCursor() quit() setControlCHook(exit) proc main = let route = envRoute() pat = inputPattern() if stdout.is_a_TTY: illwillInit() hideCursor() discard bootDataspace("syndex_card") do (turn: var Turn; root: Cap): resolve(turn, root, route) do (turn: var Turn; ds: Cap): var termBuf = newTerminalBuffer(terminalWidth(), terminalHeight()) termBuf.write(1, 1, $pat, styleBright) termBuf.drawHorizLine(1, termBuf.width(), 2) termBuf.display() discard observe(turn, ds, pat, TermEntity(pattern: pat)) while true: try: poll() except CatchableError: illwillDeinit() showCursor() quit getCurrentExceptionMsg() else: let entity = DumpEntity() runActor("syndex_card") do (root: Cap; turn: var Turn): resolve(turn, root, route) do (turn: var Turn; ds: Cap): discard observe(turn, ds, pat, entity) main()