diff --git a/analyze_structure.lua b/analyze_structure.lua index ea074ac..c9f49fa 100644 --- a/analyze_structure.lua +++ b/analyze_structure.lua @@ -181,29 +181,32 @@ end -------------------------------------------------------------------------------- -local function visit_table (t, info, visited) +local function analyze_structure (root) + assert(type(root) == 'table') - -- Who've been visited? Bookkeeping - visited[t] = (visited[t] or 0) + 1 - if visited[t] == 2 then - info[t].marker, info.next_mark = info.next_mark, info.next_mark + 1 + local info, visited, next_mark, depth = { root = root }, {}, 1, { [root] = 0 } + local queue = { root, bottom = 1, top = 2 } + + while queue.bottom < queue.top do + queue.bottom = queue.bottom + 1 + local node = queue[queue.bottom-1] + -- Who've been visited? Bookkeeping + visited[node] = (visited[node] or 0) + 1 + if visited[node] == 2 then + info[node].marker, next_mark = next_mark, next_mark + 1 + end + -- Get table info & visit children. + if visited[node] < 2 then + info[node] = get_table_info(node) + info[node].depth = depth[node] + for k, v in pairs(node) do + if type(k) == 'table' then queue[queue.top], queue.top, depth[k] = k, queue.top + 1, depth[node] + 1 end + if type(v) == 'table' then queue[queue.top], queue.top, depth[v] = v, queue.top + 1, depth[node] + 1 end + end + end end - if visited[t] >= 2 then return end - -- Get table info - info[t] = get_table_info(t) - - -- Visit children. - for k,v in pairs(t) do - if type(k) == 'table' then visit_table(k, info, visited) end - if type(v) == 'table' then visit_table(v, info, visited) end - end -end - -local function analyze_structure (t) - local info, visited = { root = t, next_mark = 1 }, {} - visit_table(t, info, visited) - info.next_mark = nil + assert(type(info) == 'table') return info end