pure 0.1.0 → 0.2.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/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
@@ -0,0 +1,35 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
describe "pure" do
|
4
|
+
describe "with nested defs" do
|
5
|
+
it "should work with different names" do
|
6
|
+
Class.new do
|
7
|
+
def f(n)
|
8
|
+
pure do
|
9
|
+
def g(h)
|
10
|
+
h**2
|
11
|
+
end
|
12
|
+
fun :h do
|
13
|
+
n
|
14
|
+
end
|
15
|
+
end.compute(Pure::NativeWorker).g
|
16
|
+
end
|
17
|
+
end.new.f(5).should == 25
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should work with the same name" do
|
21
|
+
Class.new do
|
22
|
+
def f(n)
|
23
|
+
pure do
|
24
|
+
def f(h)
|
25
|
+
h**2
|
26
|
+
end
|
27
|
+
fun :h do
|
28
|
+
n
|
29
|
+
end
|
30
|
+
end.compute(Pure::NativeWorker).f
|
31
|
+
end
|
32
|
+
end.new.f(5).should == 25
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
describe "Pure.parser" do
|
4
|
+
it "should return the current parser" do
|
5
|
+
Pure.parser.should_not == nil
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should have a default" do
|
9
|
+
Pure.parser = nil
|
10
|
+
pure do
|
11
|
+
def f
|
12
|
+
end
|
13
|
+
end.compute(Pure::NativeWorker).f
|
14
|
+
Pure.parser.should_not == nil
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should be changed with Pure.parser=" do
|
18
|
+
lambda {
|
19
|
+
mod = pure do
|
20
|
+
def f
|
21
|
+
end
|
22
|
+
end
|
23
|
+
}.should_not raise_error
|
24
|
+
previous = Pure.parser
|
25
|
+
Pure.parser = "junk"
|
26
|
+
begin
|
27
|
+
lambda {
|
28
|
+
mod = pure do
|
29
|
+
def f
|
30
|
+
end
|
31
|
+
end
|
32
|
+
}.should raise_error
|
33
|
+
ensure
|
34
|
+
Pure.parser = previous
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should raise error when no parser found" do
|
39
|
+
source = File.dirname(__FILE__) + "/../lib/pure/parser"
|
40
|
+
dest = source + "-tmp"
|
41
|
+
FileUtils.mv(source, dest)
|
42
|
+
begin
|
43
|
+
lambda {
|
44
|
+
Pure::BundledParsers.find_default
|
45
|
+
}.should raise_error(Pure::NoParserError, "no parser found")
|
46
|
+
ensure
|
47
|
+
FileUtils.mv(dest, source)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/spec/pure_spec.rb
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
require 'jumpstart'
|
4
|
+
|
5
|
+
describe "pure" do
|
6
|
+
it "should not be available without require 'pure/dsl'" do
|
7
|
+
code = %{
|
8
|
+
begin
|
9
|
+
pure do
|
10
|
+
end
|
11
|
+
rescue Exception => e
|
12
|
+
unless e.is_a?(NameError)
|
13
|
+
raise 'expected name error'
|
14
|
+
end
|
15
|
+
unless e.message =~ %r!undefined method \`pure\'!
|
16
|
+
raise 'unmatched message'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
}
|
20
|
+
lambda {
|
21
|
+
Jumpstart::Ruby.run("-e", code)
|
22
|
+
}.should_not raise_error
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should be an alias of Pure.define" do
|
26
|
+
Pure.define do
|
27
|
+
def f
|
28
|
+
33
|
29
|
+
end
|
30
|
+
end.compute(4).f.should == 33
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should not allow `fun' outside of block" do
|
34
|
+
lambda {
|
35
|
+
pure do
|
36
|
+
end.fun :x do
|
37
|
+
33
|
38
|
+
end
|
39
|
+
}.should raise_error(NoMethodError)
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "with subsequent `def' definitions" do
|
43
|
+
it "should be accepted" do
|
44
|
+
mod = pure do
|
45
|
+
def f
|
46
|
+
33
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
mod.compute(4).f.should eql(33)
|
51
|
+
|
52
|
+
mod.module_eval do
|
53
|
+
def g
|
54
|
+
44
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
mod.compute(4).g.should eql(44)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "with subsequent `fun' definitions" do
|
63
|
+
it "should be accepted" do
|
64
|
+
mod = pure do
|
65
|
+
fun :f do
|
66
|
+
33
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
mod.compute(4).f.should eql(33)
|
71
|
+
|
72
|
+
mod.module_eval do
|
73
|
+
fun :g do
|
74
|
+
44
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
mod.compute(4).g.should eql(44)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
|
2
|
+
$LOAD_PATH.unshift File.dirname(__FILE__) + '/../devel'
|
3
|
+
|
4
|
+
require 'pure/dsl'
|
5
|
+
require 'spec/autorun'
|
6
|
+
|
7
|
+
TOPLEVEL_INSTANCE = self
|
8
|
+
|
9
|
+
#
|
10
|
+
# verify compilers
|
11
|
+
#
|
12
|
+
module CompilerWorker
|
13
|
+
class Base
|
14
|
+
attr_reader :num_parallel
|
15
|
+
|
16
|
+
def define_function(spec)
|
17
|
+
lambda { |*args|
|
18
|
+
self.class.compiler.new.evaluate_function(spec, *args)
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def define_function_begin(pure_module, num_parallel)
|
23
|
+
@num_parallel = num_parallel || self.class.num_parallel
|
24
|
+
end
|
25
|
+
|
26
|
+
def define_function_end
|
27
|
+
end
|
28
|
+
|
29
|
+
class << self
|
30
|
+
attr_accessor :num_parallel
|
31
|
+
attr_reader :compiler
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
Pure::BundledParsers.available.values.map { |parser|
|
36
|
+
parser.compiler rescue nil
|
37
|
+
}.compact.each { |path, name|
|
38
|
+
names = name.split("::")
|
39
|
+
worker = Class.new Base do
|
40
|
+
require path
|
41
|
+
@compiler = names.inject(Object) { |mod, name|
|
42
|
+
mod.const_get(name)
|
43
|
+
}
|
44
|
+
end
|
45
|
+
const_set(names.last, worker)
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
module Spec::Example::ExampleGroupMethods
|
50
|
+
alias_method :describe__original, :describe
|
51
|
+
|
52
|
+
def describe(*args, &block)
|
53
|
+
if args[1] and args[1][:scope] == TOPLEVEL_INSTANCE
|
54
|
+
Pure::BundledParsers.available.each { |parser_path, parser|
|
55
|
+
workers = [Pure::NativeWorker]
|
56
|
+
|
57
|
+
name = parser.name.split("::").last
|
58
|
+
name = name.to_sym if RUBY_VERSION >= "1.9"
|
59
|
+
if CompilerWorker.constants.include?(name)
|
60
|
+
workers << CompilerWorker.const_get(name)
|
61
|
+
end
|
62
|
+
|
63
|
+
describe "[#{parser.name}]" do
|
64
|
+
before :each do
|
65
|
+
@previous_parser = Pure.parser
|
66
|
+
Pure.parser = parser
|
67
|
+
end
|
68
|
+
after :each do
|
69
|
+
Pure.parser = @previous_parser
|
70
|
+
end
|
71
|
+
workers.each { |worker|
|
72
|
+
describe "[#{worker}]" do
|
73
|
+
before :all do
|
74
|
+
@previous_worker = Pure.worker
|
75
|
+
worker.num_parallel = @previous_worker.num_parallel
|
76
|
+
Pure.worker = worker
|
77
|
+
end
|
78
|
+
after :all do
|
79
|
+
Pure.worker = @previous_worker
|
80
|
+
end
|
81
|
+
describe args.first, &block
|
82
|
+
end
|
83
|
+
}
|
84
|
+
end
|
85
|
+
}
|
86
|
+
else
|
87
|
+
describe__original(*args, &block)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
#
|
93
|
+
# Prevent Ruby2Ruby's destruction of the sexp. In practice the
|
94
|
+
# compiler resides on another ruby interpreter, making the destruction
|
95
|
+
# harmless.
|
96
|
+
#
|
97
|
+
module Pure
|
98
|
+
module Compiler
|
99
|
+
class RubyParser
|
100
|
+
alias_method :compile_function__original, :compile_function
|
101
|
+
def compile_function(spec)
|
102
|
+
compile_function__original(Marshal.load(Marshal.dump(spec)))
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
describe "pure" do
|
4
|
+
describe "function defined with splat (*) argument via `def'" do
|
5
|
+
it "should raise error" do
|
6
|
+
lambda {
|
7
|
+
pure do
|
8
|
+
def f(a, b, *stuff)
|
9
|
+
stuff
|
10
|
+
end
|
11
|
+
end
|
12
|
+
}.should raise_error(
|
13
|
+
Pure::SplatError, %r!cannot use splat.*#{__FILE__}:8!
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
describe "pure" do
|
4
|
+
describe "with two defs on the same line" do
|
5
|
+
it "should raise error unless Pure::Parser::Internal is used" do
|
6
|
+
code = lambda {
|
7
|
+
pure do
|
8
|
+
def x ; end ; def y ; end
|
9
|
+
end
|
10
|
+
}
|
11
|
+
if Pure.parser.name == "Pure::Parser::Internal"
|
12
|
+
code.should_not raise_error
|
13
|
+
else
|
14
|
+
code.should raise_error(
|
15
|
+
Pure::ParseMethodError, "failed to parse `x' at #{__FILE__}:8"
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
|
+
|
3
|
+
describe "Pure.worker" do
|
4
|
+
it "should return the current worker" do
|
5
|
+
Pure.worker.should_not == nil
|
6
|
+
end
|
7
|
+
|
8
|
+
it "should be changed with Pure.worker=" do
|
9
|
+
lambda {
|
10
|
+
mod = pure do
|
11
|
+
def f
|
12
|
+
end
|
13
|
+
end
|
14
|
+
}.should_not raise_error
|
15
|
+
previous = Pure.worker
|
16
|
+
Pure.worker = "junk"
|
17
|
+
begin
|
18
|
+
lambda {
|
19
|
+
mod = pure do
|
20
|
+
def f
|
21
|
+
end
|
22
|
+
end.compute.f
|
23
|
+
}.should raise_error
|
24
|
+
ensure
|
25
|
+
Pure.worker = previous
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should have a default" do
|
30
|
+
Pure.worker = nil
|
31
|
+
Pure.worker.should_not == nil
|
32
|
+
end
|
33
|
+
end
|
data/spec/readme_spec.rb
CHANGED
@@ -1,35 +1,39 @@
|
|
1
|
-
require '
|
2
|
-
require 'tempfile'
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
3
2
|
|
4
|
-
|
5
|
-
require here + "common"
|
6
|
-
root = here + ".."
|
7
|
-
readme = root + "README.rdoc"
|
8
|
-
lib = root + "lib"
|
3
|
+
require "jumpstart"
|
9
4
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
file.puts code
|
27
|
-
file.close
|
28
|
-
result = `"#{Jumpstart::Ruby::EXECUTABLE}" "#{file.path}"`
|
29
|
-
raise unless $?.exitstatus
|
30
|
-
result.chomp.should == expected
|
31
|
-
}
|
32
|
-
end
|
33
|
-
end
|
5
|
+
readme = "README.rdoc"
|
6
|
+
|
7
|
+
simple_sections = [
|
8
|
+
"Synopsis",
|
9
|
+
"Overrides",
|
10
|
+
"Delegates and Blocks",
|
11
|
+
"Combining Pure Modules",
|
12
|
+
"Restrictions",
|
13
|
+
"Default Number of Functions in Parallel",
|
14
|
+
]
|
15
|
+
|
16
|
+
Jumpstart.doc_to_spec(readme, *simple_sections)
|
17
|
+
|
18
|
+
Jumpstart.doc_to_spec(readme, "Dynamic Names") { |expected, actual, index|
|
19
|
+
[expected, actual].each { |expr|
|
20
|
+
expr.should match(%r!\A[\d\s]+\Z!)
|
34
21
|
}
|
35
|
-
|
22
|
+
}
|
23
|
+
|
24
|
+
Jumpstart.doc_to_spec(readme, "Worker Plugins") { |expected, actual, index|
|
25
|
+
case index
|
26
|
+
when 0, 2
|
27
|
+
actual.should == expected
|
28
|
+
when 1
|
29
|
+
require 'ruby_parser'
|
30
|
+
trimmed_expected, trimmed_actual = [expected, actual].map { |expression|
|
31
|
+
result = eval(expression, TOPLEVEL_BINDING)
|
32
|
+
result[0].merge!(:file => nil, :line => nil)
|
33
|
+
result
|
34
|
+
}
|
35
|
+
trimmed_actual.should == trimmed_expected
|
36
|
+
else
|
37
|
+
raise
|
38
|
+
end
|
39
|
+
}
|
data/spec/splat_spec.rb
CHANGED
@@ -1,15 +1,16 @@
|
|
1
|
-
require File.dirname(__FILE__) +
|
1
|
+
require File.dirname(__FILE__) + '/pure_spec_base'
|
2
2
|
|
3
|
-
describe "splat
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
3
|
+
describe "splat" do
|
4
|
+
it "should be allowed outside of pure" do
|
5
|
+
Class.new do
|
6
|
+
def f(*args)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
pure do
|
11
|
+
def g
|
12
|
+
44
|
13
|
+
end
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|