Adds support for entering multi-line sexprs in REPL

This commit is contained in:
Ram Krishnan 2018-11-10 19:50:10 -08:00
parent a47d82460c
commit dd418aa196
2 changed files with 71 additions and 18 deletions

View file

@ -1,4 +1,5 @@
(require "love.event") (require "love.event")
(local fennel (require "lib.fennel"))
(local view (require "lib.fennelview")) (local view (require "lib.fennelview"))
;; This module exists in order to expose stdio over a channel so that it ;; This module exists in order to expose stdio over a channel so that it
@ -6,14 +7,37 @@
(local (event channel) ...) (local (event channel) ...)
(defn display [s]
(io.write s)
(io.flush))
(defn prompt []
(display "\n>> "))
(defn read-chunk []
(let [input (io.read)]
(when input
(.. input "\n"))))
(var input "")
(when channel (when channel
(let [prompt (fn [] (io.write "> ") (io.flush) (io.read "*l"))] (let [(bytestream clearstream) (fennel.granulate read-chunk)
((fn looper [input] read (fennel.parser
(when input (fn []
;; This is consumed by love.handlers[event] (let [c (or (bytestream) 10)]
(love.event.push event input) (set input (.. input (string.char c)))
(print (: channel :demand)) c)))]
(looper (prompt)))) (prompt)))) (while true
(prompt)
(set input "")
(let [(ok ast) (read)]
(if (not ok)
(do
(display (.. "Error:" (view ast) "\n"))
(clearstream))
(do
(love.event.push event input)
(display (: channel :demand))))))))
{:start (fn start-repl [] {:start (fn start-repl []
(let [code (love.filesystem.read "stdio.fnl") (let [code (love.filesystem.read "stdio.fnl")

View file

@ -1,22 +1,51 @@
require("love.event") require("love.event")
local fennel = require("lib.fennel")
local view = require("lib.fennelview") local view = require("lib.fennelview")
local event, channel = ... local event, channel = ...
local function display(s)
io.write(s)
return io.flush()
end
do local _ = display end
local function prompt()
return display("\n>> ")
end
do local _ = prompt end
local function read_chunk()
local input = io.read()
if input then
return (input .. "\n")
end
end
do local _ = read_chunk end
local input = ""
local function _0_(...) local function _0_(...)
if channel then if channel then
local bytestream, clearstream = fennel.granulate(read_chunk)
local function _0_() local function _0_()
io.write("> ") local c = (bytestream() or 10)
io.flush() input = (input .. string.char(c))
return io.read("*l") return c
end end
local prompt = _0_ local read = fennel.parser(_0_)
local function looper(input) while true do
if input then prompt()
love.event.push(event, input) input = ""
print(channel:demand()) do
return looper(prompt()) local ok, ast = read()
local function _1_(...)
if not ok then
display(("Error:" .. view(ast) .. "\n"))
return clearstream()
else
love.event.push(event, input)
return display(channel:demand())
end
end
_1_(...)
end end
end end
return looper(prompt()) return nil
end end
end end
_0_(...) _0_(...)
@ -47,4 +76,4 @@ local function start_repl()
love.handlers.eval = _2_ love.handlers.eval = _2_
return nil return nil
end end
return ({start = start_repl}) return {start = start_repl}