Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- This file:
--   http://angg.twu.net/LUA/Repl2.lua.html
--   http://angg.twu.net/LUA/Repl2.lua
--           (find-angg "LUA/Repl2.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
-- Version: 2022nov05
-- Public domain.
--
-- This my n-attempt to write a REPL for Lua.
-- The suffix "2" in the name of this file means:
-- "this is a complete rewrite of Repl1.lua, with no attempts
-- to be backwards compatible."
-- At this moment this REPL is used only in lualatex. See the tests in:
--   (to "getmeaning-tests")
--   (to "texrun-tests")
-- and the documentation in:
--   http://angg.twu.net/eev-tikz.html#another-repl
--   (find-angg "LUA/lua50init.lua" "Repl2.lua")
--   (find-angg "LUA/tikz1.lua" "repl")
--
-- See the comments in my other REPLs:
--   (find-angg "LUA/Repl1.lua")
--   https://github.com/edrx/emlua/#introduction
--   http://angg.twu.net/emlua/README.org.html
--   http://angg.twu.net/dednat6.html#luatex
--
-- (defun r1 () (interactive) (find-angg "LUA/Repl1.lua"))
-- (defun r2 () (interactive) (find-angg "LUA/Repl2.lua"))

-- (find-angg "LUA/Repl1.lua" "EdrxEmacsRepl")
-- (find-angg "LUA/Repl1.lua" "MultiLineCmd")

-- «.MultiLineCmd»		(to "MultiLineCmd")
-- «.MultiLineCmd-tests»	(to "MultiLineCmd-tests")
-- «.Repl2»			(to "Repl2")
-- «.Repl2-tests»		(to "Repl2-tests")
-- «.getmeaning»		(to "getmeaning")
--   «.printmeaning»		(to "printmeaning")
--   «.printpgfkey»		(to "printpgfkey")
--   «.printtikzkey»		(to "printtikzkey")
-- «.getmeaning-tests»		(to "getmeaning-tests")
-- «.texrun»			(to "texrun")
-- «.texrun-tests»		(to "texrun-tests")



--  __  __       _ _   _ _     _             ____               _ 
-- |  \/  |_   _| | |_(_) |   (_)_ __   ___ / ___|_ __ ___   __| |
-- | |\/| | | | | | __| | |   | | '_ \ / _ \ |   | '_ ` _ \ / _` |
-- | |  | | |_| | | |_| | |___| | | | |  __/ |___| | | | | | (_| |
-- |_|  |_|\__,_|_|\__|_|_____|_|_| |_|\___|\____|_| |_| |_|\__,_|
--                                                                
-- «MultiLineCmd»  (to ".MultiLineCmd")
MultiLineCmd = Class {
  type = "MultiLineCmd",
  from = function (line) return MultiLineCmd({line}) end,
  test = function (line1, ...)
      return PPV(MultiLineCmd({line1, morelines={...}}):addmorelines())
    end,
  __tostring = function (mlc) return mlc:concat() end,
  __index = {
    add = function (mlc, line) table.insert(mlc, line) end,
    prefix = function (mlc) return mlc[1]:match("^=?") end,
    concat = function (mlc) return table.concat(mlc, "\n") end,
    --
    luacode = function (mlc)
        return (mlc:concat():gsub("^=", "return "))
      end,
    luacodepr = function (mlc)
        return (mlc:concat():gsub("^=(.*)$", "print(%1\n  )"))
      end,
    --
    incomplete0 = function (mlc, f, err)
        return err and err:find(" near '?<eof>'?$")
      end,
    status0 = function (mlc)
        local f0,err0 = loadstring(mlc:luacode())
        local f1,err1 = loadstring(mlc:luacodepr())
        if mlc:incomplete0(f0, err0) then return "incomplete" end
        if not f0 then return "comp error",nil,err0 end
        return "complete",f1,err1
      end,
    compile = function (mlc)
        mlc.status, mlc.f, mlc.err = mlc:status0()
        return mlc
      end,
    incomplete = function (mlc)
        mlc:compile()
        return mlc.status == "incomplete"
      end,
    --
    -- For MultiLineCmd.test
    addmorelines = function (mlc)
        while mlc:incomplete() and #mlc.morelines>0 do
          mlc:add(mlc.morelines[1]); table.remove(mlc.morelines, 1)
        end
        return mlc
      end,
  },
}

-- «MultiLineCmd-tests»  (to ".MultiLineCmd-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Repl2.lua"
mlc = MultiLineCmd.from("print('foo')")
PPV(mlc)
mlc:compile()
PPV(mlc)
mlc.f()

test = MultiLineCmd.test
mlc = test("print(2+3)", "foo")
mlc = test("print(2+", "3)", "foo")
mlc = test("print(2+", "3!", "foo")
mlc = test("= 2", "+3", "foo")
mlc = test("= 2+", "3", "foo")
mlc = test("= 2+", "3+", "4", "foo")
PPV(mlc)
= mlc.f()

--]]



--  ____            _ _ 
-- |  _ \ ___ _ __ | / |
-- | |_) / _ \ '_ \| | |
-- |  _ <  __/ |_) | | |
-- |_| \_\___| .__/|_|_|
--           |_|        
--
-- «Repl2»  (to ".Repl2")
-- A simple REPL. No redirection, default errorhandler, no coroutines.
--
Repl2 = Class {
  type    = "Repl2",
  new     = function () return Repl2({}) end,
  __index = {
    read00 = function (r, prompt) write(prompt); return io.read() end,
    read0 = function (r, prompt) return r:read00(prompt) end,
    read1 = function (r) return r:read0 ">>> " end,
    read2 = function (r) return r:read0 "... " end,
    read = function (r)
        r.mlc = MultiLineCmd.from(r:read1())
        while r.mlc:incomplete() do r.mlc:add(r:read2()) end
        return r
      end,
    --
    -- (find-es "lua5" "xpcall")
    comperror = function (r) return r.mlc.status == "comp error" end,
    printcomperror = function (r) print(r.mlc.err) end,
    evalprint = function (r)
        local errhandler = function(err)
            print(tostring(err) .. debug.traceback())
          end
        xpcall(r.mlc.f, errhandler)
      end,
    readevalprint = function (r)
        r:read()
        if r:comperror()
        then r:printcomperror()
	else r:evalprint()
        end
      end,
    repl = function (r)
        while not r.STOP do
          r:readevalprint()
        end
      end,
  },
}

-- «Repl2-tests»  (to ".Repl2-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "Repl2.lua"
run_repl  = function () r = Repl2.new(); r:repl() end
stop_repl = function () r.STOP = "please" end
run_repl()
print(2+
 3+
 4)
print(2+
 3!
print(2+
 nil)
stop_repl()

--]]


--             _                              _             
--   __ _  ___| |_ _ __ ___   ___  __ _ _ __ (_)_ __   __ _ 
--  / _` |/ _ \ __| '_ ` _ \ / _ \/ _` | '_ \| | '_ \ / _` |
-- | (_| |  __/ |_| | | | | |  __/ (_| | | | | | | | | (_| |
--  \__, |\___|\__|_| |_| |_|\___|\__,_|_| |_|_|_| |_|\__, |
--  |___/                                             |___/ 
--
-- See: (find-angg "LUA/tikz1.lua" "repl")
--
-- «getmeaning»      (to ".getmeaning")
--   «printmeaning»  (to ".printmeaning")
--   «printpgfkey»   (to ".printpgfkey")
--   «printtikzkey»  (to ".printtikzkey")
getmeaning0   = function (str) return token.get_meaning(str) end
getmeaning    = function (str) return token.get_meaning(str) or "" end
printmeaning0 = function (str) print(getmeaning(str)) end
printmeaning  = function (str) print(str..": "..getmeaning(str)) end
printpgfkey   = function (str) printmeaning("pgfk@"..str.."/.@cmd") end
printtikzkey  = function (str) printpgfkey("/tikz/"..str) end

-- «getmeaning-tests»  (to ".getmeaning-tests")
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
ee_dofile "~/LUA/tikz1.lua"  -- (find-fline "~/LUA/tikz1.lua")
repl = repl2
savetex()
**
* (eepitch-shell)
* (eepitch-kill)
* (eepitch-shell)
  cd /tmp/ && lualatex tikz1.tex
printmeaning("newpage")
printmeaning("pgfk@/tikz/rounded corners/.@cmd")
printpgfkey      ("/tikz/rounded corners")
printtikzkey           ("rounded corners")
printtikzkey           ("right")

--]==]




--  _                             
-- | |_ _____  ___ __ _   _ _ __  
-- | __/ _ \ \/ / '__| | | | '_ \ 
-- | ||  __/>  <| |  | |_| | | | |
--  \__\___/_/\_\_|   \__,_|_| |_|
--                                
-- «texrun»  (to ".texrun")
-- (find-angg "LUA/lua50init.lua" "Repl2.lua")
-- (find-angg "LUA/lua50init.lua" "Repl2.lua" "stop_repl2_now =")
texrun = function (str) tex.print(str.."\\repl"); stop_repl2_now() end

-- «texrun-tests»  (to ".texrun-tests")
--[==[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
ee_dofile "~/LUA/tikz1.lua"  -- (find-fline "~/LUA/tikz1.lua")
repl = repl2
savetex()
**
* (eepitch-shell)
* (eepitch-kill)
* (eepitch-shell)
  cd /tmp/ && lualatex tikz1.tex
texrun [=[                 \luaprintmeaning{bla} ]=]
texrun [=[ \def\bla{BLA}   \luaprintmeaning{bla} ]=]
texrun [=[                 \luaprintmeaning{bla} ]=]
texrun [=[ \def\bla#1{BLA} \luaprintmeaning{bla} ]=]
texrun [=[                 \luaprintmeaning{bla} ]=]
texrun [=[
  \pgfkeys{/a/.code=(a:#1)}
  \pgfkeys{/b/.code=(b:#1)}
  \pgfkeys{/c/.style={/a=AA,/b=BB,/a=#1}}
  \pgfkeys{/s/.store in=/sss}
]=]
printpgfkey("/b")
printpgfkey("/c")
printpgfkey("/s")

--]==]



-- Local Variables:
-- coding:  utf-8-unix
-- End: