fastruby 0.0.17 → 0.0.18
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/CHANGELOG +10 -0
- data/Rakefile +4 -2
- data/benchmarks/benchmark.rb +20 -44
- data/benchmarks/benchmark.rb~ +47 -0
- data/benchmarks/benchmark2.rb +19 -45
- data/benchmarks/benchmark2.rb~ +46 -0
- data/benchmarks/benchmark3.rb +19 -45
- data/benchmarks/benchmark3.rb~ +46 -0
- data/benchmarks/benchmark4.rb +30 -65
- data/benchmarks/benchmark4.rb~ +61 -0
- data/benchmarks/benchmark5.rb +25 -55
- data/benchmarks/benchmark5.rb~ +54 -0
- data/benchmarks/benchmark6.rb +19 -40
- data/benchmarks/benchmark6.rb~ +41 -0
- data/benchmarks/benchmark7.rb +23 -52
- data/benchmarks/benchmark7.rb~ +48 -0
- data/ext/fastruby_base/fastruby_base.inl +1 -0
- data/lib/fastruby/builder.rb +128 -76
- data/lib/fastruby/cache/cache.rb +9 -5
- data/lib/fastruby/fastruby_sexp.rb +18 -0
- data/lib/fastruby/inliner/inliner.rb +68 -0
- data/lib/fastruby/inliner/modules/call.rb +150 -0
- data/lib/fastruby/inliner/modules/recursive.rb +35 -0
- data/lib/fastruby/object.rb +17 -32
- data/lib/fastruby/reductor/modules/case.rb +49 -0
- data/lib/{fastruby.rb~ → fastruby/reductor/modules/for.rb} +11 -13
- data/lib/fastruby/reductor/modules/nontree.rb +31 -0
- data/lib/fastruby/reductor/modules/recursive.rb +31 -0
- data/lib/fastruby/reductor/reductor.rb +39 -0
- data/lib/fastruby/set_tree.rb +7 -1
- data/lib/fastruby/sexp_extension.rb +6 -0
- data/lib/fastruby/translator/modules/block.rb +4 -4
- data/lib/fastruby/translator/modules/call.rb +9 -26
- data/lib/fastruby/translator/modules/defn.rb +5 -3
- data/lib/fastruby/translator/modules/directive.rb +42 -0
- data/lib/fastruby/translator/modules/exceptions.rb +12 -30
- data/lib/fastruby/translator/modules/flow.rb +33 -83
- data/lib/fastruby/translator/modules/iter.rb +4 -7
- data/lib/fastruby/translator/modules/literal.rb +11 -25
- data/lib/fastruby/translator/modules/logical.rb +5 -3
- data/lib/fastruby/translator/modules/method_group.rb +4 -3
- data/lib/fastruby/translator/modules/nonlocal.rb +7 -5
- data/lib/fastruby/translator/modules/static.rb +242 -0
- data/lib/fastruby/translator/modules/variable.rb +16 -9
- data/lib/fastruby/translator/scope_mode_helper.rb +2 -27
- data/lib/fastruby/translator/translator.rb +131 -60
- data/lib/fastruby/translator/translator_modules.rb +6 -2
- data/lib/fastruby.rb +1 -1
- data/spec/reductor/base_spec.rb +46 -0
- data/spec/ruby/base_spec.rb~ +394 -0
- data/spec/ruby/block/arguments_spec.rb~ +214 -0
- data/spec/ruby/block/proc_as_block_spec.rb~ +23 -0
- data/spec/ruby/block/retry_spec.rb~ +43 -0
- data/spec/ruby/block_spec.rb~ +520 -0
- data/spec/ruby/defn/replacement_spec.rb~ +102 -0
- data/spec/ruby/integrity_spec.rb~ +40 -0
- data/spec/ruby/singleton_spec.rb~ +76 -0
- data/spec/scope_mode/base_spec.rb +14 -5
- data/spec/scope_mode/block_spec.rb +18 -9
- data/spec/scope_mode/call_spec.rb +11 -2
- data/spec/scope_mode/exception_spec.rb +11 -2
- data/spec/scope_mode/flow_spec.rb +18 -8
- data/spec/scope_mode/optimization_spec.rb +21 -13
- data/spec/static/base_spec.rb +54 -0
- data/spec/static/flow_spec.rb +48 -0
- data/spec/static/operator_spec.rb +104 -0
- metadata +58 -8
data/lib/fastruby/cache/cache.rb
CHANGED
@@ -41,12 +41,16 @@ module FastRuby
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def insert(hash,path)
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
unless ENV['FASTRUBY_NO_CACHE'] == '1'
|
45
|
+
create_hash_dir(hash)
|
46
|
+
dest = hash_dir(hash)
|
47
|
+
cp_r path, dest
|
48
|
+
end
|
47
49
|
end
|
48
50
|
|
49
51
|
def retrieve(hash)
|
52
|
+
return [] if ENV['FASTRUBY_NO_CACHE'] == '1'
|
53
|
+
|
50
54
|
create_hash_dir(hash)
|
51
55
|
dest = hash_dir(hash)
|
52
56
|
Dir[dest + "*.so"]
|
@@ -57,10 +61,10 @@ module FastRuby
|
|
57
61
|
@proc_hash[obj] = value
|
58
62
|
end
|
59
63
|
|
60
|
-
def execute(obj,
|
64
|
+
def execute(obj, *params)
|
61
65
|
@proc_hash = Hash.new unless @proc_hash
|
62
66
|
if @proc_hash[obj]
|
63
|
-
@proc_hash[obj].call(
|
67
|
+
@proc_hash[obj].call(*params)
|
64
68
|
end
|
65
69
|
end
|
66
70
|
private
|
@@ -22,6 +22,24 @@ module FastRuby
|
|
22
22
|
class FastRubySexp < Array
|
23
23
|
alias node_type first
|
24
24
|
|
25
|
+
def duplicate
|
26
|
+
map { |subtree|
|
27
|
+
if subtree.respond_to?(:node_type)
|
28
|
+
subtree.duplicate
|
29
|
+
else
|
30
|
+
subtree
|
31
|
+
end
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def map
|
36
|
+
sexp = FastRubySexp.new
|
37
|
+
self.each do |subtree|
|
38
|
+
sexp << yield(subtree)
|
39
|
+
end
|
40
|
+
sexp
|
41
|
+
end
|
42
|
+
|
25
43
|
def walk_tree(&block)
|
26
44
|
each do |subtree|
|
27
45
|
if subtree.instance_of? FastRubySexp
|
@@ -0,0 +1,68 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "set"
|
22
|
+
require "sexp"
|
23
|
+
require "define_method_handler"
|
24
|
+
|
25
|
+
module FastRuby
|
26
|
+
class Inliner
|
27
|
+
attr_accessor :infer_lvar_map
|
28
|
+
attr_accessor :infer_self
|
29
|
+
attr_reader :extra_locals
|
30
|
+
attr_reader :extra_inferences
|
31
|
+
attr_reader :inlined_methods
|
32
|
+
|
33
|
+
def initialize
|
34
|
+
@extra_locals = Set.new
|
35
|
+
@extra_inferences = Hash.new
|
36
|
+
@inlined_methods = Array.new
|
37
|
+
end
|
38
|
+
|
39
|
+
define_method_handler(:inline, :priority => -1000) do |tree|
|
40
|
+
FastRubySexp.from_sexp(tree)
|
41
|
+
end
|
42
|
+
|
43
|
+
Dir.glob(FastRuby.fastruby_load_path + "/fastruby/inliner/modules/**/*.rb").each do |path|
|
44
|
+
require path
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_local(local)
|
48
|
+
@extra_locals << local
|
49
|
+
end
|
50
|
+
|
51
|
+
def infer_type(recv)
|
52
|
+
if recv[0] == :call
|
53
|
+
if recv[2] == :infer
|
54
|
+
eval(recv[3].last.last.to_s)
|
55
|
+
end
|
56
|
+
elsif recv[0] == :lvar
|
57
|
+
@infer_lvar_map[recv[1]]
|
58
|
+
elsif recv[0] == :self
|
59
|
+
@infer_self
|
60
|
+
elsif recv[0] == :str or recv[0] == :lit
|
61
|
+
recv[1].class
|
62
|
+
else
|
63
|
+
nil
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "set"
|
22
|
+
require "sexp"
|
23
|
+
require "define_method_handler"
|
24
|
+
|
25
|
+
module FastRuby
|
26
|
+
class Inliner
|
27
|
+
def inline_local_name(method_name, local_name)
|
28
|
+
"__inlined_#{method_name}_#{local_name}".to_sym
|
29
|
+
end
|
30
|
+
|
31
|
+
define_method_handler(:inline) { |tree|
|
32
|
+
ret_tree = fs(:iter)
|
33
|
+
ret_tree << tree[1].duplicate
|
34
|
+
|
35
|
+
tree[2..-1].each do |subtree|
|
36
|
+
ret_tree << inline(subtree)
|
37
|
+
end
|
38
|
+
|
39
|
+
ret_tree
|
40
|
+
|
41
|
+
}.condition{|tree| tree.node_type == :iter}
|
42
|
+
|
43
|
+
define_method_handler(:inline) { |tree|
|
44
|
+
|
45
|
+
next tree if tree.find_tree(:block_pass)
|
46
|
+
|
47
|
+
recv_tree = tree[1] || fs(:self)
|
48
|
+
method_name = tree[2]
|
49
|
+
args_tree = tree[3]
|
50
|
+
|
51
|
+
if method_name == :lvar_type
|
52
|
+
lvar_name = args_tree[1][1] || args_tree[1][2]
|
53
|
+
lvar_type = eval(args_tree[2][1].to_s)
|
54
|
+
|
55
|
+
@infer_lvar_map[lvar_name] = lvar_type
|
56
|
+
next tree
|
57
|
+
end
|
58
|
+
|
59
|
+
recvtype = infer_type(recv_tree)
|
60
|
+
|
61
|
+
if recvtype
|
62
|
+
# search the tree of target method
|
63
|
+
next tree unless recvtype.respond_to?(:fastruby_method)
|
64
|
+
|
65
|
+
mobject = recvtype.fastruby_method(method_name)
|
66
|
+
|
67
|
+
next tree unless mobject
|
68
|
+
|
69
|
+
target_method_tree = mobject.tree
|
70
|
+
|
71
|
+
next tree unless target_method_tree
|
72
|
+
next tree if target_method_tree.find_tree(:iter)
|
73
|
+
target_method_tree_args = target_method_tree[2]
|
74
|
+
|
75
|
+
next tree if target_method_tree_args.find{|subtree| subtree.to_s =~ /^\*/}
|
76
|
+
|
77
|
+
|
78
|
+
target_method_tree_block = target_method_tree.find_tree(:scope)[1].duplicate
|
79
|
+
|
80
|
+
target_method_tree_block.walk_tree do |subtree|
|
81
|
+
if subtree.node_type == :lvar or subtree.node_type == :lasgn
|
82
|
+
subtree[1] = inline_local_name(method_name, subtree[1])
|
83
|
+
add_local subtree[1]
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
newblock = fs(:block)
|
88
|
+
|
89
|
+
(1..args_tree.size-1).each do |i|
|
90
|
+
itype = infer_type(args_tree[i])
|
91
|
+
inlined_name = inline_local_name(method_name, target_method_tree_args[i])
|
92
|
+
|
93
|
+
add_local inlined_name
|
94
|
+
|
95
|
+
self.extra_inferences[inlined_name] = itype if itype
|
96
|
+
newblock << fs(:lasgn, inlined_name, args_tree[i].duplicate)
|
97
|
+
end
|
98
|
+
|
99
|
+
inlined_name = inline_local_name(method_name, :self)
|
100
|
+
add_local inlined_name
|
101
|
+
newblock << fs(:lasgn, inlined_name, recv_tree.duplicate)
|
102
|
+
|
103
|
+
target_method_tree_block.walk_tree do |subtree|
|
104
|
+
if subtree.node_type == :call
|
105
|
+
if subtree[1] == nil
|
106
|
+
if subtree[2] == :block_given?
|
107
|
+
subtree[0..-1] = fs(:false)
|
108
|
+
else
|
109
|
+
subtree[1] = recv_tree.duplicate
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
if subtree.node_type == :self
|
114
|
+
subtree[0] = :lvar
|
115
|
+
subtree[1] = inline_local_name(method_name, :self)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
(1..target_method_tree_block.size-1).each do |i|
|
120
|
+
subtree = target_method_tree_block[i]
|
121
|
+
|
122
|
+
if subtree.find_tree(:return)
|
123
|
+
if i == target_method_tree_block.size-1
|
124
|
+
if subtree.node_type == :return
|
125
|
+
if subtree[1]
|
126
|
+
if subtree[1].find_tree(:return)
|
127
|
+
next tree
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
subtree[0..-1] = subtree[1]
|
132
|
+
end
|
133
|
+
else
|
134
|
+
# methods with return cannot be inlined
|
135
|
+
next tree
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
newblock << subtree
|
140
|
+
end
|
141
|
+
|
142
|
+
@inlined_methods << mobject
|
143
|
+
newblock
|
144
|
+
else
|
145
|
+
# nothing to do, we don't know what is the method
|
146
|
+
tree
|
147
|
+
end
|
148
|
+
}.condition{|tree| tree.node_type == :call}
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "set"
|
22
|
+
require "sexp"
|
23
|
+
require "define_method_handler"
|
24
|
+
|
25
|
+
module FastRuby
|
26
|
+
class Inliner
|
27
|
+
define_method_handler(:inline, :priority => -100) {|tree|
|
28
|
+
tree.map &method(:inline)
|
29
|
+
}.condition{|tree| tree.respond_to?(:node_type)}
|
30
|
+
|
31
|
+
define_method_handler(:inline, :priority => 1000) {|tree|
|
32
|
+
tree
|
33
|
+
}.condition{|tree| not tree.respond_to?(:node_type)}
|
34
|
+
end
|
35
|
+
end
|
data/lib/fastruby/object.rb
CHANGED
@@ -23,12 +23,22 @@ require "fastruby/getlocals"
|
|
23
23
|
require "fastruby/method_extension"
|
24
24
|
require "fastruby/cache/cache"
|
25
25
|
require "fastruby"
|
26
|
+
require "digest"
|
27
|
+
require "method_source"
|
26
28
|
|
27
29
|
# clean rubyinline cache
|
28
30
|
system("rm -fr #{ENV["HOME"]}/.ruby_inline/*")
|
29
31
|
|
30
32
|
$top_level_binding = binding
|
31
33
|
|
34
|
+
def lvar_type(*x); end
|
35
|
+
|
36
|
+
class Class
|
37
|
+
def optimize(method_name)
|
38
|
+
fastruby instance_method(method_name).source
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
32
42
|
module FastRuby
|
33
43
|
def self.encapsulate_tree(tree, method_name)
|
34
44
|
generated_tree = tree
|
@@ -49,22 +59,14 @@ module FastRuby
|
|
49
59
|
end
|
50
60
|
|
51
61
|
class Object
|
62
|
+
|
63
|
+
def infer(a); self; end
|
52
64
|
def fastruby(argument, *options_hashes)
|
53
65
|
options_hash = {:validate_lvar_types => true}
|
54
|
-
options_hash[:no_cache] = true if ENV['FASTRUBY_NO_CACHE'] == "1"
|
55
66
|
options_hashes.each do |opt|
|
56
67
|
options_hash.merge!(opt)
|
57
68
|
end
|
58
|
-
|
59
|
-
objs = Array.new
|
60
|
-
|
61
|
-
unless options_hash[:no_cache]
|
62
|
-
snippet_hash = FastRuby.cache.hash_snippet(argument,options_hash[:validate_lvar_types].to_s + "^" + FastRuby::VERSION)
|
63
|
-
objs = FastRuby.cache.retrieve(snippet_hash)
|
64
|
-
end
|
65
|
-
|
66
|
-
if objs.empty?
|
67
|
-
|
69
|
+
|
68
70
|
tree = nil
|
69
71
|
|
70
72
|
require "fastruby/fastruby_sexp"
|
@@ -80,27 +82,10 @@ class Object
|
|
80
82
|
end
|
81
83
|
|
82
84
|
return unless tree
|
83
|
-
method_name = "_anonymous_" +
|
84
|
-
Object.execute_tree(FastRuby.encapsulate_tree(tree,method_name), {:main => method_name, :self => self
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
objs.sort{|x,y|
|
89
|
-
File.new(x).ctime <=> File.new(y).ctime
|
90
|
-
}.each do |obj|
|
91
|
-
|
92
|
-
begin
|
93
|
-
$last_obj_proc = nil
|
94
|
-
require obj
|
95
|
-
if $last_obj_proc
|
96
|
-
FastRuby.cache.register_proc(obj, $last_obj_proc)
|
97
|
-
end
|
98
|
-
FastRuby.cache.execute(obj, self.kind_of?(Class) ? self : Object)
|
99
|
-
rescue Exception => e
|
100
|
-
p e
|
101
|
-
end
|
102
|
-
end
|
103
|
-
end
|
85
|
+
method_name = "_anonymous_" + Digest::SHA1.hexdigest(tree.inspect)
|
86
|
+
Object.execute_tree(FastRuby.encapsulate_tree(tree,method_name), {:main => method_name, :self => self}.merge(options_hash))
|
87
|
+
|
88
|
+
|
104
89
|
end
|
105
90
|
|
106
91
|
def self.execute_tree(tree,*options_hashes)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "set"
|
22
|
+
require "sexp"
|
23
|
+
require "define_method_handler"
|
24
|
+
|
25
|
+
module FastRuby
|
26
|
+
class Reductor
|
27
|
+
def when_array_to_if(array, temporal_var_name)
|
28
|
+
if array.size == 1
|
29
|
+
array[0] || fs(:nil)
|
30
|
+
else
|
31
|
+
first_when_tree = array[0]
|
32
|
+
comparers = first_when_tree[1][1..-1]
|
33
|
+
|
34
|
+
condition_tree = fs(:or)
|
35
|
+
comparers.each do |st|
|
36
|
+
condition_tree << fs(:call, st, :===, fs(:arglist, fs(:lvar, temporal_var_name)))
|
37
|
+
end
|
38
|
+
|
39
|
+
fs(:if, condition_tree, first_when_tree[2], when_array_to_if(array[1..-1], temporal_var_name) )
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
reduce_for(:case) do |tree|
|
44
|
+
temporal_var_name = "temporal_case_var_#{rand(1000000000)}".to_sym
|
45
|
+
ifs = when_array_to_if(tree[2..-1], temporal_var_name)
|
46
|
+
fs(:block, fs(:lasgn, temporal_var_name, tree[1]), ifs)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -18,19 +18,17 @@ you should have received a copy of the gnu general public license
|
|
18
18
|
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
19
|
|
20
20
|
=end
|
21
|
-
require "
|
22
|
-
require "
|
23
|
-
require "
|
24
|
-
require "fastruby/custom_require"
|
25
|
-
require "fastruby/set_tree"
|
26
|
-
require "base64"
|
27
|
-
|
28
|
-
class Object
|
29
|
-
def self.decode64(value)
|
30
|
-
Base64.decode64(value)
|
31
|
-
end
|
32
|
-
end
|
21
|
+
require "set"
|
22
|
+
require "sexp"
|
23
|
+
require "define_method_handler"
|
33
24
|
|
34
25
|
module FastRuby
|
35
|
-
|
26
|
+
class Reductor
|
27
|
+
reduce_for(:for) do |tree|
|
28
|
+
alter_tree = tree.dup
|
29
|
+
alter_tree[0] = :iter
|
30
|
+
alter_tree[1] = fs(:call, alter_tree[1], :each, fs(:arglist))
|
31
|
+
alter_tree
|
32
|
+
end
|
33
|
+
end
|
36
34
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "set"
|
22
|
+
require "sexp"
|
23
|
+
require "define_method_handler"
|
24
|
+
|
25
|
+
module FastRuby
|
26
|
+
class Reductor
|
27
|
+
define_method_handler(:reduce, :priority => -100) {|tree|
|
28
|
+
tree
|
29
|
+
}.condition{|tree| not tree.respond_to?(:node_type)}
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "set"
|
22
|
+
require "sexp"
|
23
|
+
require "define_method_handler"
|
24
|
+
|
25
|
+
module FastRuby
|
26
|
+
class Reductor
|
27
|
+
define_method_handler(:reduce, :priority => -100) {|tree|
|
28
|
+
tree.map &method(:reduce)
|
29
|
+
}.condition{|tree| tree.respond_to?(:node_type)}
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
=begin
|
2
|
+
|
3
|
+
This file is part of the fastruby project, http://github.com/tario/fastruby
|
4
|
+
|
5
|
+
Copyright (c) 2011 Roberto Dario Seminara <robertodarioseminara@gmail.com>
|
6
|
+
|
7
|
+
fastruby is free software: you can redistribute it and/or modify
|
8
|
+
it under the terms of the gnu general public license as published by
|
9
|
+
the free software foundation, either version 3 of the license, or
|
10
|
+
(at your option) any later version.
|
11
|
+
|
12
|
+
fastruby is distributed in the hope that it will be useful,
|
13
|
+
but without any warranty; without even the implied warranty of
|
14
|
+
merchantability or fitness for a particular purpose. see the
|
15
|
+
gnu general public license for more details.
|
16
|
+
|
17
|
+
you should have received a copy of the gnu general public license
|
18
|
+
along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
19
|
+
|
20
|
+
=end
|
21
|
+
require "set"
|
22
|
+
require "sexp"
|
23
|
+
require "define_method_handler"
|
24
|
+
|
25
|
+
module FastRuby
|
26
|
+
class Reductor
|
27
|
+
def self.reduce_for(ntype, options = {}, &blk)
|
28
|
+
define_method_handler(:reduce, options, &blk).condition{|tree| tree.respond_to?(:node_type) && tree.node_type == ntype}
|
29
|
+
end
|
30
|
+
|
31
|
+
define_method_handler(:reduce, :priority => -1000) do |tree|
|
32
|
+
FastRubySexp.from_sexp(tree)
|
33
|
+
end
|
34
|
+
|
35
|
+
Dir.glob(FastRuby.fastruby_load_path + "/fastruby/reductor/modules/**/*.rb").each do |path|
|
36
|
+
require path
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/fastruby/set_tree.rb
CHANGED
@@ -21,6 +21,7 @@ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
|
21
21
|
require "fastruby/builder"
|
22
22
|
require "fastruby/getlocals"
|
23
23
|
require "fastruby/method_extension"
|
24
|
+
require "fastruby/reductor/reductor"
|
24
25
|
|
25
26
|
module FastRuby
|
26
27
|
|
@@ -39,13 +40,16 @@ module FastRuby
|
|
39
40
|
def self.unset_tree(klass, method_name)
|
40
41
|
fastrubym = klass.fastruby_method(method_name)
|
41
42
|
fastrubym.tree = nil
|
43
|
+
fastrubym.tree_changed
|
42
44
|
nil
|
43
45
|
end
|
44
46
|
|
45
47
|
def self.set_tree(klass, method_name, tree, snippet_hash, options = {})
|
46
48
|
locals = Set.new
|
47
49
|
locals << :self
|
48
|
-
|
50
|
+
|
51
|
+
tree = Reductor.new.reduce tree
|
52
|
+
|
49
53
|
FastRuby::GetLocalsProcessor.get_locals(tree).each do |local|
|
50
54
|
locals << local
|
51
55
|
end
|
@@ -57,10 +61,12 @@ module FastRuby
|
|
57
61
|
end
|
58
62
|
|
59
63
|
fastrubym = klass.fastruby_method(method_name)
|
64
|
+
|
60
65
|
fastrubym.tree = tree
|
61
66
|
fastrubym.locals = locals
|
62
67
|
fastrubym.options = options
|
63
68
|
fastrubym.snippet_hash = snippet_hash
|
69
|
+
fastrubym.tree_changed
|
64
70
|
|
65
71
|
nil
|
66
72
|
end
|
@@ -19,10 +19,9 @@ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
|
|
19
19
|
|
20
20
|
=end
|
21
21
|
module FastRuby
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
class Context
|
23
|
+
|
24
|
+
define_translator_for(:yield, :method => :to_c_yield, :arity => 1)
|
26
25
|
def to_c_yield(tree)
|
27
26
|
|
28
27
|
block_code = proc { |name| "
|
@@ -94,6 +93,7 @@ module FastRuby
|
|
94
93
|
protected_block(ret, false)
|
95
94
|
end
|
96
95
|
|
96
|
+
define_translator_for(:block, :method => :to_c_block)
|
97
97
|
def to_c_block(tree, result_variable = nil)
|
98
98
|
if tree.size == 1
|
99
99
|
return inline_block("return Qnil;")
|