# 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
# 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
# File lib/unified_ruby.rb, line 18
18: def rewrite_argspush exp
19: exp[0] = :arglist
20: exp
21: end
# 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
# 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
# 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
# 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
# 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
# File lib/unified_ruby.rb, line 115
115: def rewrite_dasgn(exp)
116: exp[0] = :lasgn
117: exp
118: end
: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
# 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
# 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
# File lib/unified_ruby.rb, line 209
209: def rewrite_dvar(exp)
210: exp[0] = :lvar
211: exp
212: end
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# 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
# File lib/unified_ruby.rb, line 327
327: def rewrite_vcall(exp)
328: exp.push nil
329: rewrite_fcall(exp)
330: end
# 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
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.