fastruby 0.0.17 → 0.0.18
Sign up to get free protection for your applications and to get access to all the features.
- 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;")
|