# 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: case exp.size 42: when 2 then 43: _, block = exp 44: case block.first 45: when :lasgn then 46: block[1] = :"&#{block[-1]}" 47: exp = block 48: else 49: raise "huh?: #{block.inspect}" 50: end 51: when 3 then 52: _, block, recv = exp 53: case recv.first 54: when :super then 55: recv << s(:block_pass, block) 56: exp = recv 57: when :call then 58: recv.last << s(:block_pass, block) 59: exp = recv 60: when :masgn then 61: block[1] = :"&#{block[-1]}" 62: recv.last << block 63: exp = recv 64: else 65: raise "huh?: #{recv.inspect}" 66: end 67: end 68: 69: exp 70: end
# File lib/unified_ruby.rb, line 72 72: def rewrite_bmethod(exp) 73: _, args, body = exp 74: 75: args ||= s(:array) 76: body ||= s(:block) 77: 78: args = s(:args, args) unless args[0] == :array 79: 80: args = args[1] if args[1] && args[1][0] == :masgn # TODO: clean up 81: args = args[1] if args[1] && args[1][0] == :array 82: args[0] = :args 83: 84: # this is ugly because rewriters are depth first. 85: # TODO: maybe we could come up with some way to do both forms of rewriting. 86: args.map! { |s| 87: if Sexp === s 88: case s[0] 89: when :lasgn then 90: s[1] 91: when :splat then 92: :"*#{s[1][1]}" 93: else 94: raise "huh?: #{s.inspect}" 95: end 96: else 97: s 98: end 99: } 100: 101: body = s(:block, body) unless body[0] == :block 102: body.insert 1, args 103: 104: s(:scope, body) 105: end
# File lib/unified_ruby.rb, line 122 122: def rewrite_call(exp) 123: args = exp.last 124: case args 125: when nil 126: exp.pop 127: when Array 128: case args.first 129: when :array, :arglist then 130: args[0] = :arglist 131: when :argscat, :splat then 132: exp[1] = s(:arglist, args) 133: else 134: raise "unknown type in call #{args.first.inspect} in #{exp.inspect}" 135: end 136: return exp 137: end 138: 139: exp << s(:arglist) 140: 141: exp 142: end
# File lib/unified_ruby.rb, line 144 144: def rewrite_dasgn(exp) 145: exp[0] = :lasgn 146: exp 147: 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 182 182: def rewrite_defn(exp) 183: weirdo = exp.ivar || exp.attrset 184: fbody = exp.fbody(true) 185: 186: weirdo ||= fbody.cfunc if fbody 187: 188: exp.push(fbody.scope) if fbody unless weirdo 189: 190: args = exp.scope.block.args(true) unless weirdo if exp.scope 191: exp.insert 2, args if args 192: 193: # move block_arg up and in 194: block_arg = exp.scope.block.block_arg(true) rescue nil 195: if block_arg 196: block = args.block(true) 197: args << :"&#{block_arg.last}" 198: args << block if block 199: end 200: 201: # patch up attr_accessor methods 202: if weirdo then 203: case 204: when fbody && fbody.cfunc then 205: exp.insert 2, s(:args, :"*args") 206: when exp.ivar then 207: exp.insert 2, s(:args) 208: when exp.attrset then 209: exp.insert 2, s(:args, :arg) 210: else 211: raise "unknown wierdo: #{wierdo.inpsect}" 212: end 213: end 214: 215: exp 216: end
# File lib/unified_ruby.rb, line 218 218: def rewrite_defs(exp) 219: receiver = exp.delete_at 1 220: 221: # TODO: I think this would be better as rewrite_scope, but that breaks others 222: exp = s(exp.shift, exp.shift, 223: s(:scope, 224: s(:block, exp.scope.args))) if exp.scope && exp.scope.args 225: 226: result = rewrite_defn(exp) 227: result.insert 1, receiver 228: 229: result 230: end
# File lib/unified_ruby.rb, line 232 232: def rewrite_dmethod(exp) 233: exp.shift # type 234: exp.shift # dmethod name 235: exp.shift # scope / block / body 236: end
# File lib/unified_ruby.rb, line 238 238: def rewrite_dvar(exp) 239: exp[0] = :lvar 240: exp 241: end
# File lib/unified_ruby.rb, line 243 243: def rewrite_fcall(exp) 244: exp[0] = :call 245: exp.insert 1, nil 246: 247: rewrite_call(exp) 248: end
# File lib/unified_ruby.rb, line 250 250: def rewrite_flip2(exp) 251: # from: 252: # s(:flip2, 253: # s(:call, s(:lit, 1), :==, s(:arglist, s(:gvar, :$.))), 254: # s(:call, s(:lit, 2), :a?, s(:arglist, s(:call, nil, :b, s(:arglist))))) 255: # to: 256: # s(:flip2, 257: # s(:lit, 1), 258: # s(:call, s(:lit, 2), :a?, s(:arglist, s(:call, nil, :b, s(:arglist))))) 259: exp[1] = exp[1][1] if exp[1][0] == :call && exp[1][1][0] == :lit 260: exp 261: end
# File lib/unified_ruby.rb, line 107 107: def rewrite_iter(exp) 108: t, recv, args, body = exp 109: 110: # unwrap masgn args if there is only 1 thing to assign and it isn't splat 111: if Sexp === args and args.sexp_type == :masgn and args.array.size == 2 then 112: if args.array.last.sexp_type != :splat then 113: args = args.array.last 114: end 115: end 116: 117: r = s(t, recv, args, body) 118: r.delete_at 3 unless body # HACK omg this sucks 119: r 120: end
# File lib/unified_ruby.rb, line 265 265: def rewrite_masgn(exp) 266: t, lhs, lhs_splat, rhs = exp 267: 268: lhs ||= s(:array) 269: 270: if lhs_splat then 271: case lhs_splat.first 272: when :array then 273: lhs_splat = lhs_splat.last if lhs_splat.last.first == :splat 274: when :splat then 275: # do nothing 276: else 277: lhs_splat = s(:splat, lhs_splat) 278: end 279: lhs << lhs_splat 280: end 281: 282: # unwrap RHS from array IF it is only a splat node 283: rhs = rhs.last if rhs && # TODO: rhs.structure =~ s(:array, s(:splat)) 284: rhs.size == 2 && rhs.structure.flatten.first(2) == [:array, :splat] 285: 286: s(t, lhs, rhs).compact 287: end
# File lib/unified_ruby.rb, line 289 289: def rewrite_op_asgn1(exp) 290: exp[2][0] = :arglist # if exp[2][0] == :array 291: exp 292: end
# File lib/unified_ruby.rb, line 294 294: def rewrite_resbody(exp) 295: exp[1] ||= s(:array) # no args 296: 297: body = exp[2] 298: if body then 299: case body.first 300: when :lasgn, :iasgn then 301: exp[1] << exp.delete_at(2) if body[1] == s(:gvar, :$!) 302: when :block then 303: exp[1] << body.delete_at(1) if [:lasgn, :iasgn].include?(body[1][0]) && 304: body[1][1] == s(:gvar, :$!) 305: end 306: end 307: 308: exp << nil if exp.size == 2 # no body 309: 310: exp 311: end
# File lib/unified_ruby.rb, line 313 313: def rewrite_rescue(exp) 314: # SKETCHY HACK return exp if exp.size > 4 315: ignored = exp.shift 316: body = exp.shift unless exp.first.first == :resbody 317: resbody = exp.shift 318: els = exp.shift unless exp.first.first == :resbody unless exp.empty? 319: rest = exp.empty? ? nil : exp # graceful re-rewriting (see rewrite_begin) 320: 321: resbodies = [] 322: 323: unless rest then 324: while resbody do 325: resbodies << resbody 326: resbody = resbody.resbody(true) 327: end 328: 329: resbodies.each do |resbody| 330: if resbody[2] && resbody[2][0] == :block && resbody[2].size == 2 then 331: resbody[2] = resbody[2][1] 332: end 333: end 334: else 335: resbodies = [resbody] + rest 336: end 337: 338: resbodies << els if els 339: 340: s(:rescue, body, *resbodies).compact 341: end
# File lib/unified_ruby.rb, line 343 343: def rewrite_splat(exp) 344: good = [:arglist, :argspush, :array, :svalue, :yield, :super].include? context.first 345: exp = s(:array, exp) unless good 346: exp 347: end
# File lib/unified_ruby.rb, line 349 349: def rewrite_super(exp) 350: return exp if exp.structure.flatten.first(3) == [:super, :array, :splat] 351: exp.push(*exp.pop[1..1]) if exp.size == 2 && exp.last.first == :array 352: exp 353: end
# File lib/unified_ruby.rb, line 355 355: def rewrite_vcall(exp) 356: exp.push nil 357: rewrite_fcall(exp) 358: end
# File lib/unified_ruby.rb, line 360 360: def rewrite_yield(exp) 361: real_array = exp.pop if exp.size == 3 362: 363: if exp.size == 2 then 364: if real_array then 365: exp[1] = s(:array, exp[1]) if exp[1][0] != :array 366: else 367: exp.push(*exp.pop[1..1]) if exp.last.first == :array 368: end 369: end 370: 371: exp 372: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.