|
|
@@ -1,146 +1,137 @@ |
|
|
|
require 'ripper' |
|
|
|
require 'pp' |
|
|
|
|
|
|
|
module Bitshift |
|
|
|
class Parser |
|
|
|
def initialize(source) |
|
|
|
@source = source |
|
|
|
end |
|
|
|
|
|
|
|
def parse |
|
|
|
# new stuff |
|
|
|
walker = TreeWalker.new(@source) |
|
|
|
walker.parse |
|
|
|
return walker.to_s |
|
|
|
end |
|
|
|
end |
|
|
|
def parse |
|
|
|
source = STDIN.read |
|
|
|
walker = TreeWalker.new(source) |
|
|
|
walker.parse |
|
|
|
puts walker.to_s |
|
|
|
end |
|
|
|
|
|
|
|
class TreeWalker < Ripper::SexpBuilder |
|
|
|
attr_accessor :symbols |
|
|
|
class TreeWalker < Ripper::SexpBuilder |
|
|
|
attr_accessor :symbols |
|
|
|
|
|
|
|
def initialize(source) |
|
|
|
ns_hash = Hash.new { |
|
|
|
|hash, key| |
|
|
|
hash[key] = { |
|
|
|
:assignments => [], :uses => [] |
|
|
|
} |
|
|
|
def initialize(source) |
|
|
|
ns_hash = Hash.new { |
|
|
|
|hash, key| |
|
|
|
hash[key] = { |
|
|
|
:assignments => [], :uses => [] |
|
|
|
} |
|
|
|
class_hash = ns_hash.clone |
|
|
|
function_hash = ns_hash.clone |
|
|
|
var_hash = ns_hash.clone |
|
|
|
|
|
|
|
@symbols = { |
|
|
|
:namespaces => ns_hash, |
|
|
|
:classes => class_hash, |
|
|
|
:functions => function_hash, |
|
|
|
:vars => var_hash |
|
|
|
} |
|
|
|
|
|
|
|
super(source) |
|
|
|
end |
|
|
|
|
|
|
|
def block_position(node) |
|
|
|
last_node = node[0] |
|
|
|
while last_node.is_a? Array |
|
|
|
sp = last_node |
|
|
|
while not (last_el = last_node[last_node.count - 1]) or |
|
|
|
(last_el.is_a? Array and last_el[last_el.count - 1].nil?) |
|
|
|
last_node = last_node[0..last_node.count - 2] |
|
|
|
end |
|
|
|
last_node = last_el |
|
|
|
end |
|
|
|
} |
|
|
|
class_hash = ns_hash.clone |
|
|
|
function_hash = ns_hash.clone |
|
|
|
var_hash = ns_hash.clone |
|
|
|
|
|
|
|
@symbols = { |
|
|
|
:namespaces => ns_hash, |
|
|
|
:classes => class_hash, |
|
|
|
:functions => function_hash, |
|
|
|
:vars => var_hash |
|
|
|
} |
|
|
|
|
|
|
|
super(source) |
|
|
|
end |
|
|
|
|
|
|
|
last_node = node[0] |
|
|
|
while last_node.is_a? Array |
|
|
|
ep = last_node |
|
|
|
while not (last_el = last_node[last_node.count - 1]) or |
|
|
|
(last_el.is_a? Array and last_el[last_el.count - 1].nil?) |
|
|
|
last_node = last_node[0..last_node.count - 2] |
|
|
|
end |
|
|
|
last_node = last_el |
|
|
|
def block_position(node) |
|
|
|
last_node = node[0] |
|
|
|
while last_node.is_a? Array |
|
|
|
sp = last_node |
|
|
|
while not (last_el = last_node[last_node.count - 1]) or |
|
|
|
(last_el.is_a? Array and last_el[last_el.count - 1].nil?) |
|
|
|
last_node = last_node[0..last_node.count - 2] |
|
|
|
end |
|
|
|
last_node = last_el |
|
|
|
end |
|
|
|
|
|
|
|
if sp == ep |
|
|
|
return sp + [sp[0], -1] |
|
|
|
last_node = node[0] |
|
|
|
while last_node.is_a? Array |
|
|
|
ep = last_node |
|
|
|
while not (last_el = last_node[last_node.count - 1]) or |
|
|
|
(last_el.is_a? Array and last_el[last_el.count - 1].nil?) |
|
|
|
last_node = last_node[0..last_node.count - 2] |
|
|
|
end |
|
|
|
return sp + ep |
|
|
|
last_node = last_el |
|
|
|
end |
|
|
|
|
|
|
|
def on_module(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[0][1][1] |
|
|
|
symbols[:namespaces][name][:assignments] << pos |
|
|
|
return node |
|
|
|
if sp == ep |
|
|
|
return sp + [sp[0], -1] |
|
|
|
end |
|
|
|
return sp + ep |
|
|
|
end |
|
|
|
|
|
|
|
def on_class(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[0][1][1] |
|
|
|
symbols[:classes][name][:assignments] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
def on_module(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[0][1][1] |
|
|
|
symbols[:namespaces][name][:assignments] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
|
|
|
|
def on_def(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[0][1] |
|
|
|
symbols[:functions][name][:assignments] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
def on_class(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[0][1][1] |
|
|
|
symbols[:classes][name][:assignments] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
|
|
|
|
def on_call(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[node.count - 1][1] |
|
|
|
symbols[:functions][name][:uses] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
def on_def(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[0][1] |
|
|
|
symbols[:functions][name][:assignments] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
|
|
|
|
def on_vcall(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[0][1] |
|
|
|
symbols[:functions][name][:uses] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
def on_call(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[node.count - 1][1] |
|
|
|
symbols[:functions][name][:uses] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
|
|
|
|
def on_assign(*node) |
|
|
|
pos = block_position(node) |
|
|
|
return node if not node[0][0].is_a? Array |
|
|
|
name = node[0][0][1] |
|
|
|
symbols[:vars][name][:assignments] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
def on_vcall(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[0][1] |
|
|
|
symbols[:functions][name][:uses] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
|
|
|
|
def on_var_field(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[0][1] |
|
|
|
symbols[:vars][name][:uses] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
def on_assign(*node) |
|
|
|
pos = block_position(node) |
|
|
|
return node if not node[0][0].is_a? Array |
|
|
|
name = node[0][0][1] |
|
|
|
symbols[:vars][name][:assignments] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
|
|
|
|
def on_var_ref(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[0][1] |
|
|
|
symbols[:vars][name][:uses] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
def on_var_field(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[0][1] |
|
|
|
symbols[:vars][name][:uses] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
|
|
|
|
def on_command(*node) |
|
|
|
# catch require statements |
|
|
|
end |
|
|
|
def on_var_ref(*node) |
|
|
|
pos = block_position(node) |
|
|
|
name = node[0][1] |
|
|
|
symbols[:vars][name][:uses] << pos |
|
|
|
return node |
|
|
|
end |
|
|
|
|
|
|
|
def to_s |
|
|
|
new_symbols = Hash.new {|hash, key| hash[key] = Hash.new} |
|
|
|
def on_command(*node) |
|
|
|
# catch require statements |
|
|
|
end |
|
|
|
|
|
|
|
symbols.each do |type, sym_list| |
|
|
|
sym_list.each do |name, sym| |
|
|
|
new_symbols[type.to_s][name.to_s] = { |
|
|
|
"assignments" => sym[:assignments], |
|
|
|
"uses" => sym[:uses]} |
|
|
|
end |
|
|
|
end |
|
|
|
def to_s |
|
|
|
new_symbols = Hash.new {|hash, key| hash[key] = Hash.new} |
|
|
|
|
|
|
|
str = new_symbols.to_s |
|
|
|
str = str.gsub(/=>/, ":") |
|
|
|
return str |
|
|
|
symbols.each do |type, sym_list| |
|
|
|
sym_list.each do |name, sym| |
|
|
|
new_symbols[type.to_s][name.to_s] = { |
|
|
|
"assignments" => sym[:assignments], |
|
|
|
"uses" => sym[:uses]} |
|
|
|
end |
|
|
|
end |
|
|
|
|
|
|
|
str = new_symbols.to_s |
|
|
|
str = str.gsub(/=>/, ":") |
|
|
|
return str |
|
|
|
end |
|
|
|
end |