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



115
116
117
118
119
120
121
122
123
124
# File 'lib/fastruby/sexp_extension.rb', line 115

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



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

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

Instance Method Details

#duplicateObject



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

def duplicate
  map { |subtree|
    if subtree.respond_to?(:node_type)
      subtree.duplicate
    else
      subtree
    end
  }
end

#edgesObject



169
170
171
# File 'lib/fastruby/sexp_extension.rb', line 169

def edges
  Edges.new(self)
end

#find_break(&blk) ⇒ Object



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
# File 'lib/fastruby/sexp_extension.rb', line 237

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



70
71
72
73
74
75
76
77
78
79
80
# File 'lib/fastruby/fastruby_sexp.rb', line 70

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



173
174
175
176
177
178
179
180
181
182
183
# File 'lib/fastruby/sexp_extension.rb', line 173

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



223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/fastruby/sexp_extension.rb', line 223

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



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

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



185
186
187
188
189
190
191
# File 'lib/fastruby/sexp_extension.rb', line 185

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



193
194
195
# File 'lib/fastruby/sexp_extension.rb', line 193

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

#first_tree_yieldObject



200
201
202
203
204
205
206
# File 'lib/fastruby/sexp_extension.rb', line 200

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

#mapObject



53
54
55
56
57
58
59
# File 'lib/fastruby/fastruby_sexp.rb', line 53

def map
  sexp = FastRubySexp.new
  self.each do |subtree|
    sexp << yield(subtree)
  end
  sexp
end

#to_graphObject



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/fastruby/sexp_extension.rb', line 146

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

#to_rubyObject



48
49
50
51
# File 'lib/fastruby/fastruby_sexp.rb', line 48

def to_ruby
  require "ruby2ruby"
  Ruby2Ruby.new.process(to_sexp)
end

#to_sexpObject



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

def to_sexp
  ret = s()
  each do |subtree|
    if subtree.respond_to?(:to_sexp)
      ret << subtree.to_sexp
    else
      ret << subtree
    end 
  end
  
  ret
end

#transform(&blk) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/fastruby/sexp_extension.rb', line 126

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



61
62
63
64
65
66
67
68
# File 'lib/fastruby/fastruby_sexp.rb', line 61

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