|
Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
-- This file:
-- http://anggtwu.net/LUA/PrintFunction1.lua.html
-- http://anggtwu.net/LUA/PrintFunction1.lua
-- (find-angg "LUA/PrintFunction1.lua")
-- Author: Eduardo Ochs <eduardoochs@gmail.com>
--
-- Also here:
-- (find-angg "LUA/lua50init.lua" "PrintFunction")
--
-- This file defines the class `PrintFunction', that is used by `help'
-- and by `PreTraceback'. For example:
--
-- > = help(split)
-- (find-luatb "~/LUA/lua50init.lua 351 357")
--
--
-- Old comments
-- ============
-- ...and stack frames either in a very compact format that looks like
-- this (that I took from a pretraceback),
--
-- [ C ] C function (unknown name)
-- [Lua] stdin line 1
-- (find-luatb "~/LUA/lua50init.lua 2325 2329 global run_repl3_now")
-- (find-luatb "~/LUA/Repl3.lua 146 148 method repl")
--
-- or, with the method :v(), in a low-level "vertical" format that
-- looks like this:
--
-- { "currentline"=2329,
-- "func"=<function: 0x560195e1d770>,
-- "lastlinedefined"=2330,
-- "linedefined"=2325,
-- "name"="run_repl3_now",
-- "namewhat"="global",
-- "nups"=0,
-- "short_src"="/home/edrx/LUA/lua50init.lua",
-- "source"="@/home/edrx/LUA/lua50init.lua",
-- "what"="Lua"
-- }
--
-- debug.getinfo only fills the fields "name" and "namewhat" for stack
-- frames, so
--
-- PrintFunction.from(run_repl3_now)
--
-- returns just:
--
-- (find-luatb "~/LUA/lua50init.lua 2325 2330")
--
-- instead of:
--
-- (find-luatb "~/LUA/lua50init.lua 2325 2329 global run_repl3_now")
--
-- PrintFunction was inspired by the traceback in Prosody,
--
-- http://angg.twu.net/LUA/Prosody1.lua.html
-- (find-angg "LUA/Prosody1.lua")
--
-- but I changed the output format completely.
--
-- Based on/supersedes:
-- (find-angg "LUA/DGetInfo1.lua" "DGetInfo")
-- See:
-- (find-angg "LUA/PreTraceback1.lua")
-- (find-TH "Repl3" "PrintFunction1.lua")
-- (find-lua51manual "#pdf-debug.getinfo")
-- (find-lua51manual "#pdf-debug.getlocal")
--
-- (defun e () (interactive) (find-angg "LUA/PrintFunction1.lua"))
-- «.ObjToFunction» (to "ObjToFunction")
-- «.ObjToFunction-tests» (to "ObjToFunction-tests")
-- «.PrintFunction» (to "PrintFunction")
-- «.PrintFunction-any» (to "PrintFunction-any")
-- «.PrintFunction-keys» (to "PrintFunction-keys")
-- «.PrintFunction-tests» (to "PrintFunction-tests")
require "SortedKeys2" -- (find-angg "LUA/SortedKeys2.lua")
-- ___ _ _ _____ _____ _ _
-- / _ \| |__ (_)_ _|__ | ___| _ _ __ ___| |_(_) ___ _ __
-- | | | | '_ \| | | |/ _ \| |_ | | | | '_ \ / __| __| |/ _ \| '_ \
-- | |_| | |_) | | | | (_) | _|| |_| | | | | (__| |_| | (_) | | | |
-- \___/|_.__// | |_|\___/|_| \__,_|_| |_|\___|\__|_|\___/|_| |_|
-- |__/
-- `ObjToFunction.from(o)' is used by PrintFunction to make it
-- support (my) classes:
-- it returns functions unchanged,
-- it returns the __tostring method of a class when it exists,
-- it returns the __tostring method of the class of an object
-- when that makes sense and the __tostring method exists,
-- and it has some _unreliable hacks_ for classes without a
-- a __tostring method, and for objects of those classes.
--
-- In the code below:
-- "C" means "`C'lass",
-- "TM" means "`T'able with `M'etatable",
-- "CWT" means "`C'lass `W'ith a __`T'ostring", and
-- "CWOT" means "`C'lass `W'ith`O'ut a __`T'ostring".
--
-- «ObjToFunction» (to ".ObjToFunction")
-- Also here: (find-angg "LUA/lua50init.lua" "ObjToFunction")
--
ObjToFunction = Class {
type = "ObjToFunction",
from = function (o) return ObjToFunction{}:from(o) end,
__index = {
tt = function (a,o) return type(o) == "table" end,
ts = function (a,o) return type(o) == "string" end,
tf = function (a,o) return (type(o) == "function") and o end,
tm = function (a,o) return a:tt(o) and getmetatable(o) end,
isc = function (a,c) return a:tt(c) and a:tt(c.__index) and a:ts(c.type) end,
iscwt = function (a,c) return a:isc(c) and a:tf(c.__tostring) end,
--
-- `fft': First function in the table T
-- `ffc': first function in the class C
ffc = function (a,C) return a:fft(C) or a:fft(C.__index) end,
fft = function (a,T)
for _,k in ipairs(sortedkeys(T)) do
if a:tf(T[k]) then return T[k] end
end
end,
from = function (a,o)
return a:tf(o) -- o is a function,
or a:iscwt(o) -- o is a CWT,
or (a:tm(o) and a:iscwt(a:tm(o))) -- o is an object of a CWT,
or (a:isc(o) and a:ffc(o)) -- o is a CWOT,
or (a:isc(a:tm(o)) and a:ffc(a:tm(o))) -- o is an object of a CWOT
or (a:tt(o) and a:fft(o)) -- no `__tostring', no `__index'
or error("Objfunction{}:from(o) failed")
end,
},
}
-- «ObjToFunction-tests» (to ".ObjToFunction-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "PrintFunction1.lua"
foo = function (o) return PrintFunction.fromf(ObjToFunction{}:from(o)) end
= foo(foo)
= foo(Set)
= foo(Set {})
= foo(Tos)
= foo(Tos {})
= foo(Class)
--]]
-- ____ _ _ _____ _ _
-- | _ \ _ __(_)_ __ | |_| ___| _ _ __ ___| |_(_) ___ _ __
-- | |_) | '__| | '_ \| __| |_ | | | | '_ \ / __| __| |/ _ \| '_ \
-- | __/| | | | | | | |_| _|| |_| | | | | (__| |_| | (_) | | | |
-- |_| |_| |_|_| |_|\__|_| \__,_|_| |_|\___|\__|_|\___/|_| |_|
--
-- `PrintFunction.fromf' expects a function.
-- `PrintFunction.fromfunction' is a hack to support (my) classes:
-- it returns functions unchanged,
-- it returns the __tostring method of a class when it exists,
-- it returns the __tostring method of the class of an object
-- when that makes sense and the __tostring method exists,
-- and it has some _unreliable hacks_ for classes without a
-- a __tostring method, and for objects of those classes.
--
-- In the code below:
-- "C" means "`C'lass",
-- "TM" means "`T'able with `M'etatable",
-- "CWT" means "`C'lass `W'ith a __`T'ostring", and
-- "CWOT" means "`C'lass `W'ith`O'ut a __`T'ostring".
--
-- «PrintFunction» (to ".PrintFunction")
-- Also here: (find-angg "LUA/lua50init.lua" "PrintFunction")
--
PrintFunction = Class {
type = "PrintFunction",
tostring = function (o) return PrintFunction.from(o):tostring() end,
fromf = function (f) return PrintFunction(debug.getinfo(f, "nSluf")) end,
from = function (o) return PrintFunction.fromf(ObjToFunction.from(o)) end,
--
__tostring = function (pf) return pf:tostring() end,
__index = {
tostring = function (pf) return pf:_any() end,
tostring2 = function (pf) return pf:sks() end,
tostring3 = function (pf) return tostring(VTable(copy(pf))) end,
--
-- «PrintFunction-any» (to ".PrintFunction-any")
-- `pf:_any()' returns a line like `(find-luatb "..." 42)' or `[C]'
_shortsrc0 = function (pf) return ee_shorten(pf.short_src) end,
_shortsrc0 = function (pf) return ee_shorten(pf.source:sub(2)) end,
_shortsrc = function (pf) return pf.short_src and pf:_shortsrc0() end,
_name0 = function (pf) return pf.name and format("%q", pf.name) end,
_name = function (pf) return pf:_name0() or "(unknown name)" end,
_linedef = function (pf) return pf.linedefined end,
_linelast = function (pf) return pf.lastlinedefined end,
_linecurr0 = function (pf) return pf.currentline end,
_linecurr = function (pf) return pf:_linecurr0()~=-1 and pf:_linecurr0() end,
_line1 = function (pf) return pf:_linedef() end,
_line2 = function (pf) return pf:_linecurr() or pf:_linelast() end,
_tailcall0 = function (pf) return "[Lua] tail call" end,
_main0 = function (pf) return "[Lua] "..pf:_shortsrc()
.." line "..pf:_linecurr() end,
_C0 = function (pf) return "[ C ] "..pf.namewhat
.." C function "..pf:_name() end,
_tbbody0 = function (pf) return (pf:_shortsrc() or "")
.." "..(pf:_line1() or "")
.." "..(pf:_line2() or "")
.." "..(pf.namewhat or "")
.." "..(pf.name or "") end,
_tbbody = function (pf) return rtrim(pf:_tbbody0()) end,
_findluatb = function (pf) return format('(find-luatb \"%s\")', pf:_tbbody()) end,
_any = function (pf)
if pf.short_src == "[C]" then return pf:_C0() end
if pf.what == "main" then return pf:_main0() end
if pf.short_src == "(tail call)" then return pf:_tailcall0() end
return pf:_findluatb()
end,
--
-- «PrintFunction-keys» (to ".PrintFunction-keys")
-- Returns a multi-line string with all the key-value pairs of
-- `pf', grouped and sorted in a nice way. Needs SortedKeys2.
keys = [[ what namewhat source short_src
linedefined lastlinedefined currentline
nups ]],
sk1 = function (pf,k) return format("%-15s -> %s", k, mytostring(pf[k])) end,
skL = function (pf,ks)
local f = function (k) return pf:sk1(k) end
return mapconcat(f,ks,"\n")
end,
sks = function (pf) return pf:skL(SortedKeys.from(pf, pf.keys).list) end,
},
}
help = function (o) return PrintFunction.tostring(o) end
-- «PrintFunction-tests» (to ".PrintFunction-tests")
--[[
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
dofile "PrintFunction1.lua"
= help(split)
= help(print)
= help(mytostring)
= help(Set)
= help(Set {})
Foo = Class {
type = "Foo",
__mul = function (a,b) return a[1]*b[1] end,
__index = {
},
}
= help(Foo)
= help(Foo {2})
= help(Tos)
= help(Tos {})
= help(Class)
o = print
o = split
= PrintFunction.from(o):tostring()
= PrintFunction.from(o):tostring2()
= PrintFunction.from(o):tostring3()
--]]
-- (find-angg "LUA/DGetInfo1.lua" "DGetInfos")
-- Local Variables:
-- coding: utf-8-unix
-- End: