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,30 @@
|
|
1
|
+
require File.expand_path('../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::AstNode#functional_compile" do
|
4
|
+
|
5
|
+
context('when called on a leaf node') do
|
6
|
+
let(:node) { CodeTree::expr{ 12 } }
|
7
|
+
subject{ node.functional_compile }
|
8
|
+
it { should == "12" }
|
9
|
+
end
|
10
|
+
|
11
|
+
context('when called on a ?') do
|
12
|
+
let(:node) { CodeTree::expr{ x } }
|
13
|
+
subject{ node.functional_compile }
|
14
|
+
it { should == "scope[:x]" }
|
15
|
+
end
|
16
|
+
|
17
|
+
context('when called on a object-like expression') do
|
18
|
+
let(:node) { CodeTree::expr{ (say x, "Hello") } }
|
19
|
+
subject{ node.functional_compile }
|
20
|
+
it { should == 'receiver.say(scope[:x], "Hello")' }
|
21
|
+
end
|
22
|
+
|
23
|
+
context('when called with specific arguments') do
|
24
|
+
let(:node) { CodeTree::expr{ (say x, "Hello") } }
|
25
|
+
subject{ node.functional_compile('r', 'hash', 'get') }
|
26
|
+
it { should == 'r.say(hash.get(:x), "Hello")' }
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.expand_path('../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::AstNode#functional_eval" do
|
4
|
+
|
5
|
+
context('when called on a leaf node') do
|
6
|
+
let(:node) { CodeTree::expr{ 12 } }
|
7
|
+
subject{ node.functional_eval(Kernel, { }) }
|
8
|
+
it { should == 12 }
|
9
|
+
end
|
10
|
+
|
11
|
+
context('when called on a ?') do
|
12
|
+
let(:node) { CodeTree::expr{ x } }
|
13
|
+
subject{ node.functional_eval(Kernel, :x => 12) }
|
14
|
+
it { should == 12 }
|
15
|
+
end
|
16
|
+
|
17
|
+
context('when called on a object-like expression') do
|
18
|
+
let(:node) { CodeTree::expr{ (say x, "You") } }
|
19
|
+
let(:master) { x = Object.new; def x.say(*args); args.join(" "); end; x}
|
20
|
+
|
21
|
+
subject{ node.functional_eval(master, :x => "hello") }
|
22
|
+
|
23
|
+
it { subject.should == "hello You" }
|
24
|
+
end
|
25
|
+
|
26
|
+
context('when called on a object-like expression with specific scope method') do
|
27
|
+
let(:node) { CodeTree::expr{ (say x, "You") } }
|
28
|
+
let(:master) { x = Object.new; def x.say(*args); args.join(" "); end; x}
|
29
|
+
subject{ node.functional_eval(master, {:x => "hello"}, :fetch) }
|
30
|
+
it { subject.should == "hello You" }
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.expand_path('../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::AstNode#functional_proc" do
|
4
|
+
|
5
|
+
let(:receiver) {
|
6
|
+
o = Object.new
|
7
|
+
def o.upcase(x); x.upcase; end
|
8
|
+
o
|
9
|
+
}
|
10
|
+
|
11
|
+
context('when called on a leaf node') do
|
12
|
+
let(:node) { CodeTree::expr{ 12 } }
|
13
|
+
subject{ node.functional_proc.call(nil, nil) }
|
14
|
+
it { should == 12 }
|
15
|
+
end
|
16
|
+
|
17
|
+
context('when called on a ?') do
|
18
|
+
let(:node) { CodeTree::expr{ x } }
|
19
|
+
subject{ node.functional_proc.call(receiver, :x => "hello") }
|
20
|
+
it { should == "hello" }
|
21
|
+
end
|
22
|
+
|
23
|
+
context('when called on a object-like expression') do
|
24
|
+
let(:node) { CodeTree::expr{ (upcase x) } }
|
25
|
+
subject{ node.functional_proc.call(receiver, :x => "hello") }
|
26
|
+
it { should == 'HELLO' }
|
27
|
+
end
|
28
|
+
|
29
|
+
context('when called with specific arguments') do
|
30
|
+
let(:node) { CodeTree::expr{ (upcase x) } }
|
31
|
+
subject{ node.functional_proc(:fetch).call(receiver, :x => "hello") }
|
32
|
+
it { should == 'HELLO' }
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.expand_path('../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::AstNode#object_compile" do
|
4
|
+
|
5
|
+
context('when called on a leaf node, through coercion') do
|
6
|
+
let(:node) { CodeTree::expr{ 12 } }
|
7
|
+
subject{ node.object_compile }
|
8
|
+
it { should == "12" }
|
9
|
+
end
|
10
|
+
|
11
|
+
context('when called on a ?') do
|
12
|
+
let(:node) { CodeTree::expr{ x } }
|
13
|
+
subject{ node.object_compile }
|
14
|
+
it { should == "scope[:x]" }
|
15
|
+
end
|
16
|
+
|
17
|
+
context('when called on an expression') do
|
18
|
+
let(:node) { CodeTree::expr{ x + z } }
|
19
|
+
subject{ node.object_compile }
|
20
|
+
it { should == "scope[:x].+(scope[:z])" }
|
21
|
+
end
|
22
|
+
|
23
|
+
context('when called on a object-like expression') do
|
24
|
+
let(:node) { CodeTree::expr{ x.say_hello } }
|
25
|
+
subject{ node.object_compile }
|
26
|
+
it { should == "scope[:x].say_hello()" }
|
27
|
+
end
|
28
|
+
|
29
|
+
context('when called with specific arguments') do
|
30
|
+
let(:node) { CodeTree::expr{ x.say_hello } }
|
31
|
+
subject{ node.object_compile('hash', :get) }
|
32
|
+
it { should == "hash.get(:x).say_hello()"}
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require File.expand_path('../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::AstNode#object_eval" do
|
4
|
+
|
5
|
+
context('when called on a leaf node, through coercion') do
|
6
|
+
let(:node) { CodeTree::expr{ 12 } }
|
7
|
+
subject{ node.object_eval }
|
8
|
+
it { should == 12 }
|
9
|
+
end
|
10
|
+
|
11
|
+
context('when called on a ?') do
|
12
|
+
let(:node) { CodeTree::expr{ x } }
|
13
|
+
subject{ node.object_eval(:x => 12) }
|
14
|
+
it { should == 12 }
|
15
|
+
end
|
16
|
+
|
17
|
+
context('when called on an expression') do
|
18
|
+
let(:node) { CodeTree::expr{ x + z } }
|
19
|
+
subject{ node.object_eval(:x => 12, :z => 15) }
|
20
|
+
it { should == 27 }
|
21
|
+
end
|
22
|
+
|
23
|
+
context('when called on a object-like expression') do
|
24
|
+
let(:node) { CodeTree::expr{ x.say_hello } }
|
25
|
+
let(:twel) { x = Object.new; def x.say_hello(); "hello"; end; x}
|
26
|
+
subject{ node.object_eval(:x => twel) }
|
27
|
+
it { should == "hello" }
|
28
|
+
end
|
29
|
+
|
30
|
+
context('when called on a object-like expression and specific scope method') do
|
31
|
+
let(:node) { CodeTree::expr{ x.say_hello } }
|
32
|
+
let(:twel) { x = Object.new; def x.say_hello(); "hello"; end; x}
|
33
|
+
subject{ node.object_eval({:x => twel}, :fetch) }
|
34
|
+
it { should == "hello" }
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require File.expand_path('../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::AstNode#object_proc" do
|
4
|
+
|
5
|
+
context('when called on a leaf node, through coercion') do
|
6
|
+
let(:node) { CodeTree::expr{ 12 } }
|
7
|
+
subject{ node.object_proc.call(nil) }
|
8
|
+
it { should == 12 }
|
9
|
+
end
|
10
|
+
|
11
|
+
context('when called on a ?') do
|
12
|
+
let(:node) { CodeTree::expr{ x } }
|
13
|
+
subject{ node.object_proc.call(:x => 12) }
|
14
|
+
it { should == 12 }
|
15
|
+
end
|
16
|
+
|
17
|
+
context('when called on an expression') do
|
18
|
+
let(:node) { CodeTree::expr{ x + z } }
|
19
|
+
subject{ node.object_proc.call(:x => 12, :z => 15) }
|
20
|
+
it { should == 27 }
|
21
|
+
end
|
22
|
+
|
23
|
+
context('when called on a object-like expression') do
|
24
|
+
let(:node) { CodeTree::expr{ x.upcase } }
|
25
|
+
subject{ node.object_proc.call(:x => "teller") }
|
26
|
+
it { should == "TELLER" }
|
27
|
+
end
|
28
|
+
|
29
|
+
context('when called with specific arguments') do
|
30
|
+
let(:node) { CodeTree::expr{ x.upcase } }
|
31
|
+
subject{ node.object_proc(:fetch).call(:x => "teller") }
|
32
|
+
it { should == "TELLER"}
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require File.expand_path('../../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::Matcher#args_match" do
|
4
|
+
|
5
|
+
let(:imatch) { CodeTree::Matcher.new nil }
|
6
|
+
|
7
|
+
context "when called with a capture match" do
|
8
|
+
let(:matcher) { CodeTree::parse{ x } }
|
9
|
+
let(:matched) { CodeTree::parse{ 12 } }
|
10
|
+
let(:match_data) { { } }
|
11
|
+
let(:subject) { imatch.args_match([ matcher ], [ matched ], match_data)}
|
12
|
+
|
13
|
+
specify {
|
14
|
+
subject.should be_true
|
15
|
+
match_data[:x].should == matched
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when called with a literal match" do
|
20
|
+
let(:matcher) { CodeTree::parse{ 12 } }
|
21
|
+
let(:matched) { CodeTree::parse{ 12 } }
|
22
|
+
let(:match_data) { { } }
|
23
|
+
let(:subject) { imatch.args_match([ matcher ], [ matched ], match_data)}
|
24
|
+
|
25
|
+
specify { subject.should be_true }
|
26
|
+
end
|
27
|
+
|
28
|
+
context "when called with a literal no-match" do
|
29
|
+
let(:matcher) { CodeTree::parse{ 13 } }
|
30
|
+
let(:matched) { CodeTree::parse{ 12 } }
|
31
|
+
let(:match_data) { { } }
|
32
|
+
let(:subject) { imatch.args_match([ matcher ], [ matched ], match_data)}
|
33
|
+
|
34
|
+
specify { subject.should be_false }
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when called with a recursive match" do
|
38
|
+
let(:matcher) { CodeTree::parse{ (match :hello, x) } }
|
39
|
+
let(:matched) { CodeTree::parse{ (hello "You") } }
|
40
|
+
let(:match_data) { { } }
|
41
|
+
let(:subject) { imatch.args_match([ matcher ], [ matched ], match_data)}
|
42
|
+
|
43
|
+
specify {
|
44
|
+
subject.should be_true
|
45
|
+
match_data[:x].should == CodeTree::parse{ "You" }
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
context "when called with a recursive match with varargs and one arg" do
|
50
|
+
let(:matcher) { CodeTree::parse{ (match :hello, x[]) } }
|
51
|
+
let(:matched) { CodeTree::parse{ (hello "You") } }
|
52
|
+
let(:match_data) { { } }
|
53
|
+
let(:subject) { imatch.args_match([ matcher ], [ matched ], match_data)}
|
54
|
+
|
55
|
+
specify {
|
56
|
+
subject.should be_true
|
57
|
+
match_data[:x].should == [ CodeTree::parse{ "You"} ]
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when called with a recursive match with varargs and many args" do
|
62
|
+
let(:matcher) { CodeTree::parse{ (match :hello, x[]) } }
|
63
|
+
let(:matched) { CodeTree::parse{ (hello "You", "and", 'world') } }
|
64
|
+
let(:match_data) { { } }
|
65
|
+
let(:subject) { imatch.args_match([ matcher ], [ matched ], match_data)}
|
66
|
+
|
67
|
+
specify {
|
68
|
+
subject.should be_true
|
69
|
+
match_data[:x].should == [ CodeTree::parse{ "You"}, CodeTree::parse{ "and"}, CodeTree::parse{ "world"} ]
|
70
|
+
}
|
71
|
+
end
|
72
|
+
|
73
|
+
context "when called with a recursive no-match with empty varargs" do
|
74
|
+
let(:matcher) { CodeTree::parse{ (match :hello, x, y[]) } }
|
75
|
+
let(:matched) { CodeTree::parse{ (hello "You") } }
|
76
|
+
let(:match_data) { { } }
|
77
|
+
let(:subject) { imatch.args_match([ matcher ], [ matched ], match_data)}
|
78
|
+
|
79
|
+
specify { subject.should be_false }
|
80
|
+
end
|
81
|
+
|
82
|
+
context "when called with a recursive no-match" do
|
83
|
+
let(:matcher) { CodeTree::parse{ (match :hello, "world") } }
|
84
|
+
let(:matched) { CodeTree::parse{ (hello 12) } }
|
85
|
+
let(:match_data) { { } }
|
86
|
+
let(:subject) { imatch.args_match([ matcher ], [ matched ], match_data)}
|
87
|
+
|
88
|
+
specify { subject.should be_false }
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require File.expand_path('../../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::Matcher#match" do
|
4
|
+
|
5
|
+
context 'When capture are provided' do
|
6
|
+
let(:matcher) { CodeTree::parse{ (match :hello, (match :whos, x, y)) } }
|
7
|
+
let(:matched) { CodeTree::parse{ (hello (whos "world", "others")) } }
|
8
|
+
let(:subject) { CodeTree::Matcher.new(matcher) =~ matched }
|
9
|
+
specify {
|
10
|
+
subject[:x].literal.should == "world"
|
11
|
+
subject[:y].literal.should == "others"
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
context "When applying correct matches" do
|
16
|
+
[
|
17
|
+
[CodeTree::parse{ (match :hello, "world") }, CodeTree::parse{ (hello "world") }],
|
18
|
+
[CodeTree::parse{ (match :hello, x) }, CodeTree::parse{ (hello "world") }],
|
19
|
+
[CodeTree::parse{ (match :hello, x, y, z) }, CodeTree::parse{ (hello "world", "and", "others") }],
|
20
|
+
[CodeTree::parse{ (match :hello, (match :world, x)) }, CodeTree::parse{ (hello (world "I")) }],
|
21
|
+
].each do |matcher, matched|
|
22
|
+
let(:subject){ CodeTree::Matcher.new(matcher) =~ matched }
|
23
|
+
it { should_not be_nil }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "When applying incorrect matches" do
|
28
|
+
[
|
29
|
+
[CodeTree::parse{ (match :hello, "world") }, CodeTree::parse{ (hello 12) }],
|
30
|
+
[CodeTree::parse{ (match :hello, "world") }, CodeTree::parse{ (hello "world", "and", "others") }],
|
31
|
+
[CodeTree::parse{ (match :hello, (match :world, x)) }, CodeTree::parse{ (hello "world") }],
|
32
|
+
].each do |matcher, matched|
|
33
|
+
let(:subject){ CodeTree::Matcher.new(matcher) =~ matched }
|
34
|
+
it { should be_nil }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require File.expand_path('../../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::Matcher#function_match" do
|
4
|
+
|
5
|
+
context "called with a literal match" do
|
6
|
+
let(:match) { CodeTree::parse{ (match :hello) } }
|
7
|
+
let(:victim) { CodeTree::parse{ (hello "world") } }
|
8
|
+
let(:match_data) { Hash.new }
|
9
|
+
|
10
|
+
subject{ ::CodeTree::Matcher.new(match).function_match(match, victim, match_data) }
|
11
|
+
|
12
|
+
specify {
|
13
|
+
subject.should == true
|
14
|
+
match_data.should == {}
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
context "called with a capture match" do
|
19
|
+
let(:match) { CodeTree::parse{ (match something) } }
|
20
|
+
let(:victim) { CodeTree::parse{ (hello "world") } }
|
21
|
+
let(:match_data) { Hash.new }
|
22
|
+
|
23
|
+
subject{ ::CodeTree::Matcher.new(match).function_match(match, victim, match_data) }
|
24
|
+
|
25
|
+
specify {
|
26
|
+
subject.should == true
|
27
|
+
match_data.should == {:something => :hello}
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
context "called without match" do
|
32
|
+
let(:match) { CodeTree::parse{ (match :hello) } }
|
33
|
+
let(:victim) { CodeTree::parse{ (i "world") } }
|
34
|
+
let(:match_data) { Hash.new }
|
35
|
+
|
36
|
+
subject{ ::CodeTree::Matcher.new(match).function_match(match, victim, match_data) }
|
37
|
+
|
38
|
+
specify {
|
39
|
+
subject.should == false
|
40
|
+
match_data.should == {}
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.expand_path('../../../../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "CodeTree::Matcher#match" do
|
4
|
+
|
5
|
+
context "when called on something that matches" do
|
6
|
+
let(:matcher) { CodeTree::matcher{ (match :say, x) } }
|
7
|
+
let(:matched) { CodeTree::parse { (say "hello") } }
|
8
|
+
subject{ matcher =~ matched }
|
9
|
+
it { should_not be_nil }
|
10
|
+
specify{ subject[:x].should == CodeTree::parse{"hello"} }
|
11
|
+
end
|
12
|
+
|
13
|
+
context "when called on something that does not match" do
|
14
|
+
let(:matcher) { CodeTree::matcher{ (match :say, x) } }
|
15
|
+
let(:matched) { CodeTree::parse { (nosay "hello") } }
|
16
|
+
subject{ matcher =~ matched }
|
17
|
+
it { should be_nil }
|
18
|
+
end
|
19
|
+
|
20
|
+
context "a generic matcher" do
|
21
|
+
let(:matcher) { CodeTree::matcher{ (match x, y[]) } }
|
22
|
+
|
23
|
+
context 'against a ruby object' do
|
24
|
+
let(:expr) { 12 }
|
25
|
+
subject { matcher =~ expr }
|
26
|
+
it { should be_nil }
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'against a literal' do
|
30
|
+
let(:expr) { CodeTree::parse{ 12 } }
|
31
|
+
subject { matcher =~ expr }
|
32
|
+
it { should_not be_nil }
|
33
|
+
specify { subject[:x].should == :_ }
|
34
|
+
specify { subject[:y].should == [12] }
|
35
|
+
end
|
36
|
+
|
37
|
+
context 'against a variable' do
|
38
|
+
let(:expr) { CodeTree::parse{ var } }
|
39
|
+
subject { matcher =~ expr }
|
40
|
+
it { should_not be_nil }
|
41
|
+
specify { subject[:x].should == :'?' }
|
42
|
+
specify { subject[:y].should == [ CodeTree::parse{ :var }] }
|
43
|
+
end
|
44
|
+
|
45
|
+
context 'against a function with one literal argument' do
|
46
|
+
let(:expr) { CodeTree::parse{ (func "a") } }
|
47
|
+
subject { matcher =~ expr }
|
48
|
+
it { should_not be_nil }
|
49
|
+
specify { subject[:x].should == :func }
|
50
|
+
specify { subject[:y].should == [ CodeTree::parse{ "a" } ] }
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'against a function with two arguments' do
|
54
|
+
let(:expr) { CodeTree::parse{ (func "a", b) } }
|
55
|
+
subject { matcher =~ expr }
|
56
|
+
it { should_not be_nil }
|
57
|
+
specify { subject[:x].should == :func }
|
58
|
+
specify { subject[:y].should == [ CodeTree::parse{ "a" }, CodeTree::parse{ b } ] }
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|