# 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.