pure 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.rdoc +7 -0
- data/MANIFEST +44 -20
- data/README.rdoc +553 -16
- data/Rakefile +25 -2
- data/devel/jumpstart.rb +606 -253
- data/install.rb +1 -2
- data/lib/pure.rb +38 -16
- data/lib/pure/bundled_parsers.rb +4 -0
- data/lib/pure/bundled_plugin.rb +49 -0
- data/lib/pure/compiler/ruby_parser.rb +63 -0
- data/lib/pure/delegate.rb +16 -0
- data/lib/pure/driver.rb +33 -0
- data/lib/pure/dsl.rb +2 -0
- data/lib/pure/dsl_definition.rb +11 -0
- data/lib/pure/error.rb +89 -0
- data/lib/pure/extracted_functions.rb +11 -0
- data/lib/pure/extractor.rb +59 -0
- data/lib/pure/names.rb +9 -0
- data/lib/pure/native_worker.rb +27 -0
- data/lib/pure/parser/impl/base_parser.rb +21 -0
- data/lib/pure/parser/impl/internal.rb +31 -0
- data/lib/pure/parser/impl/ripper.rb +96 -0
- data/lib/pure/parser/impl/ruby_parser.rb +77 -0
- data/lib/pure/parser/internal.rb +4 -0
- data/lib/pure/parser/ripper.rb +2 -0
- data/lib/pure/parser/ruby_parser.rb +2 -0
- data/lib/pure/pure.rb +32 -0
- data/lib/pure/pure_module.rb +141 -0
- data/lib/pure/util.rb +15 -0
- data/lib/pure/version.rb +4 -0
- data/spec/compiler_ruby_parser_spec.rb +79 -0
- data/spec/compute_overrides_spec.rb +99 -0
- data/spec/compute_spec.rb +86 -0
- data/spec/compute_thread_spec.rb +29 -0
- data/spec/compute_timed_spec.rb +40 -0
- data/spec/delegate_spec.rb +141 -0
- data/spec/fstat_example.rb +26 -0
- data/spec/parser_sexp_spec.rb +100 -0
- data/spec/parser_spec.rb +18 -31
- data/spec/pure_combine_spec.rb +77 -0
- data/spec/pure_def_spec.rb +186 -0
- data/spec/pure_define_method_spec.rb +24 -0
- data/spec/pure_eval_spec.rb +18 -0
- data/spec/pure_fun_spec.rb +243 -0
- data/spec/pure_nested_spec.rb +35 -0
- data/spec/pure_parser_spec.rb +50 -0
- data/spec/pure_spec.rb +81 -0
- data/spec/pure_spec_base.rb +106 -0
- data/spec/pure_splat_spec.rb +18 -0
- data/spec/pure_two_defs_spec.rb +20 -0
- data/spec/pure_worker_spec.rb +33 -0
- data/spec/readme_spec.rb +36 -32
- data/spec/splat_spec.rb +12 -11
- data/spec/worker_spec.rb +89 -0
- metadata +157 -41
- data/devel/jumpstart/lazy_attribute.rb +0 -38
- data/devel/jumpstart/ruby.rb +0 -44
- data/devel/jumpstart/simple_installer.rb +0 -85
- data/lib/pure/pure_private/creator.rb +0 -27
- data/lib/pure/pure_private/driver.rb +0 -48
- data/lib/pure/pure_private/error.rb +0 -32
- data/lib/pure/pure_private/extractor.rb +0 -79
- data/lib/pure/pure_private/extractor_ripper.rb +0 -95
- data/lib/pure/pure_private/extractor_ruby_parser.rb +0 -47
- data/lib/pure/pure_private/function_database.rb +0 -10
- data/lib/pure/pure_private/singleton_features.rb +0 -67
- data/lib/pure/pure_private/util.rb +0 -23
- data/spec/basic_spec.rb +0 -38
- data/spec/combine_spec.rb +0 -62
- data/spec/common.rb +0 -44
- data/spec/error_spec.rb +0 -146
- data/spec/fun_spec.rb +0 -122
- data/spec/lazy_spec.rb +0 -22
- data/spec/subseqent_spec.rb +0 -42
- data/spec/timed_spec.rb +0 -30
data/spec/parser_spec.rb
CHANGED
@@ -1,36 +1,23 @@
|
|
1
|
-
require File.dirname(__FILE__) +
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
2
|
|
3
|
-
describe "
|
4
|
-
|
5
|
-
pure do
|
6
|
-
|
3
|
+
describe "parser" do
|
4
|
+
describe "provided by user" do
|
5
|
+
it "should be accepted by pure" do
|
6
|
+
memo = nil
|
7
|
+
parser = Class.new do
|
8
|
+
define_method :extract do |*args|
|
9
|
+
memo = args
|
10
|
+
Hash.new
|
11
|
+
end
|
12
|
+
def name
|
13
|
+
"SampleParser"
|
14
|
+
end
|
15
|
+
end.new
|
16
|
+
mod = pure(parser) do
|
17
|
+
def f(x, y)
|
18
|
+
end
|
7
19
|
end
|
8
|
-
|
9
|
-
lambda {
|
10
|
-
Pure.parser
|
11
|
-
}.should_not raise_error
|
12
|
-
end
|
13
|
-
|
14
|
-
it "should be swappable" do
|
15
|
-
previous = Pure.parser
|
16
|
-
begin
|
17
|
-
Pure.parser = "ruby_parser"
|
18
|
-
Pure.parser.should == "ruby_parser"
|
19
|
-
ensure
|
20
|
-
Pure.parser = previous
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should have a default unless Method#parameters available" do
|
25
|
-
Pure.parser = nil
|
26
|
-
pure do
|
27
|
-
def f
|
28
|
-
end
|
29
|
-
end.compute(:f, 3)
|
30
|
-
if Method.instance_methods.include?(:parameters)
|
31
|
-
Pure.parser.should == nil
|
32
|
-
else
|
33
|
-
Pure.parser.should_not == nil
|
20
|
+
memo.should == [mod, :f, __FILE__, 17]
|
34
21
|
end
|
35
22
|
end
|
36
23
|
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
# factor out due to parsers changing
|
4
|
+
module PureCombineSpec
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def create_mod_a
|
8
|
+
pure do
|
9
|
+
def area(width, height)
|
10
|
+
width*height
|
11
|
+
end
|
12
|
+
|
13
|
+
def border
|
14
|
+
5
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_mod_b
|
20
|
+
pure do
|
21
|
+
def width(border)
|
22
|
+
20 + border
|
23
|
+
end
|
24
|
+
|
25
|
+
def height(border)
|
26
|
+
30 + border
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_combined
|
32
|
+
mod_a = create_mod_a
|
33
|
+
mod_b = create_mod_b
|
34
|
+
pure do
|
35
|
+
include mod_a
|
36
|
+
include mod_b
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "pure" do
|
42
|
+
describe "modules combined with other pure modules" do
|
43
|
+
max_threads = 5
|
44
|
+
|
45
|
+
it "should work with modules included into empty module" do
|
46
|
+
combined = PureCombineSpec.create_combined
|
47
|
+
(1..max_threads).each { |n|
|
48
|
+
combined.compute(n).area.should == (20 + 5)*(30 + 5)
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should work with modules included into overriding module" do
|
53
|
+
combined = PureCombineSpec.create_combined
|
54
|
+
combined_override = pure do
|
55
|
+
include combined
|
56
|
+
def border
|
57
|
+
99
|
58
|
+
end
|
59
|
+
end
|
60
|
+
(1..max_threads).each { |n|
|
61
|
+
combined_override.compute(n).area.should == (20 + 99)*(30 + 99)
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should work with one module included into another" do
|
66
|
+
mod_a = PureCombineSpec.create_mod_a
|
67
|
+
mod_b = PureCombineSpec.create_mod_b
|
68
|
+
mod_a.module_eval do
|
69
|
+
include mod_b
|
70
|
+
end
|
71
|
+
(1..max_threads).each { |n|
|
72
|
+
mod_a.compute(n).area.should == (20 + 5)*(30 + 5)
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
@@ -0,0 +1,186 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
describe "pure" do
|
4
|
+
describe "`def' definitions" do
|
5
|
+
it "should be parsed with 1 arg default" do
|
6
|
+
lambda {
|
7
|
+
pure do
|
8
|
+
def f(x = 99)
|
9
|
+
x
|
10
|
+
end
|
11
|
+
end
|
12
|
+
}.should raise_error(
|
13
|
+
Pure::DefaultArgumentError,
|
14
|
+
"cannot use default argument in pure function at #{__FILE__}:8"
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should be parsed with non-paren 1 arg" do
|
19
|
+
pure do
|
20
|
+
def f x
|
21
|
+
x + 33
|
22
|
+
end
|
23
|
+
end.compute(3, :x => 44).f.should == 77
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should be parsed with non-paren 1 arg splat" do
|
27
|
+
lambda {
|
28
|
+
pure do
|
29
|
+
def f *x
|
30
|
+
x + 33
|
31
|
+
end
|
32
|
+
end
|
33
|
+
}.should raise_error(Pure::SplatError)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should be parsed with non-paren 2 arg splat" do
|
37
|
+
lambda {
|
38
|
+
pure do
|
39
|
+
def f x, *y
|
40
|
+
x + 33
|
41
|
+
end
|
42
|
+
end
|
43
|
+
}.should raise_error(Pure::SplatError)
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should be parsed with non-paren 2 args" do
|
47
|
+
pure do
|
48
|
+
def f x, y
|
49
|
+
x + y
|
50
|
+
end
|
51
|
+
end.compute(3, :x => 33, :y => 44).f.should == 77
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should be parsed with 2 arg default" do
|
55
|
+
lambda {
|
56
|
+
pure do
|
57
|
+
def f(x, y = 99)
|
58
|
+
x + y
|
59
|
+
end
|
60
|
+
end
|
61
|
+
}.should raise_error(Pure::DefaultArgumentError)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should be parsed with non-paren 1 arg default" do
|
65
|
+
lambda {
|
66
|
+
pure do
|
67
|
+
def f x = 99
|
68
|
+
x + 44
|
69
|
+
end
|
70
|
+
end
|
71
|
+
}.should raise_error(Pure::DefaultArgumentError)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should be parsed with non-paren 2 arg 1 default" do
|
75
|
+
lambda {
|
76
|
+
pure do
|
77
|
+
def f x, y = 99
|
78
|
+
x + y
|
79
|
+
end
|
80
|
+
end
|
81
|
+
}.should raise_error(Pure::DefaultArgumentError)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should be parsed with non-paren 2 arg 2 default" do
|
85
|
+
lambda {
|
86
|
+
pure do
|
87
|
+
def f x = 77, y = 99
|
88
|
+
x + y
|
89
|
+
end
|
90
|
+
end
|
91
|
+
}.should raise_error(Pure::DefaultArgumentError)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should ignore &block" do
|
95
|
+
pure do
|
96
|
+
def f(&block)
|
97
|
+
33
|
98
|
+
end
|
99
|
+
end.compute(4).f.should == 33
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should ignore &block with 1 arg" do
|
103
|
+
pure do
|
104
|
+
def f(x, &block)
|
105
|
+
x + 44
|
106
|
+
end
|
107
|
+
end.compute(4, :x => 33).f.should == 77
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should ignore &block with 2 arg" do
|
111
|
+
pure do
|
112
|
+
def f(x, y, &block)
|
113
|
+
x + 44
|
114
|
+
end
|
115
|
+
end.compute(4, :x => 33, :y => nil).f.should == 77
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should ignore &block with 1 arg default" do
|
119
|
+
lambda {
|
120
|
+
pure do
|
121
|
+
def f(x = 11, &block)
|
122
|
+
x + 44
|
123
|
+
end
|
124
|
+
end
|
125
|
+
}.should raise_error(Pure::DefaultArgumentError)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "should ignore no-paren &block" do
|
129
|
+
pure do
|
130
|
+
def f &block
|
131
|
+
33
|
132
|
+
end
|
133
|
+
end.compute(4).f.should == 33
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should ignore no-paren &block with 1 arg" do
|
137
|
+
pure do
|
138
|
+
def f x, &block
|
139
|
+
x + 44
|
140
|
+
end
|
141
|
+
end.compute(4, :x => 33).f.should == 77
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should ignore no-paren &block with 2 arg" do
|
145
|
+
pure do
|
146
|
+
def f x, y, &block
|
147
|
+
x + 44
|
148
|
+
end
|
149
|
+
end.compute(4, :x => 33, :y => nil).f.should == 77
|
150
|
+
end
|
151
|
+
|
152
|
+
it "should ignore no-paren &block with 1 arg default" do
|
153
|
+
lambda {
|
154
|
+
pure do
|
155
|
+
def f x = 11, &block
|
156
|
+
x + 44
|
157
|
+
end
|
158
|
+
end
|
159
|
+
}.should raise_error(Pure::DefaultArgumentError)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should have fun_name and arg_names" do
|
163
|
+
pure do
|
164
|
+
def f(x, y)
|
165
|
+
[fun_name, arg_names, x + y]
|
166
|
+
end
|
167
|
+
end.compute(:x => 11, :y => 22).f.should == [:f, [:x, :y], 33]
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should have fun_name and arg_names, given 1 arg" do
|
171
|
+
pure do
|
172
|
+
def f(x)
|
173
|
+
[fun_name, arg_names, x]
|
174
|
+
end
|
175
|
+
end.compute(:x => 11).f.should == [:f, [:x], 11]
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should have fun_name and arg_names, given no args" do
|
179
|
+
pure do
|
180
|
+
def f
|
181
|
+
[fun_name, arg_names]
|
182
|
+
end
|
183
|
+
end.compute.f.should == [:f, []]
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
describe "pure" do
|
4
|
+
it "should raise error when define_method called" do
|
5
|
+
lambda {
|
6
|
+
pure do
|
7
|
+
define_method :area do |width, height|
|
8
|
+
width*height
|
9
|
+
end
|
10
|
+
|
11
|
+
def width
|
12
|
+
5
|
13
|
+
end
|
14
|
+
|
15
|
+
def height
|
16
|
+
7
|
17
|
+
end
|
18
|
+
end.compute :area, 3
|
19
|
+
}.should raise_error(
|
20
|
+
Pure::DefineMethodError,
|
21
|
+
%r!cannot use define_method.* at #{__FILE__}:7!
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
describe "pure" do
|
4
|
+
describe "defined inside eval" do
|
5
|
+
it "should raise an error" do
|
6
|
+
lambda {
|
7
|
+
code = %{
|
8
|
+
pure do
|
9
|
+
def f
|
10
|
+
33
|
11
|
+
end
|
12
|
+
end
|
13
|
+
}
|
14
|
+
eval(code)
|
15
|
+
}.should raise_error(Pure::EvalError, %r!#{__FILE__}:14!)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,243 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
require 'jumpstart'
|
4
|
+
|
5
|
+
describe "pure" do
|
6
|
+
describe "`fun' definitions" do
|
7
|
+
it "should work with symbols" do
|
8
|
+
pure do
|
9
|
+
fun :area => [:width, :height] do |w, h|
|
10
|
+
w*h
|
11
|
+
end
|
12
|
+
|
13
|
+
fun :width => [:border] do |b|
|
14
|
+
20 + b
|
15
|
+
end
|
16
|
+
|
17
|
+
fun :height => :border do |b|
|
18
|
+
30 + b
|
19
|
+
end
|
20
|
+
|
21
|
+
fun :border do
|
22
|
+
5
|
23
|
+
end
|
24
|
+
end.compute(4).area.should == (20 + 5)*(30 + 5)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should work with symbols and parens" do
|
28
|
+
pure do
|
29
|
+
fun(:area => [:width, :height]) do |w, h|
|
30
|
+
w*h
|
31
|
+
end
|
32
|
+
|
33
|
+
fun(:width => [:border]) do |b|
|
34
|
+
20 + b
|
35
|
+
end
|
36
|
+
|
37
|
+
fun(:height => :border) do |b|
|
38
|
+
30 + b
|
39
|
+
end
|
40
|
+
|
41
|
+
fun(:border) do
|
42
|
+
5
|
43
|
+
end
|
44
|
+
end.compute(4).area.should == (20 + 5)*(30 + 5)
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should work with mixed symbols and strings" do
|
48
|
+
pure do
|
49
|
+
fun :area => [:width, "height"] do |w, h|
|
50
|
+
w*h
|
51
|
+
end
|
52
|
+
|
53
|
+
fun "width" => [:border] do |b|
|
54
|
+
20 + b
|
55
|
+
end
|
56
|
+
|
57
|
+
fun :height => "border" do |b|
|
58
|
+
30 + b
|
59
|
+
end
|
60
|
+
|
61
|
+
fun :border do
|
62
|
+
5
|
63
|
+
end
|
64
|
+
end.compute(4).area.should == (20 + 5)*(30 + 5)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should work with `def' definitions" do
|
68
|
+
pure do
|
69
|
+
fun :width do
|
70
|
+
33
|
71
|
+
end
|
72
|
+
|
73
|
+
def height
|
74
|
+
44
|
75
|
+
end
|
76
|
+
|
77
|
+
fun :area => [:width, :height] do |w, h|
|
78
|
+
w*h
|
79
|
+
end
|
80
|
+
end.compute(3).area.should == 33*44
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should be overwritten by later `def' definitions" do
|
84
|
+
Jumpstart::Ruby.no_warnings {
|
85
|
+
pure do
|
86
|
+
fun :f do
|
87
|
+
44
|
88
|
+
end
|
89
|
+
|
90
|
+
def f
|
91
|
+
33
|
92
|
+
end
|
93
|
+
end.compute(10).f.should == 33
|
94
|
+
}
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should overwrite earlier `def' definitions" do
|
98
|
+
Jumpstart::Ruby.no_warnings {
|
99
|
+
pure do
|
100
|
+
def f
|
101
|
+
33
|
102
|
+
end
|
103
|
+
|
104
|
+
fun :f do
|
105
|
+
44
|
106
|
+
end
|
107
|
+
end.compute(10).f.should == 44
|
108
|
+
}
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should support splat in block args" do
|
112
|
+
pure do
|
113
|
+
fun :area => [:width, :height] do |*a|
|
114
|
+
a[0]*a[1]
|
115
|
+
end
|
116
|
+
|
117
|
+
def width
|
118
|
+
3
|
119
|
+
end
|
120
|
+
|
121
|
+
def height
|
122
|
+
4
|
123
|
+
end
|
124
|
+
end.compute(3).area.should == 12
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should support splat with single-element array" do
|
128
|
+
pure do
|
129
|
+
name = [:f]
|
130
|
+
fun(*name) do
|
131
|
+
33
|
132
|
+
end
|
133
|
+
end.compute(3).f.should == 33
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should not preclude `def' definitions called `fun'" do
|
137
|
+
pure do
|
138
|
+
def misery(fun)
|
139
|
+
fun**2
|
140
|
+
end
|
141
|
+
|
142
|
+
def fun(a, b)
|
143
|
+
a + b
|
144
|
+
end
|
145
|
+
|
146
|
+
def a
|
147
|
+
3
|
148
|
+
end
|
149
|
+
|
150
|
+
def b
|
151
|
+
5
|
152
|
+
end
|
153
|
+
end.compute(3).misery.should == 64
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should raise error when given hash of size != 1" do
|
157
|
+
lambda {
|
158
|
+
pure do
|
159
|
+
fun :x => 1, :y => 2 do
|
160
|
+
end
|
161
|
+
end
|
162
|
+
}.should raise_error(ArgumentError)
|
163
|
+
end
|
164
|
+
|
165
|
+
it "should raise error given more than 1 argument" do
|
166
|
+
lambda {
|
167
|
+
pure do
|
168
|
+
fun :x, :y do
|
169
|
+
end
|
170
|
+
end
|
171
|
+
}.should raise_error(ArgumentError)
|
172
|
+
end
|
173
|
+
|
174
|
+
it "should raise error with &block unless Pure::Parser::Internal is used" do
|
175
|
+
code = lambda {
|
176
|
+
pure do
|
177
|
+
fun :f, &lambda { 33 }
|
178
|
+
end.compute(4).f.should == 33
|
179
|
+
}
|
180
|
+
if Pure.parser.name == "Pure::Parser::Internal"
|
181
|
+
code.should_not raise_error
|
182
|
+
else
|
183
|
+
code.should raise_error(Pure::ParseError)
|
184
|
+
end
|
185
|
+
|
186
|
+
code = lambda {
|
187
|
+
pure do
|
188
|
+
t = lambda { 33 }
|
189
|
+
fun :f, &t
|
190
|
+
end.compute(4).f.should == 33
|
191
|
+
}
|
192
|
+
if Pure.parser.name == "Pure::Parser::Internal"
|
193
|
+
code.should_not raise_error
|
194
|
+
else
|
195
|
+
code.should raise_error(Pure::ParseError)
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should allow function names containing any characters" do
|
200
|
+
%w[- / ? : ; . ! [ ] ( )].each { |char|
|
201
|
+
pure do
|
202
|
+
fun "f#{char}f" do
|
203
|
+
33
|
204
|
+
end
|
205
|
+
end.compute[:"f#{char}f"].should == 33
|
206
|
+
}
|
207
|
+
end
|
208
|
+
|
209
|
+
it "should have fun_name and arg_names, given multiple args" do
|
210
|
+
pure do
|
211
|
+
fun :f => [:x, :y] do |x, y|
|
212
|
+
[fun_name, arg_names, x + y]
|
213
|
+
end
|
214
|
+
end.compute(:x => 11, :y => 22).f.should == [:f, [:x, :y], 33]
|
215
|
+
end
|
216
|
+
|
217
|
+
it "should have fun_name and fun_args, given 1 arg" do
|
218
|
+
pure do
|
219
|
+
fun :f => :x do |x|
|
220
|
+
[fun_name, arg_names, x]
|
221
|
+
end
|
222
|
+
end.compute(:x => 11).f.should == [:f, [:x], 11]
|
223
|
+
end
|
224
|
+
|
225
|
+
it "should have fun_name and fun_args, given no args" do
|
226
|
+
pure do
|
227
|
+
fun :f do
|
228
|
+
[fun_name, arg_names]
|
229
|
+
end
|
230
|
+
end.compute.f.should == [:f, []]
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should not see internals of the compiler" do
|
234
|
+
lambda {
|
235
|
+
pure do
|
236
|
+
fun :f do
|
237
|
+
spec
|
238
|
+
end
|
239
|
+
end.compute.f
|
240
|
+
}.should raise_error(NameError)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|