sbyc 0.1.0 → 0.1.1

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.
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
+