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") (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,39 @@
(local (event channel) ...) (local (event channel) ...)
(when channel (defn display [s]
(let [prompt (fn [] (io.write "> ") (io.flush) (io.read "*l"))] (io.write s)
((fn looper [input] (io.flush))
(defn prompt []
(display "\n>> "))
(defn read-chunk []
(let [input (io.read)]
(when input (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) (love.event.push event input)
(print (: channel :demand)) (display (: channel :demand))))))))
(looper (prompt)))) (prompt))))
{: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,50 @@
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()
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) love.event.push(event, input)
print(channel:demand()) return display(channel:demand())
return looper(prompt())
end end
end end
return looper(prompt()) _1_(...)
end
end
return nil
end end
end end
_0_(...) _0_(...)
@ -47,4 +75,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}