Merge branch 'fix-multi-line-sexprs-in-repl' into 'master'

Adds support for entering multi-line sexprs in REPL

See merge request alexjgriffith/min-love2d-fennel!1
This commit is contained in:
Alexander Griffith 2018-11-12 00:26:01 +00:00
commit 05a2b28752
2 changed files with 72 additions and 18 deletions

View file

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

View file

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