sbyc 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|