Warning: this is an htmlized version!
The original is here, and
the conversion rules are here.
-- interactive.lua - an interactive mode for Lua, written in Lua.
-- By Eduardo Ochs <eduardoochs@gmail.com>
-- Version: 2007mar17
-- http://angg.twu.net/LUA/interactive.lua
-- http://angg.twu.net/LUA/interactive.lua.html
-- (find-es "lua5")
-- (find-es "lua5" "incompletep")

-- (find-bgprocess "inkscape ~/LUA/interactive.svg")

--  _                                 _      _       
-- (_)_ __   ___ ___  _ __ ___  _ __ | | ___| |_ ___ 
-- | | '_ \ / __/ _ \| '_ ` _ \| '_ \| |/ _ \ __/ _ \
-- | | | | | (_| (_) | | | | | | |_) | |  __/ ||  __/
-- |_|_| |_|\___\___/|_| |_| |_| .__/|_|\___|\__\___|
--                             |_|                   

-- (find-angg "LUA/lua50init.lua")
-- (find-angg "LUA/lua50init.lua" "preparef2n")
-- (find-es "lua5" "signal")
-- (find-es "lua5" "xpcall")

-- The default, top-level interactive mode for Lua has several nice
-- features:
-- (1) It detects incomplete inputs, and knows how to ask for more
--     lines.
-- (2) It supports one special prefix: "=".
-- (3) It can display stack dumps ("tracebacks") in case of errors;
--     they are relatively nice. Problems: tail calls; what to do when
--     the information in those tracebacks is not enough?
-- (4) If the interactive mode is waiting for input then a "^C" leaves
--     Lua, but if a script is running it is aborted and we get the
--     prompt again.
--
-- However:
-- (5) There's no way to call that interactive interpreter from a Lua
--     script - the closest that we have is debug.debug(), that does
--     not handle multi-line commands or the "=" prefix.
--
-- This file implements an interactive mode written in pure Lua that
-- can be called from anywhere in a Lua script and that handles all
-- the issues above, except (4) the "^C"s, as that would need either
-- C or the posix library.
--
-- At some points here we use "PP" instead of "print". "PP" can print
-- some complex data structures, but it gets into infinite loops when
-- faced with circular data structures... and as "^C"s don't behave as
-- nicely as they should there's no way to just break out of these
-- infinite loops without leaving Lua. Which mean: take care!


-- loadstring2: like loadstring, but with two error messages (or sort of)
-- (find-luamanualw3m "#pdf-loadstring")
loadstring2 = function (str, chunkname)
    local compiledcode, errormsg = loadstring(str, chunkname)
    local pat = ": unexpected symbol near '<eof>'$"
    if errormsg then
      if string.find(errmsg, ": unexpected symbol near '<eof>'$") then
        return nil, nil, "incomplete"
      else
        return nil, errormsg, nil
      end
    end
    return compiledcode, nil, nil
  end





* (eepitch-lua51)
= string.sub("abcd", 1, 2)

iline = ""
iprefix = ""
icode = ""
icompiled = nil
ierrormsg = nil
ichunkname = "istdin"

interactive1 = function ()
    local iincomplete
    local pat = ": unexpected symbol near '<eof>'$"
    io.write("i> ")
    iline = io.read()
    if not iline then return end                -- eof
    if string.sub(iline, 1, 1) == "=" then
      iprefix = "="
      icode = "return " .. string.sub(iline, 2)
    else
      iprefix = ""
      icode = iline
    end
    while true do
      icompiled, ierrormsg = loadstring(icode, "(interactive)")
      iincomplete = ierrormsg and string.find(ierrormsg, pat)
      if not iincomplete then break end
      io.write("i>> ")
      iline = io.read()
      if not iline then return end              -- eof
      icode = icode .. "\n" .. iline
    end
    if ierrormsg then
      print(ierrormsg)
    else
      local iresult
      return true
--    if iprefix == "=" then print(icompiled()) end
--    if iprefix == ""  then icompiled() end
    end
  end

= interactive1()
= PP(2,
  3,
  4)

icompiled()
PP(icompiled())



    if errormsg then
      if 






iprompt1 = "d> "
iprompt2 = "d>> "
iline  = ""
iline1 = ""
ilines = {}

iprefixes = { "", "=", "==", "%D", "%:" }
ibestprefix    = ""
iline1noprefix = ""
ihasprefix = function (prefix, str)
    local plen, slen = string.len(prefix), string.len(str)
    return plen <= slen and string.sub(str, 1, plen) == prefix
  end
itestprefix = function (prefix, line)
    local plen, bplen = string.len(prefix), string.len(ibestprefix)
    if plen > bplen and ihasprefix(plen, line) then
      ibestprefix = prefix
    end
  end
igetbestprefix = function ()
    ibestprefix = ""
    for _,prefix in ipairs(iprefixes) do
      itestprefix(prefix, ilastlineread)
    end
    iline1noprefix = string.sub(ilastlineread, string.len(ibestprefix) + 1)

  end

ireadp = function (prompt) io.write(prompt); ilastlineread = io.read() end
iread2 = function () ireadp(iprompt2); tinsert(ilines, ilastlineread) end
iread1 = function ()
    ireadp(iprompt2)

    igetbestprefix();


bestprefix = function (prefixes, line)
    local bestprefix = ""
    local bplen = string.len(bestprefix)
    for _,prefix in ipairs(iprefixes) do
      local plen  = string.len(prefix)
      if plen > bplen and string.sub(line, 1, plen) == prefix then
        bestprefix = prefix
        bplen = string.len(bestprefix)
      end
    end
    return bestprefix, string.sub(line, bplen + 1)
  end

      itestprefix(prefix, ilastlineread)
    end
    
    


iread1


iread1 = function () ireadp(iprompt1); tinsert(ilines, iline) end


iloadstring = function ()
    icode = table.concat(userlines, "\n")
    icompiled, ierror = loadstring(icode, ichunkname)
  end
itestincomplete = function ()
    local pat = ": unexpected symbol near '<eof>'$"
    if ierror and string.find(ierror, pat) then ierror2 = "incomplete" end
  end
itestabort = function () if iline == "." then ierror2 = "abort" end end



ilastlineread = ""




igetlongestprefix = 

ibestprefix = ""






    if string.len(prefix) <= string.len(str) and string.sub(str, string.len(prefix)


* (eepitch-lua51)
= string.sub("foo", 1, 1)
= string.sub("foo", 1, 2)

-- (find-luamanualw3m "#pdf-string.sub")
-- (find-es "lua5")
-- (find-es "lua5" "0-based")





iprefix = function 


istatus = 





    local pat = ": unexpected symbol near '<eof>'$"
    userstatus = usererror and string.find(usererror, pat) and "incomplete"
  end


got line?
is it an abort?/


    if not errormsg then
      return compiledcode, nil, nil
    else



    if errormsg and string.find(errmsg, pat) then
      return nil, nil, "incomplete"
    else
      return comp
    return compiledcode, errormsg, incomplete
  end



incompletepat = ": unexpected symbol near '<eof>'$"
incompletep   = function (errmsg)
    if errmsg and string.find(errmsg, incompletepat) then return true end
  end
myloadstring = function (T)
    T.code, T.err = loadstring(table.concat(T, "\n"))
    T.incomplete  = incompletep(T.err)
    return T
  end
myreadmore = function (T)
    io.write(prompt or (table.getn(T) == 0 and "-> " or "->> "))
    local line = io.read()
    if line then table.insert(T, line); return true end
  end
myreadlines = function (T)
    if myreadmore(T) then
      while myloadstring(T).incomplete and myreadmore(T) do end
    end
    return T
  end



-- (find-angg "LUA/lua50init.lua" "loadtcl")


-- (find-luamanualw3m "#pdf-debug.debug")
-- (find-luamanualw3m "#6" "interactive mode")
-- (find-luamanualw3m "#6" "incomplete statement")
-- (find-expcommand "interpreter")
-- (find-lua51file "src/lua.c")
-- (find-lua51file "src/lua.c" "interactive mode")
-- (find-lua51file "src/lua.c" "case 'i':")
-- (find-lua51file "src/lua.c" "collectargs(argv, &has_i, &has_v, &has_e);")
-- (find-lua51tag "dotty")
-- (find-lua51tag "loadline")