|
Warning: this is an htmlized version!
The original is here, 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: