sbyc 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. data/lib/sbyc.rb +1 -1
  2. data/lib/sbyc/codetree.rb +9 -6
  3. data/lib/sbyc/codetree/ast_node.rb +39 -4
  4. data/lib/sbyc/codetree/eval/functional_eval.rb +1 -1
  5. data/lib/sbyc/codetree/eval/object_eval.rb +1 -1
  6. data/lib/sbyc/codetree/name2x.rb +2 -0
  7. data/lib/sbyc/codetree/name2x/delegate.rb +57 -0
  8. data/lib/sbyc/codetree/name2x/module_delegate.rb +25 -0
  9. data/lib/sbyc/codetree/proc_parser.rb +46 -14
  10. data/lib/sbyc/codetree/producing.rb +2 -1
  11. data/lib/sbyc/codetree/producing/producer.rb +12 -0
  12. data/lib/sbyc/codetree/producing/tracing_methods.rb +77 -0
  13. data/test/spec/unit/sbyc/codetree/ast_node/code_inject.spec +57 -0
  14. data/test/spec/unit/sbyc/codetree/ast_node/digest.spec +83 -0
  15. data/test/spec/unit/sbyc/codetree/ast_node/rename.spec +36 -0
  16. data/test/spec/unit/sbyc/codetree/ast_node/to_s.spec +1 -1
  17. data/test/spec/unit/sbyc/codetree/ast_node/visit.spec +2 -2
  18. data/test/spec/unit/sbyc/codetree/name2x/delegate/coerce.spec +38 -0
  19. data/test/spec/unit/sbyc/codetree/name2x/delegate/fetch.spec +15 -0
  20. data/test/spec/unit/sbyc/codetree/name2x/delegate/name2class.spec +31 -0
  21. data/test/spec/unit/sbyc/codetree/name2x/delegate/name2module.spec +31 -0
  22. data/test/spec/unit/sbyc/codetree/name2x/delegate/name2name.spec +31 -0
  23. data/test/spec/unit/sbyc/codetree/name2x/module_delegate/name2class.spec +27 -0
  24. data/test/spec/unit/sbyc/codetree/name2x/module_delegate/name2module.spec +22 -0
  25. data/test/spec/unit/sbyc/codetree/name2x/module_delegate/name2name.spec +18 -0
  26. data/test/spec/unit/sbyc/codetree/parse.spec +32 -0
  27. data/test/spec/unit/sbyc/codetree/proc_parser/expr.spec +1 -1
  28. data/test/spec/unit/sbyc/codetree/proc_parser/parse.spec +34 -1
  29. data/test/spec/unit/sbyc/codetree/producing/producer/add_extension.spec +62 -0
  30. data/test/spec/unit/sbyc/codetree/producing/tracing_methods.spec +36 -0
  31. data/test/spec/unit/sbyc/codetree/producing/tracing_methods/default_options.spec +10 -0
  32. data/test/spec/unit/sbyc/codetree/producing/tracing_methods/prepare_options.spec +18 -0
  33. data/test/spec/unit/sbyc/codetree/producing/tracing_methods/trace.spec +59 -0
  34. data/test/spec/unit/sbyc/codetree/producing/tracing_methods/trace_rule_entered.spec +25 -0
  35. data/test/spec/unit/sbyc/codetree/producing/tracing_methods/trace_rule_exited.spec +25 -0
  36. metadata +27 -4
@@ -0,0 +1,57 @@
1
+ require File.expand_path('../../../../../spec_helper', __FILE__)
2
+
3
+ describe "CodeTree::AstNode#code_inject!" do
4
+
5
+ module CodeTreeAstNodeCodeInject
6
+ module Hello; end
7
+ module Capitalize; end
8
+ module Varref; end
9
+ end
10
+
11
+ let(:parsed) { CodeTree.parse{ (hello (capitalize name)) }.rename!(CodeTree::OPERATOR_NAMES) }
12
+
13
+ context "When called with a map" do
14
+ let(:map_arg) { {:varref => CodeTreeAstNodeCodeInject::Varref,
15
+ :hello => CodeTreeAstNodeCodeInject::Hello,
16
+ :capitalize => CodeTreeAstNodeCodeInject::Capitalize} }
17
+ subject{ parsed.code_inject!(map_arg) }
18
+ it { should == parsed }
19
+ it { should be_kind_of(CodeTreeAstNodeCodeInject::Hello) }
20
+ specify {
21
+ subject.children[0].should be_kind_of(CodeTreeAstNodeCodeInject::Capitalize)
22
+ subject.children[0].children[0].should be_kind_of(CodeTreeAstNodeCodeInject::Varref)
23
+ }
24
+ end
25
+
26
+ context "When called with a proc" do
27
+ subject{ parsed.code_inject!{|name|
28
+ case name
29
+ when :varref
30
+ CodeTreeAstNodeCodeInject::Varref
31
+ when :hello
32
+ CodeTreeAstNodeCodeInject::Hello
33
+ when :capitalize
34
+ CodeTreeAstNodeCodeInject::Capitalize
35
+ end
36
+ } }
37
+ it { should == parsed }
38
+ it { should be_kind_of(CodeTreeAstNodeCodeInject::Hello) }
39
+ specify {
40
+ subject.children[0].should be_kind_of(CodeTreeAstNodeCodeInject::Capitalize)
41
+ subject.children[0].children[0].should be_kind_of(CodeTreeAstNodeCodeInject::Varref)
42
+ }
43
+ end
44
+
45
+ context "When called with a module" do
46
+ let(:map_arg){ CodeTreeAstNodeCodeInject }
47
+ subject{ parsed.code_inject!(map_arg) }
48
+ it { should == parsed }
49
+ it { should be_kind_of(CodeTreeAstNodeCodeInject::Hello) }
50
+ specify {
51
+ subject.children[0].should be_kind_of(CodeTreeAstNodeCodeInject::Capitalize)
52
+ subject.children[0].children[0].should be_kind_of(CodeTreeAstNodeCodeInject::Varref)
53
+ }
54
+ end
55
+
56
+ end
57
+
@@ -0,0 +1,83 @@
1
+ require File.expand_path('../../../../../spec_helper', __FILE__)
2
+
3
+ describe "CodeTree::AstNode#digest" do
4
+
5
+ module CodeTreeAstNodeDigestTest
6
+ class Dyadic
7
+ attr_reader :left, :right
8
+ def initialize(left, right)
9
+ @left, @right = left, right
10
+ end
11
+ end
12
+ class And < Dyadic; end
13
+ class Or < Dyadic; end
14
+ class Complement
15
+ attr_reader :term
16
+ def initialize(term)
17
+ @term = term
18
+ end
19
+ end
20
+ class Varref
21
+ attr_reader :varname
22
+ def initialize(varname)
23
+ @varname = varname
24
+ end
25
+ end
26
+ end
27
+
28
+ context "when called with a hash" do
29
+ let(:parsed) { CodeTree.parse{ ~(a & (b | c)) } }
30
+ subject{ parsed.digest(:'?' => CodeTreeAstNodeDigestTest::Varref,
31
+ :& => CodeTreeAstNodeDigestTest::And,
32
+ :| => CodeTreeAstNodeDigestTest::Or,
33
+ :~ => CodeTreeAstNodeDigestTest::Complement) }
34
+ it { should be_kind_of(CodeTreeAstNodeDigestTest::Complement) }
35
+ specify {
36
+ subject.term.should be_kind_of(CodeTreeAstNodeDigestTest::And)
37
+ subject.term.left.should be_kind_of(CodeTreeAstNodeDigestTest::Varref)
38
+ subject.term.left.varname.should == :a
39
+ subject.term.right.should be_kind_of(CodeTreeAstNodeDigestTest::Or)
40
+ subject.term.right.left.should be_kind_of(CodeTreeAstNodeDigestTest::Varref)
41
+ }
42
+ end
43
+
44
+ context "when called with a proc" do
45
+ let(:parsed) { CodeTree.parse{ ~(a & (b | c)) } }
46
+ subject{ parsed.digest{|name|
47
+ case name
48
+ when :'?'
49
+ CodeTreeAstNodeDigestTest::Varref
50
+ when :&
51
+ CodeTreeAstNodeDigestTest::And
52
+ when :|
53
+ CodeTreeAstNodeDigestTest::Or
54
+ when :~
55
+ CodeTreeAstNodeDigestTest::Complement
56
+ end
57
+ } }
58
+ it { should be_kind_of(CodeTreeAstNodeDigestTest::Complement) }
59
+ specify {
60
+ subject.term.should be_kind_of(CodeTreeAstNodeDigestTest::And)
61
+ subject.term.left.should be_kind_of(CodeTreeAstNodeDigestTest::Varref)
62
+ subject.term.left.varname.should == :a
63
+ subject.term.right.should be_kind_of(CodeTreeAstNodeDigestTest::Or)
64
+ subject.term.right.left.should be_kind_of(CodeTreeAstNodeDigestTest::Varref)
65
+ }
66
+ end
67
+
68
+ context "when called with a module" do
69
+ let(:parsed) { CodeTree.parse{ ~(a & (b | c)) } }
70
+ let(:renamed) { parsed.rename!(CodeTree::OPERATOR_NAMES) }
71
+ subject{ renamed.digest(CodeTreeAstNodeDigestTest) }
72
+ it { should be_kind_of(CodeTreeAstNodeDigestTest::Complement) }
73
+ specify {
74
+ subject.term.should be_kind_of(CodeTreeAstNodeDigestTest::And)
75
+ subject.term.left.should be_kind_of(CodeTreeAstNodeDigestTest::Varref)
76
+ subject.term.left.varname.should == :a
77
+ subject.term.right.should be_kind_of(CodeTreeAstNodeDigestTest::Or)
78
+ subject.term.right.left.should be_kind_of(CodeTreeAstNodeDigestTest::Varref)
79
+ }
80
+ end
81
+
82
+ end
83
+
@@ -0,0 +1,36 @@
1
+ require File.expand_path('../../../../../spec_helper', __FILE__)
2
+
3
+ describe "CodeTree::AstNode#rename" do
4
+
5
+ let(:expr){ CodeTree::parse{ ~(a & (b | c)) } }
6
+
7
+ context "When called with CodeTree::OPERATOR_NAMES" do
8
+ subject{ expr.rename!(CodeTree::OPERATOR_NAMES) }
9
+ it { should == expr }
10
+ specify { subject.to_s.should == "(complement (and (varref :a), (or (varref :b), (varref :c))))" }
11
+ end
12
+
13
+ context "When called with a hash" do
14
+ subject{ expr.rename!(:~ => :not, :& => :and, :| => :or, :'?' => :varref) }
15
+ it { should == expr }
16
+ specify { subject.to_s.should == "(not (and (varref :a), (or (varref :b), (varref :c))))" }
17
+ end
18
+
19
+ context "When called with a proc" do
20
+ subject{ expr.rename!{|name|
21
+ case name
22
+ when :~
23
+ :not
24
+ when :&
25
+ :and
26
+ when :|
27
+ :or
28
+ when :'?'
29
+ :varref
30
+ end
31
+ }}
32
+ it { should == expr }
33
+ specify { subject.to_s.should == "(not (and (varref :a), (or (varref :b), (varref :c))))" }
34
+ end
35
+
36
+ end
@@ -1,6 +1,6 @@
1
1
  require File.expand_path('../../../../../spec_helper', __FILE__)
2
2
 
3
- describe "CodeTree::AstNode#inspect" do
3
+ describe "CodeTree::AstNode#to_s" do
4
4
 
5
5
  subject{ node.to_s }
6
6
 
@@ -1,6 +1,6 @@
1
1
  require File.expand_path('../../../../../spec_helper', __FILE__)
2
2
 
3
- describe "CodeTree::AstNode#functional_eval" do
3
+ describe "CodeTree::AstNode#visit" do
4
4
 
5
5
  context('when called on a leaf node, through coercion') do
6
6
  let(:node) { CodeTree::AstNode.coerce(12) }
@@ -17,7 +17,7 @@ describe "CodeTree::AstNode#functional_eval" do
17
17
  context('when called for productions') do
18
18
  let(:node) { CodeTree::parse{ (say x, "Hello") } }
19
19
  subject {
20
- node.produce{|n, collected|
20
+ node.visit{|n, collected|
21
21
  case n.function
22
22
  when :'_'
23
23
  collected.first.inspect
@@ -0,0 +1,38 @@
1
+ require File.expand_path('../../../../../../spec_helper', __FILE__)
2
+
3
+ describe "CodeTree::Name2X::Delegate.coerce" do
4
+
5
+ subject{ CodeTree::Name2X::Delegate::coerce(arg) }
6
+
7
+ context "When called on a Delegate instance" do
8
+ let(:arg) { CodeTree::Name2X::Delegate.new({}) }
9
+ it { should be_kind_of(CodeTree::Name2X::Delegate) }
10
+ end
11
+
12
+ context "When called on a hash" do
13
+ let(:arg) { Hash.new }
14
+ it { should be_kind_of(CodeTree::Name2X::Delegate) }
15
+ end
16
+
17
+ context "When called on a proc" do
18
+ let(:arg) { Kernel.proc{|x| x} }
19
+ it { should be_kind_of(CodeTree::Name2X::Delegate) }
20
+ end
21
+
22
+ context "When called on a module" do
23
+ let(:arg) { CodeTree }
24
+ it { should be_kind_of(CodeTree::Name2X::Delegate) }
25
+ end
26
+
27
+ context "When called on an object responding to :[]" do
28
+ let(:arg) { o = Object.new; def o.[](name); end; o; }
29
+ it { should be_kind_of(CodeTree::Name2X::Delegate) }
30
+ end
31
+
32
+ context "When called on something else" do
33
+ let(:arg) { Object.new }
34
+ subject{ lambda{ CodeTree::Name2X::Delegate::coerce(arg) } }
35
+ it { should raise_error(ArgumentError) }
36
+ end
37
+
38
+ end
@@ -0,0 +1,15 @@
1
+ require File.expand_path('../../../../../../spec_helper', __FILE__)
2
+
3
+ describe "CodeTree::Name2X::Delegate#fetch" do
4
+
5
+ let(:hash){ {:to_name => :name,
6
+ :to_module => CodeTree,
7
+ :to_class => Class.new} }
8
+
9
+ let(:delegate){ CodeTree::Name2X::Delegate.new(hash) }
10
+
11
+ subject{ delegate.fetch(:to_module) }
12
+
13
+ it { should == CodeTree }
14
+
15
+ end
@@ -0,0 +1,31 @@
1
+ require File.expand_path('../../../../../../spec_helper', __FILE__)
2
+
3
+ describe "CodeTree::Name2X::Delegate#name2class" do
4
+
5
+ let(:hash){ {:to_name => :name,
6
+ :to_module => CodeTree,
7
+ :to_class => CodeTree::AstNode} }
8
+
9
+ let(:delegate){ CodeTree::Name2X::Delegate.new(hash) }
10
+
11
+ describe "when called with a target module" do
12
+ subject{ delegate.name2class(:to_module) }
13
+ it { should be_nil }
14
+ end
15
+
16
+ describe "when called with a target class" do
17
+ subject{ delegate.name2class(:to_class) }
18
+ it { should == CodeTree::AstNode }
19
+ end
20
+
21
+ describe "when called on something else" do
22
+ subject{ delegate.name2class(:to_name) }
23
+ it { should be_nil }
24
+ end
25
+
26
+ describe "when called on unexisting" do
27
+ subject{ delegate.name2class(:not_exists) }
28
+ it { should be_nil }
29
+ end
30
+
31
+ end
@@ -0,0 +1,31 @@
1
+ require File.expand_path('../../../../../../spec_helper', __FILE__)
2
+
3
+ describe "CodeTree::Name2X::Delegate#name2module" do
4
+
5
+ let(:hash){ {:to_name => :name,
6
+ :to_module => CodeTree,
7
+ :to_class => CodeTree::AstNode} }
8
+
9
+ let(:delegate){ CodeTree::Name2X::Delegate.new(hash) }
10
+
11
+ describe "when called with a target module" do
12
+ subject{ delegate.name2module(:to_module) }
13
+ it { should == CodeTree }
14
+ end
15
+
16
+ describe "when called with a target module, through a class" do
17
+ subject{ delegate.name2module(:to_class) }
18
+ it { should == CodeTree::AstNode }
19
+ end
20
+
21
+ describe "when called on something else" do
22
+ subject{ delegate.name2module(:to_name) }
23
+ it { should be_nil }
24
+ end
25
+
26
+ describe "when called on unexisting" do
27
+ subject{ delegate.name2module(:not_exists) }
28
+ it { should be_nil }
29
+ end
30
+
31
+ end
@@ -0,0 +1,31 @@
1
+ require File.expand_path('../../../../../../spec_helper', __FILE__)
2
+
3
+ describe "CodeTree::Name2X::Delegate#name2name" do
4
+
5
+ let(:hash){ {:to_name => :name,
6
+ :to_module => CodeTree,
7
+ :to_class => CodeTree::AstNode} }
8
+
9
+ let(:delegate){ CodeTree::Name2X::Delegate.new(hash) }
10
+
11
+ describe "when called with a target module" do
12
+ subject{ delegate.name2name(:to_module) }
13
+ it { should be_nil }
14
+ end
15
+
16
+ describe "when called with a target class" do
17
+ subject{ delegate.name2name(:to_class) }
18
+ it { should be_nil }
19
+ end
20
+
21
+ describe "when called with a target Symbol" do
22
+ subject{ delegate.name2name(:to_name) }
23
+ it { should == :name }
24
+ end
25
+
26
+ describe "when called on unexisting" do
27
+ subject{ delegate.name2name(:not_exists) }
28
+ it { should be_nil }
29
+ end
30
+
31
+ end
@@ -0,0 +1,27 @@
1
+ require File.expand_path('../../../../../../spec_helper', __FILE__)
2
+
3
+ describe "CodeTree::Name2X::ModuleDelegate#name2class" do
4
+
5
+ let(:delegate){ CodeTree::Name2X::ModuleDelegate.new(CodeTree) }
6
+
7
+ describe "when called on some valid capitalized target" do
8
+ subject{ delegate.name2class(:AstNode) }
9
+ it { should == CodeTree::AstNode }
10
+ end
11
+
12
+ describe "when called on some valid non-capitalized target" do
13
+ subject{ delegate.name2class(:astNode) }
14
+ it { should == CodeTree::AstNode }
15
+ end
16
+
17
+ describe "when called on some valid non-capitalized target with underscores" do
18
+ subject{ delegate.name2class(:ast_node) }
19
+ it { should == CodeTree::AstNode }
20
+ end
21
+
22
+ describe "when called with no such target" do
23
+ subject{ delegate.name2module(:nosuchone) }
24
+ it { should be_nil }
25
+ end
26
+
27
+ end
@@ -0,0 +1,22 @@
1
+ require File.expand_path('../../../../../../spec_helper', __FILE__)
2
+
3
+ describe "CodeTree::Name2X::ModuleDelegate#name2module" do
4
+
5
+ let(:delegate){ CodeTree::Name2X::ModuleDelegate.new(CodeTree) }
6
+
7
+ describe "when called on some valid capitalized target" do
8
+ subject{ delegate.name2module(:Producing) }
9
+ it { should == CodeTree::Producing }
10
+ end
11
+
12
+ describe "when called on some valid non-capitalized target" do
13
+ subject{ delegate.name2module(:producing) }
14
+ it { should == CodeTree::Producing }
15
+ end
16
+
17
+ describe "when called with no such target" do
18
+ subject{ delegate.name2module(:nosuchone) }
19
+ it { should be_nil }
20
+ end
21
+
22
+ end
@@ -0,0 +1,18 @@
1
+ require File.expand_path('../../../../../../spec_helper', __FILE__)
2
+
3
+ describe "CodeTree::Name2X::ModuleDelegate#name2name" do
4
+
5
+ let(:delegate){ CodeTree::Name2X::ModuleDelegate.new(CodeTree) }
6
+
7
+ [ [:Producing, :Producing],
8
+ [:producing, :Producing],
9
+ [:AstNode, :AstNode],
10
+ [:astNode, :AstNode],
11
+ [:ast_node, :AstNode] ].each do |source, expected|
12
+ describe "when called on #{source}, should return #{expected}" do
13
+ subject{ delegate.name2name(source) }
14
+ it { should == expected }
15
+ end
16
+ end
17
+
18
+ end
@@ -0,0 +1,32 @@
1
+ require File.expand_path('../../../../spec_helper', __FILE__)
2
+ describe "CodeTree::parse" do
3
+
4
+ let(:code) { lambda {
5
+ (puts (to_s x))
6
+ (say "hello")
7
+ } }
8
+ let(:expected){ ["(puts (to_s (? (_ :x))))", '(say (_ "hello"))'] }
9
+
10
+ context "when called with a multiline option and proc as first" do
11
+ subject { CodeTree::parse(code, :multiline => true) }
12
+ specify{
13
+ subject.collect{|s| s.inspect}.should == expected
14
+ }
15
+ end
16
+
17
+ context "when called with a multiline option and proc as block, with nil as first" do
18
+ subject { CodeTree::parse(nil, :multiline => true, &code) }
19
+ specify{
20
+ subject.collect{|s| s.inspect}.should == expected
21
+ }
22
+ end
23
+
24
+ context "when called with a multiline option and proc as block, and nothing as first" do
25
+ subject { CodeTree::parse(:multiline => true, &code) }
26
+ specify{
27
+ subject.collect{|s| s.inspect}.should == expected
28
+ }
29
+ end
30
+
31
+ end
32
+