Class: FastRuby::FastRubySexp

Inherits:
Array
  • Object
show all
Defined in:
lib/fastruby/fastruby_sexp.rb,
lib/fastruby/sexp_extension.rb,
lib/fastruby/sexp_extension_edges.rb

Defined Under Namespace

Classes: Edges

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_sexp(value) ⇒ Object



86
87
88
89
90
91
92
93
94
95
# File 'lib/fastruby/sexp_extension.rb', line 86

def self.from_sexp(value)
  return nil if value == nil
  return value if value.kind_of? FastRubySexp

  ary = FastRuby::FastRubySexp.new
  value.each do |x|
    ary << x.to_fastruby_sexp
  end
  ary
end

.parse(code) ⇒ Object



114
115
116
# File 'lib/fastruby/sexp_extension.rb', line 114

def self.parse(code)
  from_sexp(RubyParser.new.parse(code))
end

Instance Method Details

#edgesObject



141
142
143
# File 'lib/fastruby/sexp_extension.rb', line 141

def edges
  Edges.new(self)
end

#find_break(&blk) ⇒ Object



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/fastruby/sexp_extension.rb', line 209

def find_break(&blk)
  subarray = if node_type == :while
    []
  elsif node_type == :iter
    self[1..-2]
  elsif node_type == :break
    blk.call(self)
    return; nil
  else
    self[1..-1]
  end

  subarray.each do |subtree|
    if subtree.respond_to? :find_break
      subtree.find_break(&blk)
    end 
  end
end

#find_tree(ndtype = nil) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/fastruby/fastruby_sexp.rb', line 34

def find_tree(ndtype = nil)
  walk_tree do |subtree|
    if (not block_given?) || yield(subtree)
      if (not ndtype) || ndtype == subtree.node_type
        return subtree
      end
    end
  end
  
  return nil
end

#first_treeObject



145
146
147
148
149
150
151
152
153
154
155
# File 'lib/fastruby/sexp_extension.rb', line 145

def first_tree
  if respond_to? "first_tree_#{node_type}" 
    send("first_tree_#{node_type}")
  else
    return self[1].first_tree if self.count == 2 and self[1].respond_to? :node_type
    return self[1].first_tree if [:if,:block,:while,:until,:or,:and,:ensure].include? node_type
    return self[2].first_tree if [:lasgn,:iasgn,:gasgn,:cdecl].include? node_type

    self
  end    
end

#first_tree_callObject



195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/fastruby/sexp_extension.rb', line 195

def first_tree_call
  recv = self[1]
  if recv
    recv.first_tree
  else
    args_tree = self[3]
    if args_tree.size > 1
      args_tree[1].first_tree
    else
      self
    end
  end
end

#first_tree_iterObject



180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/fastruby/sexp_extension.rb', line 180

def first_tree_iter
  call_tree = self[1]
  recv = call_tree[1]
  if recv
    recv.first_tree
  else
    args_tree = call_tree[3]
    if args_tree.size > 1
      args_tree[1].first_tree
    else
      call_tree
    end
  end
end

#first_tree_rescueObject



157
158
159
160
161
162
163
# File 'lib/fastruby/sexp_extension.rb', line 157

def first_tree_rescue
  if self[1].node_type == :resbody
    return self
  else
    return self[1].first_tree
  end
end

#first_tree_returnObject Also known as: first_tree_break, first_tree_next



165
166
167
# File 'lib/fastruby/sexp_extension.rb', line 165

def first_tree_return
  self[1] ? self[1].first_tree : self
end

#first_tree_yieldObject



172
173
174
175
176
177
178
# File 'lib/fastruby/sexp_extension.rb', line 172

def first_tree_yield
  if self.size > 1
    self[-1].first_tree
  else
    self
  end
end

#to_graphObject



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/fastruby/sexp_extension.rb', line 118

def to_graph
  graph = Graph.new
  self.edges.each &graph.method(:add_edge)

  if ENV['FASTRUBY_GRAPH_VERTEX_CHECK'] == '1' 
    output_vertexes = [];

    self.walk_tree do |subtree|
      if graph.each_vertex_output(subtree).count == 0
        # vertexes with no output
        unless [:arglist,:scope].include? subtree.node_type 
          output_vertexes << subtree
          if output_vertexes.count > 1
            raise RuntimeError, "invalid output vertexes #{output_vertexes.map &:node_type}"
          end
        end
      end
    end
  end

  graph
end

#transform(&blk) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/fastruby/sexp_extension.rb', line 97

def transform(&blk)
  ret = FastRuby::FastRubySexp.from_sexp( blk.call(self) )

  unless ret
    ret = FastRuby::FastRubySexp.new
    each{|st2|
      if st2.respond_to?(:transform)
        ret << st2.transform(&blk)
      else
        ret << st2
      end
    } 
  end

  ret
end

#walk_tree(&block) ⇒ Object



25
26
27
28
29
30
31
32
# File 'lib/fastruby/fastruby_sexp.rb', line 25

def walk_tree(&block)
  each do |subtree|
    if subtree.instance_of? FastRubySexp
      subtree.walk_tree(&block)
    end
  end
  block.call(self)
end