Files
Upsilon/build/struct_layout/ast_to_json.rb
Romain Goyet d70bad84f3 Rename the scripts folder to build
And the build folder to output
2019-09-18 17:46:38 +02:00

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)