Warning: this is an htmlized version!
The original is across this link,
and the conversion rules are here.
-- repl.lua:
-- This file:
--   http://angg.twu.net/dednat5/repl.lua.html
--   http://angg.twu.net/dednat5/repl.lua
--                    (find-dn5 "repl.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
-- Version: 2011jul27
-- License: GPL3
--

-- (find-es "lua5" "loadstring_and_eof")
-- (find-es "lua5" "traceback")
-- (find-luamanualw3m "#pdf-xpcall")
-- (find-luamanualw3m "#pdf-unpack")
-- (find-luamanualw3m "#pdf-select")
-- (find-TH "repl")


require "common"     -- (find-dn5 "common.lua")
require "eoo"        -- (find-dn5 "eoo.lua")

Repl = Class {
  type    = "Repl",
  __index = {
    prefixbody = function (repl, str) return str:match("^ *(=?=?=?)(.*)") end,
    incomplete_pat = "unexpected symbol near '<eof>'",
    incomplete_lua = function (repl, str)
        local f, err = loadstring(str)
        if err and err:match(repl.incomplete_pat) then return "incomplete" end
      end,
    incomplete = function (repl)
        local prefix, body = repl:prefixbody(repl.str)
        if prefix == "" then return repl:incomplete_lua(body) end
        if prefix == "=" then return repl:incomplete_lua("return "..body) end
        if prefix == "==" then return repl:incomplete_lua("return "..body) end
        if prefix == "===" then return repl:incomplete3(body) end
      end,
    eval_lua = function (repl, str, p)
        local f, err = loadstring(str)
        if err then print(err); return end
        local handler  = function () print(debug.traceback()) end
        local out      = pack(xpcall(f, handler))
        local fresults = function () return unpack(out, 2, out.n) end
        if out[1] then
          if p then return p(fresults()) else return fresults() end
        end
      end,
    eval = function (repl)
        local prefix, body = repl:prefixbody(repl.str)
        if prefix == "" then return repl:eval_lua(body) end
        if prefix == "=" then return repl:eval_lua("return "..body, print) end
        if prefix == "==" then return repl:eval_lua("return "..body, PP) end
        if prefix == "===" then return repl:eval3(body) end
      end,
    incomplete3 = function (repl, body) error "Not implemented: ===" end,
    eval3       = function (repl, body) error "Not implemented: ===" end,
    PS1 = "D> ",
    PS2 = "DD> ",
    abort_pat = "^ *%^D$",
    read_ = function (repl, prompt) io.write(prompt); return io.read() end,
    read1 = function (repl) return repl:read_(repl.PS1) end,
    read2 = function (repl) return repl:read_(repl.PS2) end,
    read = function (repl)
        repl.str = repl:read1()
        if repl.str:match(repl.abort_pat) then return nil end
        repl.prefix = repl:prefixbody(repl.str)
        while repl:incomplete(repl.str) do
          repl.str = repl.str.."\n"..repl:read2() end
        return repl.str
      end,
    readeval = function (repl) repl:read(); return repl:eval() end,
    repl = function (repl) while repl:read() do repl:eval() end end,
  },
}

repl = function () Repl{}:repl() end



-- dump-to: tests
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "eoo.lua"
dofile "repl.lua"
r = Repl {}
r:readeval()
  = 1 +
    2 +
    3, "foo"

repl()
  = 1
  == 1 +
     2 +
     3, "foo"
  == "foo", {20, 30}
  print(2, 3)
  == foo(bar())
  == foo bar
  ==
  ^D

--]==]

-- Local Variables:
-- coding:             raw-text-unix
-- ee-anchor-format:   "«%s»"
-- End: