Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- This file: edrxrepl.lua - a REPL for Lua.
--   https://github.com/edrx/edrxrepl/
--    http://angg.twu.net/edrxrepl/edrxrepl.lua.html
--    http://angg.twu.net/edrxrepl/edrxrepl.lua
--     (find-angg        "edrxrepl/edrxrepl.lua")
--         https://github.com/edrx/edrxrepl
--         https://github.com/edrx/edrxrepl#Introduction
--
-- In the HTML version the sexp hyperlinks work.
-- See: (find-eev-quick-intro "3. Elisp hyperlinks")
--      (find-eepitch-intro "3. Test blocks")
--
-- Author:  Eduardo Ochs <eduardoochs@gmail.com>
-- Version: 20210824
-- License: GPL3 at this moment.
-- If you need another license, get in touch!
--
-- Some eev-isms:
-- (defun o () (interactive) (find-angg "edrxrepl/README.org"))
-- (defun r () (interactive) (find-angg "edrxrepl/edrxrepl.lua"))
-- (defun x () (interactive) (find-angg "edrxrepl/edrxpcall.lua"))


-- This file is being rewritten.



-- The class EdrxRepl uses
-- the class EdrxPcall,
--  that is defined here:
require "edrxpcall"   -- (find-angg "edrxrepl/edrxpcall.lua")



-- «.EdrxRepl»			(to "EdrxRepl")
-- «.EdrxRepl-emacs»		(to "EdrxRepl-emacs")
-- «.EdrxRepl-tests»		(to "EdrxRepl-tests")



--  ____            _ 
-- |  _ \ ___ _ __ | |
-- | |_) / _ \ '_ \| |
-- |  _ <  __/ |_) | |
-- |_| \_\___| .__/|_|
--           |_|      
--
-- «EdrxRepl»  (to ".EdrxRepl")
-- Also in: (find-angg "LUA/lua50init.lua" "Repl")
-- A simple REPL for Lua that handles errors well enough.
-- It uses EdrxPcall to run code.
-- Usage:
--
--   REPL = EdrxRepl:new(); REPL:repl()
--
-- To exit the REPL set REPL.stop to true.
--
-- NOTE ON '='s: The EdrxRepl class implements a trick that is found in
-- the REPLs of Lua5.1 and Lua5.2 but was dropped from Lua5.3 onwards.
-- It is explained in the manpages for lua5.1 and lua5.2 as:
-- 
--   If a line starts with '=', then lua displays the values of all
--   the expressions in the remainder of the line. The expressions
--   must be separated by commas.
-- 
-- In Lua5.3 they changed that to this (also copied from the manpage):
-- 
--   If the line contains an expression or list of expressions, then
--   the line is evaluated and the results are printed.
-- 
-- See for example this thread:
-- http://lua-users.org/lists/lua-l/2020-10/msg00209.html


EdrxRepl = Class {
  type = "EdrxRepl",
  new  = function () return EdrxRepl({}) end,
  __index = {
    bigstr = function (r) return table.concat(r.lines, "\n") end,
    code = function (r) return r:bigstr():gsub("^=", "return ") end,
    --
    -- incompletep = function (r) return r:incompletep0(r:code()) end,
    -- incompletep0 = function (r, bigstr)
    --     local f, err = loadstring(bigstr)
    --     return (f == nil) and r:incompleteerrp(err)
    --   end,
    --
    read00 = function (r, prompt) io.write(prompt); return io.read() end,
    read0 = function (r, prompt) table.insert(r.lines, r:read00(prompt)) end,
    read1 = function (r) return r:read0 ">>> "  end,
    read2 = function (r) return r:read0 "... " end,
    read = function (r)
        r.lines = {}
        r:read1()
        while r:trapincomplete() do r:read2() end
        return r
      end,
    --
    incompleteerrp = function (r, err)
        return err:find(" near '?<eof>'?$")
      end,
    trapincomplete = function (r)
        r.f, r.err = loadstring(r:code())
        return (r.err and r:incompleteerrp(r.err)) and "[incomplete]"
      end,
    trapcomperror = function (r)
        r.f, r.err = loadstring(r:code())
        return r.err and "[comp error]"
      end,
    trapexecerror = function (r)
        r.xpc = EdrxPcall.new():call(r.f)
	if not r.xpc:success() then
          r.err = r.xpc.err_msg
          r.tb  = r.xpc:tbshorter()
	  return "[exec error]"
        end
      end,
    readevalprint = function (r)
        r:read()
        if r:trapcomperror() then return r:printcomperror() end
        if r:trapexecerror() then return r:printexecerror() end
        if r:bigstr():match("^=")
	then print(r.xpc:outsuccess())
        end
      end,
    --
    -- The standard interface:
    repl = function (r) while not r.stop do r:readevalprint() end end,
    --
    -- «EdrxRepl-emacs»  (to ".EdrxRepl-emacs")
    -- The emacs interface:
    erepltest = function (r)
        while not r.stop do
	  print(r:esend(r:read00(r:eprompt())))
	end
      end,
    --
    e0 = function (r) r.lines = {}; return r end,      -- clear .lines
    eprompt = function (r)
        r.lines = r.lines or {}
        if #r.lines == 0 then return ">>> " else return "... " end
      end,
    etrapexecerror = function (r)
        r.xpc = EdrxPcall.new():prcall(r.f)
	if not r.xpc:success() then
          r.err = r.xpc.err_msg
          r.tb  = r.xpc:tbshorter()
	  return "[exec error]"
        end
      end,
    esend = function (r, line)
        table.insert(r.lines, line)
        if r: trapincomplete() then return r:eretincomplete() end
        if r: trapcomperror()  then return r:e0():eretcomperror() end
        if r:etrapexecerror()  then return r:e0():eretexecerror() end
        if r:bigstr():match("^=")
        then return r:e0():eretsuccessprint()
        else return r:e0():eretsuccessnonprint()
        end
      end,
    eretincomplete = function (r) return "(incomplete)" end,
    eretcomperror  = function (r) return "(comp error)", r.err end,
    eretexecerror  = function (r) return "(exec error)", r.xpc:prout(nil, "\n") end,
    eretsuccessprint = function (r) return "(success: =)", r.xpc:prout("=", "\n") end,
    eretsuccessnonprint = function (r) return "(success)", r.xpc:prout() end,
  },
}


-- «EdrxRepl-tests»  (to ".EdrxRepl-tests")
-- (find-elisp-intro "5. Variables" "If you execute lines 1, 3, and 4")
-- (find-angg "LUA/lua50init.lua")
--[[
* (eepitch-shell)
* (eepitch-kill)
* (eepitch-shell)
export LUA_INIT=""
export LUA_INIT=@$HOME/LUA/lua50init.lua
lua5.1
lua5.2
lua5.3
lua5.4
PP()

* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "edrxrepl.lua"
REPL = EdrxRepl.new()
-- REPL:repl()
REPL:repl()

print(
  1+2
)
= 1+2
= 1, 2, 3
= 20, 30, nil, 40, nil
REPL.stop = 1

* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "edrxrepl.lua"
REPL = EdrxRepl.new()
REPL:erepltest()
print(
  1+2
)
= 1+2
= 1, 2, 3
= 20, 30, nil, 40, nil
a = 22
a = a + 33
a = a +
    200
= a
= a +
  2 +
  3
= a +
  2 +
  nil
REPL.stop = 1

REPL.stop = 1


* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "edrxrepl.lua"
EdrxPcall.__index.tb_e = 10
EdrxPcall.__index.tb_e = 5
EdrxPcall.__index.tb_e = 6
REPL = EdrxRepl.new()
REPL:erepltest()
= a + 2 + nil


--]]