{ *repl* = this incomplete-input = "" evaluate-all: [] in: _ := error: @no-expressions evaluate-all: [e] in: t := t evaluate: e evaluate-all: (e . es) in: t := { t evaluate: e evaluate-all: es in: t } call do-input: (s: String) in: env := { parsed = { (incomplete-input .. s) parse-expressions } with-restarts: { incomplete -> { *repl* incomplete-input = incomplete-input .. s .. "\n" [] } call } bind: { @(parse-error: (@(unexpected: e) . _) at: _) -> if: (e in?: ["", "ending"]) then: { restart: 'incomplete } else: { *repl* incomplete-input = "" } @(parse-error: _ at: _) -> (*repl* incomplete-input = "") } parsed match: { [] -> @ok es -> { *repl* incomplete-input = "" (evaluate-all: es in: env) show print } call } } call get-value: t := (interaction: "enter value: ") parse-expressions match: { [] -> get-value: t es -> evaluate-all: es in: t } get-n-values: 0 := [] get-n-values: n := (get-value: Lobby) . (get-n-values: (n - 1)) repl-debugger = Object clone do: { run: e := { Restart show-options-for: e { basic-repl } bind: { @prompt -> restart: 'use-prompt with: "[!]> " @(special: n) -> when: (n all?: @digit?) do: { r = Restart get: (n to: Integer) r jump: (get-n-values: r action arguments length) } } } call } (env: Object) basic-repl := { prompt = { signal: @prompt; "> " } with-restarts: { use-prompt -> { p | p } } in = { interaction: prompt } handle: { @end-of-input -> { signal: @quit; "" } call @interrupt -> { signal: @quit; "" } call } in match: { $: . name -> signal: @(special: name) source -> { try := { do-input: source in: env } with-restarts: { retry -> try abort -> @ok } try } call } signal: @loop } repeat (env: Object) repl := { stop | with: *debugger* as: repl-debugger do: { frame = 0 { env basic-repl } bind: { @prompt -> restart: 'use-prompt with: ( if: incomplete-input empty? then: { "[" .. frame show .. "]> " } else: { "." .. ($. repeat: frame show length) .. ".. " } ) @loop -> (super frame = frame + 1) when: incomplete-input empty? @(special: "h") -> ":h\thelp" print @quit -> { ask := { "really quit? (y/n) " display { read-char } (after: { "" print }) match: { $y -> stop yield $n -> @ok _ -> ask } } call ask } call } } } call/cc } call