fastruby 0.0.19 → 0.0.20

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 (121) hide show
  1. data/CHANGELOG +8 -0
  2. data/{README → README.rdoc} +6 -1
  3. data/Rakefile +7 -7
  4. data/benchmarks/benchmark.rb~ +14 -2
  5. data/ext/fastruby_base/fastruby_base.inl +8 -4
  6. data/lib/fastruby/builder/inference_updater.rb +76 -0
  7. data/lib/fastruby/builder/inference_updater.rb~ +76 -0
  8. data/lib/fastruby/builder/inferencer.rb +38 -0
  9. data/lib/fastruby/{inliner → builder}/inliner.rb +16 -27
  10. data/lib/fastruby/builder/inliner.rb~ +60 -0
  11. data/lib/fastruby/builder/locals_inference.rb +53 -0
  12. data/lib/fastruby/builder/lvar_type.rb +43 -0
  13. data/lib/fastruby/builder/lvar_type.rb~ +44 -0
  14. data/lib/fastruby/builder/pipeline.rb +43 -0
  15. data/lib/fastruby/builder/pipeline.rb~ +43 -0
  16. data/lib/fastruby/{reductor → builder}/reductor.rb +6 -3
  17. data/lib/fastruby/builder/reductor.rb~ +42 -0
  18. data/lib/fastruby/builder.rb +73 -25
  19. data/lib/fastruby/builder.rb~ +311 -0
  20. data/lib/fastruby/corelib/fixnum.rb +75 -0
  21. data/lib/fastruby/corelib/fixnum.rb~ +146 -0
  22. data/lib/fastruby/corelib/integer.rb +96 -0
  23. data/lib/fastruby/corelib/integer.rb~ +96 -0
  24. data/lib/fastruby/corelib.rb +23 -0
  25. data/lib/fastruby/corelib.rb~ +23 -0
  26. data/lib/fastruby/getlocals.rb +3 -1
  27. data/lib/fastruby/logging.rb +2 -2
  28. data/lib/fastruby/modules/inferencer/infer.rb +31 -0
  29. data/lib/fastruby/modules/inferencer/literal.rb +42 -0
  30. data/lib/fastruby/modules/inliner/call.rb +327 -0
  31. data/lib/fastruby/{inliner/modules/call.rb → modules/inliner/call.rb~} +14 -24
  32. data/lib/fastruby/modules/inliner/defn.rb +41 -0
  33. data/lib/fastruby/modules/inliner/defn.rb~ +29 -0
  34. data/lib/fastruby/modules/inliner/recursive.rb +40 -0
  35. data/lib/fastruby/{inliner/modules/recursive.rb → modules/inliner/recursive.rb~} +1 -1
  36. data/lib/fastruby/modules/lvar_type/call.rb +36 -0
  37. data/lib/fastruby/modules/lvar_type/call.rb~ +36 -0
  38. data/lib/fastruby/modules/lvar_type/defn.rb +42 -0
  39. data/lib/fastruby/modules/lvar_type/defn.rb~ +42 -0
  40. data/lib/fastruby/modules/lvar_type/lasgn.rb +41 -0
  41. data/lib/fastruby/modules/lvar_type/lasgn.rb~ +42 -0
  42. data/lib/fastruby/modules/lvar_type/recursive.rb +33 -0
  43. data/lib/fastruby/modules/lvar_type/recursive.rb~ +33 -0
  44. data/lib/fastruby/{reductor/modules → modules/reductor}/case.rb +0 -0
  45. data/lib/fastruby/modules/reductor/fastruby_flag.rb +33 -0
  46. data/lib/fastruby/{reductor/modules → modules/reductor}/for.rb +0 -0
  47. data/lib/fastruby/{reductor/modules → modules/reductor}/nontree.rb +0 -0
  48. data/lib/fastruby/modules/reductor/nontree.rb~ +32 -0
  49. data/lib/fastruby/{reductor/modules → modules/reductor}/recursive.rb +1 -1
  50. data/lib/fastruby/modules/reductor/recursive.rb~ +31 -0
  51. data/lib/fastruby/{translator/modules → modules/translator}/block.rb +0 -0
  52. data/lib/fastruby/modules/translator/call.rb +344 -0
  53. data/lib/fastruby/{translator/modules/call.rb → modules/translator/call.rb~} +24 -3
  54. data/lib/fastruby/{translator/modules → modules/translator}/defn.rb +10 -9
  55. data/lib/fastruby/modules/translator/defn.rb~ +267 -0
  56. data/lib/fastruby/{translator/modules → modules/translator}/directive.rb +3 -1
  57. data/lib/fastruby/modules/translator/directive.rb~ +44 -0
  58. data/lib/fastruby/{translator/modules → modules/translator}/exceptions.rb +3 -1
  59. data/lib/fastruby/modules/translator/exceptions.rb~ +120 -0
  60. data/lib/fastruby/{translator/modules → modules/translator}/flow.rb +0 -0
  61. data/lib/fastruby/modules/translator/iter.rb +745 -0
  62. data/lib/fastruby/{translator/modules/iter.rb → modules/translator/iter.rb~} +103 -48
  63. data/lib/fastruby/modules/translator/literal.rb +150 -0
  64. data/lib/fastruby/{translator/modules/literal.rb → modules/translator/literal.rb~} +3 -3
  65. data/lib/fastruby/{translator/modules → modules/translator}/logical.rb +0 -0
  66. data/lib/fastruby/{translator/modules → modules/translator}/method_group.rb +0 -0
  67. data/lib/fastruby/{translator/modules → modules/translator}/nonlocal.rb +18 -6
  68. data/lib/fastruby/modules/translator/nonlocal.rb~ +298 -0
  69. data/lib/fastruby/modules/translator/static.rb +290 -0
  70. data/lib/fastruby/{translator/modules/static.rb → modules/translator/static.rb~} +66 -17
  71. data/lib/fastruby/modules/translator/variable.rb +280 -0
  72. data/lib/fastruby/{translator/modules/variable.rb → modules/translator/variable.rb~} +14 -44
  73. data/lib/fastruby/modules.rb +30 -0
  74. data/lib/fastruby/object.rb +42 -6
  75. data/lib/fastruby/object.rb~ +159 -0
  76. data/lib/fastruby/set_tree.rb +7 -11
  77. data/lib/fastruby/set_tree.rb~ +71 -0
  78. data/lib/fastruby/sexp_extension.rb +29 -7
  79. data/lib/fastruby/sexp_extension.rb~ +262 -0
  80. data/lib/fastruby/translator/scope_mode_helper.rb~ +138 -0
  81. data/lib/fastruby/translator/translator.rb +87 -92
  82. data/lib/fastruby/translator/translator.rb~ +1600 -0
  83. data/lib/fastruby/translator/translator_modules.rb +3 -1
  84. data/lib/fastruby/translator/translator_modules.rb~ +53 -0
  85. data/lib/fastruby.rb +3 -1
  86. data/lib/fastruby.rb~ +3 -1
  87. data/lib/fastruby_only/base.rb +1 -0
  88. data/spec/corelib/numeric/fixnum_spec.rb +110 -0
  89. data/spec/corelib/numeric/fixnum_spec.rb~ +104 -0
  90. data/spec/corelib/numeric/integer_spec.rb +173 -0
  91. data/spec/corelib/numeric/integer_spec.rb~ +173 -0
  92. data/spec/fastruby_only/base_spec.rb +74 -0
  93. data/spec/graph/base_spec.rb +2 -1
  94. data/spec/graph/base_spec.rb~ +35 -0
  95. data/spec/graph/path_spec.rb +2 -2
  96. data/spec/graph/path_spec.rb~ +48 -0
  97. data/spec/graph/vertex_spec.rb +2 -1
  98. data/spec/graph/vertex_spec.rb~ +58 -0
  99. data/spec/reductor/base_spec.rb +1 -1
  100. data/spec/ruby/block/lambda_spec.rb~ +163 -0
  101. data/spec/ruby/block/proc_as_block_spec.rb~ +69 -1
  102. data/spec/ruby/block_spec.rb~ +2 -494
  103. data/spec/ruby/call/base_call_spec.rb +1 -1
  104. data/spec/ruby/call/base_call_spec.rb~ +2 -60
  105. data/spec/ruby/defn/replacement_spec.rb +26 -14
  106. data/spec/ruby/defn/replacement_spec.rb~ +13 -3
  107. data/spec/ruby/exception/internal_ex_spec.rb~ +86 -0
  108. data/spec/ruby/integrity_spec.rb~ +35 -1
  109. data/spec/ruby/variable_spec.rb~ +31 -0
  110. data/spec/scope_mode/flow_spec.rb +1 -1
  111. data/spec/scope_mode/flow_spec.rb~ +109 -0
  112. data/spec/sugar/base_spec.rb +29 -0
  113. data/spec/sugar/base_spec.rb~ +16 -0
  114. metadata +100 -43
  115. data/spec/fastruby/inliner/modules/call_spec.rb +0 -0
  116. data/spec/fastruby/translator/modules/nonlocal_spec.rb +0 -0
  117. data/spec/fastruby/translator/translator_spec.rb +0 -0
  118. data/spec/ruby/block/arguments_spec.rb~ +0 -214
  119. data/spec/ruby/block/break_spec.rb~ +0 -236
  120. data/spec/ruby/block/next_spec.rb~ +0 -85
  121. data/spec/ruby/block/retry_spec.rb~ +0 -43
@@ -20,7 +20,6 @@ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
20
20
  =end
21
21
  module FastRuby
22
22
  class Context
23
-
24
23
  define_translator_for(:call, :method => :to_c_call)
25
24
  def to_c_call(tree, result_var = nil)
26
25
  repass_var = @repass_var
@@ -30,6 +29,29 @@ module FastRuby
30
29
  args = tree[3]
31
30
  args_tree = tree[3]
32
31
 
32
+ if mname == :_class
33
+ if result_var
34
+ return "#{result_var} = CLASS_OF(#{to_c(recv)});"
35
+ else
36
+ return "CLASS_OF(#{to_c(recv)})"
37
+ end
38
+ end
39
+
40
+ if mname == :_raise
41
+ if result_var
42
+ return "
43
+ #{_raise(to_c(args_tree[1]), "")};
44
+ #{result_var} = Qnil;
45
+ "
46
+ else
47
+ return inline_block lambda{"
48
+ #{_raise(to_c(args_tree[1]), "")};
49
+ return Qnil;
50
+ "}
51
+ end
52
+ end
53
+
54
+
33
55
  # search block_pass on arguments
34
56
  block_pass_arg = args.find{|arg| if arg == :arglist
35
57
  false
@@ -57,7 +79,7 @@ module FastRuby
57
79
  recvtype = infer_type(recv)
58
80
 
59
81
  if args.size > 1
60
- if (not recvtype) or args.last[0] == :splat
82
+ if (not recvtype) or args.last[0] == :splat or true
61
83
  if block_pass_arg
62
84
  call_tree = tree.dup
63
85
  call_tree[3] = args.select{|arg| if arg == :arglist
@@ -74,7 +96,6 @@ module FastRuby
74
96
  s(:lasgn, :__x_proc, s(:call, block_pass_arg[1], :to_proc, s(:arglist))),
75
97
  s(:iter, call_tree, block_arguments_tree, block_tree)
76
98
  ).to_fastruby_sexp
77
-
78
99
  if result_var
79
100
  return to_c(replace_iter_tree,result_var)
80
101
  else
@@ -44,15 +44,18 @@ module FastRuby
44
44
 
45
45
 
46
46
  if (rb_obj_is_kind_of(plocals->self, rb_cClass) || rb_obj_is_kind_of(plocals->self, rb_cModule)) {
47
- rb_define_method(plocals->self, #{method_name.to_s.inspect}, #{anonymous_method_name}, -1);
47
+
48
+ #{unless options[:fastruby_only]
49
+ "rb_define_method(plocals->self, #{method_name.to_s.inspect}, #{anonymous_method_name}, -1);"
50
+ end
51
+ }
48
52
 
49
53
  #{global_klass_variable} = plocals->self;
50
54
  // set tree
51
- rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 5,
55
+ rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 4,
52
56
  #{global_klass_variable},
53
57
  rb_str_new2(#{method_name.to_s.inspect}),
54
58
  #{literal_value tree},
55
- #{literal_value snippet_hash},
56
59
  #{literal_value alt_options}
57
60
 
58
61
  );
@@ -63,11 +66,10 @@ module FastRuby
63
66
 
64
67
  #{global_klass_variable} = CLASS_OF(obj);
65
68
  // set tree
66
- rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 5,
69
+ rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 4,
67
70
  #{global_klass_variable},
68
71
  rb_str_new2(#{method_name.to_s.inspect}),
69
72
  #{literal_value tree},
70
- #{literal_value snippet_hash},
71
73
  #{literal_value alt_options}
72
74
 
73
75
  );
@@ -109,11 +111,10 @@ module FastRuby
109
111
 
110
112
  #{global_klass_variable} = CLASS_OF(obj);
111
113
  // set tree
112
- rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 5,
114
+ rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 4,
113
115
  #{global_klass_variable},
114
116
  rb_str_new2(#{method_name.to_s.inspect}),
115
117
  #{literal_value tree},
116
- #{literal_value snippet_hash},
117
118
  #{literal_value alt_options}
118
119
 
119
120
  );
@@ -155,11 +156,11 @@ private
155
156
  method_name[1] = 0;
156
157
 
157
158
  sprintf(method_name+1, \"#{method_name}\");
158
- sprintf(method_name+strlen(method_name), \"%lu\", (unsigned long)NUM2PTR(rb_obj_id(CLASS_OF(self))));
159
+ sprintf(method_name+strlen(method_name), \"%li\", (long)NUM2PTR(rb_obj_id(CLASS_OF(self))));
159
160
 
160
161
  int i;
161
162
  for (i=0; i<argc_; i++) {
162
- sprintf(method_name+strlen(method_name), \"%lu\", (unsigned long)NUM2PTR(rb_obj_id(CLASS_OF(argv[i]))));
163
+ sprintf(method_name+strlen(method_name), \"%li\", (long)NUM2PTR(rb_obj_id(CLASS_OF(argv[i]))));
163
164
  }
164
165
 
165
166
  void** address = 0;
@@ -0,0 +1,267 @@
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
+
24
+ define_translator_for(:defn, :method => :to_c_defn)
25
+ def to_c_defn(tree, result_var = nil)
26
+
27
+ method_name = tree[1]
28
+ args_tree = tree[2].select{|x| x.to_s[0] != ?&}
29
+
30
+ global_klass_variable = add_global_name("VALUE", "Qnil");
31
+
32
+ hash = Hash.new
33
+ value_cast = ( ["VALUE"]*(args_tree.size+2) ).join(",")
34
+
35
+ strmethodargs = "self,block,(VALUE)&frame"
36
+
37
+ anonymous_method_name = anonymous_dispatcher(global_klass_variable, method_name)
38
+ alt_options = options.dup
39
+
40
+ alt_options.delete(:self)
41
+ alt_options.delete(:main)
42
+
43
+ code = "
44
+
45
+
46
+ if (rb_obj_is_kind_of(plocals->self, rb_cClass) || rb_obj_is_kind_of(plocals->self, rb_cModule)) {
47
+
48
+ #{unless options[:fastruby_only]
49
+ "rb_define_method(plocals->self, #{method_name.to_s.inspect}, #{anonymous_method_name}, -1);"
50
+ end
51
+ }
52
+
53
+ #{global_klass_variable} = plocals->self;
54
+ // set tree
55
+ rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 4,
56
+ #{global_klass_variable},
57
+ rb_str_new2(#{method_name.to_s.inspect}),
58
+ #{literal_value tree},
59
+ #{literal_value alt_options}
60
+
61
+ );
62
+
63
+ } else {
64
+ VALUE obj = plocals->self;
65
+ rb_define_singleton_method(obj, #{method_name.to_s.inspect}, #{anonymous_method_name}, -1 );
66
+
67
+ #{global_klass_variable} = CLASS_OF(obj);
68
+ // set tree
69
+ rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 4,
70
+ #{global_klass_variable},
71
+ rb_str_new2(#{method_name.to_s.inspect}),
72
+ #{literal_value tree},
73
+ #{literal_value alt_options}
74
+
75
+ );
76
+ }
77
+
78
+ "
79
+
80
+ if result_var
81
+ code + "\n#{result_var} = Qnil;"
82
+ else
83
+ inline_block code + "\nreturn Qnil;\n"
84
+ end
85
+ end
86
+
87
+ define_translator_for(:defs, :method => :to_c_defs)
88
+ def to_c_defs(tree, result_var = nil)
89
+ method_name = tree[2]
90
+ args_tree = tree[3].select{|x| x.to_s[0] != ?&}
91
+
92
+ global_klass_variable = add_global_name("VALUE", "Qnil");
93
+
94
+ hash = Hash.new
95
+ value_cast = ( ["VALUE"]*(args_tree.size+2) ).join(",")
96
+
97
+ strmethodargs = "self,block,(VALUE)&frame"
98
+
99
+ anonymous_method_name = anonymous_dispatcher(global_klass_variable, method_name)
100
+
101
+ alt_options = options.dup
102
+
103
+ alt_options.delete(:self)
104
+ alt_options.delete(:main)
105
+
106
+ code = "
107
+
108
+ VALUE obj = Qnil;
109
+ #{to_c tree[1], "obj"};
110
+ rb_define_singleton_method(obj, #{method_name.to_s.inspect}, #{anonymous_method_name}, -1 );
111
+
112
+ #{global_klass_variable} = CLASS_OF(obj);
113
+ // set tree
114
+ rb_funcall(#{literal_value FastRuby}, #{intern_num :set_tree}, 4,
115
+ #{global_klass_variable},
116
+ rb_str_new2(#{method_name.to_s.inspect}),
117
+ #{literal_value tree},
118
+ #{literal_value alt_options}
119
+
120
+ );
121
+
122
+ "
123
+
124
+ if result_var
125
+ code + "\n#{result_var} = Qnil;"
126
+ else
127
+ inline_block code + "\nreturn Qnil;\n"
128
+ end
129
+
130
+ end
131
+
132
+ define_translator_for(:scope, :method => :to_c_scope)
133
+ def to_c_scope(tree, result_var = nil)
134
+ if tree[1]
135
+ if result_var
136
+ to_c(tree[1], result_var)
137
+ else
138
+ to_c(tree[1])
139
+ end
140
+ else
141
+ "Qnil"
142
+ end
143
+ end
144
+
145
+ private
146
+
147
+ def anonymous_dispatcher(global_klass_variable, method_name)
148
+
149
+ strmethodargs = "self,block,(VALUE)&frame"
150
+
151
+ anonymous_function{ |anonymous_method_name| "VALUE #{anonymous_method_name}(int argc_, VALUE* argv, VALUE self) {
152
+ VALUE klass = #{global_klass_variable};
153
+ char method_name[argc_*40+64];
154
+
155
+ method_name[0] = '_';
156
+ method_name[1] = 0;
157
+
158
+ sprintf(method_name+1, \"#{method_name}\");
159
+ sprintf(method_name+strlen(method_name), \"%l\", (long)NUM2PTR(rb_obj_id(CLASS_OF(self))));
160
+
161
+ int i;
162
+ for (i=0; i<argc_; i++) {
163
+ sprintf(method_name+strlen(method_name), \"%l\", (long)NUM2PTR(rb_obj_id(CLASS_OF(argv[i]))));
164
+ }
165
+
166
+ void** address = 0;
167
+ void* fptr = 0;
168
+ ID id;
169
+ VALUE rb_method_hash;
170
+
171
+ id = rb_intern(method_name);
172
+ rb_method_hash = rb_funcall(klass, #{intern_num :method_hash},1,#{literal_value method_name});
173
+
174
+ if (rb_method_hash != Qnil) {
175
+ VALUE tmp = rb_hash_aref(rb_method_hash, PTR2NUM(id));
176
+ if (tmp != Qnil) {
177
+ address = (void**)NUM2PTR(tmp);
178
+ fptr = *address;
179
+ }
180
+ }
181
+
182
+ if (fptr == 0) {
183
+ VALUE argv_class[argc_+1];
184
+
185
+ argv_class[0] = CLASS_OF(self);
186
+ for (i=0; i<argc_; i++) {
187
+ argv_class[i+1] = CLASS_OF(argv[i]);
188
+ }
189
+
190
+ VALUE signature = rb_ary_new4(argc_+1,argv_class);
191
+
192
+ rb_funcall(#{global_klass_variable}, #{intern_num :build}, 2, signature,rb_str_new2(#{method_name.to_s.inspect}));
193
+
194
+ id = rb_intern(method_name);
195
+ rb_method_hash = rb_funcall(klass, #{intern_num :method_hash},1,#{literal_value method_name});
196
+
197
+ if (rb_method_hash != Qnil) {
198
+ VALUE tmp = rb_hash_aref(rb_method_hash, PTR2NUM(id));
199
+ if (tmp != Qnil) {
200
+ address = (void**)NUM2PTR(tmp);
201
+ fptr = *address;
202
+ }
203
+ }
204
+
205
+ if (fptr == 0) {
206
+ rb_raise(rb_eRuntimeError, \"Error: method not found after build\");
207
+ }
208
+
209
+ }
210
+
211
+ struct {
212
+ void* parent_frame;
213
+ void* plocals;
214
+ jmp_buf jmp;
215
+ VALUE return_value;
216
+ int rescue;
217
+ VALUE last_error;
218
+ VALUE next_recv;
219
+ int targetted;
220
+ struct FASTRUBYTHREADDATA* thread_data;
221
+ } frame;
222
+
223
+ frame.parent_frame = 0;
224
+ frame.rescue = 0;
225
+ frame.return_value = Qnil;
226
+ frame.thread_data = rb_current_thread_data();
227
+ frame.targetted = 0;
228
+
229
+ volatile VALUE block = Qfalse;
230
+
231
+ if (rb_block_given_p()) {
232
+ struct {
233
+ void* block_function_address;
234
+ void* block_function_param;
235
+ VALUE proc;
236
+ } block_struct;
237
+
238
+ block_struct.block_function_address = re_yield;
239
+ block_struct.block_function_param = 0;
240
+ block_struct.proc = rb_block_proc();
241
+
242
+ block = (VALUE)&block_struct;
243
+ }
244
+
245
+ int aux = setjmp(frame.jmp);
246
+ if (aux != 0) {
247
+ if (aux == FASTRUBY_TAG_RAISE) {
248
+ rb_funcall(self, #{intern_num :raise}, 1, frame.thread_data->exception);
249
+ }
250
+
251
+ if (frame.targetted == 0) {
252
+ frb_jump_tag(aux);
253
+ }
254
+
255
+ return Qnil;
256
+ }
257
+
258
+ VALUE tmp = Qnil;
259
+ if (argv == 0) argv = &tmp;
260
+
261
+ return ((VALUE(*)(VALUE,VALUE,VALUE,int,VALUE*))fptr)(#{strmethodargs}, argc_, argv);
262
+ }"
263
+ }
264
+
265
+ end
266
+ end
267
+ end
@@ -21,7 +21,9 @@ along with fastruby. if not, see <http://www.gnu.org/licenses/>.
21
21
  module FastRuby
22
22
  class Context
23
23
 
24
- define_translator_for(:call, :priority => 100){ |tree, result_var=nil|
24
+ define_translator_for(:call, :priority => 100){ |*x|
25
+ tree, result_var = x
26
+
25
27
  directive_code = directive(tree)
26
28
 
27
29
  if result_var
@@ -0,0 +1,44 @@
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
+
24
+ define_translator_for(:call, :priority => 100){ |*x|
25
+ tree, result_var = x
26
+
27
+ directive_code = directive(tree)
28
+
29
+ if result_var
30
+ return "#{result_var} = #{directive_code};\n"
31
+ else
32
+ return directive_code
33
+ end
34
+
35
+ }.condition{|*x|
36
+ tree = x.first; tree.node_type == :call && directive(tree)
37
+ }
38
+
39
+ define_translator_for(:call, :method => :to_c_attrasgn, :arity => 1)
40
+ def to_c_attrasgn(tree)
41
+ to_c_call(tree)
42
+ end
43
+ end
44
+ end
@@ -107,7 +107,9 @@ module FastRuby
107
107
  end
108
108
  end
109
109
 
110
- define_translator_for(:call, :priority => 100){ |tree, result_var=nil|
110
+ define_translator_for(:call, :priority => 100){ |*x|
111
+ tree, result_var = x
112
+
111
113
  # raise code
112
114
  args = tree[3]
113
115
  _raise(args[1],args[2])
@@ -0,0 +1,120 @@
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
+
24
+ define_translator_for(:rescue, :method => :to_c_rescue, :arity => 1)
25
+ def to_c_rescue(tree)
26
+ catch_on_throw do
27
+ if tree[1][0] == :resbody
28
+ else_tree = tree[2]
29
+
30
+ if else_tree
31
+ to_c else_tree
32
+ else
33
+ "Qnil"
34
+ end
35
+ else
36
+ resbody_tree = tree[2]
37
+ else_tree = nil
38
+ if tree[-1]
39
+ if tree[-1][0] != :resbody
40
+ else_tree = tree[-1]
41
+ end
42
+ end
43
+
44
+ catch_condition_array = []
45
+ lasgn_code = ""
46
+ resbody_code = to_c(resbody_tree[2])
47
+
48
+ rescue_code = ""
49
+
50
+ tree[1..-1].each do |resbody_tree|
51
+ next if resbody_tree[0] != :resbody
52
+
53
+ if resbody_tree[1].size == 1
54
+ resbody_tree[1][1] = s(:const, :Exception)
55
+ end
56
+
57
+ if resbody_tree[1].last[0] == :lasgn
58
+ lasgn_code = to_c(resbody_tree[1].last)
59
+ end
60
+
61
+ resbody_tree[1][1..-1].each do |xtree|
62
+ if xtree[0] != :lasgn
63
+ trapcode = "rb_eException";
64
+
65
+ if xtree
66
+ trapcode = to_c(xtree)
67
+ end
68
+
69
+ catch_condition_array << "(rb_obj_is_kind_of(frame.thread_data->exception,#{trapcode}) == Qtrue)"
70
+ end
71
+ end
72
+
73
+ rescue_code << "
74
+ if (aux == FASTRUBY_TAG_RAISE) {
75
+ if (#{catch_condition_array.join(" || ")})
76
+ {
77
+ // trap exception
78
+ frame.targetted = 1;
79
+
80
+ #{lasgn_code};
81
+
82
+ #{resbody_code};
83
+ }
84
+ }
85
+ "
86
+ end
87
+
88
+ frame_call(
89
+ "ret = " + frame(to_c(tree[1])+";","
90
+ #{rescue_code}
91
+ ", else_tree ? to_c(else_tree) : nil, 1)
92
+
93
+ )
94
+ end
95
+ end
96
+ end
97
+
98
+ define_translator_for(:ensure, :method => :to_c_ensure, :arity => 1)
99
+ def to_c_ensure(tree)
100
+ if tree.size == 2
101
+ to_c tree[1]
102
+ else
103
+ ensured_code = to_c tree[2]
104
+ inline_block {
105
+ "#{frame(to_c(tree[1]),ensured_code,ensured_code,1)};"
106
+ }
107
+ end
108
+ end
109
+
110
+ define_translator_for(:call, :priority => 100){ |*x|
111
+ tree, result_var = x
112
+
113
+ # raise code
114
+ args = tree[3]
115
+ _raise(args[1],args[2])
116
+ }.condition{|*x|
117
+ tree = x.first; tree.node_type == :call && tree[2] == :raise
118
+ }
119
+ end
120
+ end