ParseTree 1.1.1 → 1.2.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 +19 -0
- data/Makefile +24 -7
- data/Manifest.txt +12 -10
- data/ParseTree.gemspec +39 -0
- data/README.txt +1 -1
- data/bin/parse_tree_abc +86 -0
- data/bin/parse_tree_deps +66 -0
- data/bin/parse_tree_show +49 -0
- data/lib/composite_sexp_processor.rb +43 -0
- data/{parse_tree.rb → lib/parse_tree.rb} +104 -32
- data/{sexp_processor.rb → lib/sexp_processor.rb} +89 -19
- data/{something.rb → test/something.rb} +0 -0
- data/test/test_all.rb +13 -0
- data/{test_composite_sexp_processor.rb → test/test_composite_sexp_processor.rb} +0 -0
- data/test/test_parse_tree.rb +275 -0
- data/{test_sexp_processor.rb → test/test_sexp_processor.rb} +0 -9
- metadata +22 -16
- data/composite_sexp_processor.rb +0 -24
- data/parse_tree_abc +0 -62
- data/parse_tree_show +0 -28
- data/test_all.rb +0 -7
- data/test_parse_tree.rb +0 -275
| @@ -2,31 +2,53 @@ | |
| 2 2 | 
             
            $TESTING = false unless defined? $TESTING
         | 
| 3 3 |  | 
| 4 4 | 
             
            class Object
         | 
| 5 | 
            +
             | 
| 6 | 
            +
              ##
         | 
| 7 | 
            +
              # deep_clone is the usual Marshalling hack to make a deep copy.
         | 
| 8 | 
            +
              # It is rather slow, so use it sparingly. Helps with debugging
         | 
| 9 | 
            +
              # SexpProcessors since you usually shift off sexps.
         | 
| 10 | 
            +
             | 
| 5 11 | 
             
              def deep_clone
         | 
| 6 12 | 
             
                Marshal.load(Marshal.dump(self))
         | 
| 7 13 | 
             
              end
         | 
| 8 14 | 
             
            end
         | 
| 9 15 |  | 
| 16 | 
            +
            ##
         | 
| 17 | 
            +
            # Sexps are the basic storage mechanism of SexpProcessor.  Sexps have
         | 
| 18 | 
            +
            # a +type+ (to be renamed +node_type+) which is the first element of
         | 
| 19 | 
            +
            # the Sexp. The type is used by SexpProcessor to determine whom to
         | 
| 20 | 
            +
            # dispatch the Sexp to for processing.
         | 
| 21 | 
            +
             | 
| 10 22 | 
             
            class Sexp < Array # ZenTest FULL
         | 
| 11 23 |  | 
| 12 24 | 
             
              @@array_types = [ :array, :args, ]
         | 
| 13 25 |  | 
| 26 | 
            +
              ##
         | 
| 27 | 
            +
              # Named positional parameters.
         | 
| 28 | 
            +
              # Use with +SexpProcessor.require_empty=false+.
         | 
| 14 29 | 
             
              attr_accessor :accessors
         | 
| 15 | 
            -
              attr_accessor :unpack
         | 
| 16 30 |  | 
| 17 | 
            -
               | 
| 31 | 
            +
              ##
         | 
| 32 | 
            +
              # Create a new Sexp containing +args+.
         | 
| 18 33 |  | 
| 19 34 | 
             
              def initialize(*args)
         | 
| 20 | 
            -
                @unpack = false
         | 
| 21 35 | 
             
                @accessors = []
         | 
| 22 36 | 
             
                super(args)
         | 
| 23 37 | 
             
              end
         | 
| 24 38 |  | 
| 39 | 
            +
              ##
         | 
| 40 | 
            +
              # Returns true if the node_type is +array+ or +args+.
         | 
| 41 | 
            +
              #
         | 
| 42 | 
            +
              # REFACTOR: to TypedSexp - we only care when we have units.
         | 
| 43 | 
            +
             | 
| 25 44 | 
             
              def array_type?
         | 
| 26 45 | 
             
                type = self.first
         | 
| 27 46 | 
             
                @@array_types.include? type
         | 
| 28 47 | 
             
              end
         | 
| 29 48 |  | 
| 49 | 
            +
              ##
         | 
| 50 | 
            +
              # Enumeratates the sexp yielding to +b+ when the node_type == +t+.
         | 
| 51 | 
            +
             | 
| 30 52 | 
             
              def each_of_type(t, &b)
         | 
| 31 53 | 
             
                each do | elem |
         | 
| 32 54 | 
             
                  if Sexp === elem then
         | 
| @@ -36,7 +58,10 @@ class Sexp < Array # ZenTest FULL | |
| 36 58 | 
             
                end
         | 
| 37 59 | 
             
              end
         | 
| 38 60 |  | 
| 39 | 
            -
               | 
| 61 | 
            +
              ##
         | 
| 62 | 
            +
              # Replaces all elements whose node_type is +from+ with +to+. Used
         | 
| 63 | 
            +
              # only for the most trivial of rewrites.
         | 
| 64 | 
            +
             | 
| 40 65 | 
             
              def find_and_replace_all(from, to)
         | 
| 41 66 | 
             
                each_with_index do | elem, index |
         | 
| 42 67 | 
             
                  if Sexp === elem then
         | 
| @@ -47,6 +72,30 @@ class Sexp < Array # ZenTest FULL | |
| 47 72 | 
             
                end
         | 
| 48 73 | 
             
              end
         | 
| 49 74 |  | 
| 75 | 
            +
              ##
         | 
| 76 | 
            +
              # Fancy-Schmancy method used to implement named positional accessors
         | 
| 77 | 
            +
              # via +accessors+.
         | 
| 78 | 
            +
              #
         | 
| 79 | 
            +
              # Example:
         | 
| 80 | 
            +
              #
         | 
| 81 | 
            +
              #   class MyProcessor < SexpProcessor
         | 
| 82 | 
            +
              #     def initialize
         | 
| 83 | 
            +
              #       super
         | 
| 84 | 
            +
              #       self.require_empty = false
         | 
| 85 | 
            +
              #       self.sexp_accessors = {
         | 
| 86 | 
            +
              #         :call => [:lhs, :name, :rhs]
         | 
| 87 | 
            +
              #       }
         | 
| 88 | 
            +
              #       ...
         | 
| 89 | 
            +
              #     end
         | 
| 90 | 
            +
              #   
         | 
| 91 | 
            +
              #     def process_call(exp)
         | 
| 92 | 
            +
              #       lhs = exp.lhs
         | 
| 93 | 
            +
              #       name = exp.name
         | 
| 94 | 
            +
              #       rhs = exp.rhs
         | 
| 95 | 
            +
              #       ...
         | 
| 96 | 
            +
              #     end
         | 
| 97 | 
            +
              #   end
         | 
| 98 | 
            +
             | 
| 50 99 | 
             
              def method_missing(meth, *a, &b)
         | 
| 51 100 | 
             
                super unless @accessors.include? meth
         | 
| 52 101 |  | 
| @@ -54,11 +103,14 @@ class Sexp < Array # ZenTest FULL | |
| 54 103 | 
             
                return self.at(index)
         | 
| 55 104 | 
             
              end
         | 
| 56 105 |  | 
| 106 | 
            +
              ##
         | 
| 107 | 
            +
              # Returns the Sexp without the node_type.
         | 
| 108 | 
            +
             | 
| 57 109 | 
             
              def sexp_body
         | 
| 58 110 | 
             
                self[1..-1]
         | 
| 59 111 | 
             
              end
         | 
| 60 112 |  | 
| 61 | 
            -
              def ==(obj)
         | 
| 113 | 
            +
              def ==(obj) # :nodoc:
         | 
| 62 114 | 
             
                case obj
         | 
| 63 115 | 
             
                when Sexp
         | 
| 64 116 | 
             
                  super
         | 
| @@ -67,25 +119,29 @@ class Sexp < Array # ZenTest FULL | |
| 67 119 | 
             
                end
         | 
| 68 120 | 
             
              end
         | 
| 69 121 |  | 
| 70 | 
            -
              def to_a
         | 
| 122 | 
            +
              def to_a # :nodoc:
         | 
| 71 123 | 
             
                self.map { |o| Sexp === o ? o.to_a : o }
         | 
| 72 124 | 
             
              end
         | 
| 73 125 |  | 
| 74 | 
            -
              def inspect
         | 
| 126 | 
            +
              def inspect # :nodoc:
         | 
| 75 127 | 
             
                sexp_str = self.map {|x|x.inspect}.join(', ')
         | 
| 76 128 | 
             
                return "Sexp.new(#{sexp_str})"
         | 
| 77 129 | 
             
              end
         | 
| 78 130 |  | 
| 79 | 
            -
              def pretty_print(q)
         | 
| 131 | 
            +
              def pretty_print(q) # :nodoc:
         | 
| 80 132 | 
             
                q.group(1, 's(', ')') do
         | 
| 81 133 | 
             
                  q.seplist(self) {|v| q.pp v }
         | 
| 82 134 | 
             
                end
         | 
| 83 135 | 
             
              end
         | 
| 84 136 |  | 
| 85 | 
            -
              def to_s
         | 
| 137 | 
            +
              def to_s # :nodoc:
         | 
| 86 138 | 
             
                inspect
         | 
| 87 139 | 
             
              end
         | 
| 88 140 |  | 
| 141 | 
            +
              ##
         | 
| 142 | 
            +
              # If run with debug, Sexp will raise if you shift on an empty
         | 
| 143 | 
            +
              # Sexp. Helps with debugging.
         | 
| 144 | 
            +
             | 
| 89 145 | 
             
              def shift
         | 
| 90 146 | 
             
                raise "I'm empty" if self.empty?
         | 
| 91 147 | 
             
                super
         | 
| @@ -93,7 +149,10 @@ class Sexp < Array # ZenTest FULL | |
| 93 149 |  | 
| 94 150 | 
             
            end
         | 
| 95 151 |  | 
| 96 | 
            -
             | 
| 152 | 
            +
            ##
         | 
| 153 | 
            +
            # This is just a stupid shortcut to make indentation much cleaner.
         | 
| 154 | 
            +
             | 
| 155 | 
            +
            def s(*args)
         | 
| 97 156 | 
             
              Sexp.new(*args)
         | 
| 98 157 | 
             
            end
         | 
| 99 158 |  | 
| @@ -114,7 +173,6 @@ end | |
| 114 173 | 
             
            # Here is a simple example:
         | 
| 115 174 | 
             
            #
         | 
| 116 175 | 
             
            #   class MyProcessor < SexpProcessor
         | 
| 117 | 
            -
            #   
         | 
| 118 176 | 
             
            #     def initialize
         | 
| 119 177 | 
             
            #       super
         | 
| 120 178 | 
             
            #       self.strict = false
         | 
| @@ -124,7 +182,6 @@ end | |
| 124 182 | 
             
            #       val = exp.shift
         | 
| 125 183 | 
             
            #       return val
         | 
| 126 184 | 
             
            #     end
         | 
| 127 | 
            -
            #   
         | 
| 128 185 | 
             
            #   end
         | 
| 129 186 |  | 
| 130 187 | 
             
            class SexpProcessor
         | 
| @@ -263,11 +320,7 @@ class SexpProcessor | |
| 263 320 | 
             
                      else
         | 
| 264 321 | 
             
                        sub_result = sub_exp
         | 
| 265 322 | 
             
                      end
         | 
| 266 | 
            -
                       | 
| 267 | 
            -
                        result.push(*sub_result)
         | 
| 268 | 
            -
                      else
         | 
| 269 | 
            -
                        result << sub_result
         | 
| 270 | 
            -
                      end
         | 
| 323 | 
            +
                      result << sub_result
         | 
| 271 324 | 
             
                    end
         | 
| 272 325 |  | 
| 273 326 | 
             
                    # NOTE: this is costly, but we are in the generic processor
         | 
| @@ -293,9 +346,26 @@ class SexpProcessor | |
| 293 346 | 
             
              # Raises unless the Sexp type for +list+ matches +typ+
         | 
| 294 347 |  | 
| 295 348 | 
             
              def assert_type(list, typ)
         | 
| 296 | 
            -
                raise TypeError, "Expected type #{typ.inspect} in #{list.inspect}"  | 
| 297 | 
            -
                   | 
| 349 | 
            +
                raise TypeError, "Expected type #{typ.inspect} in #{list.inspect}" if
         | 
| 350 | 
            +
                  list.first != typ
         | 
| 298 351 | 
             
              end
         | 
| 299 352 |  | 
| 353 | 
            +
              ##
         | 
| 354 | 
            +
              # A fairly generic processor for a dummy node. Dummy nodes are used
         | 
| 355 | 
            +
              # when your processor is doing a complicated rewrite that replaces
         | 
| 356 | 
            +
              # the current sexp with multiple sexps.
         | 
| 357 | 
            +
              #
         | 
| 358 | 
            +
              # Bogus Example:
         | 
| 359 | 
            +
              #
         | 
| 360 | 
            +
              # def process_something(exp)
         | 
| 361 | 
            +
              #   return s(:dummy, process(exp), s(:extra, 42))
         | 
| 362 | 
            +
             | 
| 363 | 
            +
              def process_dummy(exp)
         | 
| 364 | 
            +
                result = @expected.new(:dummy)
         | 
| 365 | 
            +
                until exp.empty? do
         | 
| 366 | 
            +
                  result << self.process(exp.shift)
         | 
| 367 | 
            +
                end
         | 
| 368 | 
            +
                result
         | 
| 369 | 
            +
              end
         | 
| 300 370 | 
             
            end
         | 
| 301 371 |  | 
| 
            File without changes
         | 
    
        data/test/test_all.rb
    ADDED
    
    
| 
            File without changes
         | 
| @@ -0,0 +1,275 @@ | |
| 1 | 
            +
            #!/usr/local/bin/ruby -w
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'test/unit'
         | 
| 4 | 
            +
            require 'parse_tree'
         | 
| 5 | 
            +
            require 'something'
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            class TestParseTree < Test::Unit::TestCase
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              # TODO: need a test of interpolated strings
         | 
| 10 | 
            +
             | 
| 11 | 
            +
              @@missing = [nil]
         | 
| 12 | 
            +
              @@empty = [:defn, :empty,
         | 
| 13 | 
            +
                [:scope,
         | 
| 14 | 
            +
                  [:args]]]
         | 
| 15 | 
            +
              @@stupid = [:defn, :stupid,
         | 
| 16 | 
            +
                [:scope,
         | 
| 17 | 
            +
                  [:block,
         | 
| 18 | 
            +
                    [:args],
         | 
| 19 | 
            +
                    [:return, [:nil]]]]]
         | 
| 20 | 
            +
              @@simple = [:defn, :simple,
         | 
| 21 | 
            +
                [:scope,
         | 
| 22 | 
            +
                  [:block,
         | 
| 23 | 
            +
                    [:args, :arg1],
         | 
| 24 | 
            +
                    [:fcall, :print,
         | 
| 25 | 
            +
                      [:array, [:lvar, :arg1]]],
         | 
| 26 | 
            +
                    [:fcall, :puts,
         | 
| 27 | 
            +
                      [:array,
         | 
| 28 | 
            +
                        [:call,
         | 
| 29 | 
            +
                          [:call,
         | 
| 30 | 
            +
                            [:lit, 4],
         | 
| 31 | 
            +
                            :+,
         | 
| 32 | 
            +
                            [:array, [:lit, 2]]],
         | 
| 33 | 
            +
                         :to_s]]]]]]
         | 
| 34 | 
            +
              @@global = [:defn, :global,
         | 
| 35 | 
            +
                [:scope,
         | 
| 36 | 
            +
                  [:block,
         | 
| 37 | 
            +
                    [:args],
         | 
| 38 | 
            +
                    [:call,
         | 
| 39 | 
            +
                      [:gvar, :$stderr],
         | 
| 40 | 
            +
                      :fputs,
         | 
| 41 | 
            +
                      [:array, [:str, "blah"]]]]]]
         | 
| 42 | 
            +
              @@lasgn_call = [:defn, :lasgn_call,
         | 
| 43 | 
            +
                [:scope,
         | 
| 44 | 
            +
                  [:block,
         | 
| 45 | 
            +
                    [:args],
         | 
| 46 | 
            +
                    [:lasgn, :c,
         | 
| 47 | 
            +
                      [:call,
         | 
| 48 | 
            +
                        [:lit, 2],
         | 
| 49 | 
            +
                        :+,
         | 
| 50 | 
            +
                        [:array, [:lit, 3]]]]]]]
         | 
| 51 | 
            +
              @@conditional1 = [:defn, :conditional1,
         | 
| 52 | 
            +
                [:scope,
         | 
| 53 | 
            +
                  [:block,
         | 
| 54 | 
            +
                    [:args, :arg1],
         | 
| 55 | 
            +
                    [:if,
         | 
| 56 | 
            +
                      [:call,
         | 
| 57 | 
            +
                        [:lvar, :arg1],
         | 
| 58 | 
            +
                        :==,
         | 
| 59 | 
            +
                        [:array, [:lit, 0]]],
         | 
| 60 | 
            +
                      [:return,
         | 
| 61 | 
            +
                        [:lit, 1]], nil]]]]
         | 
| 62 | 
            +
              @@conditional2 = [:defn, :conditional2,
         | 
| 63 | 
            +
                [:scope,
         | 
| 64 | 
            +
                  [:block,
         | 
| 65 | 
            +
                    [:args, :arg1],
         | 
| 66 | 
            +
                    [:if,
         | 
| 67 | 
            +
                      [:call,
         | 
| 68 | 
            +
                        [:lvar, :arg1],
         | 
| 69 | 
            +
                        :==,
         | 
| 70 | 
            +
                        [:array, [:lit, 0]]], nil,
         | 
| 71 | 
            +
                      [:return,
         | 
| 72 | 
            +
                        [:lit, 2]]]]]]
         | 
| 73 | 
            +
              @@conditional3 = [:defn, :conditional3,
         | 
| 74 | 
            +
                [:scope,
         | 
| 75 | 
            +
                  [:block,
         | 
| 76 | 
            +
                    [:args, :arg1],
         | 
| 77 | 
            +
                    [:if,
         | 
| 78 | 
            +
                      [:call,
         | 
| 79 | 
            +
                        [:lvar, :arg1],
         | 
| 80 | 
            +
                        :==,
         | 
| 81 | 
            +
                        [:array, [:lit, 0]]],
         | 
| 82 | 
            +
                      [:return,
         | 
| 83 | 
            +
                        [:lit, 3]],
         | 
| 84 | 
            +
                      [:return,
         | 
| 85 | 
            +
                        [:lit, 4]]]]]]
         | 
| 86 | 
            +
              @@conditional4 = [:defn, :conditional4,
         | 
| 87 | 
            +
                [:scope,
         | 
| 88 | 
            +
                  [:block,
         | 
| 89 | 
            +
                    [:args, :arg1],
         | 
| 90 | 
            +
                    [:if,
         | 
| 91 | 
            +
                      [:call,
         | 
| 92 | 
            +
                        [:lvar, :arg1],
         | 
| 93 | 
            +
                        :==,
         | 
| 94 | 
            +
                        [:array, [:lit, 0]]],
         | 
| 95 | 
            +
                      [:return, [:lit, 2]],
         | 
| 96 | 
            +
                      [:if,
         | 
| 97 | 
            +
                        [:call,
         | 
| 98 | 
            +
                          [:lvar, :arg1],
         | 
| 99 | 
            +
                          :<,
         | 
| 100 | 
            +
                          [:array, [:lit, 0]]],
         | 
| 101 | 
            +
                        [:return, [:lit, 3]],
         | 
| 102 | 
            +
                        [:return, [:lit, 4]]]]]]]
         | 
| 103 | 
            +
              @@iteration_body = [:scope,
         | 
| 104 | 
            +
                [:block,
         | 
| 105 | 
            +
                  [:args],
         | 
| 106 | 
            +
                  [:lasgn, :array,
         | 
| 107 | 
            +
                    [:array, [:lit, 1], [:lit, 2], [:lit, 3]]],
         | 
| 108 | 
            +
                  [:iter,
         | 
| 109 | 
            +
                    [:call,
         | 
| 110 | 
            +
                      [:lvar, :array], :each],
         | 
| 111 | 
            +
                    [:dasgn_curr, :x],
         | 
| 112 | 
            +
                    [:fcall, :puts, [:array, [:call, [:dvar, :x], :to_s]]]]]]
         | 
| 113 | 
            +
              @@iteration1 = [:defn, :iteration1, @@iteration_body]
         | 
| 114 | 
            +
              @@iteration2 = [:defn, :iteration2, @@iteration_body]
         | 
| 115 | 
            +
              @@iteration3 = [:defn, :iteration3,
         | 
| 116 | 
            +
                [:scope,
         | 
| 117 | 
            +
                  [:block,
         | 
| 118 | 
            +
                    [:args],
         | 
| 119 | 
            +
                    [:lasgn, :array1,
         | 
| 120 | 
            +
                      [:array, [:lit, 1], [:lit, 2], [:lit, 3]]],
         | 
| 121 | 
            +
                    [:lasgn, :array2,
         | 
| 122 | 
            +
                      [:array, [:lit, 4], [:lit, 5], [:lit, 6], [:lit, 7]]],
         | 
| 123 | 
            +
                    [:iter,
         | 
| 124 | 
            +
                      [:call,
         | 
| 125 | 
            +
                        [:lvar, :array1], :each],
         | 
| 126 | 
            +
                      [:dasgn_curr, :x],
         | 
| 127 | 
            +
                      [:iter,
         | 
| 128 | 
            +
                        [:call,
         | 
| 129 | 
            +
                          [:lvar, :array2], :each],
         | 
| 130 | 
            +
                        [:dasgn_curr, :y],
         | 
| 131 | 
            +
                        [:block,
         | 
| 132 | 
            +
                          [:fcall, :puts,
         | 
| 133 | 
            +
                            [:array, [:call, [:dvar, :x], :to_s]]],
         | 
| 134 | 
            +
                          [:fcall, :puts,
         | 
| 135 | 
            +
                            [:array, [:call, [:dvar, :y], :to_s]]]]]]]]]
         | 
| 136 | 
            +
              @@iteration4 = [:defn,
         | 
| 137 | 
            +
             :iteration4,
         | 
| 138 | 
            +
             [:scope,
         | 
| 139 | 
            +
              [:block,
         | 
| 140 | 
            +
               [:args],
         | 
| 141 | 
            +
               [:iter,
         | 
| 142 | 
            +
                [:call, [:lit, 1], :upto, [:array, [:lit, 3]]],
         | 
| 143 | 
            +
                [:dasgn_curr, :n],
         | 
| 144 | 
            +
                [:fcall, :puts, [:array, [:call, [:dvar, :n], :to_s]]]]]]]
         | 
| 145 | 
            +
              @@iteration5 = [:defn,
         | 
| 146 | 
            +
             :iteration5,
         | 
| 147 | 
            +
             [:scope,
         | 
| 148 | 
            +
                  [:block,
         | 
| 149 | 
            +
               [:args],
         | 
| 150 | 
            +
               [:iter,
         | 
| 151 | 
            +
                [:call, [:lit, 3], :downto, [:array, [:lit, 1]]],
         | 
| 152 | 
            +
                [:dasgn_curr, :n],
         | 
| 153 | 
            +
                [:fcall, :puts, [:array, [:call, [:dvar, :n], :to_s]]]]]]]
         | 
| 154 | 
            +
              @@iteration6 = [:defn,
         | 
| 155 | 
            +
             :iteration6,
         | 
| 156 | 
            +
             [:scope,
         | 
| 157 | 
            +
                  [:block,
         | 
| 158 | 
            +
               [:args],
         | 
| 159 | 
            +
               [:iter,
         | 
| 160 | 
            +
                [:call, [:lit, 3], :downto, [:array, [:lit, 1]]],
         | 
| 161 | 
            +
                nil,
         | 
| 162 | 
            +
                [:fcall, :puts, [:array, [:str, "hello"]]]]]]]
         | 
| 163 | 
            +
              @@multi_args = [:defn, :multi_args,
         | 
| 164 | 
            +
                [:scope,
         | 
| 165 | 
            +
                  [:block,
         | 
| 166 | 
            +
                    [:args, :arg1, :arg2],
         | 
| 167 | 
            +
                    [:lasgn, :arg3,
         | 
| 168 | 
            +
                      [:call,
         | 
| 169 | 
            +
                        [:call,
         | 
| 170 | 
            +
                          [:lvar, :arg1],
         | 
| 171 | 
            +
                          :*,
         | 
| 172 | 
            +
                          [:array, [:lvar, :arg2]]],
         | 
| 173 | 
            +
                        :*,
         | 
| 174 | 
            +
                        [:array, [:lit, 7]]]],
         | 
| 175 | 
            +
                    [:fcall, :puts, [:array, [:call, [:lvar, :arg3], :to_s]]],
         | 
| 176 | 
            +
                    [:return,
         | 
| 177 | 
            +
                      [:str, "foo"]]]]]
         | 
| 178 | 
            +
              @@bools = [:defn, :bools,
         | 
| 179 | 
            +
                [:scope,
         | 
| 180 | 
            +
                  [:block,
         | 
| 181 | 
            +
                    [:args, :arg1],
         | 
| 182 | 
            +
                    [:if,
         | 
| 183 | 
            +
                      [:call,
         | 
| 184 | 
            +
                        [:lvar, :arg1], :nil?],
         | 
| 185 | 
            +
                      [:return,
         | 
| 186 | 
            +
                        [:false]],
         | 
| 187 | 
            +
                      [:return,
         | 
| 188 | 
            +
                        [:true]]]]]]
         | 
| 189 | 
            +
              @@case_stmt = [:defn, :case_stmt,
         | 
| 190 | 
            +
                [:scope,
         | 
| 191 | 
            +
                  [:block,
         | 
| 192 | 
            +
                    [:args],
         | 
| 193 | 
            +
                    [:lasgn, :var, [:lit, 2]],
         | 
| 194 | 
            +
                    [:lasgn, :result, [:str, ""]],
         | 
| 195 | 
            +
                    [:case,
         | 
| 196 | 
            +
                      [:lvar, :var],
         | 
| 197 | 
            +
                      [:when,
         | 
| 198 | 
            +
                        [:array, [:lit, 1]],
         | 
| 199 | 
            +
                        [:block,
         | 
| 200 | 
            +
                          [:fcall, :puts, [:array, [:str, "something"]]],
         | 
| 201 | 
            +
                          [:lasgn, :result, [:str, "red"]]]],
         | 
| 202 | 
            +
                      [:when,
         | 
| 203 | 
            +
                        [:array, [:lit, 2], [:lit, 3]],
         | 
| 204 | 
            +
                        [:lasgn, :result, [:str, "yellow"]]],
         | 
| 205 | 
            +
                      [:when, [:array, [:lit, 4]], nil],
         | 
| 206 | 
            +
                      [:lasgn, :result, [:str, "green"]]],
         | 
| 207 | 
            +
                    [:case,
         | 
| 208 | 
            +
                      [:lvar, :result],
         | 
| 209 | 
            +
                      [:when, [:array, [:str, "red"]], [:lasgn, :var, [:lit, 1]]],
         | 
| 210 | 
            +
                      [:when, [:array, [:str, "yellow"]], [:lasgn, :var, [:lit, 2]]],
         | 
| 211 | 
            +
                      [:when, [:array, [:str, "green"]], [:lasgn, :var, [:lit, 3]]],
         | 
| 212 | 
            +
                      nil],
         | 
| 213 | 
            +
                    [:return, [:lvar, :result]]]]]
         | 
| 214 | 
            +
              @@eric_is_stubborn = [:defn,
         | 
| 215 | 
            +
                :eric_is_stubborn,
         | 
| 216 | 
            +
                [:scope,
         | 
| 217 | 
            +
                  [:block,
         | 
| 218 | 
            +
                    [:args],
         | 
| 219 | 
            +
                    [:lasgn, :var, [:lit, 42]],
         | 
| 220 | 
            +
                    [:lasgn, :var2, [:call, [:lvar, :var], :to_s]],
         | 
| 221 | 
            +
                    [:call, [:gvar, :$stderr], :fputs, [:array, [:lvar, :var2]]],
         | 
| 222 | 
            +
                    [:return, [:lvar, :var2]]]]]
         | 
| 223 | 
            +
              @@interpolated = [:defn,
         | 
| 224 | 
            +
                :interpolated,
         | 
| 225 | 
            +
                [:scope,
         | 
| 226 | 
            +
                  [:block,
         | 
| 227 | 
            +
                    [:args],
         | 
| 228 | 
            +
                    [:lasgn, :var, [:lit, 14]],
         | 
| 229 | 
            +
                    [:lasgn, :var2, [:dstr, "var is ", [:lvar, :var], [:str, ". So there."]]]]]]
         | 
| 230 | 
            +
              @@unknown_args = [:defn, :unknown_args,
         | 
| 231 | 
            +
                [:scope,
         | 
| 232 | 
            +
                  [:block,
         | 
| 233 | 
            +
                    [:args, :arg1, :arg2],
         | 
| 234 | 
            +
                    [:return, [:lvar, :arg1]]]]]
         | 
| 235 | 
            +
              @@determine_args = [:defn, :determine_args,
         | 
| 236 | 
            +
                [:scope,
         | 
| 237 | 
            +
                  [:block,
         | 
| 238 | 
            +
                    [:args],
         | 
| 239 | 
            +
                      [:call,
         | 
| 240 | 
            +
                        [:lit, 5],
         | 
| 241 | 
            +
                        :==,
         | 
| 242 | 
            +
                        [:array,
         | 
| 243 | 
            +
                          [:fcall,
         | 
| 244 | 
            +
                            :unknown_args,
         | 
| 245 | 
            +
                            [:array, [:lit, 4], [:str, "known"]]]]]]]]
         | 
| 246 | 
            +
             | 
| 247 | 
            +
              @@__all = [:class, :Something, :Object]
         | 
| 248 | 
            +
             | 
| 249 | 
            +
              def setup
         | 
| 250 | 
            +
                @thing = ParseTree.new
         | 
| 251 | 
            +
              end
         | 
| 252 | 
            +
             | 
| 253 | 
            +
              Something.instance_methods(false).sort.each do |meth|
         | 
| 254 | 
            +
                if class_variables.include?("@@#{meth}") then
         | 
| 255 | 
            +
                  @@__all << eval("@@#{meth}")
         | 
| 256 | 
            +
                  eval "def test_#{meth}; assert_equal @@#{meth}, @thing.parse_tree_for_method(Something, :#{meth}); end"
         | 
| 257 | 
            +
                else
         | 
| 258 | 
            +
                  eval "def test_#{meth}; flunk \"You haven't added @@#{meth} yet\"; end"
         | 
| 259 | 
            +
                end
         | 
| 260 | 
            +
              end
         | 
| 261 | 
            +
             | 
| 262 | 
            +
              def test_missing
         | 
| 263 | 
            +
                assert_equal(@@missing,
         | 
| 264 | 
            +
            		 @thing.parse_tree_for_method(Something, :missing),
         | 
| 265 | 
            +
            		 "Must return -3 for missing methods")
         | 
| 266 | 
            +
              end
         | 
| 267 | 
            +
             | 
| 268 | 
            +
              def test_class
         | 
| 269 | 
            +
                assert_equal([@@__all],
         | 
| 270 | 
            +
            		 @thing.parse_tree(Something),
         | 
| 271 | 
            +
            		 "Must return a lot of shit")
         | 
| 272 | 
            +
              end
         | 
| 273 | 
            +
             | 
| 274 | 
            +
            end
         | 
| 275 | 
            +
             |