ParseTree 1.7.1 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +32 -0
 - data/Manifest.txt +2 -0
 - data/README.txt +28 -24
 - data/Rakefile +14 -7
 - data/lib/parse_tree.rb +47 -14
 - data/lib/sexp.rb +46 -3
 - data/lib/sexp_processor.rb +15 -19
 - data/lib/unified_ruby.rb +147 -0
 - data/test/pt_testcase.rb +158 -53
 - data/test/test_parse_tree.rb +2 -1
 - data/test/test_sexp.rb +28 -3
 - data/test/test_sexp_processor.rb +74 -17
 - data/test/test_unified_ruby.rb +229 -0
 - metadata +8 -6
 
    
        data/lib/unified_ruby.rb
    ADDED
    
    | 
         @@ -0,0 +1,147 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            module UnifiedRuby
         
     | 
| 
      
 3 
     | 
    
         
            +
              def rewrite_bmethod(exp)
         
     | 
| 
      
 4 
     | 
    
         
            +
                exp[0] = :scope
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                args =
         
     | 
| 
      
 7 
     | 
    
         
            +
                  if exp.masgn and exp.masgn.dasgn_curr then
         
     | 
| 
      
 8 
     | 
    
         
            +
                    arg = exp.masgn(true).dasgn_curr(true).sexp_body
         
     | 
| 
      
 9 
     | 
    
         
            +
                    raise "nope: #{arg.size}" unless arg.size == 1
         
     | 
| 
      
 10 
     | 
    
         
            +
                    s(:args, :"*#{arg.last}")
         
     | 
| 
      
 11 
     | 
    
         
            +
                  else
         
     | 
| 
      
 12 
     | 
    
         
            +
                    args = exp.dasgn_curr(true)
         
     | 
| 
      
 13 
     | 
    
         
            +
                    if args then
         
     | 
| 
      
 14 
     | 
    
         
            +
                      s(:args, *args.sexp_body)
         
     | 
| 
      
 15 
     | 
    
         
            +
                    else
         
     | 
| 
      
 16 
     | 
    
         
            +
                      exp.delete_at 1 # nil
         
     | 
| 
      
 17 
     | 
    
         
            +
                      s(:args)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                exp = s(:scope, s(:block, *exp.sexp_body)) unless exp.block
         
     | 
| 
      
 22 
     | 
    
         
            +
                exp.block.insert 1, args
         
     | 
| 
      
 23 
     | 
    
         
            +
                exp.find_and_replace_all(:dvar, :lvar)
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                exp
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              ##
         
     | 
| 
      
 29 
     | 
    
         
            +
              # :defn is one of the most complex of all the ASTs in ruby. We do
         
     | 
| 
      
 30 
     | 
    
         
            +
              # one of 3 different translations:
         
     | 
| 
      
 31 
     | 
    
         
            +
              #
         
     | 
| 
      
 32 
     | 
    
         
            +
              # 1) From:
         
     | 
| 
      
 33 
     | 
    
         
            +
              #
         
     | 
| 
      
 34 
     | 
    
         
            +
              #   s(:defn, :name, s(:scope, s(:block, s(:args, ...), ...)))
         
     | 
| 
      
 35 
     | 
    
         
            +
              #   s(:defn, :name, s(:bmethod, s(:masgn, s(:dasgn_curr, :args)), s(:block, ...)))
         
     | 
| 
      
 36 
     | 
    
         
            +
              #   s(:defn, :name, s(:fbody, s(:bmethod, s(:masgn, s(:dasgn_curr, :splat)), s(:block, ...))))
         
     | 
| 
      
 37 
     | 
    
         
            +
              #
         
     | 
| 
      
 38 
     | 
    
         
            +
              # to:
         
     | 
| 
      
 39 
     | 
    
         
            +
              #
         
     | 
| 
      
 40 
     | 
    
         
            +
              #   s(:defn, :name, s(:args, ...), s(:scope, s:(block, ...)))
         
     | 
| 
      
 41 
     | 
    
         
            +
              #
         
     | 
| 
      
 42 
     | 
    
         
            +
              # 2) From:
         
     | 
| 
      
 43 
     | 
    
         
            +
              #
         
     | 
| 
      
 44 
     | 
    
         
            +
              #   s(:defn, :writer=, s(:attrset, :@name))
         
     | 
| 
      
 45 
     | 
    
         
            +
              #
         
     | 
| 
      
 46 
     | 
    
         
            +
              # to:
         
     | 
| 
      
 47 
     | 
    
         
            +
              #
         
     | 
| 
      
 48 
     | 
    
         
            +
              #   s(:defn, :writer=, s(:args), s(:attrset, :@name))
         
     | 
| 
      
 49 
     | 
    
         
            +
              #
         
     | 
| 
      
 50 
     | 
    
         
            +
              # 3) From:
         
     | 
| 
      
 51 
     | 
    
         
            +
              #
         
     | 
| 
      
 52 
     | 
    
         
            +
              #   s(:defn, :reader, s(:ivar, :@name))
         
     | 
| 
      
 53 
     | 
    
         
            +
              #
         
     | 
| 
      
 54 
     | 
    
         
            +
              # to:
         
     | 
| 
      
 55 
     | 
    
         
            +
              #
         
     | 
| 
      
 56 
     | 
    
         
            +
              #   s(:defn, :reader, s(:args), s(:ivar, :@name))
         
     | 
| 
      
 57 
     | 
    
         
            +
              #
         
     | 
| 
      
 58 
     | 
    
         
            +
              #
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              def rewrite_defn(exp)
         
     | 
| 
      
 61 
     | 
    
         
            +
                weirdo = exp.ivar || exp.attrset
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
                # move args up
         
     | 
| 
      
 64 
     | 
    
         
            +
                args = exp.scope.block.args(true) unless weirdo
         
     | 
| 
      
 65 
     | 
    
         
            +
                exp.insert 2, args if args
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                # move block_arg up and in
         
     | 
| 
      
 68 
     | 
    
         
            +
                block_arg = exp.scope.block.block_arg(true) rescue nil
         
     | 
| 
      
 69 
     | 
    
         
            +
                exp.args << block_arg if block_arg
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                # patch up attr_accessor methods
         
     | 
| 
      
 72 
     | 
    
         
            +
                exp.insert 2, s(:args) if weirdo
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                exp
         
     | 
| 
      
 75 
     | 
    
         
            +
              end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
              def rewrite_dmethod(exp)
         
     | 
| 
      
 78 
     | 
    
         
            +
                exp.shift # type
         
     | 
| 
      
 79 
     | 
    
         
            +
                exp.shift # dmethod name
         
     | 
| 
      
 80 
     | 
    
         
            +
                exp.shift # scope / block / body
         
     | 
| 
      
 81 
     | 
    
         
            +
              end
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
              def rewrite_fbody(exp)
         
     | 
| 
      
 84 
     | 
    
         
            +
                return *exp.sexp_body
         
     | 
| 
      
 85 
     | 
    
         
            +
              end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
              def rewrite_fcall(exp)
         
     | 
| 
      
 88 
     | 
    
         
            +
                exp[0] = :call
         
     | 
| 
      
 89 
     | 
    
         
            +
                exp.insert 1, nil
         
     | 
| 
      
 90 
     | 
    
         
            +
                exp.push nil if exp.size <= 3
         
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
                args = exp[-1]
         
     | 
| 
      
 93 
     | 
    
         
            +
                if Array === args and args.first == :array then
         
     | 
| 
      
 94 
     | 
    
         
            +
                  args[0] = :arglist
         
     | 
| 
      
 95 
     | 
    
         
            +
                elsif args.nil? then
         
     | 
| 
      
 96 
     | 
    
         
            +
                  exp[-1] = s(:arglist)
         
     | 
| 
      
 97 
     | 
    
         
            +
                else
         
     | 
| 
      
 98 
     | 
    
         
            +
                  exp[-1] = s(:arglist, args) unless args.nil?
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                exp
         
     | 
| 
      
 102 
     | 
    
         
            +
              end
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
              def rewrite_resbody(exp) # TODO: clean up and move to unified
         
     | 
| 
      
 105 
     | 
    
         
            +
                result = s()
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                code = result
         
     | 
| 
      
 108 
     | 
    
         
            +
                while exp and exp.first == :resbody do
         
     | 
| 
      
 109 
     | 
    
         
            +
                  code << exp.shift
         
     | 
| 
      
 110 
     | 
    
         
            +
                  list = exp.shift || s(:array)
         
     | 
| 
      
 111 
     | 
    
         
            +
                  body = exp.shift rescue nil
         
     | 
| 
      
 112 
     | 
    
         
            +
                  exp  = exp.shift rescue nil
         
     | 
| 
      
 113 
     | 
    
         
            +
             
     | 
| 
      
 114 
     | 
    
         
            +
                  # code may be nil, :lasgn, or :block
         
     | 
| 
      
 115 
     | 
    
         
            +
                  case body.first
         
     | 
| 
      
 116 
     | 
    
         
            +
                  when nil then
         
     | 
| 
      
 117 
     | 
    
         
            +
                    # do nothing
         
     | 
| 
      
 118 
     | 
    
         
            +
                  when :lasgn then
         
     | 
| 
      
 119 
     | 
    
         
            +
                    # TODO: check that it is assigning $!
         
     | 
| 
      
 120 
     | 
    
         
            +
                    list << body
         
     | 
| 
      
 121 
     | 
    
         
            +
                    body = nil
         
     | 
| 
      
 122 
     | 
    
         
            +
                  when :block then
         
     | 
| 
      
 123 
     | 
    
         
            +
                    # TODO: check that it is assigning $!
         
     | 
| 
      
 124 
     | 
    
         
            +
                    list << body.delete_at(1) if body[1].first == :lasgn
         
     | 
| 
      
 125 
     | 
    
         
            +
                  else
         
     | 
| 
      
 126 
     | 
    
         
            +
                    # do nothing (expression form)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  end if body
         
     | 
| 
      
 128 
     | 
    
         
            +
             
     | 
| 
      
 129 
     | 
    
         
            +
                  code << list << body
         
     | 
| 
      
 130 
     | 
    
         
            +
                  if exp then
         
     | 
| 
      
 131 
     | 
    
         
            +
                    code = s()
         
     | 
| 
      
 132 
     | 
    
         
            +
                    result << code
         
     | 
| 
      
 133 
     | 
    
         
            +
                  end
         
     | 
| 
      
 134 
     | 
    
         
            +
                end
         
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
                raise unless result.first == :resbody
         
     | 
| 
      
 137 
     | 
    
         
            +
                raise unless Sexp === result[1] and result[1].first == :array
         
     | 
| 
      
 138 
     | 
    
         
            +
                raise unless result[2].nil? or (Sexp === result[2] and ! result[2].empty?)
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
                result
         
     | 
| 
      
 141 
     | 
    
         
            +
              end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
              def rewrite_vcall(exp)
         
     | 
| 
      
 144 
     | 
    
         
            +
                exp.push nil
         
     | 
| 
      
 145 
     | 
    
         
            +
                rewrite_fcall(exp)
         
     | 
| 
      
 146 
     | 
    
         
            +
              end
         
     | 
| 
      
 147 
     | 
    
         
            +
            end
         
     | 
    
        data/test/pt_testcase.rb
    CHANGED
    
    | 
         @@ -1,3 +1,5 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            $TESTING = true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
       1 
3 
     | 
    
         
             
            require 'test/unit/testcase'
         
     | 
| 
       2 
4 
     | 
    
         
             
            require 'sexp_processor' # for deep_clone
         
     | 
| 
       3 
5 
     | 
    
         
             
            require 'unique'
         
     | 
| 
         @@ -9,6 +11,10 @@ class Examples 
     | 
|
| 
       9 
11 
     | 
    
         
             
              def a_method(x); x+1; end
         
     | 
| 
       10 
12 
     | 
    
         
             
              alias an_alias a_method
         
     | 
| 
       11 
13 
     | 
    
         | 
| 
      
 14 
     | 
    
         
            +
              define_method(:bmethod_noargs) do
         
     | 
| 
      
 15 
     | 
    
         
            +
                x + 1
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
       12 
18 
     | 
    
         
             
              define_method(:unsplatted) do |x|
         
     | 
| 
       13 
19 
     | 
    
         
             
                x + 1
         
     | 
| 
       14 
20 
     | 
    
         
             
              end
         
     | 
| 
         @@ -133,11 +139,32 @@ class ParseTreeTestCase < Test::Unit::TestCase 
     | 
|
| 
       133 
139 
     | 
    
         
             
                                       [:nil]]]
         
     | 
| 
       134 
140 
     | 
    
         
             
                },
         
     | 
| 
       135 
141 
     | 
    
         | 
| 
      
 142 
     | 
    
         
            +
                "block_lasgn" => {
         
     | 
| 
      
 143 
     | 
    
         
            +
                  "Ruby"        => "x = (y = 1\n(y + 2))",
         
     | 
| 
      
 144 
     | 
    
         
            +
                  "ParseTree"   => [:lasgn, :x,
         
     | 
| 
      
 145 
     | 
    
         
            +
                                    [:block,
         
     | 
| 
      
 146 
     | 
    
         
            +
                                     [:lasgn, :y, [:lit, 1]],
         
     | 
| 
      
 147 
     | 
    
         
            +
                                     [:call, [:lvar, :y], :+, [:array, [:lit, 2]]]]],
         
     | 
| 
      
 148 
     | 
    
         
            +
                },
         
     | 
| 
      
 149 
     | 
    
         
            +
             
     | 
| 
       136 
150 
     | 
    
         
             
                "block_pass"  => {
         
     | 
| 
       137 
151 
     | 
    
         
             
                  "Ruby"        => "a(&b)",
         
     | 
| 
       138 
152 
     | 
    
         
             
                  "ParseTree"   => [:block_pass, [:vcall, :b], [:fcall, :a]],
         
     | 
| 
       139 
153 
     | 
    
         
             
                },
         
     | 
| 
       140 
154 
     | 
    
         | 
| 
      
 155 
     | 
    
         
            +
                "block_pass_args_and_splat" => {
         
     | 
| 
      
 156 
     | 
    
         
            +
                  "Ruby" => "def blah(*args, &block)\n  other(42, *args, &block)\nend",
         
     | 
| 
      
 157 
     | 
    
         
            +
                  "ParseTree" => [:defn, :blah,
         
     | 
| 
      
 158 
     | 
    
         
            +
                                  [:scope,
         
     | 
| 
      
 159 
     | 
    
         
            +
                                   [:block,
         
     | 
| 
      
 160 
     | 
    
         
            +
                                    [:args, "*args".intern],
         
     | 
| 
      
 161 
     | 
    
         
            +
                                    [:block_arg, :block],
         
     | 
| 
      
 162 
     | 
    
         
            +
                                    [:block_pass,
         
     | 
| 
      
 163 
     | 
    
         
            +
                                     [:lvar, :block],
         
     | 
| 
      
 164 
     | 
    
         
            +
                                     [:fcall, :other,
         
     | 
| 
      
 165 
     | 
    
         
            +
                                      [:argscat, [:array, [:lit, 42]], [:lvar, :args]]]]]]],
         
     | 
| 
      
 166 
     | 
    
         
            +
                },
         
     | 
| 
      
 167 
     | 
    
         
            +
             
     | 
| 
       141 
168 
     | 
    
         
             
                "block_pass_omgwtf" => {
         
     | 
| 
       142 
169 
     | 
    
         
             
                  "Ruby" => "define_attr_method(:x, :sequence_name, &Proc.new { |*args| nil })",
         
     | 
| 
       143 
170 
     | 
    
         
             
                  "ParseTree" => [:block_pass,
         
     | 
| 
         @@ -161,29 +188,26 @@ class ParseTreeTestCase < Test::Unit::TestCase 
     | 
|
| 
       161 
188 
     | 
    
         
             
                                     [:fcall, :other, [:splat, [:lvar, :args]]]]]]],
         
     | 
| 
       162 
189 
     | 
    
         
             
                },
         
     | 
| 
       163 
190 
     | 
    
         | 
| 
       164 
     | 
    
         
            -
                "block_pass_args_and_splat" => {
         
     | 
| 
       165 
     | 
    
         
            -
                  "Ruby" => "def blah(*args, &block)\n  other(42, *args, &block)\nend",
         
     | 
| 
       166 
     | 
    
         
            -
                  "ParseTree" => [:defn, :blah,
         
     | 
| 
       167 
     | 
    
         
            -
                                  [:scope,
         
     | 
| 
       168 
     | 
    
         
            -
                                   [:block,
         
     | 
| 
       169 
     | 
    
         
            -
                                    [:args, "*args".intern],
         
     | 
| 
       170 
     | 
    
         
            -
                                    [:block_arg, :block],
         
     | 
| 
       171 
     | 
    
         
            -
                                    [:block_pass,
         
     | 
| 
       172 
     | 
    
         
            -
                                     [:lvar, :block],
         
     | 
| 
       173 
     | 
    
         
            -
                                     [:fcall, :other,
         
     | 
| 
       174 
     | 
    
         
            -
                                      [:argscat, [:array, [:lit, 42]], [:lvar, :args]]]]]]],
         
     | 
| 
       175 
     | 
    
         
            -
                },
         
     | 
| 
       176 
     | 
    
         
            -
             
     | 
| 
       177 
191 
     | 
    
         
             
                "bmethod"  => {
         
     | 
| 
       178 
192 
     | 
    
         
             
                  "Ruby"        => [Examples, :unsplatted],
         
     | 
| 
       179 
193 
     | 
    
         
             
                  "ParseTree"   => [:defn,
         
     | 
| 
       180 
194 
     | 
    
         
             
                                    :unsplatted,
         
     | 
| 
       181 
195 
     | 
    
         
             
                                    [:bmethod,
         
     | 
| 
       182 
196 
     | 
    
         
             
                                     [:dasgn_curr, :x],
         
     | 
| 
       183 
     | 
    
         
            -
                                     [:call, [:dvar, :x],  
     | 
| 
      
 197 
     | 
    
         
            +
                                     [:call, [:dvar, :x], :+, [:array, [:lit, 1]]]]],
         
     | 
| 
       184 
198 
     | 
    
         
             
                  "Ruby2Ruby"   => "def unsplatted(x)\n  (x + 1)\nend"
         
     | 
| 
       185 
199 
     | 
    
         
             
                },
         
     | 
| 
       186 
200 
     | 
    
         | 
| 
      
 201 
     | 
    
         
            +
                "bmethod_noargs"  => {
         
     | 
| 
      
 202 
     | 
    
         
            +
                  "Ruby"        => [Examples, :bmethod_noargs],
         
     | 
| 
      
 203 
     | 
    
         
            +
                  "ParseTree"   => [:defn,
         
     | 
| 
      
 204 
     | 
    
         
            +
                                    :bmethod_noargs,
         
     | 
| 
      
 205 
     | 
    
         
            +
                                    [:bmethod,
         
     | 
| 
      
 206 
     | 
    
         
            +
                                     nil,
         
     | 
| 
      
 207 
     | 
    
         
            +
                                     [:call, [:vcall, :x], "+".intern, [:array, [:lit, 1]]]]],
         
     | 
| 
      
 208 
     | 
    
         
            +
                  "Ruby2Ruby"   => "def bmethod_noargs\n  (x + 1)\nend"
         
     | 
| 
      
 209 
     | 
    
         
            +
                },
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
       187 
211 
     | 
    
         
             
                "bmethod_splat" => {
         
     | 
| 
       188 
212 
     | 
    
         
             
                  "Ruby" => [Examples, :splatted],
         
     | 
| 
       189 
213 
     | 
    
         
             
                  "ParseTree" => [:defn, :splatted,
         
     | 
| 
         @@ -218,6 +242,14 @@ class ParseTreeTestCase < Test::Unit::TestCase 
     | 
|
| 
       218 
242 
     | 
    
         
             
                  "ParseTree"   => [:fcall, :puts, [:array, [:lit, 42]]],
         
     | 
| 
       219 
243 
     | 
    
         
             
                },
         
     | 
| 
       220 
244 
     | 
    
         | 
| 
      
 245 
     | 
    
         
            +
                "call_expr" => {
         
     | 
| 
      
 246 
     | 
    
         
            +
                  "Ruby"        => "(v = (1 + 1)).zero?",
         
     | 
| 
      
 247 
     | 
    
         
            +
                  "ParseTree"   => [:call,
         
     | 
| 
      
 248 
     | 
    
         
            +
                                    [:lasgn, :v,
         
     | 
| 
      
 249 
     | 
    
         
            +
                                     [:call, [:lit, 1], :+, [:array, [:lit, 1]]]],
         
     | 
| 
      
 250 
     | 
    
         
            +
                                    :zero?],
         
     | 
| 
      
 251 
     | 
    
         
            +
                },
         
     | 
| 
      
 252 
     | 
    
         
            +
             
     | 
| 
       221 
253 
     | 
    
         
             
                "call_index" => { # see attrasgn_index_equals for opposite
         
     | 
| 
       222 
254 
     | 
    
         
             
                  "Ruby"        => "a[42]",
         
     | 
| 
       223 
255 
     | 
    
         
             
                  "ParseTree"   => [:call, [:vcall, :a], :[], [:array, [:lit, 42]]],
         
     | 
| 
         @@ -310,14 +342,6 @@ class ParseTreeTestCase < Test::Unit::TestCase 
     | 
|
| 
       310 
342 
     | 
    
         
             
                                         [:fcall, :puts, [:array, [:str, "hello"]]]]]]]]],
         
     | 
| 
       311 
343 
     | 
    
         
             
                },
         
     | 
| 
       312 
344 
     | 
    
         | 
| 
       313 
     | 
    
         
            -
                "class_super_object"  => {
         
     | 
| 
       314 
     | 
    
         
            -
                  "Ruby"        => "class X < Object\nend",
         
     | 
| 
       315 
     | 
    
         
            -
                  "ParseTree"   => [:class,
         
     | 
| 
       316 
     | 
    
         
            -
                                    :X,
         
     | 
| 
       317 
     | 
    
         
            -
                                    [:const, :Object],
         
     | 
| 
       318 
     | 
    
         
            -
                                    [:scope]],
         
     | 
| 
       319 
     | 
    
         
            -
                },
         
     | 
| 
       320 
     | 
    
         
            -
             
     | 
| 
       321 
345 
     | 
    
         
             
                "class_super_array"  => {
         
     | 
| 
       322 
346 
     | 
    
         
             
                  "Ruby"        => "class X < Array\nend",
         
     | 
| 
       323 
347 
     | 
    
         
             
                  "ParseTree"   => [:class,
         
     | 
| 
         @@ -334,6 +358,14 @@ class ParseTreeTestCase < Test::Unit::TestCase 
     | 
|
| 
       334 
358 
     | 
    
         
             
                                    [:scope]],
         
     | 
| 
       335 
359 
     | 
    
         
             
                },
         
     | 
| 
       336 
360 
     | 
    
         | 
| 
      
 361 
     | 
    
         
            +
                "class_super_object"  => {
         
     | 
| 
      
 362 
     | 
    
         
            +
                  "Ruby"        => "class X < Object\nend",
         
     | 
| 
      
 363 
     | 
    
         
            +
                  "ParseTree"   => [:class,
         
     | 
| 
      
 364 
     | 
    
         
            +
                                    :X,
         
     | 
| 
      
 365 
     | 
    
         
            +
                                    [:const, :Object],
         
     | 
| 
      
 366 
     | 
    
         
            +
                                    [:scope]],
         
     | 
| 
      
 367 
     | 
    
         
            +
                },
         
     | 
| 
      
 368 
     | 
    
         
            +
             
     | 
| 
       337 
369 
     | 
    
         
             
                "colon2"  => {
         
     | 
| 
       338 
370 
     | 
    
         
             
                  "Ruby"        => "X::Y",
         
     | 
| 
       339 
371 
     | 
    
         
             
                  "ParseTree"   => [:colon2, [:const, :X], :Y],
         
     | 
| 
         @@ -458,14 +490,15 @@ class ParseTreeTestCase < Test::Unit::TestCase 
     | 
|
| 
       458 
490 
     | 
    
         
             
                  "ParseTree"   => [:defn, :something?, [:scope, [:block, [:args], [:nil]]]],
         
     | 
| 
       459 
491 
     | 
    
         
             
                },
         
     | 
| 
       460 
492 
     | 
    
         | 
| 
       461 
     | 
    
         
            -
             
     | 
| 
       462 
     | 
    
         
            -
             
     | 
| 
       463 
     | 
    
         
            -
             
     | 
| 
       464 
     | 
    
         
            -
             
     | 
| 
       465 
     | 
    
         
            -
             
     | 
| 
       466 
     | 
    
         
            -
             
     | 
| 
       467 
     | 
    
         
            -
             
     | 
| 
       468 
     | 
    
         
            -
             
     | 
| 
      
 493 
     | 
    
         
            +
                "defn_optargs" => {
         
     | 
| 
      
 494 
     | 
    
         
            +
                  "Ruby"      => "def x(a, *args)\n  p(a, args)\nend",
         
     | 
| 
      
 495 
     | 
    
         
            +
                  "ParseTree" => [:defn, :x,
         
     | 
| 
      
 496 
     | 
    
         
            +
                                  [:scope,
         
     | 
| 
      
 497 
     | 
    
         
            +
                                   [:block,
         
     | 
| 
      
 498 
     | 
    
         
            +
                                    [:args, :a, "*args".intern],
         
     | 
| 
      
 499 
     | 
    
         
            +
                                    [:fcall, :p,
         
     | 
| 
      
 500 
     | 
    
         
            +
                                     [:array, [:lvar, :a], [:lvar, :args]]]]]],
         
     | 
| 
      
 501 
     | 
    
         
            +
                },
         
     | 
| 
       469 
502 
     | 
    
         | 
| 
       470 
503 
     | 
    
         
             
                "defn_or" => {
         
     | 
| 
       471 
504 
     | 
    
         
             
                  "Ruby"        => "def |(o)\n  # do nothing\nend",
         
     | 
| 
         @@ -475,15 +508,25 @@ class ParseTreeTestCase < Test::Unit::TestCase 
     | 
|
| 
       475 
508 
     | 
    
         
             
                "defn_rescue" => {
         
     | 
| 
       476 
509 
     | 
    
         
             
                  "Ruby" => "def eql?(resource)\n  (self.uuid == resource.uuid) rescue false\nend",
         
     | 
| 
       477 
510 
     | 
    
         
             
                  "ParseTree" => [:defn, :eql?,
         
     | 
| 
       478 
     | 
    
         
            -
             
     | 
| 
       479 
     | 
    
         
            -
             
     | 
| 
       480 
     | 
    
         
            -
             
     | 
| 
       481 
     | 
    
         
            -
             
     | 
| 
       482 
     | 
    
         
            -
             
     | 
| 
       483 
     | 
    
         
            -
             
     | 
| 
       484 
     | 
    
         
            -
             
     | 
| 
       485 
     | 
    
         
            -
             
     | 
| 
       486 
     | 
    
         
            -
             
     | 
| 
      
 511 
     | 
    
         
            +
                                  [:scope,
         
     | 
| 
      
 512 
     | 
    
         
            +
                                   [:block,
         
     | 
| 
      
 513 
     | 
    
         
            +
                                    [:args, :resource],
         
     | 
| 
      
 514 
     | 
    
         
            +
                                    [:rescue,
         
     | 
| 
      
 515 
     | 
    
         
            +
                                     [:call,
         
     | 
| 
      
 516 
     | 
    
         
            +
                                      [:call, [:self], :uuid],
         
     | 
| 
      
 517 
     | 
    
         
            +
                                      :==,
         
     | 
| 
      
 518 
     | 
    
         
            +
                                      [:array, [:call, [:lvar, :resource], :uuid]]],
         
     | 
| 
      
 519 
     | 
    
         
            +
                                     [:resbody, nil, [:false]]]]]],
         
     | 
| 
      
 520 
     | 
    
         
            +
                },
         
     | 
| 
      
 521 
     | 
    
         
            +
             
     | 
| 
      
 522 
     | 
    
         
            +
                "defn_splat_no_name" => {
         
     | 
| 
      
 523 
     | 
    
         
            +
                  "Ruby"      => "def x(a, *)\n  p(a)\nend",
         
     | 
| 
      
 524 
     | 
    
         
            +
                  "ParseTree" => [:defn, :x,
         
     | 
| 
      
 525 
     | 
    
         
            +
                                  [:scope,
         
     | 
| 
      
 526 
     | 
    
         
            +
                                   [:block,
         
     | 
| 
      
 527 
     | 
    
         
            +
                                    [:args, :a, "*".intern],
         
     | 
| 
      
 528 
     | 
    
         
            +
                                    [:fcall, :p,
         
     | 
| 
      
 529 
     | 
    
         
            +
                                     [:array, [:lvar, :a]]]]]],
         
     | 
| 
       487 
530 
     | 
    
         
             
                },
         
     | 
| 
       488 
531 
     | 
    
         | 
| 
       489 
532 
     | 
    
         
             
                "defn_zarray" => { # tests memory allocation for returns
         
     | 
| 
         @@ -668,11 +711,41 @@ end", 
     | 
|
| 
       668 
711 
     | 
    
         
             
                  "ParseTree"   => [:hash, [:lit, 1], [:lit, 2], [:lit, 3], [:lit, 4]],
         
     | 
| 
       669 
712 
     | 
    
         
             
                },
         
     | 
| 
       670 
713 
     | 
    
         | 
| 
      
 714 
     | 
    
         
            +
                "hash_rescue"  => {
         
     | 
| 
      
 715 
     | 
    
         
            +
                  "Ruby"        => "{ 1 => (2 rescue 3) }",
         
     | 
| 
      
 716 
     | 
    
         
            +
                  "ParseTree"   => [:hash,
         
     | 
| 
      
 717 
     | 
    
         
            +
                                    [:lit, 1],
         
     | 
| 
      
 718 
     | 
    
         
            +
                                    [:rescue, [:lit, 2], [:resbody, nil, [:lit, 3]]]],
         
     | 
| 
      
 719 
     | 
    
         
            +
                },
         
     | 
| 
      
 720 
     | 
    
         
            +
             
     | 
| 
       671 
721 
     | 
    
         
             
                "iasgn"  => {
         
     | 
| 
       672 
722 
     | 
    
         
             
                  "Ruby"        => "@a = 4",
         
     | 
| 
       673 
723 
     | 
    
         
             
                  "ParseTree"   => [:iasgn, :@a, [:lit, 4]],
         
     | 
| 
       674 
724 
     | 
    
         
             
                },
         
     | 
| 
       675 
725 
     | 
    
         | 
| 
      
 726 
     | 
    
         
            +
                "if_block_condition" => {
         
     | 
| 
      
 727 
     | 
    
         
            +
                  "Ruby"        => "if (x = 5\n(x + 1)) then\n  nil\nend",
         
     | 
| 
      
 728 
     | 
    
         
            +
                  "ParseTree"   => [:if,
         
     | 
| 
      
 729 
     | 
    
         
            +
                                    [:block,
         
     | 
| 
      
 730 
     | 
    
         
            +
                                     [:lasgn, :x, [:lit, 5]],
         
     | 
| 
      
 731 
     | 
    
         
            +
                                     [:call,
         
     | 
| 
      
 732 
     | 
    
         
            +
                                      [:lvar, :x],
         
     | 
| 
      
 733 
     | 
    
         
            +
                                      :+,
         
     | 
| 
      
 734 
     | 
    
         
            +
                                      [:array, [:lit, 1]]]],
         
     | 
| 
      
 735 
     | 
    
         
            +
                                    [:nil],
         
     | 
| 
      
 736 
     | 
    
         
            +
                                    nil],
         
     | 
| 
      
 737 
     | 
    
         
            +
                },
         
     | 
| 
      
 738 
     | 
    
         
            +
             
     | 
| 
      
 739 
     | 
    
         
            +
                "if_lasgn_short" => {
         
     | 
| 
      
 740 
     | 
    
         
            +
                  "Ruby"        => "if x = obj.x then\n  x.do_it\nend",
         
     | 
| 
      
 741 
     | 
    
         
            +
                  "ParseTree"   => [:if,
         
     | 
| 
      
 742 
     | 
    
         
            +
                                    [:lasgn, :x,
         
     | 
| 
      
 743 
     | 
    
         
            +
                                     [:call, [:vcall, :obj], :x]],
         
     | 
| 
      
 744 
     | 
    
         
            +
                                    [:call,
         
     | 
| 
      
 745 
     | 
    
         
            +
                                     [:lvar, :x], :do_it],
         
     | 
| 
      
 746 
     | 
    
         
            +
                                    nil],
         
     | 
| 
      
 747 
     | 
    
         
            +
                },
         
     | 
| 
      
 748 
     | 
    
         
            +
             
     | 
| 
       676 
749 
     | 
    
         
             
                "iteration1" => {
         
     | 
| 
       677 
750 
     | 
    
         
             
                  "Ruby"        => "loop { }",
         
     | 
| 
       678 
751 
     | 
    
         
             
                  "ParseTree"   => [:iter, [:fcall, :loop], nil],
         
     | 
| 
         @@ -811,11 +884,14 @@ end", 
     | 
|
| 
       811 
884 
     | 
    
         
             
                                    [:array,  [:vcall, :c], [:vcall, :d]]],
         
     | 
| 
       812 
885 
     | 
    
         
             
                },
         
     | 
| 
       813 
886 
     | 
    
         | 
| 
       814 
     | 
    
         
            -
                " 
     | 
| 
       815 
     | 
    
         
            -
                  "Ruby"        => "a,  
     | 
| 
      
 887 
     | 
    
         
            +
                "masgn_argscat"  => {
         
     | 
| 
      
 888 
     | 
    
         
            +
                  "Ruby"        => "a, b, *c = 1, 2, *[3, 4]",
         
     | 
| 
       816 
889 
     | 
    
         
             
                  "ParseTree"   => [:masgn,
         
     | 
| 
       817 
     | 
    
         
            -
                                    [:array, [:lasgn, :a], [: 
     | 
| 
       818 
     | 
    
         
            -
                                    [: 
     | 
| 
      
 890 
     | 
    
         
            +
                                    [:array, [:lasgn, :a], [:lasgn, :b]],
         
     | 
| 
      
 891 
     | 
    
         
            +
                                    [:lasgn, :c],
         
     | 
| 
      
 892 
     | 
    
         
            +
                                    [:argscat,
         
     | 
| 
      
 893 
     | 
    
         
            +
                                     [:array, [:lit, 1], [:lit, 2]],
         
     | 
| 
      
 894 
     | 
    
         
            +
                                     [:array, [:lit, 3], [:lit, 4]]]]
         
     | 
| 
       819 
895 
     | 
    
         
             
                },
         
     | 
| 
       820 
896 
     | 
    
         | 
| 
       821 
897 
     | 
    
         
             
                "masgn_attrasgn"  => {
         
     | 
| 
         @@ -825,6 +901,31 @@ end", 
     | 
|
| 
       825 
901 
     | 
    
         
             
                                     [:array, [:vcall, :d], [:vcall, :e]]],
         
     | 
| 
       826 
902 
     | 
    
         
             
                },
         
     | 
| 
       827 
903 
     | 
    
         | 
| 
      
 904 
     | 
    
         
            +
                "masgn_iasgn"  => {
         
     | 
| 
      
 905 
     | 
    
         
            +
                  "Ruby"        => "a, @b = c, d",
         
     | 
| 
      
 906 
     | 
    
         
            +
                  "ParseTree"   => [:masgn,
         
     | 
| 
      
 907 
     | 
    
         
            +
                                    [:array, [:lasgn, :a], [:iasgn, "@b".intern]],
         
     | 
| 
      
 908 
     | 
    
         
            +
                                    [:array,  [:vcall, :c], [:vcall, :d]]],
         
     | 
| 
      
 909 
     | 
    
         
            +
                },
         
     | 
| 
      
 910 
     | 
    
         
            +
             
     | 
| 
      
 911 
     | 
    
         
            +
                "masgn_masgn" => {
         
     | 
| 
      
 912 
     | 
    
         
            +
                  "Ruby"        => "a, (b, c) = [1, [2, 3]]",
         
     | 
| 
      
 913 
     | 
    
         
            +
                  "ParseTree"   => [:masgn,
         
     | 
| 
      
 914 
     | 
    
         
            +
                                    [:array,
         
     | 
| 
      
 915 
     | 
    
         
            +
                                     [:lasgn, :a],
         
     | 
| 
      
 916 
     | 
    
         
            +
                                     [:masgn,
         
     | 
| 
      
 917 
     | 
    
         
            +
                                      [:array,
         
     | 
| 
      
 918 
     | 
    
         
            +
                                       [:lasgn, :b],
         
     | 
| 
      
 919 
     | 
    
         
            +
                                       [:lasgn, :c]]]],
         
     | 
| 
      
 920 
     | 
    
         
            +
                                    [:to_ary,
         
     | 
| 
      
 921 
     | 
    
         
            +
                                     [:array,
         
     | 
| 
      
 922 
     | 
    
         
            +
                                      [:lit, 1],
         
     | 
| 
      
 923 
     | 
    
         
            +
                                      [:array,
         
     | 
| 
      
 924 
     | 
    
         
            +
                                       [:lit, 2],
         
     | 
| 
      
 925 
     | 
    
         
            +
                                       [:lit, 3]]]]]
         
     | 
| 
      
 926 
     | 
    
         
            +
             
     | 
| 
      
 927 
     | 
    
         
            +
                },
         
     | 
| 
      
 928 
     | 
    
         
            +
             
     | 
| 
       828 
929 
     | 
    
         
             
                "masgn_splat"  => {
         
     | 
| 
       829 
930 
     | 
    
         
             
                  "Ruby"        => "a, b, *c = d, e, f, g",
         
     | 
| 
       830 
931 
     | 
    
         
             
                  "ParseTree"   => [:masgn,
         
     | 
| 
         @@ -835,7 +936,6 @@ end", 
     | 
|
| 
       835 
936 
     | 
    
         
             
                                     [:vcall, :f], [:vcall, :g]]]
         
     | 
| 
       836 
937 
     | 
    
         
             
                },
         
     | 
| 
       837 
938 
     | 
    
         | 
| 
       838 
     | 
    
         
            -
             
     | 
| 
       839 
939 
     | 
    
         
             
                "match"  => {
         
     | 
| 
       840 
940 
     | 
    
         
             
                  "Ruby"        => "1 if /x/",
         
     | 
| 
       841 
941 
     | 
    
         
             
                  "ParseTree"   => [:if, [:match, [:lit, /x/]], [:lit, 1], nil],
         
     | 
| 
         @@ -994,8 +1094,12 @@ end", 
     | 
|
| 
       994 
1094 
     | 
    
         
             
                },
         
     | 
| 
       995 
1095 
     | 
    
         | 
| 
       996 
1096 
     | 
    
         
             
                "splat"  => {
         
     | 
| 
       997 
     | 
    
         
            -
                  "Ruby"        => "a(*b)",
         
     | 
| 
       998 
     | 
    
         
            -
                  "ParseTree"   => [: 
     | 
| 
      
 1097 
     | 
    
         
            +
                  "Ruby"        => "def x(*b)\n  a(*b)\nend",
         
     | 
| 
      
 1098 
     | 
    
         
            +
                  "ParseTree"   => [:defn, :x,
         
     | 
| 
      
 1099 
     | 
    
         
            +
                                    [:scope,
         
     | 
| 
      
 1100 
     | 
    
         
            +
                                     [:block,
         
     | 
| 
      
 1101 
     | 
    
         
            +
                                      [:args, :"*b"],
         
     | 
| 
      
 1102 
     | 
    
         
            +
                                      [:fcall, :a, [:splat, [:lvar, :b]]]]]],
         
     | 
| 
       999 
1103 
     | 
    
         
             
                },
         
     | 
| 
       1000 
1104 
     | 
    
         | 
| 
       1001 
1105 
     | 
    
         
             
                # TODO: all supers need to pass args
         
     | 
| 
         @@ -1070,6 +1174,12 @@ end", 
     | 
|
| 
       1070 
1174 
     | 
    
         
             
                  "ParseTree"   => [:vcall, :method],
         
     | 
| 
       1071 
1175 
     | 
    
         
             
                },
         
     | 
| 
       1072 
1176 
     | 
    
         | 
| 
      
 1177 
     | 
    
         
            +
                "while_post" => {
         
     | 
| 
      
 1178 
     | 
    
         
            +
                  "Ruby"        => "begin\n  (1 + 1)\nend while false",
         
     | 
| 
      
 1179 
     | 
    
         
            +
                  "ParseTree"   => [:while, [:false],
         
     | 
| 
      
 1180 
     | 
    
         
            +
                                    [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false],
         
     | 
| 
      
 1181 
     | 
    
         
            +
                },
         
     | 
| 
      
 1182 
     | 
    
         
            +
             
     | 
| 
       1073 
1183 
     | 
    
         
             
                "while_pre" => {
         
     | 
| 
       1074 
1184 
     | 
    
         
             
                  "Ruby"        => "while false do\n  (1 + 1)\nend",
         
     | 
| 
       1075 
1185 
     | 
    
         
             
                  "ParseTree"   => [:while, [:false],
         
     | 
| 
         @@ -1081,12 +1191,6 @@ end", 
     | 
|
| 
       1081 
1191 
     | 
    
         
             
                  "ParseTree"   => [:while, [:false], nil, true],
         
     | 
| 
       1082 
1192 
     | 
    
         
             
                },
         
     | 
| 
       1083 
1193 
     | 
    
         | 
| 
       1084 
     | 
    
         
            -
                "while_post" => {
         
     | 
| 
       1085 
     | 
    
         
            -
                  "Ruby"        => "begin\n  (1 + 1)\nend while false",
         
     | 
| 
       1086 
     | 
    
         
            -
                  "ParseTree"   => [:while, [:false],
         
     | 
| 
       1087 
     | 
    
         
            -
                                    [:call, [:lit, 1], :+, [:array, [:lit, 1]]], false],
         
     | 
| 
       1088 
     | 
    
         
            -
                },
         
     | 
| 
       1089 
     | 
    
         
            -
             
     | 
| 
       1090 
1194 
     | 
    
         
             
                "xstr" => {
         
     | 
| 
       1091 
1195 
     | 
    
         
             
                  "Ruby"        => "`touch 5`",
         
     | 
| 
       1092 
1196 
     | 
    
         
             
                  "ParseTree"   => [:xstr, 'touch 5'],
         
     | 
| 
         @@ -1170,7 +1274,8 @@ end", 
     | 
|
| 
       1170 
1274 
     | 
    
         | 
| 
       1171 
1275 
     | 
    
         
             
              def self.inherited(c)
         
     | 
| 
       1172 
1276 
     | 
    
         
             
                output_name = c.name.to_s.sub(/^Test/, '')
         
     | 
| 
       1173 
     | 
    
         
            -
                raise "Unknown class #{c} 
     | 
| 
      
 1277 
     | 
    
         
            +
                raise "Unknown class #{c} in @@testcase_order" unless
         
     | 
| 
      
 1278 
     | 
    
         
            +
                  @@testcase_order.include? output_name
         
     | 
| 
       1174 
1279 
     | 
    
         | 
| 
       1175 
1280 
     | 
    
         
             
                input_name = self.previous(output_name)
         
     | 
| 
       1176 
1281 
     | 
    
         |