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.
Files changed (67) hide show
  1. data/CHANGELOG +10 -0
  2. data/Rakefile +4 -2
  3. data/benchmarks/benchmark.rb +20 -44
  4. data/benchmarks/benchmark.rb~ +47 -0
  5. data/benchmarks/benchmark2.rb +19 -45
  6. data/benchmarks/benchmark2.rb~ +46 -0
  7. data/benchmarks/benchmark3.rb +19 -45
  8. data/benchmarks/benchmark3.rb~ +46 -0
  9. data/benchmarks/benchmark4.rb +30 -65
  10. data/benchmarks/benchmark4.rb~ +61 -0
  11. data/benchmarks/benchmark5.rb +25 -55
  12. data/benchmarks/benchmark5.rb~ +54 -0
  13. data/benchmarks/benchmark6.rb +19 -40
  14. data/benchmarks/benchmark6.rb~ +41 -0
  15. data/benchmarks/benchmark7.rb +23 -52
  16. data/benchmarks/benchmark7.rb~ +48 -0
  17. data/ext/fastruby_base/fastruby_base.inl +1 -0
  18. data/lib/fastruby/builder.rb +128 -76
  19. data/lib/fastruby/cache/cache.rb +9 -5
  20. data/lib/fastruby/fastruby_sexp.rb +18 -0
  21. data/lib/fastruby/inliner/inliner.rb +68 -0
  22. data/lib/fastruby/inliner/modules/call.rb +150 -0
  23. data/lib/fastruby/inliner/modules/recursive.rb +35 -0
  24. data/lib/fastruby/object.rb +17 -32
  25. data/lib/fastruby/reductor/modules/case.rb +49 -0
  26. data/lib/{fastruby.rb~ → fastruby/reductor/modules/for.rb} +11 -13
  27. data/lib/fastruby/reductor/modules/nontree.rb +31 -0
  28. data/lib/fastruby/reductor/modules/recursive.rb +31 -0
  29. data/lib/fastruby/reductor/reductor.rb +39 -0
  30. data/lib/fastruby/set_tree.rb +7 -1
  31. data/lib/fastruby/sexp_extension.rb +6 -0
  32. data/lib/fastruby/translator/modules/block.rb +4 -4
  33. data/lib/fastruby/translator/modules/call.rb +9 -26
  34. data/lib/fastruby/translator/modules/defn.rb +5 -3
  35. data/lib/fastruby/translator/modules/directive.rb +42 -0
  36. data/lib/fastruby/translator/modules/exceptions.rb +12 -30
  37. data/lib/fastruby/translator/modules/flow.rb +33 -83
  38. data/lib/fastruby/translator/modules/iter.rb +4 -7
  39. data/lib/fastruby/translator/modules/literal.rb +11 -25
  40. data/lib/fastruby/translator/modules/logical.rb +5 -3
  41. data/lib/fastruby/translator/modules/method_group.rb +4 -3
  42. data/lib/fastruby/translator/modules/nonlocal.rb +7 -5
  43. data/lib/fastruby/translator/modules/static.rb +242 -0
  44. data/lib/fastruby/translator/modules/variable.rb +16 -9
  45. data/lib/fastruby/translator/scope_mode_helper.rb +2 -27
  46. data/lib/fastruby/translator/translator.rb +131 -60
  47. data/lib/fastruby/translator/translator_modules.rb +6 -2
  48. data/lib/fastruby.rb +1 -1
  49. data/spec/reductor/base_spec.rb +46 -0
  50. data/spec/ruby/base_spec.rb~ +394 -0
  51. data/spec/ruby/block/arguments_spec.rb~ +214 -0
  52. data/spec/ruby/block/proc_as_block_spec.rb~ +23 -0
  53. data/spec/ruby/block/retry_spec.rb~ +43 -0
  54. data/spec/ruby/block_spec.rb~ +520 -0
  55. data/spec/ruby/defn/replacement_spec.rb~ +102 -0
  56. data/spec/ruby/integrity_spec.rb~ +40 -0
  57. data/spec/ruby/singleton_spec.rb~ +76 -0
  58. data/spec/scope_mode/base_spec.rb +14 -5
  59. data/spec/scope_mode/block_spec.rb +18 -9
  60. data/spec/scope_mode/call_spec.rb +11 -2
  61. data/spec/scope_mode/exception_spec.rb +11 -2
  62. data/spec/scope_mode/flow_spec.rb +18 -8
  63. data/spec/scope_mode/optimization_spec.rb +21 -13
  64. data/spec/static/base_spec.rb +54 -0
  65. data/spec/static/flow_spec.rb +48 -0
  66. data/spec/static/operator_spec.rb +104 -0
  67. metadata +58 -8
@@ -0,0 +1,242 @@
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
+ module FastRuby
22
+ class Context
23
+ define_translator_for(:iter, :arity => 1, :priority => 1) { |*x|
24
+ ret = nil
25
+ tree = x.first
26
+
27
+ enable_handler_group(:static_call) do
28
+ ret = x.size == 1 ? to_c(tree[3]) : to_c(tree[3], x.last)
29
+ end
30
+ ret
31
+ }.condition{ |*x|
32
+ tree = x.first
33
+ tree.node_type == :iter && tree[1][2] == :_static
34
+ }
35
+
36
+ define_translator_for(:iter, :arity => 1, :priority => 1) { |*x|
37
+ ret = nil
38
+ tree = x.first
39
+
40
+ disable_handler_group(:static_call) do
41
+ ret = x.size == 1 ? to_c(tree[3]) : to_c(tree[3], x.last)
42
+ end
43
+ ret
44
+ }.condition{ |*x|
45
+ tree = x.first
46
+ tree.node_type == :iter && tree[1][2] == :_dynamic
47
+ }
48
+
49
+ handler_scope(:group => :static_call, :priority => 1000) do
50
+ define_translator_for(:call) do |tree, result=nil|
51
+ method_name = tree[2].to_s
52
+ recv_tree = tree[1]
53
+
54
+ if recv_tree
55
+ if (not tree[2].to_s =~ /^[a-zA-Z]/) and tree[2].to_s.size <= 3
56
+ c_op = tree[2].to_s
57
+ c_op = '==' if tree[2] == :===
58
+ code = "( ( #{to_c(tree[1])} )#{c_op}(#{to_c(tree[3][1])}) )"
59
+ else
60
+ raise "invalid static call #{method_name}"
61
+ end
62
+ else
63
+ args = tree[3][1..-1].map(&method(:to_c)).join(",")
64
+ code = "#{method_name}( #{args} )"
65
+ end
66
+
67
+ if result
68
+ "#{result} = #{code};"
69
+ else
70
+ code
71
+ end
72
+ end
73
+
74
+ define_translator_for(:lit) do |tree, result=nil|
75
+ if result
76
+ "#{result} = #{tree[1]};"
77
+ else
78
+ tree[1].to_s
79
+ end
80
+ end
81
+
82
+ define_translator_for(:if) do |tree, result_variable_ = nil|
83
+ condition_tree = tree[1]
84
+ impl_tree = tree[2]
85
+ else_tree = tree[3]
86
+
87
+ result_variable = result_variable_ || "last_expression"
88
+
89
+ code = "
90
+ {
91
+ VALUE condition_result;
92
+ #{to_c condition_tree, "condition_result"};
93
+ if (condition_result) {
94
+ #{to_c impl_tree, result_variable};
95
+ }#{else_tree ?
96
+ " else {
97
+ #{to_c else_tree, result_variable};
98
+ }
99
+ " : ""
100
+ }
101
+ }
102
+ "
103
+
104
+ if result_variable_
105
+ code
106
+ else
107
+ inline_block code + "; return last_expression;"
108
+ end
109
+ end
110
+
111
+ define_translator_for(:while) do |tree, result_var = nil|
112
+ begin_while = "begin_while_"+rand(10000000).to_s
113
+ end_while = "end_while_"+rand(10000000).to_s
114
+ aux_varname = "_aux_" + rand(10000000).to_s
115
+ code = "
116
+ {
117
+ VALUE while_condition;
118
+ VALUE #{aux_varname};
119
+
120
+ #{begin_while}:
121
+ #{to_c tree[1], "while_condition"};
122
+ if (!(while_condition)) goto #{end_while};
123
+ #{to_c tree[2], aux_varname};
124
+ goto #{begin_while};
125
+ #{end_while}:
126
+
127
+ #{
128
+ if result_var
129
+ "#{result_var} = Qnil;"
130
+ else
131
+ "return Qnil;"
132
+ end
133
+ }
134
+ }
135
+ "
136
+
137
+ if result_var
138
+ code
139
+ else
140
+ inline_block code
141
+ end
142
+
143
+ end
144
+
145
+ define_translator_for(:and) do |tree, return_var = nil|
146
+ if return_var
147
+ "
148
+ {
149
+ VALUE op1 = Qnil;
150
+ VALUE op2 = Qnil;
151
+ #{to_c tree[1], "op1"};
152
+ #{to_c tree[2], "op2"};
153
+ #{return_var} = ((op1) &&(op2));
154
+ }
155
+ "
156
+ else
157
+ "((#{to_c tree[1]}) && (#{to_c tree[2]}))"
158
+ end
159
+
160
+ end
161
+
162
+ define_translator_for(:or) do |tree, return_var = nil|
163
+ if return_var
164
+ "
165
+ {
166
+ VALUE op1 = Qnil;
167
+ VALUE op2 = Qnil;
168
+ #{to_c tree[1], "op1"};
169
+ #{to_c tree[2], "op2"};
170
+ #{return_var} = ((op1) ||(op2));
171
+ }
172
+ "
173
+ else
174
+ "((#{to_c tree[1]}) || (#{to_c tree[2]}))"
175
+ end
176
+
177
+ end
178
+
179
+ define_translator_for(:not) do |tree, return_var = nil|
180
+ if return_var
181
+ "
182
+ {
183
+ VALUE op1 = Qnil;
184
+ #{to_c tree[1], "op1"};
185
+ #{return_var} = ((op1) ? 0: 1);
186
+ }
187
+ "
188
+ else
189
+ "((#{to_c tree[1]}) ? 0 : 1)"
190
+ end
191
+ end
192
+
193
+ end
194
+
195
+ define_method_handler(:initialize_to_c){|*x|}.condition do |*x|
196
+ disable_handler_group(:static_call, :to_c); false
197
+ end
198
+
199
+
200
+ define_method_handler(:infer_value) { |tree|
201
+ Value.new(eval(tree[1].to_s))
202
+ }.condition{|tree| tree.node_type == :const}
203
+
204
+ define_method_handler(:infer_value) { |tree|
205
+ args_tree = tree[3]
206
+ receiver_tree = tree[1]
207
+
208
+ value_1 = infer_value(receiver_tree)
209
+ value_2 = infer_value(args_tree[1])
210
+
211
+ next false unless (value_1 and value_2)
212
+
213
+ Value.new(value_1.value == value_2.value)
214
+ }.condition{|tree|
215
+ next false unless tree.node_type == :call
216
+
217
+ args_tree = tree[3]
218
+ method_name = tree[2]
219
+
220
+ next false unless method_name == :==
221
+ next false if args_tree.size < 2
222
+
223
+ true
224
+ }
225
+ define_method_handler(:infer_value) { |tree|
226
+ args_tree = tree[3]
227
+ receiver_tree = tree[1]
228
+ infered_type = infer_type(receiver_tree)
229
+
230
+ if infered_type
231
+ Value.new(infered_type)
232
+ else
233
+ nil
234
+ end
235
+ }.condition{|tree|
236
+ next false unless tree.node_type == :call
237
+ method_name = tree[2]
238
+ next false unless method_name == :_class
239
+ true
240
+ }
241
+ end
242
+ end
@@ -19,14 +19,13 @@ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
19
19
 
20
20
  =end
21
21
  module FastRuby
22
- module VariabeTranslator
23
- register_translator_module self
24
-
25
-
22
+ class Context
23
+ define_translator_for(:cvar, :method => :to_c_cvar, :arity => 1)
26
24
  def to_c_cvar(tree)
27
25
  "rb_cvar_get(CLASS_OF(plocals->self) != rb_cClass ? CLASS_OF(plocals->self) : plocals->self,#{intern_num tree[1]})"
28
26
  end
29
27
 
28
+ define_translator_for(:cvasgn, :method => :to_c_cvasgn)
30
29
  def to_c_cvasgn(tree, result_var = nil)
31
30
  if result_var
32
31
  "
@@ -50,6 +49,7 @@ module FastRuby
50
49
  end
51
50
  end
52
51
 
52
+ define_translator_for(:gvar, :method => :to_c_gvar, :arity => 1)
53
53
  def to_c_gvar(tree)
54
54
  if (tree[1] == :$!)
55
55
  "pframe->thread_data->exception"
@@ -58,6 +58,7 @@ module FastRuby
58
58
  end
59
59
  end
60
60
 
61
+ define_translator_for(:gasgn, :method => :to_c_gasgn)
61
62
  def to_c_gasgn(tree, result_var = nil)
62
63
  if result_var
63
64
  "
@@ -71,10 +72,12 @@ module FastRuby
71
72
  end
72
73
  end
73
74
 
75
+ define_translator_for(:ivar, :method => :to_c_ivar, :arity => 1)
74
76
  def to_c_ivar(tree)
75
77
  "rb_ivar_get(#{locals_accessor}self,#{intern_num tree[1]})"
76
78
  end
77
79
 
80
+ define_translator_for(:iasgn, :method => :to_c_iasgn)
78
81
  def to_c_iasgn(tree, result_var = nil)
79
82
  if result_var
80
83
  "
@@ -88,10 +91,11 @@ module FastRuby
88
91
  end
89
92
  end
90
93
 
91
- def to_c_const(tree)
94
+ define_translator_for(:const, :arity => 1) do |tree|
92
95
  "rb_const_get(CLASS_OF(plocals->self), #{intern_num(tree[1])})"
93
96
  end
94
97
 
98
+ define_translator_for(:cdecl, :method => :to_c_cdecl)
95
99
  def to_c_cdecl(tree, result_var_ = nil)
96
100
 
97
101
  result_var = result_var_ || "value"
@@ -136,10 +140,12 @@ module FastRuby
136
140
  end
137
141
  end
138
142
 
143
+ define_translator_for(:colon3, :method => :to_c_colon3, :arity => 1)
139
144
  def to_c_colon3(tree)
140
145
  "rb_const_get_from(rb_cObject, #{intern_num tree[1]})"
141
146
  end
142
-
147
+
148
+ define_translator_for(:colon2, :method => :to_c_colon2)
143
149
  def to_c_colon2(tree, result_var = nil)
144
150
  code = "
145
151
  {
@@ -194,6 +200,7 @@ module FastRuby
194
200
  end
195
201
  end
196
202
 
203
+ define_translator_for(:lasgn, :method => :to_c_lasgn)
197
204
  def to_c_lasgn(tree, result_var = nil)
198
205
  code = "
199
206
  {
@@ -244,12 +251,12 @@ module FastRuby
244
251
  end
245
252
  end
246
253
  end
247
-
248
- def to_c_lvar(tree)
254
+
255
+ define_translator_for(:lvar, :arity => 1) do |tree|
249
256
  locals_accessor + tree[1].to_s
250
257
  end
251
258
 
252
-
259
+ define_translator_for(:defined, :method => :to_c_defined, :arity => 1)
253
260
  def to_c_defined(tree)
254
261
  nt = tree[1].node_type
255
262
 
@@ -26,34 +26,8 @@ module FastRuby
26
26
  new.get_scope_mode(tree_)
27
27
  end
28
28
 
29
- def when_array_to_if(array)
30
- if array.size == 1
31
- array[0] || s(:nil)
32
- else
33
- first_when_tree = array[0]
34
- comparers = first_when_tree[1][1..-1]
35
-
36
- condition_tree = s(:or)
37
- comparers.each do |st|
38
- condition_tree << s(:call, st, :===, s(:arglist, s(:lvar, :temporal_case_var)))
39
- end
40
-
41
- s(:if, condition_tree, first_when_tree[2], when_array_to_if(array[1..-1]) )
42
- end
43
- end
44
-
45
29
  def get_scope_mode(tree_)
46
- tree = FastRuby::FastRubySexp.from_sexp(tree_).transform do |subtree|
47
- if subtree.node_type == :for
48
- s(:iter,s(:call, subtree[1],:each, s(:arglist)),subtree[2], subtree[3] )
49
- elsif subtree.node_type == :case
50
- ifs = when_array_to_if(subtree[2..-1])
51
-
52
- s(:block, s(:lasgn, :temporal_case_var, subtree[1]), ifs)
53
- else
54
- nil
55
- end
56
- end
30
+ tree = FastRuby::FastRubySexp.from_sexp(tree_)
57
31
 
58
32
  if tree.node_type == :defn
59
33
  args_tree = tree[2]
@@ -95,6 +69,7 @@ module FastRuby
95
69
  writes = Set.new
96
70
 
97
71
  path.each do |st2|
72
+ next unless st2
98
73
  if st2.node_type == :call
99
74
  if has_call and st2[1] == nil
100
75
  return :dag