Browse Source

traceback and debug enhancements, schema output

now all debug messages are sent on stderr also voluntary zencode
statements as 'debug', as well new statements are added like 'schema'
to dump HEAP structure without contents and 'backtrace' for execution
log
master
Jaromil 3 years ago
parent
commit
8db9001e7f
  1. 11
      src/lua/init.lua
  2. 57
      src/lua/inspect.lua
  3. 29
      src/lua/zencode.lua
  4. 2
      src/lua/zencode_coconut.lua
  5. 10
      src/lua/zencode_data.lua
  6. 14
      src/lua/zencode_debug.lua
  7. 14
      src/lua/zencode_then.lua

11
src/lua/init.lua

@ -24,6 +24,17 @@ function fatal(msg)
if type(msg) == "string" then warn(trim(msg),2) end
debug.traceback()
-- if ZEN_traceback ~= "" then ZEN:debug() end
if DEBUG > 1 then
-- TODO: ZEN:backtrace() and traceback as sorted array
warn(ZEN_traceback)
end
if DEBUG > 2 then
-- TODO: ZEN:dump()
I.warn({ HEAP = { IN = IN,
TMP = TMP,
ACK = ACK,
OUT = OUT }})
end
ZEN:debug()
msg = msg or "fatal error"
error(msg,2)

57
src/lua/inspect.lua

@ -250,11 +250,13 @@ function Inspector:putKey(k)
self:puts("]")
end
function Inspector:putTable(t)
function Inspector:putTable(t, exp)
if t == inspect.KEY or t == inspect.METATABLE then
self:puts(tostring(t))
-- self:puts("["..#t.."]")
elseif self:alreadyVisited(t) then
self:puts('<table ', self:getId(t), '>')
-- self:puts("["..#t.."]")
elseif self.level >= self.depth then
self:puts('{...}')
else
@ -275,7 +277,7 @@ function Inspector:putTable(t)
for i=1, sequenceLength do
if count > 0 then self:puts(',') end
self:puts(' ')
self:putValue(t[i])
self:putValue(t[i], exp)
count = count + 1
end
@ -284,7 +286,7 @@ function Inspector:putTable(t)
self:tabify()
self:putKey(k)
self:puts(' = ')
self:putValue(t[k])
self:putValue(t[k], exp)
count = count + 1
end
@ -292,7 +294,7 @@ function Inspector:putTable(t)
if count > 0 then self:puts(',') end
self:tabify()
self:puts('<metatable> = ')
self:putValue(mt)
self:putValue(mt, exp)
end
end)
@ -306,50 +308,50 @@ function Inspector:putTable(t)
end
end
function Inspector:putValue(v)
function Inspector:putValue(v, exp)
local tv = type(v)
enc = CONF.encoding or url64
local exporter = exp or export_obj
if tv == 'string' then
self:puts(smartQuote(escape(v)))
elseif tv == 'number' or tv == 'boolean' or tv == 'nil' or
tv == 'cdata' or tv == 'ctype' then
self:puts(tostring(v))
elseif tv == 'table' then
self:putTable(v)
if #v > 0 then self:puts("["..#v.."] ") end
self:putTable(v, exporter)
elseif iszen(tv) then
if tv == "zenroom.octet" then
self:puts("octet[" .. #v .. "] " .. ZEN:export(v))
self:puts("octet[" .. #v .. "] " .. exporter(v))
elseif tv == "zenroom.big" then
local i = v:octet()
self:puts("int[" .. #i.. "] " .. ZEN:export(i))
self:puts("int[" .. #i.. "] " .. exporter(i))
elseif tv == "zenroom.ecp" then
local i = v:octet()
if v == "Infinity" or v == ECP.infinity() then
self:puts("ecp[...] (Infinity)")
else
self:puts("ecp[" .. #i.. "] " .. ZEN:export(i))
self:puts("ecp[" .. #i.. "] " .. exporter(i))
end
elseif tv == "zenroom.ecp2" then
local i = v:octet()
if v == "Infinity" or v == ECP2.infinity() then
self:puts("ecp[...] (Infinity)")
else
self:puts("ecp2[" ..#i.. "] ".. ZEN:export(i))
self:puts("ecp2[" ..#i.. "] ".. exporter(i))
end
elseif tv == "zenroom.fp12" then
local i = v:octet()
self:puts("fp12[" ..#i.. "] ".. ZEN:export(i))
self:puts("fp12[" ..#i.. "] ".. exporter(i))
elseif tv == "zenroom.ecdh" then
local pk = v:public()
local sk = v:private()
if not pk and not sk then self:puts("ecdh keyring is empty\n")
else
if pk then self:puts("ecdh.public["..#pk.."] ".. ZEN:export(pk).."\n") end
if sk then self:puts("ecdh.private["..#sk.."] ".. ZEN:export(sk).."\n") end
if pk then self:puts("ecdh.public["..#pk.."] ".. exporter(pk).."\n") end
if sk then self:puts("ecdh.private["..#sk.."] ".. exporter(sk).."\n") end
end
else
self:puts(ZEN:export(v:octet()))
self:puts(exporter(v:octet()))
end
else
self:puts('<',tv,' ',self:getId(v),'>')
@ -365,7 +367,7 @@ function inspect.inspect(root, options)
local newline = options.newline or '\n'
local indent = options.indent or ' '
local process = options.process
local schema = options.schema or false
if process then
root = processRecursive(process, root, {}, {})
end
@ -381,7 +383,13 @@ function inspect.inspect(root, options)
tableAppearances = countTableAppearances(root)
}, Inspector_mt)
inspector:putValue(root)
-- option schema only (don't print contents)
if schema then
local _f = function(_) return("") end
inspector:putValue(root, _f)
else
inspector:putValue(root)
end
return table.concat(inspector.buffer)
end
@ -390,7 +398,7 @@ end
function inspect.encode(item)
t = type(item)
if iszen(t) then
return ZEN:export(item)
return export_obj(item)
-- elseif iszen(t) then
-- if t == "zenroom.ecp" and ECP.isinf(item) then
-- return "Infinity"
@ -417,6 +425,17 @@ function inspect.print(root, options)
return root
end
--- Print the prototype (no contents only schema) of a table in a tree
--- representation, works with complex data structures and prints to
--- STDOUT.
--
-- @function INSPECT.schema(object)
-- @param object complex table data structure
function inspect.schema(root, options)
warn(inspect.inspect(root, { schema = true }))
return root
end
--- Print all contents of a table to STDERR. Works same way as @{print}.
--
-- @function INSPECT.warn(object)

29
src/lua/zencode.lua

@ -54,6 +54,7 @@ local zencode = {
schemas = { },
id = 0,
AST = {},
traceback = { }, -- execution backtrace
eval_cache = { }, -- zencode_eval if...then conditions
checks = { version = false }, -- version, scenario checked, etc.
OK = true -- set false by asserts
@ -116,7 +117,7 @@ ACK = ACK or { } -- When processing, destination for push*
OUT = OUT or { } -- print out
AST = AST or { } -- AST of parsed Zencode
WHO = nil
_G['ZEN_traceback'] = "Zencode traceback:\n"
@ -129,6 +130,7 @@ function zencode:begin()
self.eval_cache = { }
self.checks = { version = false } -- version, scenario checked, etc.
self.OK = true -- set false by asserts
self.traceback = { }
-- Reset HEAP
self.machine = { }
@ -141,7 +143,6 @@ function zencode:begin()
WHO = nil
collectgarbage'collect'
-- Zencode init traceback
_G['ZEN_traceback'] = "Zencode traceback:\n"
self.machine = new_state_machine()
return true
end
@ -181,27 +182,22 @@ function zencode:trace(src)
local tr = trim(src)
-- TODO: tabbing, ugly but ok for now
if string.sub(tr,1,1) == '[' then
_G['ZEN_traceback'] = _G['ZEN_traceback']..tr.."\n"
table.insert(self.traceback, tr)
else
_G['ZEN_traceback'] = _G['ZEN_traceback'].." . "..tr.."\n"
table.insert(self.traceback, " . "..tr)
end
-- " -> ".. src:gsub("^%s*", "") .."\n"
end
-- trace function execution also on success
function zencode:ftrace(src)
-- take current line of zencode
_G['ZEN_traceback'] = _G['ZEN_traceback']..
" D ZEN:"..trim(src).."\n"
-- " -> ".. src:gsub("^%s*", "") .."\n"
table.insert(self.traceback, " D ZEN:"..trim(src))
end
-- log zencode warning in traceback
function zencode:wtrace(src)
-- take current line of zencode
_G['ZEN_traceback'] = _G['ZEN_traceback']..
" W ZEN:"..trim(src).."\n"
-- " -> ".. src:gsub("^%s*", "") .."\n"
table.insert(self.traceback, " W ZEN:"..trim(src))
end
function zencode:run()
@ -266,8 +262,15 @@ function zencode:run()
end
end
function zencode.heap()
return({ IN = IN,
TMP = TMP,
ACK = ACK,
OUT = OUT })
end
function zencode.debug()
warn(ZEN_traceback)
I.warn(ZEN.traceback)
I.warn({ HEAP = { IN = IN,
TMP = TMP,
ACK = ACK,
@ -275,7 +278,7 @@ function zencode.debug()
end
function zencode.debug_json()
write(JSON.encode({ TRACE = ZEN_traceback,
write(JSON.encode({ TRACE = ZEN.traceback,
HEAP = { IN = IN,
TMP = TMP,
ACK = ACK,

2
src/lua/zencode_coconut.lua

@ -273,7 +273,7 @@ When("I verify the signature proof is correct", function()
end)
When("the petition signature is not a duplicate", function()
local k = ZEN:export(ACK.petition_signature.uid_signature)
local k = export_obj(ACK.petition_signature.uid_signature)
if type(ACK.petition.list) == 'table' then
ZEN.assert(
ACK.petition.list[k] == nil,

10
src/lua/zencode_data.lua

@ -373,25 +373,25 @@ end
-- Convert a data object to the desired format (argument name provided
-- as string), or use CONF.encoding when called without argument
--
-- @function ZEN:export(object, format)
-- @function export_obj(object, format)
-- @param object data element to be converted
-- @param format pointer to a converter function
-- @return object converted to format
local function export_arr(object, format)
ZEN.assert(iszen(type(object)), "ZEN:export called on a ".. type(object))
ZEN.assert(iszen(type(object)), "export_arr called on a ".. type(object))
local conv_f = nil
local ft = type(format)
if format and ft == 'function' then conv_f = format goto ok end
if format and ft == 'string' then conv_f = get_encoding(format).fun goto ok end
conv_f = CONF.output.encoding.fun -- fallback to configured conversion function
::ok::
ZEN.assert(type(conv_f) == 'function' , "ZEN:export conversion function not configured")
ZEN.assert(type(conv_f) == 'function' , "export_arr conversion function not configured")
return conv_f(object) -- TODO: protected call
end
function ZEN:export(object, format)
function export_obj(object, format)
-- CONF { encoding = <function 1>,
-- encoding_prefix = "u64" }
ZEN.assert(object, "ZEN:export object not found")
ZEN.assert(object, "export_obj object not found")
if type(object) == 'table' then
local tres = { }
for k,v in ipairs(object) do -- only flat tables support recursion

14
src/lua/zencode_debug.lua

@ -18,14 +18,20 @@
-- debug functions
local function debug_traceback()
I.print(ZEN_traceback)
for k,v in pairs(ZEN.traceback) do
act(v)
end
end
Given("backtrace", function() debug_traceback() end)
When("backtrace", function() debug_traceback() end)
Then("backtrace", function() debug_traceback() end)
local function debug_heap_dump()
I.print(HEAP)
I.warn({HEAP = ZEN.heap()})
end
local function debug_heap_schema()
I.schema({SCHEMA = ZEN.heap()})
-- print only keys without values
end
@ -35,3 +41,7 @@ end
Given("debug", function() ZEN.debug() end)
When("debug", function() ZEN.debug() end)
Then("debug", function() ZEN.debug() end)
Given("schema", function() debug_heap_schema() end)
When("schema", function() debug_heap_schema() end)
Then("schema", function() debug_heap_schema() end)

14
src/lua/zencode_then.lua

@ -28,7 +28,7 @@ end)
Then("print '' '' as ''", function(k,v,s)
OUT[k] = ZEN:export( ZEN:import(v, input_encoding(s).fun), s)
OUT[k] = export_obj( ZEN:import(v, input_encoding(s).fun), s)
end)
Then("print all data", function()
@ -49,12 +49,12 @@ end)
Then("print as '' my ''", function(conv,obj) ZEN:Iam()
ZEN.assert(ACK[obj], "My data: "..obj.." not found to print: "..conv)
if not OUT[WHO] then OUT[WHO] = { } end
OUT[WHO][obj] = ZEN:export(ACK[obj], conv)
OUT[WHO][obj] = export_obj(ACK[obj], conv)
end)
Then("print my '' as ''", function(obj,conv) ZEN:Iam()
ZEN.assert(ACK[obj], "My data: "..obj.." not found to print: "..conv)
if not OUT[WHO] then OUT[WHO] = { } end
OUT[WHO][obj] = ZEN:export(ACK[obj], conv)
OUT[WHO][obj] = export_obj(ACK[obj], conv)
end)
Then("print the ''", function(key)
@ -64,17 +64,17 @@ Then("print the ''", function(key)
end
end)
Then("print as '' the ''", function(conv, obj) OUT[obj] = ZEN:export(ACK[obj], conv) end)
Then("print the '' as ''", function(obj, conv) OUT[obj] = ZEN:export(ACK[obj], conv) end)
Then("print as '' the ''", function(conv, obj) OUT[obj] = export_obj(ACK[obj], conv) end)
Then("print the '' as ''", function(obj, conv) OUT[obj] = export_obj(ACK[obj], conv) end)
Then("print as '' the '' inside ''", function(conv, obj, section)
local src = ACK[section][obj]
ZEN.assert(src, "Not found "..obj.." inside "..section)
OUT[obj] = ZEN:export(src, conv)
OUT[obj] = export_obj(src, conv)
end)
Then("print the '' as '' inside ''", function(obj, conv, section)
local src = ACK[section][obj]
ZEN.assert(src, "Not found "..obj.." inside "..section)
OUT[obj] = ZEN:export(src, conv)
OUT[obj] = export_obj(src, conv)
end)

Loading…
Cancel
Save