UnifiedRuby

Public Instance Methods

process(exp) click to toggle source
    # File lib/unified_ruby.rb, line 7
 7:   def process exp
 8:     exp = Sexp.from_array exp unless Sexp === exp or exp.nil?
 9:     super
10:   end
rewrite_argscat(exp) click to toggle source
    # File lib/unified_ruby.rb, line 12
12:   def rewrite_argscat exp
13:     _, ary, val = exp
14:     ary = s(:array, ary) unless ary.first == :array
15:     ary << s(:splat, val)
16:   end
rewrite_argspush(exp) click to toggle source
    # File lib/unified_ruby.rb, line 18
18:   def rewrite_argspush exp
19:     exp[0] = :arglist
20:     exp
21:   end
rewrite_attrasgn(exp) click to toggle source
    # File lib/unified_ruby.rb, line 23
23:   def rewrite_attrasgn(exp)
24:     last = exp.last
25: 
26:     if Sexp === last then
27:       last[0] = :arglist if last[0] == :array
28:     else
29:       exp << s(:arglist)
30:     end
31: 
32:     exp
33:   end
rewrite_begin(exp) click to toggle source
    # File lib/unified_ruby.rb, line 35
35:   def rewrite_begin(exp)
36:     raise "wtf: #{exp.inspect}" if exp.size > 2
37:     exp.last
38:   end
rewrite_block_pass(exp) click to toggle source
    # File lib/unified_ruby.rb, line 40
40:   def rewrite_block_pass exp
41:     if exp.size == 3 then
42:       _, block, recv = exp
43:       case recv.first
44:       when :super then
45:         recv << s(:block_pass, block)
46:         exp = recv
47:       when :call then
48:         recv.last << s(:block_pass, block)
49:         exp = recv
50:       else
51:         raise "huh?: #{recv.inspect}"
52:       end
53:     end
54: 
55:     exp
56:   end
rewrite_bmethod(exp) click to toggle source
    # File lib/unified_ruby.rb, line 58
58:   def rewrite_bmethod(exp)
59:     _, args, body = exp
60: 
61:     args ||= s(:array)
62:     body ||= s(:block)
63: 
64:     args = s(:args, args) unless args[0] == :array
65: 
66:     args = args[1] if args[1] && args[1][0] == :masgn # TODO: clean up
67:     args = args[1] if args[1] && args[1][0] == :array
68:     args[0] = :args
69: 
70:     # this is ugly because rewriters are depth first.
71:     # TODO: maybe we could come up with some way to do both forms of rewriting.
72:     args.map! { |s|
73:       if Sexp === s
74:         case s[0]
75:         when :lasgn then
76:           s[1]
77:         when :splat then
78:           :"*#{s[1][1]}"
79:         else
80:           raise "huh?: #{s.inspect}"
81:         end
82:       else
83:         s
84:       end
85:     }
86: 
87:     body = s(:block, body) unless body[0] == :block
88:     body.insert 1, args
89: 
90:     s(:scope, body)
91:   end
rewrite_call(exp) click to toggle source
     # File lib/unified_ruby.rb, line 93
 93:   def rewrite_call(exp)
 94:     args = exp.last
 95:     case args
 96:     when nil
 97:       exp.pop
 98:     when Array
 99:       case args.first
100:       when :array, :arglist then
101:         args[0] = :arglist
102:       when :argscat, :splat then
103:         exp[1] = s(:arglist, args)
104:       else
105:         raise "unknown type in call #{args.first.inspect} in #{exp.inspect}"
106:       end
107:       return exp
108:     end
109: 
110:     exp << s(:arglist)
111: 
112:     exp
113:   end
rewrite_dasgn(exp) click to toggle source
     # File lib/unified_ruby.rb, line 115
115:   def rewrite_dasgn(exp)
116:     exp[0] = :lasgn
117:     exp
118:   end
Also aliased as: rewrite_dasgn_curr
rewrite_dasgn_curr(exp) click to toggle source
Alias for: rewrite_dasgn
rewrite_defn(exp) click to toggle source

:defn is one of the most complex of all the ASTs in ruby. We do one of 3 different translations:

1) From:

  s(:defn, :name, s(:scope, s(:block, s(:args, ...), ...)))
  s(:defn, :name, s(:bmethod, s(:masgn, s(:dasgn_curr, :args)), s(:block, ...)))
  s(:defn, :name, s(:fbody, s(:bmethod, s(:masgn, s(:dasgn_curr, :splat)), s(:block, ...))))

to:

  s(:defn, :name, s(:args, ...), s(:scope, s:(block, ...)))

2) From:

  s(:defn, :writer=, s(:attrset, :@name))

to:

  s(:defn, :writer=, s(:args), s(:attrset, :@name))

3) From:

  s(:defn, :reader, s(:ivar, :@name))

to:

  s(:defn, :reader, s(:args), s(:ivar, :@name))
     # File lib/unified_ruby.rb, line 153
153:   def rewrite_defn(exp)
154:     weirdo = exp.ivar || exp.attrset
155:     fbody  = exp.fbody(true)
156: 
157:     weirdo ||= fbody.cfunc if fbody
158: 
159:     exp.push(fbody.scope) if fbody unless weirdo
160: 
161:     args = exp.scope.block.args(true) unless weirdo
162:     exp.insert 2, args if args
163: 
164:     # move block_arg up and in
165:     block_arg = exp.scope.block.block_arg(true) rescue nil
166:     if block_arg
167:       block = args.block(true)
168:       args << :"&#{block_arg.last}"
169:       args << block if block
170:     end
171: 
172:     # patch up attr_accessor methods
173:     if weirdo then
174:       case
175:       when fbody && fbody.cfunc then
176:         exp.insert 2, s(:args, :"*args")
177:       when exp.ivar then
178:         exp.insert 2, s(:args)
179:       when exp.attrset then
180:         exp.insert 2, s(:args, :arg)
181:       else
182:         raise "unknown wierdo: #{wierdo.inpsect}"
183:       end
184:     end
185: 
186:     exp
187:   end
rewrite_defs(exp) click to toggle source
     # File lib/unified_ruby.rb, line 189
189:   def rewrite_defs(exp)
190:     receiver = exp.delete_at 1
191: 
192:     # TODO: I think this would be better as rewrite_scope, but that breaks others
193:     exp = s(exp.shift, exp.shift,
194:             s(:scope,
195:               s(:block, exp.scope.args))) if exp.scope && exp.scope.args
196: 
197:     result = rewrite_defn(exp)
198:     result.insert 1, receiver
199: 
200:     result
201:   end
rewrite_dmethod(exp) click to toggle source
     # File lib/unified_ruby.rb, line 203
203:   def rewrite_dmethod(exp)
204:     exp.shift # type
205:     exp.shift # dmethod name
206:     exp.shift # scope / block / body
207:   end
rewrite_dvar(exp) click to toggle source
     # File lib/unified_ruby.rb, line 209
209:   def rewrite_dvar(exp)
210:     exp[0] = :lvar
211:     exp
212:   end
rewrite_fcall(exp) click to toggle source
     # File lib/unified_ruby.rb, line 214
214:   def rewrite_fcall(exp)
215:     exp[0] = :call
216:     exp.insert 1, nil
217: 
218:     rewrite_call(exp)
219:   end
rewrite_flip2(exp) click to toggle source
     # File lib/unified_ruby.rb, line 221
221:   def rewrite_flip2(exp)
222:     # from:
223:     # s(:flip2,
224:     #   s(:call, s(:lit, 1), :==, s(:arglist, s(:gvar, :$.))),
225:     #   s(:call, s(:lit, 2), :a?, s(:arglist, s(:call, nil, :b, s(:arglist)))))
226:     # to:
227:     # s(:flip2,
228:     #   s(:lit, 1),
229:     #   s(:call, s(:lit, 2), :a?, s(:arglist, s(:call, nil, :b, s(:arglist)))))
230:     exp[1] = exp[1][1] if exp[1][0] == :call && exp[1][1][0] == :lit
231:     exp
232:   end
Also aliased as: rewrite_flip3
rewrite_flip3(exp) click to toggle source
Alias for: rewrite_flip2
rewrite_masgn(exp) click to toggle source
     # File lib/unified_ruby.rb, line 236
236:   def rewrite_masgn(exp)
237:     raise "wtf: #{exp}" unless exp.size == 4 # TODO: remove 2009-01-29
238:     t, lhs, lhs_splat, rhs = exp
239: 
240:     lhs ||= s(:array)
241: 
242:     if lhs_splat then
243:       case lhs_splat.first
244:       when :array then
245:         lhs_splat = lhs_splat.last if lhs_splat.last.first == :splat
246:       when :splat then
247:         # do nothing
248:       else
249:         lhs_splat = s(:splat, lhs_splat)
250:       end
251:       lhs << lhs_splat
252:     end
253: 
254:     # unwrap RHS from array IF it is only a splat node
255:     rhs = rhs.last if rhs && # TODO: rhs.structure =~ s(:array, s(:splat))
256:       rhs.size == 2 && rhs.structure.flatten.first(2) == [:array, :splat]
257: 
258:     s(t, lhs, rhs).compact
259:   end
rewrite_op_asgn1(exp) click to toggle source
     # File lib/unified_ruby.rb, line 261
261:   def rewrite_op_asgn1(exp)
262:     exp[2][0] = :arglist # if exp[2][0] == :array
263:     exp
264:   end
rewrite_resbody(exp) click to toggle source
     # File lib/unified_ruby.rb, line 266
266:   def rewrite_resbody(exp)
267:     exp[1] ||= s(:array)        # no args
268: 
269:     body = exp[2]
270:     if body then
271:       case body.first
272:       when :lasgn, :iasgn then
273:         exp[1] << exp.delete_at(2) if body[1] == s(:gvar, :$!)
274:       when :block then
275:         exp[1] << body.delete_at(1) if [:lasgn, :iasgn].include?(body[1][0]) &&
276:           body[1][1] == s(:gvar, :$!)
277:       end
278:     end
279: 
280:     exp << nil if exp.size == 2 # no body
281: 
282:     exp
283:   end
rewrite_rescue(exp) click to toggle source
     # File lib/unified_ruby.rb, line 285
285:   def rewrite_rescue(exp)
286:     # SKETCHY HACK return exp if exp.size > 4
287:     ignored = exp.shift
288:     body    = exp.shift unless exp.first.first == :resbody
289:     resbody = exp.shift
290:     els     = exp.shift unless exp.first.first == :resbody unless exp.empty?
291:     rest    = exp.empty? ? nil : exp # graceful re-rewriting (see rewrite_begin)
292: 
293:     resbodies = []
294: 
295:     unless rest then
296:       while resbody do
297:         resbodies << resbody
298:         resbody = resbody.resbody(true)
299:       end
300: 
301:       resbodies.each do |resbody|
302:         if resbody[2] && resbody[2][0] == :block && resbody[2].size == 2 then
303:           resbody[2] = resbody[2][1]
304:         end
305:       end
306:     else
307:       resbodies = [resbody] + rest
308:     end
309: 
310:     resbodies << els if els
311: 
312:     s(:rescue, body, *resbodies).compact
313:   end
rewrite_splat(exp) click to toggle source
     # File lib/unified_ruby.rb, line 315
315:   def rewrite_splat(exp)
316:     good = [:arglist, :argspush, :array, :svalue, :yield, :super].include? context.first
317:     exp = s(:array, exp) unless good
318:     exp
319:   end
rewrite_super(exp) click to toggle source
     # File lib/unified_ruby.rb, line 321
321:   def rewrite_super(exp)
322:     return exp if exp.structure.flatten.first(3) == [:super, :array, :splat]
323:     exp.push(*exp.pop[1..1]) if exp.size == 2 && exp.last.first == :array
324:     exp
325:   end
rewrite_vcall(exp) click to toggle source
     # File lib/unified_ruby.rb, line 327
327:   def rewrite_vcall(exp)
328:     exp.push nil
329:     rewrite_fcall(exp)
330:   end
rewrite_yield(exp) click to toggle source
     # File lib/unified_ruby.rb, line 332
332:   def rewrite_yield(exp)
333:     real_array = exp.pop if exp.size == 3
334: 
335:     if exp.size == 2 then
336:       if real_array then
337:         exp[1] = s(:array, exp[1]) if exp[1][0] != :array
338:       else
339:         exp.push(*exp.pop[1..1]) if exp.last.first == :array
340:       end
341:     end
342: 
343:     exp
344:   end
rewrite_zarray(exp) click to toggle source
     # File lib/unified_ruby.rb, line 346
346:   def rewrite_zarray(exp)
347:     exp[0] = :array
348:     exp
349:   end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.