Compare commits

...

5 Commits

Author SHA1 Message Date
Lars Mueller 0cb90208a3 Fix dbg.(vars|locals) on PUC Lua 5.1 2022-07-08 15:56:56 +02:00
Lars Mueller 458104a9dd Clean up tests a tiny bit 2022-07-08 15:54:48 +02:00
Lars Mueller 34a11f701e Fix hypothetical bug in getargs 2022-07-08 14:32:27 +02:00
Lars Mueller 56b51c5e26 Inline expression 2022-07-08 14:27:32 +02:00
Lars Mueller 756be9d15d dbg.error: Fix stack level 2022-07-06 16:51:55 +02:00
3 changed files with 49 additions and 22 deletions

60
dbg.lua
View File

@ -1,30 +1,33 @@
local debug = ...
local function vars(where, getvar, setvar)
function dbg.locals(level)
level = (level or 1) + 1
local idx = {}
do
local i = 1
while true do
local name = getvar(where, i)
local name = debug.getlocal(level, i)
if name == nil then break end
idx[name] = i
i = i + 1
end
end
return setmetatable({}, {
__index = function(_, name)
local _, value = getvar(where, assert(idx[name], "no variable with given name"))
local _, value = debug.getlocal(level, assert(idx[name], "no variable with given name"))
return value
end,
__newindex = function(_, name, value)
setvar(where, assert(idx[name], "no variable with given name"), value)
debug.setlocal(level, assert(idx[name], "no variable with given name"), value)
end,
__call = function()
local i = 0
local function iterate()
i = i + 1
-- Making this a tail call requires changing `where`
local name, value = getvar(where, i)
-- Making this a tail call requires passing `level - 1`
local name, value = debug.getlocal(level, i)
return name, value
end
return iterate
@ -32,21 +35,45 @@ local function vars(where, getvar, setvar)
})
end
function dbg.locals(level)
level = level or 1
return vars(level + 1, debug.getlocal, debug.setlocal)
end
function dbg.upvals(func)
if type(func) ~= "function" then
func = debug.getinfo((func or 1) + 1, "f").func
end
return vars(func, debug.getupvalue, debug.setupvalue)
local idx = {}
do
local i = 1
while true do
local name = debug.getupvalue(func, i)
if name == nil then break end
idx[name] = i
i = i + 1
end
end
return setmetatable({}, {
__index = function(_, name)
local _, value = debug.getupvalue(func, assert(idx[name], "no upval with given name"))
return value
end,
__newindex = function(_, name, value)
debug.setupvalue(func, assert(idx[name], "no upval with given name"), value)
end,
__call = function()
local i = 0
local function iterate()
i = i + 1
return debug.getupvalue(func, i)
end
return iterate
end
})
end
function dbg.vars(level)
level = (level or 1) + 1
local func = debug.getinfo(level, "f").func
local idx, is_local = {}, {}
-- Upvals
do
@ -69,6 +96,7 @@ function dbg.vars(level)
i = i + 1
end
end
return setmetatable({}, {
__index = function(_, name)
local var_idx = assert(idx[name], "no variable with given name")
@ -99,9 +127,9 @@ function dbg.vars(level)
until not is_local[name]
if name == nil then
i, upvals = 1, false
return iterate()
end
else
end
if not upvals then
name, value = debug.getlocal(level, i)
i = i + 1
end
@ -233,8 +261,8 @@ local function getargs(func)
local i = 1
while true do
local name = debug.getlocal(2, i)
if name == nil or name:match"^%(" then break end
table.insert(args, name)
if name == nil then break end
if not name:match"^%(" then table.insert(args, name) end
i = i + 1
end
error(args)

2
dd.lua
View File

@ -164,7 +164,7 @@ local error = error -- localize error to allow overriding _G.error = dbg.error
function dbg.error(msg, level)
print("caught error: "); dbg.pp(msg)
if dd(level, true) then
if dd((level or 1) + 1, true) then
return error(msg, level)
end
end

View File

@ -14,12 +14,12 @@ local function assert_vars(vartype, expected)
end
assert(i == #expected)
end
local f = function(c, e) -- luacheck: ignore
(function(c, e) -- luacheck: ignore
assert(a == nil)
assert(b == "b")
assert_vars("upvals", {
"a", nil;
"b", "b";
"a", a;
"b", b;
"assert_vars", assert_vars;
})
do
@ -49,5 +49,4 @@ local f = function(c, e) -- luacheck: ignore
"f", f;
"g", g;
})
end
f()
end)()