mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-01-18 16:27:34 +01:00
84 lines
1.7 KiB
Ruby
84 lines
1.7 KiB
Ruby
#!/usr/bin/env ruby
|
|
|
|
# Takes an clang-generated AST in stdin
|
|
# Outputs a D3-compliant JSON file
|
|
|
|
require 'json'
|
|
|
|
class CodeStruct
|
|
attr_accessor :name, :starts_at, :size
|
|
|
|
def initialize(parent, name, starts_at)
|
|
@parent = parent
|
|
@name = name
|
|
@starts_at = starts_at
|
|
@size = 0
|
|
@children = []
|
|
@parent.add_child(self) unless @parent.nil?
|
|
end
|
|
|
|
def ends_at(offset)
|
|
@size = offset-@starts_at
|
|
end
|
|
|
|
def add_child(s)
|
|
@children.push(s)
|
|
end
|
|
|
|
def as_d3_dict
|
|
res = {name: name}
|
|
if @children.empty?
|
|
res[:value] = size
|
|
else
|
|
res[:children] = @children.map{|c| c.as_d3_dict}
|
|
end
|
|
res
|
|
end
|
|
|
|
def log(space = 0)
|
|
puts (" "*space) + "#{name} (SIZE=#{size})"
|
|
@children.each do |child|
|
|
child.log(space+2)
|
|
end
|
|
end
|
|
end
|
|
|
|
def handleNewLine(line, index, stack)
|
|
# Example : " 213736 | class Timer (primary base)"
|
|
offset, depth, name = line.match(/\s*([0-9]+)\s\|(\s+)(.*)/).captures
|
|
offset = offset.to_i
|
|
depth = (depth.size-1)/2
|
|
|
|
parent = stack[depth-1]
|
|
stack[depth..-1].each do |finished|
|
|
finished.ends_at(offset)
|
|
end
|
|
stack = stack[0...depth]
|
|
struct = CodeStruct.new(parent, name, offset)
|
|
stack.push(struct)
|
|
|
|
return stack
|
|
end
|
|
|
|
class_name = ARGV[0]
|
|
|
|
stack = []
|
|
ignore_line = true
|
|
STDIN.each_line.with_index do |l,i|
|
|
if l == " 0 | class #{class_name}\n"
|
|
ignore_line = false
|
|
end
|
|
if l.start_with?(" | ") && ignore_line == false
|
|
ignore_line = true
|
|
end_offset = l.match(/sizeof=([0-9]+)/).captures.first
|
|
end_offset = end_offset.to_i
|
|
stack[-1].ends_at(end_offset)
|
|
stack[0].ends_at(end_offset)
|
|
end
|
|
unless ignore_line
|
|
stack = handleNewLine(l, i, stack)
|
|
end
|
|
end
|
|
|
|
puts JSON.generate(stack[0].as_d3_dict)
|