sbyc 0.1.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/LICENCE.textile +12 -0
- data/README.textile +44 -0
- data/lib/sbyc.rb +14 -0
- data/lib/sbyc/codetree.rb +82 -0
- data/lib/sbyc/codetree/ast_node.rb +101 -0
- data/lib/sbyc/codetree/eval.rb +3 -0
- data/lib/sbyc/codetree/eval/ast_node_ext.rb +38 -0
- data/lib/sbyc/codetree/eval/functional_eval.rb +36 -0
- data/lib/sbyc/codetree/eval/object_eval.rb +36 -0
- data/lib/sbyc/codetree/matching.rb +3 -0
- data/lib/sbyc/codetree/matching/ast_node_ext.rb +14 -0
- data/lib/sbyc/codetree/matching/match_data.rb +30 -0
- data/lib/sbyc/codetree/matching/matcher.rb +83 -0
- data/lib/sbyc/codetree/proc_parser.rb +91 -0
- data/lib/sbyc/codetree/producing.rb +1 -0
- data/lib/sbyc/codetree/producing/producer.rb +68 -0
- data/lib/sbyc/codetree/rewriting.rb +4 -0
- data/lib/sbyc/codetree/rewriting/class_methods.rb +15 -0
- data/lib/sbyc/codetree/rewriting/compiler.rb +28 -0
- data/lib/sbyc/codetree/rewriting/instance_methods.rb +92 -0
- data/lib/sbyc/codetree/rewriting/match.rb +59 -0
- data/test/spec/documentation/codetree/production.spec +59 -0
- data/test/spec/documentation/readme/assumptions.spec +33 -0
- data/test/spec/documentation/readme/functional_evaluation.spec +29 -0
- data/test/spec/documentation/readme/object_evaluation.spec +17 -0
- data/test/spec/documentation/readme/rewriting.spec +60 -0
- data/test/spec/documentation/readme/semantics.spec +21 -0
- data/test/spec/documentation/readme/synopsis.spec +27 -0
- data/test/spec/documentation/readme/syntax.spec +26 -0
- data/test/spec/spec_helper.rb +13 -0
- data/test/spec/test_all.rb +6 -0
- data/test/spec/unit/sbyc/codetree/ast_node/coerce.spec +60 -0
- data/test/spec/unit/sbyc/codetree/ast_node/equality.spec +75 -0
- data/test/spec/unit/sbyc/codetree/ast_node/inspect.spec +23 -0
- data/test/spec/unit/sbyc/codetree/ast_node/literal.spec +15 -0
- data/test/spec/unit/sbyc/codetree/ast_node/to_a.spec +27 -0
- data/test/spec/unit/sbyc/codetree/ast_node/to_s.spec +23 -0
- data/test/spec/unit/sbyc/codetree/ast_node/visit.spec +34 -0
- data/test/spec/unit/sbyc/codetree/eval/functional_compile.spec +30 -0
- data/test/spec/unit/sbyc/codetree/eval/functional_eval.spec +34 -0
- data/test/spec/unit/sbyc/codetree/eval/functional_proc.spec +36 -0
- data/test/spec/unit/sbyc/codetree/eval/object_compile.spec +36 -0
- data/test/spec/unit/sbyc/codetree/eval/object_eval.spec +38 -0
- data/test/spec/unit/sbyc/codetree/eval/object_proc.spec +36 -0
- data/test/spec/unit/sbyc/codetree/matching/matcher/args_match.spec +91 -0
- data/test/spec/unit/sbyc/codetree/matching/matcher/do_match.spec +39 -0
- data/test/spec/unit/sbyc/codetree/matching/matcher/function_match.spec +45 -0
- data/test/spec/unit/sbyc/codetree/matching/matcher/match.spec +64 -0
- data/test/spec/unit/sbyc/codetree/proc_parser/expr.spec +20 -0
- data/test/spec/unit/sbyc/codetree/proc_parser/parse.spec +83 -0
- data/test/spec/unit/sbyc/codetree/producing/producer.spec +31 -0
- data/test/spec/unit/sbyc/codetree/producing/producer/apply_args_conventions.spec +60 -0
- data/test/spec/unit/sbyc/codetree/rewriting/instance_methods/apply_args_conventions.spec +60 -0
- data/test/spec/unit/sbyc/codetree/rewriting/instance_methods/node.spec +19 -0
- data/test/spec/unit/sbyc/codetree/rewriting/instance_methods/rewrite.spec +76 -0
- data/test/spec/unit/sbyc/codetree/rewriting/match/apply.spec +23 -0
- data/test/spec/unit/sbyc/codetree/rewriting/match/coerce.spec +48 -0
- data/test/spec/unit/sbyc/codetree/rewriting/match/matches.spec +27 -0
- metadata +129 -0
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            require File.expand_path('../../../../../spec_helper', __FILE__)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "CodeTree::ProcParser::Expr" do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              let(:the_expr) { CodeTree::ProcParser::Expr.new }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              describe("should not have access to Kernel methods") do
         | 
| 8 | 
            +
                specify{ 
         | 
| 9 | 
            +
                  x = the_expr.instance_eval{ puts "hello" } 
         | 
| 10 | 
            +
                  lambda{ x.__to_functional_code }.should_not raise_error
         | 
| 11 | 
            +
                  x.__to_functional_code.should be_kind_of(CodeTree::AstNode)
         | 
| 12 | 
            +
                }
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
              
         | 
| 15 | 
            +
              describe "should not have a to_s method" do
         | 
| 16 | 
            +
                subject { the_expr.to_s.__to_functional_code }
         | 
| 17 | 
            +
                it { should be_kind_of(CodeTree::AstNode) }
         | 
| 18 | 
            +
              end
         | 
| 19 | 
            +
              
         | 
| 20 | 
            +
            end
         | 
| @@ -0,0 +1,83 @@ | |
| 1 | 
            +
            require File.expand_path('../../../../../spec_helper', __FILE__)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "CodeTree::ProcParser#parse" do
         | 
| 4 | 
            +
              
         | 
| 5 | 
            +
              subject { CodeTree::ProcParser::parse(code) }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              context "when called with an argument" do 
         | 
| 8 | 
            +
                let(:expected)   { "(+ (? (_ :a)), (_ 12))" }
         | 
| 9 | 
            +
              
         | 
| 10 | 
            +
                context("with a simple literal") do
         | 
| 11 | 
            +
                  let(:code)  { proc {|t| 12 } }
         | 
| 12 | 
            +
                  specify     { subject.should be_kind_of(CodeTree::AstNode) }
         | 
| 13 | 
            +
                  specify     { subject.inspect.should == CodeTree::parse{ 12 }.inspect }
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              
         | 
| 16 | 
            +
                context("with a simple operator call") do
         | 
| 17 | 
            +
                  let(:code)  { proc {|t| t[:a] + 12 }             }
         | 
| 18 | 
            +
                  specify     { subject.inspect.should == expected }
         | 
| 19 | 
            +
                end
         | 
| 20 | 
            +
                  
         | 
| 21 | 
            +
                context("with a simple operator call and dot heuristic") do
         | 
| 22 | 
            +
                  let(:code)        { proc {|t| t.a + 12 } }
         | 
| 23 | 
            +
                  specify { subject.inspect.should == expected }
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
                  
         | 
| 26 | 
            +
                context("with left literal at left") do
         | 
| 27 | 
            +
                  let(:code)        { proc {|t| 12 + t[:a]       } }
         | 
| 28 | 
            +
                  specify { subject.inspect.should == expected }
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
                  
         | 
| 31 | 
            +
                context("with left literal at left and dot heuristic") do
         | 
| 32 | 
            +
                  let(:code)        { proc {|t| 12 + t.a       } }
         | 
| 33 | 
            +
                  specify { subject.inspect.should == expected }
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
              end
         | 
| 36 | 
            +
              
         | 
| 37 | 
            +
              context "when called without argument" do
         | 
| 38 | 
            +
                let(:expected)   { "(+ (? (_ :a)), (_ 12))" }
         | 
| 39 | 
            +
              
         | 
| 40 | 
            +
                context("with a simple literal") do
         | 
| 41 | 
            +
                  let(:code)        { proc { 12 } }
         | 
| 42 | 
            +
                  specify     { subject.should be_kind_of(CodeTree::AstNode) }
         | 
| 43 | 
            +
                  specify { subject.inspect.should == CodeTree::parse{ 12 }.inspect }
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
              
         | 
| 46 | 
            +
                context("with a simple operator call") do
         | 
| 47 | 
            +
                  let(:code)        { proc { a + 12 } }
         | 
| 48 | 
            +
                  specify { subject.inspect.should == expected }
         | 
| 49 | 
            +
                end
         | 
| 50 | 
            +
              
         | 
| 51 | 
            +
                context("with left literal at left") do
         | 
| 52 | 
            +
                  let(:code)        { proc { 12 + a } }
         | 
| 53 | 
            +
                  specify { subject.inspect.should == expected }
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
              end
         | 
| 56 | 
            +
               
         | 
| 57 | 
            +
              context "when called and used with method calls" do
         | 
| 58 | 
            +
                let(:expected)   { "(plus (? (_ :a)), (_ 12))" }
         | 
| 59 | 
            +
               
         | 
| 60 | 
            +
                context("with a simple method call") do
         | 
| 61 | 
            +
                  let(:code)        { proc {|t| t[:a].plus(12)   } }
         | 
| 62 | 
            +
                  specify { subject.inspect.should == expected }
         | 
| 63 | 
            +
                end
         | 
| 64 | 
            +
                  
         | 
| 65 | 
            +
                context("with a simple method call and dot heuristic") do
         | 
| 66 | 
            +
                  let(:code)        { proc {|t| t.a.plus(12)   } }
         | 
| 67 | 
            +
                  specify { subject.inspect.should == expected }
         | 
| 68 | 
            +
                end
         | 
| 69 | 
            +
              end
         | 
| 70 | 
            +
              
         | 
| 71 | 
            +
              context "when call on expressions that refer to ruby Kernel methods" do
         | 
| 72 | 
            +
                let(:expected) { "(puts (to_s (? (_ :x))))"}
         | 
| 73 | 
            +
                let(:code)     { lambda { (puts (to_s x)) } }
         | 
| 74 | 
            +
                specify{ subject.inspect.should == expected }
         | 
| 75 | 
            +
              end
         | 
| 76 | 
            +
              
         | 
| 77 | 
            +
              context "when call on expressions that refer to typical inherited methods/operators" do
         | 
| 78 | 
            +
                let(:expected) { "(== (hash (? (_ :x))), (_ 12))"}
         | 
| 79 | 
            +
                let(:code)     { lambda { x.hash == 12 } }
         | 
| 80 | 
            +
                specify{ subject.inspect.should == expected }
         | 
| 81 | 
            +
              end
         | 
| 82 | 
            +
              
         | 
| 83 | 
            +
            end
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            require File.expand_path('../../../../../spec_helper', __FILE__)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "CodeTree::Producing::Producer" do
         | 
| 4 | 
            +
              
         | 
| 5 | 
            +
              let(:expr){ CodeTree::parse{ ~(a & b) } }
         | 
| 6 | 
            +
              
         | 
| 7 | 
            +
              context 'when called with default rules' do
         | 
| 8 | 
            +
                let(:producer) { 
         | 
| 9 | 
            +
                  CodeTree::producer{|p|
         | 
| 10 | 
            +
                    p.rule(:~){|r, n| "not(#{r.apply(n[0])})"                  }
         | 
| 11 | 
            +
                    p.rule(:&){|r, n| "(#{r.apply(n.children).join(' and ')})" }
         | 
| 12 | 
            +
                    p.rule(:|){|r, n| "(#{r.apply(n.children).join(' or ')})"  }
         | 
| 13 | 
            +
                  }
         | 
| 14 | 
            +
                }
         | 
| 15 | 
            +
                subject{ producer.apply(expr) }
         | 
| 16 | 
            +
                it{ should == "not((a and b))" }
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
              
         | 
| 19 | 
            +
              context 'when called without default rules' do
         | 
| 20 | 
            +
                let(:producer) { 
         | 
| 21 | 
            +
                  CodeTree::producer(false){|p|
         | 
| 22 | 
            +
                    p.rule("*"){|r,n| [n.function] + r.apply(n.children)}
         | 
| 23 | 
            +
                  }
         | 
| 24 | 
            +
                }
         | 
| 25 | 
            +
                subject{ producer.apply(expr) }
         | 
| 26 | 
            +
                specify{ producer.rules.size.should == 1 }
         | 
| 27 | 
            +
                it{ should == [:~, [:&, [:'?', [:_, :a]], [:'?', [:_, :b]]]] }
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
              
         | 
| 30 | 
            +
            end
         | 
| 31 | 
            +
             | 
| @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            require File.expand_path('../../../../../../spec_helper', __FILE__)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "CodeTree::Producing::Producer#apply_args_conventions" do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              let(:producer) { ::CodeTree::producer }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              context "when called with a literal" do
         | 
| 8 | 
            +
                let(:node)     { 12 }
         | 
| 9 | 
            +
                subject { producer.send(:apply_args_conventions,node) }
         | 
| 10 | 
            +
                it { should == node }
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              context "when called with a single ASTNode instance" do
         | 
| 14 | 
            +
                let(:node)     { ::CodeTree::parse{ 12 }  }
         | 
| 15 | 
            +
                subject { producer.send(:apply_args_conventions,node) }
         | 
| 16 | 
            +
                it { should == node }
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              context "when called with multiple ASTNode instances" do
         | 
| 20 | 
            +
                let(:child1)   { ::CodeTree::parse{ "hello" }                          }
         | 
| 21 | 
            +
                let(:child2)   { ::CodeTree::parse{ "world" }                          }
         | 
| 22 | 
            +
                subject        { producer.send(:apply_args_conventions,child1, child2)   }
         | 
| 23 | 
            +
                it { should == [child1, child2] }
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              context "when called with an array of ASTNode instances" do
         | 
| 27 | 
            +
                let(:child1)   { ::CodeTree::parse{ "hello" }                          }
         | 
| 28 | 
            +
                let(:child2)   { ::CodeTree::parse{ "world" }                          }
         | 
| 29 | 
            +
                subject        { producer.send(:apply_args_conventions,[child1, child2]) }
         | 
| 30 | 
            +
                it { should == [child1, child2] }
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              context "when called with a function and a single ASTNode child" do
         | 
| 34 | 
            +
                let(:function) { :testfunc                      }
         | 
| 35 | 
            +
                let(:child)    { ::CodeTree::parse{ 12 }            }
         | 
| 36 | 
            +
                let(:expected) { ::CodeTree::parse{ (testfunc 12) } }
         | 
| 37 | 
            +
                subject{ producer.send(:apply_args_conventions,function, child) }
         | 
| 38 | 
            +
                it { should == expected }
         | 
| 39 | 
            +
              end 
         | 
| 40 | 
            +
              
         | 
| 41 | 
            +
              context "when called with a function and two ASTNode children" do
         | 
| 42 | 
            +
                let(:function) { :say                                              }
         | 
| 43 | 
            +
                let(:child1)   { ::CodeTree::parse{ "hello" }                          }
         | 
| 44 | 
            +
                let(:child2)   { ::CodeTree::parse{ "world" }                          }
         | 
| 45 | 
            +
                let(:expected) { ::CodeTree::parse{ (say "hello", "world") }           }
         | 
| 46 | 
            +
                subject{ producer.send(:apply_args_conventions,function, child1, child2) }
         | 
| 47 | 
            +
                it { should == expected }
         | 
| 48 | 
            +
              end 
         | 
| 49 | 
            +
              
         | 
| 50 | 
            +
              context "when called with a function and mix of ASTNode children" do
         | 
| 51 | 
            +
                let(:function) { :say                                              }
         | 
| 52 | 
            +
                let(:child1)   { ::CodeTree::parse{ "hello" }                          }
         | 
| 53 | 
            +
                let(:child2)   { ::CodeTree::parse{ "you" }                            }
         | 
| 54 | 
            +
                let(:child3)   { ::CodeTree::parse{ "world" }                          }
         | 
| 55 | 
            +
                let(:expected) { ::CodeTree::parse{ (say "hello", "you", "world") }    }
         | 
| 56 | 
            +
                subject{ producer.send(:apply_args_conventions,function, child1, [child2, child3]) }
         | 
| 57 | 
            +
                it { should == expected }
         | 
| 58 | 
            +
              end 
         | 
| 59 | 
            +
              
         | 
| 60 | 
            +
            end
         | 
| @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            require File.expand_path('../../../../../../spec_helper', __FILE__)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "CodeTree::Rewriting::Rewriter#apply_args_conventions" do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              let(:rewriter) { ::CodeTree::rewriter }
         | 
| 6 | 
            +
             | 
| 7 | 
            +
              context "when called with a literal" do
         | 
| 8 | 
            +
                let(:node)     { 12 }
         | 
| 9 | 
            +
                subject { rewriter.apply_args_conventions(node) }
         | 
| 10 | 
            +
                it { should == node }
         | 
| 11 | 
            +
              end
         | 
| 12 | 
            +
             | 
| 13 | 
            +
              context "when called with a single ASTNode instance" do
         | 
| 14 | 
            +
                let(:node)     { ::CodeTree::parse{ 12 }  }
         | 
| 15 | 
            +
                subject { rewriter.apply_args_conventions(node) }
         | 
| 16 | 
            +
                it { should == node }
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              context "when called with multiple ASTNode instances" do
         | 
| 20 | 
            +
                let(:child1)   { ::CodeTree::parse{ "hello" }                          }
         | 
| 21 | 
            +
                let(:child2)   { ::CodeTree::parse{ "world" }                          }
         | 
| 22 | 
            +
                subject        { rewriter.apply_args_conventions(child1, child2)   }
         | 
| 23 | 
            +
                it { should == [child1, child2] }
         | 
| 24 | 
            +
              end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
              context "when called with an array of ASTNode instances" do
         | 
| 27 | 
            +
                let(:child1)   { ::CodeTree::parse{ "hello" }                          }
         | 
| 28 | 
            +
                let(:child2)   { ::CodeTree::parse{ "world" }                          }
         | 
| 29 | 
            +
                subject        { rewriter.apply_args_conventions([child1, child2]) }
         | 
| 30 | 
            +
                it { should == [child1, child2] }
         | 
| 31 | 
            +
              end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
              context "when called with a function and a single ASTNode child" do
         | 
| 34 | 
            +
                let(:function) { :testfunc                      }
         | 
| 35 | 
            +
                let(:child)    { ::CodeTree::parse{ 12 }            }
         | 
| 36 | 
            +
                let(:expected) { ::CodeTree::parse{ (testfunc 12) } }
         | 
| 37 | 
            +
                subject{ rewriter.apply_args_conventions(function, child) }
         | 
| 38 | 
            +
                it { should == expected }
         | 
| 39 | 
            +
              end 
         | 
| 40 | 
            +
              
         | 
| 41 | 
            +
              context "when called with a function and two ASTNode children" do
         | 
| 42 | 
            +
                let(:function) { :say                                              }
         | 
| 43 | 
            +
                let(:child1)   { ::CodeTree::parse{ "hello" }                          }
         | 
| 44 | 
            +
                let(:child2)   { ::CodeTree::parse{ "world" }                          }
         | 
| 45 | 
            +
                let(:expected) { ::CodeTree::parse{ (say "hello", "world") }           }
         | 
| 46 | 
            +
                subject{ rewriter.apply_args_conventions(function, child1, child2) }
         | 
| 47 | 
            +
                it { should == expected }
         | 
| 48 | 
            +
              end 
         | 
| 49 | 
            +
              
         | 
| 50 | 
            +
              context "when called with a function and mix of ASTNode children" do
         | 
| 51 | 
            +
                let(:function) { :say                                              }
         | 
| 52 | 
            +
                let(:child1)   { ::CodeTree::parse{ "hello" }                          }
         | 
| 53 | 
            +
                let(:child2)   { ::CodeTree::parse{ "you" }                            }
         | 
| 54 | 
            +
                let(:child3)   { ::CodeTree::parse{ "world" }                          }
         | 
| 55 | 
            +
                let(:expected) { ::CodeTree::parse{ (say "hello", "you", "world") }    }
         | 
| 56 | 
            +
                subject{ rewriter.apply_args_conventions(function, child1, [child2, child3]) }
         | 
| 57 | 
            +
                it { should == expected }
         | 
| 58 | 
            +
              end 
         | 
| 59 | 
            +
              
         | 
| 60 | 
            +
            end
         | 
| @@ -0,0 +1,19 @@ | |
| 1 | 
            +
            require File.expand_path('../../../../../../spec_helper', __FILE__)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "CodeTree::Rewriting::Rewriter#copy" do
         | 
| 4 | 
            +
              
         | 
| 5 | 
            +
              let(:engine) { CodeTree::rewriter }
         | 
| 6 | 
            +
              
         | 
| 7 | 
            +
              context "when called with a literal" do 
         | 
| 8 | 
            +
                subject{ engine.node(:test, [ 12 ]) }
         | 
| 9 | 
            +
                it { should == CodeTree::parse{ (test 12) } }
         | 
| 10 | 
            +
              end
         | 
| 11 | 
            +
              
         | 
| 12 | 
            +
              context "when called with copy in mind" do
         | 
| 13 | 
            +
                let(:node) { CodeTree::parse{ 12 } } 
         | 
| 14 | 
            +
                subject{ engine.node(node.function, node.children) }
         | 
| 15 | 
            +
                it { should == CodeTree::parse{ 12 } }
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
              
         | 
| 18 | 
            +
            end
         | 
| 19 | 
            +
             | 
| @@ -0,0 +1,76 @@ | |
| 1 | 
            +
            require File.expand_path('../../../../../../spec_helper', __FILE__)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "CodeTree::Rewriting::Rewriter" do
         | 
| 4 | 
            +
             | 
| 5 | 
            +
              describe "when called without scope" do 
         | 
| 6 | 
            +
                subject{
         | 
| 7 | 
            +
                  CodeTree::rewriter {|r|
         | 
| 8 | 
            +
                    r.rule(:concat)        {|r, node, *args| args.collect{|c| r.apply(c)}.join }
         | 
| 9 | 
            +
                    r.rule(:_)             {|r, node| node.literal                             }
         | 
| 10 | 
            +
                  }
         | 
| 11 | 
            +
                }
         | 
| 12 | 
            +
              
         | 
| 13 | 
            +
                it { should be_kind_of(CodeTree::Rewriting::Rewriter) }
         | 
| 14 | 
            +
              
         | 
| 15 | 
            +
                context("when applied on an ast string") do
         | 
| 16 | 
            +
                  specify { subject.rewrite("(concat 1, 2, 3)").should == "123" }
         | 
| 17 | 
            +
                end
         | 
| 18 | 
            +
              
         | 
| 19 | 
            +
                context("when applied with a proc argument") do
         | 
| 20 | 
            +
                  let(:code){ lambda{ (concat 1, 2, 3) } }
         | 
| 21 | 
            +
                  specify { subject.rewrite(code).should == "123" }
         | 
| 22 | 
            +
                end
         | 
| 23 | 
            +
              
         | 
| 24 | 
            +
                context("when applied with a block") do
         | 
| 25 | 
            +
                  specify { subject.rewrite{ (concat 1, 2, 3) }.should == "123" }
         | 
| 26 | 
            +
                end
         | 
| 27 | 
            +
                
         | 
| 28 | 
            +
              end
         | 
| 29 | 
            +
             | 
| 30 | 
            +
              describe "when called with a scope object" do 
         | 
| 31 | 
            +
                subject{
         | 
| 32 | 
            +
                  CodeTree::rewriter     {|r|
         | 
| 33 | 
            +
                    r.rule(:concat)        {|r, node, *args| args.collect{|c| r.apply(c)}.join }
         | 
| 34 | 
            +
                    r.rule(:get)           {|r, node, name|  r.scope[r.apply(name)]            }
         | 
| 35 | 
            +
                    r.rule(:_)             {|r, node| node.literal                             }
         | 
| 36 | 
            +
                  }
         | 
| 37 | 
            +
                }
         | 
| 38 | 
            +
              
         | 
| 39 | 
            +
                it { should be_kind_of(CodeTree::Rewriting::Rewriter) }
         | 
| 40 | 
            +
              
         | 
| 41 | 
            +
                context("when applied on an ast string") do
         | 
| 42 | 
            +
                  specify { subject.rewrite("(get :hello)", :hello => "world").should == "world" }
         | 
| 43 | 
            +
                end
         | 
| 44 | 
            +
                  
         | 
| 45 | 
            +
                context("when applied with a proc argument") do
         | 
| 46 | 
            +
                  let(:code){ lambda{ (get :hello) } }
         | 
| 47 | 
            +
                  specify { subject.rewrite(code, :hello => "world").should == "world" }
         | 
| 48 | 
            +
                end
         | 
| 49 | 
            +
                  
         | 
| 50 | 
            +
                context("when applied with a block") do
         | 
| 51 | 
            +
                  specify { subject.rewrite(:hello => "world"){ (get :hello) }.should == "world" }
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
              end
         | 
| 54 | 
            +
              
         | 
| 55 | 
            +
              describe "when only an ANY match is installed" do
         | 
| 56 | 
            +
                subject{ CodeTree::rewriter{|r| 
         | 
| 57 | 
            +
                  r.rule(CodeTree::Rewriting::Rewriter::Match::ANY){|r, node, arg| node.leaf? ? arg : r.apply(arg) } 
         | 
| 58 | 
            +
                }}
         | 
| 59 | 
            +
                
         | 
| 60 | 
            +
                it "should return inner-most argument" do
         | 
| 61 | 
            +
                  subject.rewrite{ (call (other (one :hello))) }.should == :hello
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
              end
         | 
| 64 | 
            +
              
         | 
| 65 | 
            +
              describe "when only an LEAF/BRANCH are used" do
         | 
| 66 | 
            +
                subject{ CodeTree::rewriter{|r| 
         | 
| 67 | 
            +
                  r.rule(CodeTree::Rewriting::Rewriter::Match::BRANCH){|r, node, child| r.apply(child)}
         | 
| 68 | 
            +
                  r.rule(CodeTree::Rewriting::Rewriter::Match::LEAF){|r, node| node.literal}
         | 
| 69 | 
            +
                }}
         | 
| 70 | 
            +
                
         | 
| 71 | 
            +
                it "should return inner-most argument" do
         | 
| 72 | 
            +
                  subject.rewrite{ (call (other (one :hello))) }.should == :hello
         | 
| 73 | 
            +
                end
         | 
| 74 | 
            +
              end
         | 
| 75 | 
            +
              
         | 
| 76 | 
            +
            end
         | 
| @@ -0,0 +1,23 @@ | |
| 1 | 
            +
            require File.expand_path('../../../../../../spec_helper', __FILE__)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "CodeTree::Rewriting::Rewriter::Match#apply" do
         | 
| 4 | 
            +
              
         | 
| 5 | 
            +
              let(:predicate) { true }
         | 
| 6 | 
            +
              let(:block)     { lambda{ |r, node, *args| [r, node, args] } }
         | 
| 7 | 
            +
              subject { CodeTree::Rewriting::Rewriter::Match.new(predicate, block) }
         | 
| 8 | 
            +
              
         | 
| 9 | 
            +
              context "when called on a leaf node" do
         | 
| 10 | 
            +
                let(:node) { CodeTree::AstNode.coerce(:literal) }
         | 
| 11 | 
            +
                specify { 
         | 
| 12 | 
            +
                  subject.apply("rewriter", node).should == ["rewriter", node, [ :literal ]]
         | 
| 13 | 
            +
                }
         | 
| 14 | 
            +
              end
         | 
| 15 | 
            +
              
         | 
| 16 | 
            +
              context "when called on a branch node" do
         | 
| 17 | 
            +
                let(:node) { CodeTree::AstNode.new(:branch, [1, 2, 3]) }
         | 
| 18 | 
            +
                specify { 
         | 
| 19 | 
            +
                  subject.apply("rewriter", node).should == ["rewriter", node, [1, 2, 3]]
         | 
| 20 | 
            +
                }
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
              
         | 
| 23 | 
            +
            end
         | 
| @@ -0,0 +1,48 @@ | |
| 1 | 
            +
            require File.expand_path('../../../../../../spec_helper', __FILE__)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "CodeTree::Rewriting::Rewriter::Match.coerce?" do
         | 
| 4 | 
            +
              
         | 
| 5 | 
            +
              let(:branch) { CodeTree::parse{ (branch :hello) } }
         | 
| 6 | 
            +
              let(:leaf)   { CodeTree::parse{ :hello }          }
         | 
| 7 | 
            +
              
         | 
| 8 | 
            +
              context("when called with a symbol") do
         | 
| 9 | 
            +
                subject{ CodeTree::Rewriting::Rewriter::Match.coerce(:branch, nil) }
         | 
| 10 | 
            +
                
         | 
| 11 | 
            +
                it { should === branch }
         | 
| 12 | 
            +
                it { should_not === leaf }
         | 
| 13 | 
            +
              end
         | 
| 14 | 
            +
              
         | 
| 15 | 
            +
              context("when called with a proc") do
         | 
| 16 | 
            +
                let(:predicate) { lambda{|node| node.leaf? }}
         | 
| 17 | 
            +
                subject{ CodeTree::Rewriting::Rewriter::Match.coerce(predicate, nil) }
         | 
| 18 | 
            +
                
         | 
| 19 | 
            +
                it { should_not === branch }
         | 
| 20 | 
            +
                it { should === leaf }
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
              
         | 
| 23 | 
            +
              context("when called with '.'") do
         | 
| 24 | 
            +
                subject{ CodeTree::Rewriting::Rewriter::Match.coerce(".", nil) }
         | 
| 25 | 
            +
                
         | 
| 26 | 
            +
                it { should === 12 }
         | 
| 27 | 
            +
                it { should === branch }
         | 
| 28 | 
            +
                it { should === leaf }
         | 
| 29 | 
            +
              end
         | 
| 30 | 
            +
              
         | 
| 31 | 
            +
              context("when called with '*'") do
         | 
| 32 | 
            +
                subject{ CodeTree::Rewriting::Rewriter::Match.coerce("*", nil) }
         | 
| 33 | 
            +
                
         | 
| 34 | 
            +
                it { should_not === 12 }
         | 
| 35 | 
            +
                it { should === branch }
         | 
| 36 | 
            +
                it { should_not === leaf }
         | 
| 37 | 
            +
              end
         | 
| 38 | 
            +
              
         | 
| 39 | 
            +
              context("when called with '@*'") do
         | 
| 40 | 
            +
                subject{ CodeTree::Rewriting::Rewriter::Match.coerce("@*", nil) }
         | 
| 41 | 
            +
                
         | 
| 42 | 
            +
                it { should_not === 12 }
         | 
| 43 | 
            +
                it { should_not === branch }
         | 
| 44 | 
            +
                it { should === leaf }
         | 
| 45 | 
            +
              end
         | 
| 46 | 
            +
              
         | 
| 47 | 
            +
            end
         | 
| 48 | 
            +
              
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            require File.expand_path('../../../../../../spec_helper', __FILE__)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            describe "CodeTree::Rewriting::Rewriter::Match#matches?" do
         | 
| 4 | 
            +
              
         | 
| 5 | 
            +
              let(:branch)  { CodeTree::AstNode.new(:branch, [1, 2, 3]) }
         | 
| 6 | 
            +
              let(:literal) { CodeTree::AstNode.coerce(12) }
         | 
| 7 | 
            +
              
         | 
| 8 | 
            +
              context "when built with a symbol" do
         | 
| 9 | 
            +
                subject { CodeTree::Rewriting::Rewriter::Match.coerce(:_, nil) }
         | 
| 10 | 
            +
                specify { 
         | 
| 11 | 
            +
                  (subject.matches? branch).should be_false
         | 
| 12 | 
            +
                  (subject.matches? literal).should be_true
         | 
| 13 | 
            +
                  (subject === branch).should be_false
         | 
| 14 | 
            +
                  (subject === literal).should be_true
         | 
| 15 | 
            +
                }
         | 
| 16 | 
            +
              end
         | 
| 17 | 
            +
              
         | 
| 18 | 
            +
              context "when built with a proc" do
         | 
| 19 | 
            +
                let(:proc) { lambda {|node| node.name == :branch } }
         | 
| 20 | 
            +
                subject { CodeTree::Rewriting::Rewriter::Match.coerce(proc, nil) }
         | 
| 21 | 
            +
                specify { 
         | 
| 22 | 
            +
                  (subject.matches? branch).should be_true
         | 
| 23 | 
            +
                  (subject.matches? literal).should be_false
         | 
| 24 | 
            +
                }
         | 
| 25 | 
            +
              end
         | 
| 26 | 
            +
              
         | 
| 27 | 
            +
            end
         |