fastruby 0.0.16 → 0.0.17

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 (78) hide show
  1. data/CHANGELOG +17 -1
  2. data/Rakefile +1 -1
  3. data/ext/fastruby_base/fastruby_base.inl +81 -3
  4. data/lib/fastruby/fastruby_sexp.rb +21 -0
  5. data/lib/fastruby/getlocals.rb +2 -1
  6. data/lib/fastruby/object.rb +1 -1
  7. data/lib/fastruby/sexp_extension.rb +189 -0
  8. data/lib/fastruby/sexp_extension_edges.rb +210 -0
  9. data/lib/fastruby/translator/modules/block.rb +29 -22
  10. data/lib/fastruby/translator/modules/call.rb +211 -34
  11. data/lib/fastruby/translator/modules/defn.rb +64 -29
  12. data/lib/fastruby/translator/modules/exceptions.rb +1 -1
  13. data/lib/fastruby/translator/modules/flow.rb +93 -31
  14. data/lib/fastruby/translator/modules/iter.rb +277 -340
  15. data/lib/fastruby/translator/modules/literal.rb +97 -20
  16. data/lib/fastruby/translator/modules/logical.rb +40 -5
  17. data/lib/fastruby/translator/modules/method_group.rb +41 -19
  18. data/lib/fastruby/translator/modules/nonlocal.rb +74 -29
  19. data/lib/fastruby/translator/modules/variable.rb +151 -42
  20. data/lib/fastruby/translator/scope_mode_helper.rb +161 -0
  21. data/lib/fastruby/translator/translator.rb +389 -302
  22. data/lib/fastruby.rb +1 -1
  23. data/lib/fastruby.rb~ +36 -0
  24. data/spec/edges_helper.rb +91 -0
  25. data/spec/graph/base_spec.rb +35 -0
  26. data/spec/graph/path_spec.rb +48 -0
  27. data/spec/graph/vertex_spec.rb +58 -0
  28. data/spec/ruby/block/proc_as_block_spec.rb +214 -0
  29. data/spec/ruby/block/redo_spec.rb +133 -0
  30. data/spec/ruby/defn/single_function_spec.rb +50 -0
  31. data/spec/scope_mode/base_spec.rb +55 -0
  32. data/spec/scope_mode/block_spec.rb +105 -0
  33. data/spec/scope_mode/call_spec.rb +24 -0
  34. data/spec/scope_mode/exception_spec.rb +34 -0
  35. data/spec/scope_mode/flow_spec.rb +99 -0
  36. data/spec/scope_mode/optimization_spec.rb +130 -0
  37. data/spec/sexp2graph/base_spec.rb +36 -0
  38. data/spec/sexp2graph/exception_spec.rb +172 -0
  39. data/spec/sexp2graph/flow_spec.rb +67 -0
  40. data/spec/sexp2graph/logical_spec.rb +21 -0
  41. data/spec/sexp2graph/variable_spec.rb +26 -0
  42. metadata +110 -120
  43. data/lib/fastruby/self +0 -82
  44. data/lib/len +0 -280
  45. data/spec/block/proc_as_block_spec.rb +0 -111
  46. data/spec/block/redo_spec.rb +0 -67
  47. /data/spec/{base_spec.rb → ruby/base_spec.rb} +0 -0
  48. /data/spec/{block → ruby/block}/arguments_spec.rb +0 -0
  49. /data/spec/{block → ruby/block}/block_as_proc_spec.rb +0 -0
  50. /data/spec/{block → ruby/block}/break_spec.rb +0 -0
  51. /data/spec/{block → ruby/block}/callcc_spec.rb +0 -0
  52. /data/spec/{block → ruby/block}/lambda_spec.rb +0 -0
  53. /data/spec/{block → ruby/block}/next_spec.rb +0 -0
  54. /data/spec/{block → ruby/block}/proc_spec.rb +0 -0
  55. /data/spec/{block → ruby/block}/retry_spec.rb +0 -0
  56. /data/spec/{block_spec.rb → ruby/block_spec.rb} +0 -0
  57. /data/spec/{call → ruby/call}/base_call_spec.rb +0 -0
  58. /data/spec/{call → ruby/call}/multiple_args_spec.rb +0 -0
  59. /data/spec/{control_spec.rb → ruby/control_spec.rb} +0 -0
  60. /data/spec/{defn → ruby/defn}/default_args_spec.rb +0 -0
  61. /data/spec/{defn → ruby/defn}/multiple_args_spec.rb +0 -0
  62. /data/spec/{defn → ruby/defn}/replacement_spec.rb +0 -0
  63. /data/spec/{exception → ruby/exception}/base_spec.rb +0 -0
  64. /data/spec/{exception → ruby/exception}/ensure_spec.rb +0 -0
  65. /data/spec/{exception → ruby/exception}/exc_trap_spec.rb +0 -0
  66. /data/spec/{exception → ruby/exception}/internal_ex_spec.rb +0 -0
  67. /data/spec/{exception → ruby/exception}/syntaxis_spec.rb +0 -0
  68. /data/spec/{expression_spec.rb → ruby/expression_spec.rb} +0 -0
  69. /data/spec/{flow_control → ruby/flow_control}/case_spec.rb +0 -0
  70. /data/spec/{flow_control → ruby/flow_control}/for_spec.rb +0 -0
  71. /data/spec/{integrity_spec.rb → ruby/integrity_spec.rb} +0 -0
  72. /data/spec/{jump → ruby/jump}/next_spec.rb +0 -0
  73. /data/spec/{literal_spec.rb → ruby/literal_spec.rb} +0 -0
  74. /data/spec/{module_spec.rb → ruby/module_spec.rb} +0 -0
  75. /data/spec/{return_spec.rb → ruby/return_spec.rb} +0 -0
  76. /data/spec/{singleton_spec.rb → ruby/singleton_spec.rb} +0 -0
  77. /data/spec/{sugar_spec.rb → ruby/sugar_spec.rb} +0 -0
  78. /data/spec/{variable_spec.rb → ruby/variable_spec.rb} +0 -0
@@ -34,35 +34,81 @@ module FastRuby
34
34
  literal_value tree[1]
35
35
  end
36
36
 
37
- def to_c_hash(tree)
37
+ def to_c_hash(tree, result_var = nil)
38
+
39
+ hash_tmp_var = "_hash_"+rand(1000000).to_s
40
+ key_tmp_var = "_key_"+rand(1000000).to_s
41
+ value_tmp_var = "_value_"+rand(1000000).to_s
38
42
 
39
43
  hash_aset_code = ""
40
44
  (0..(tree.size-3)/2).each do |i|
41
45
  strkey = to_c tree[1 + i * 2]
42
46
  strvalue = to_c tree[2 + i * 2]
43
- hash_aset_code << "rb_hash_aset(hash, #{strkey}, #{strvalue});"
47
+ hash_aset_code << "
48
+ {
49
+ VALUE #{key_tmp_var} = Qnil;
50
+ VALUE #{value_tmp_var} = Qnil;
51
+
52
+ #{to_c tree[1 + i * 2], key_tmp_var};
53
+ #{to_c tree[2 + i * 2], value_tmp_var};
54
+
55
+ rb_hash_aset(#{hash_tmp_var}, #{key_tmp_var}, #{value_tmp_var});
56
+ }
57
+ "
58
+ end
59
+
60
+ code = "
61
+ {
62
+ VALUE #{hash_tmp_var} = rb_hash_new();
63
+ #{hash_aset_code};
64
+ #{
65
+ if result_var
66
+ "#{result_var} = #{hash_tmp_var}"
67
+ else
68
+ "return #{hash_tmp_var}"
69
+ end
70
+ };
71
+ }
72
+ "
73
+
74
+ if result_var
75
+ code
76
+ else
77
+ inline_block code
44
78
  end
45
-
46
- anonymous_function{ |name| "
47
- static VALUE #{name}(VALUE value_params) {
48
- #{@frame_struct} *pframe;
49
- #{@locals_struct} *plocals;
50
- pframe = (void*)value_params;
51
- plocals = (void*)pframe->plocals;
52
-
53
- VALUE hash = rb_hash_new();
54
- #{hash_aset_code}
55
- return hash;
56
- }
57
- " } + "((VALUE)pframe)"
58
79
  end
59
80
 
60
- def to_c_array(tree)
81
+ def to_c_array(tree, result_var = nil)
61
82
  if tree.size > 1
62
- strargs = tree[1..-1].map{|subtree| to_c subtree}.join(",")
63
- "rb_ary_new3(#{tree.size-1}, #{strargs})"
83
+ if result_var
84
+ prefix = "_array_element_" + rand(10000000).to_s + "_"
85
+ "
86
+ {
87
+ #{
88
+ (0..tree.size-2).map{|x|
89
+ "VALUE #{prefix}#{x};"
90
+ }.join("\n");
91
+ }
92
+
93
+ #{
94
+ (0..tree.size-2).map{|x|
95
+ to_c(tree[x+1], prefix+x.to_s)
96
+ }.join("\n");
97
+ }
98
+
99
+ #{result_var} = rb_ary_new3(#{tree.size-1}, #{(0..tree.size-2).map{|x| prefix+x.to_s}.join(",")} );
100
+ }
101
+ "
102
+ else
103
+ strargs = tree[1..-1].map{|subtree| to_c subtree}.join(",")
104
+ "rb_ary_new3(#{tree.size-1}, #{strargs})"
105
+ end
64
106
  else
107
+ if result_var
108
+ "#{result_var} = rb_ary_new3(0);"
109
+ else
65
110
  "rb_ary_new3(0)"
111
+ end
66
112
  end
67
113
  end
68
114
 
@@ -78,8 +124,39 @@ module FastRuby
78
124
  "Qtrue"
79
125
  end
80
126
 
81
- def to_c_dot2(tree)
82
- "rb_range_new(#{to_c tree[1]}, #{to_c tree[2]},0)"
127
+ def to_c_dot2(tree, result_var = nil)
128
+
129
+ begin_var = "_begin"+rand(10000000).to_s
130
+ end_var = "_end"+rand(10000000).to_s
131
+
132
+ if result_var
133
+ "
134
+ {
135
+ VALUE #{begin_var} = Qnil;
136
+ VALUE #{end_var} = Qnil;
137
+
138
+ #{to_c tree[1], begin_var};
139
+ #{to_c tree[2], end_var};
140
+
141
+ #{result_var} = rb_range_new(#{begin_var}, #{end_var},0);
142
+ }
143
+ "
144
+ else
145
+ if result_var
146
+ "
147
+ {
148
+ VALUE #{begin_var} = Qnil;
149
+ VALUE #{end_var} = Qnil;
150
+ #{to_c tree[1], begin_var};
151
+ #{to_c tree[2], end_var};
152
+
153
+ #{result_var} = rb_range_new(#{begin_var}, #{end_var},0)
154
+ }
155
+ "
156
+ else
157
+ "rb_range_new(#{to_c tree[1]}, #{to_c tree[2]},0)"
158
+ end
159
+ end
83
160
  end
84
161
 
85
162
  end
@@ -22,16 +22,51 @@ module FastRuby
22
22
  module LogicalOperatorTranslator
23
23
  register_translator_module self
24
24
 
25
- def to_c_and(tree)
26
- "(RTEST(#{to_c tree[1]}) && RTEST(#{to_c tree[2]})) ? Qtrue : Qfalse"
25
+ def to_c_and(tree, return_var = nil)
26
+ if return_var
27
+ "
28
+ {
29
+ VALUE op1 = Qnil;
30
+ VALUE op2 = Qnil;
31
+ #{to_c tree[1], "op1"};
32
+ #{to_c tree[2], "op2"};
33
+ #{return_var} = (RTEST(op1) && RTEST(op2)) ? Qtrue : Qfalse;
34
+ }
35
+ "
36
+ else
37
+ "(RTEST(#{to_c tree[1]}) && RTEST(#{to_c tree[2]})) ? Qtrue : Qfalse"
38
+ end
39
+
27
40
  end
28
41
 
29
- def to_c_or(tree)
42
+ def to_c_or(tree, return_var = nil)
43
+ if return_var
44
+ "
45
+ {
46
+ VALUE op1 = Qnil;
47
+ VALUE op2 = Qnil;
48
+ #{to_c tree[1], "op1"};
49
+ #{to_c tree[2], "op2"};
50
+ #{return_var} = (RTEST(op1) || RTEST(op2)) ? Qtrue : Qfalse;
51
+ }
52
+ "
53
+ else
30
54
  "(RTEST(#{to_c tree[1]}) || RTEST(#{to_c tree[2]})) ? Qtrue : Qfalse"
55
+ end
31
56
  end
32
57
 
33
- def to_c_not(tree)
34
- "RTEST(#{to_c tree[1]}) ? Qfalse : Qtrue"
58
+ def to_c_not(tree, return_var = nil)
59
+ if return_var
60
+ "
61
+ {
62
+ VALUE op1 = Qnil;
63
+ #{to_c tree[1], "op1"};
64
+ #{return_var} = (RTEST(op1)) ? Qfalse: Qtrue;
65
+ }
66
+ "
67
+ else
68
+ "RTEST(#{to_c tree[1]}) ? Qfalse : Qtrue"
69
+ end
35
70
  end
36
71
 
37
72
  end
@@ -22,47 +22,64 @@ module FastRuby
22
22
  module BlockTranslator
23
23
  register_translator_module self
24
24
 
25
- def to_c_class(tree)
25
+ def to_c_class(tree, result_var = nil)
26
26
  str_class_name = get_class_name(tree[1])
27
27
  container_tree = get_container_tree(tree[1])
28
28
 
29
29
  if container_tree == s(:self)
30
30
  method_group("
31
+ VALUE superklass = rb_cObject;
32
+ #{
33
+ if tree[2]
34
+ to_c tree[2], "superklass"
35
+ end
36
+ };
31
37
  VALUE tmpklass = rb_define_class(
32
38
  #{str_class_name.inspect},
33
- #{tree[2] ? to_c(tree[2]) : "rb_cObject"}
39
+ superklass
34
40
  );
35
- ", tree[3])
41
+ ", tree[3], result_var)
36
42
  else
37
43
  method_group("
38
- VALUE container_klass = #{to_c(container_tree)};
44
+ VALUE container_klass = Qnil;
45
+ VALUE superklass = rb_cObject;
46
+
47
+ #{
48
+ if tree[2]
49
+ to_c tree[2], "superklass"
50
+ end
51
+ };
52
+
53
+ #{to_c(container_tree, "container_klass")};
39
54
  VALUE tmpklass = rb_define_class_under(
40
55
  container_klass,
41
56
  #{str_class_name.inspect},
42
- #{tree[2] ? to_c(tree[2]) : "rb_cObject"}
57
+ superklass
43
58
  );
44
- ", tree[3])
59
+ ", tree[3], result_var)
45
60
  end
46
61
  end
47
62
 
48
- def to_c_module(tree)
63
+ def to_c_module(tree, result_var = nil)
49
64
  str_class_name = get_class_name(tree[1])
50
65
  container_tree = get_container_tree(tree[1])
51
66
 
52
67
  if container_tree == s(:self)
53
68
  method_group("
54
69
  VALUE tmpklass = rb_define_module(#{str_class_name.inspect});
55
- ", tree[2])
70
+ ", tree[2], result_var)
56
71
  else
57
72
  method_group("
58
- VALUE container_klass = #{to_c(container_tree)};
73
+ VALUE container_klass = Qnil;
74
+
75
+ #{to_c(container_tree, "container_klass")};
59
76
  VALUE tmpklass = rb_define_module_under(container_klass,#{str_class_name.inspect});
60
- ", tree[2])
77
+ ", tree[2], result_var)
61
78
  end
62
79
  end
63
80
 
64
81
  private
65
- def method_group(init_code, tree)
82
+ def method_group(init_code, tree, result_var)
66
83
 
67
84
  alt_locals = Set.new
68
85
  alt_locals << :self
@@ -112,7 +129,7 @@ private
112
129
 
113
130
  plocals = (typeof(plocals))stack_chunk_alloc(stack_chunk ,sizeof(typeof(*plocals))/sizeof(void*));
114
131
 
115
- plocals->parent_locals = LONG2FIX(frame.thread_data->last_plocals);
132
+ plocals->parent_locals = frame.thread_data->last_plocals;
116
133
  void* old_parent_locals = frame.thread_data->last_plocals;
117
134
  frame.thread_data->last_plocals = plocals;
118
135
 
@@ -120,7 +137,7 @@ private
120
137
  plocals->active = Qtrue;
121
138
  plocals->self = self;
122
139
  plocals->targetted = Qfalse;
123
- plocals->call_frame = LONG2FIX(0);
140
+ plocals->call_frame = 0;
124
141
 
125
142
  #{to_c tree};
126
143
 
@@ -141,17 +158,22 @@ private
141
158
  }
142
159
  end
143
160
 
144
- inline_block("
161
+ code = "
162
+ {
145
163
  #{init_code}
146
164
 
147
165
  rb_funcall(tmpklass, #{intern_num :__id__},0);
148
166
 
149
167
  #{fun}(tmpklass);
150
- return Qnil;
151
-
152
-
153
- ")
154
-
168
+ }
169
+ "
170
+
171
+ if result_var
172
+ code + "\n#{result_var} = Qnil;\n"
173
+ else
174
+ inline_block code + "\nreturn Qnil;\n"
175
+ end
176
+
155
177
  end
156
178
 
157
179
  def get_class_name(argument)
@@ -22,70 +22,115 @@ module FastRuby
22
22
  module NonLocalTranslator
23
23
  register_translator_module self
24
24
 
25
- def to_c_return(tree)
26
- inline_block "
27
- plocals->return_value = #{to_c(tree[1])};
28
- plocals->targetted = 1;
29
- longjmp(pframe->jmp, FASTRUBY_TAG_RETURN);
25
+ def to_c_return(tree, return_variable = nil)
26
+ code = "
27
+ #{to_c(tree[1],"last_expression")};
28
+ goto local_return;
30
29
  return Qnil;
31
30
  "
31
+ if return_variable
32
+ code
33
+ else
34
+ inline_block code
35
+ end
32
36
  end
33
37
 
34
- def to_c_break(tree)
35
- inline_block(
36
- "
38
+ def to_c_break(tree, result_var = nil)
39
+
40
+ value_tmp_var = "value_" + rand(10000000).to_s
41
+
42
+ code = "
37
43
 
38
- VALUE value = #{tree[1] ? to_c(tree[1]) : "Qnil"};
44
+ {
45
+ VALUE #{value_tmp_var} = Qnil;
46
+ #{
47
+ if tree[1]
48
+ to_c(tree[1], value_tmp_var)
49
+ end
50
+ };
39
51
 
40
52
  typeof(pframe) target_frame_;
41
- target_frame_ = (void*)FIX2LONG(plocals->call_frame);
53
+ target_frame_ = (void*)plocals->call_frame;
42
54
 
43
55
  if (target_frame_ == 0) {
44
56
  #{_raise("rb_eLocalJumpError","illegal break")};
45
57
  }
46
58
 
47
- plocals->call_frame = LONG2FIX(0);
59
+ plocals->call_frame = 0;
48
60
 
49
- target_frame_->return_value = value;
61
+ target_frame_->return_value = #{value_tmp_var};
50
62
  target_frame_->targetted = 1;
51
63
  pframe->thread_data->exception = Qnil;
52
- longjmp(pframe->jmp,FASTRUBY_TAG_BREAK);"
53
- )
64
+ longjmp(pframe->jmp,FASTRUBY_TAG_BREAK);
65
+
66
+ }
67
+ "
68
+
69
+ if result_var
70
+ code
71
+ else
72
+ inline_block code
73
+ end
54
74
  end
55
75
 
56
- def to_c_retry(tree)
57
- inline_block(
58
- "
76
+ def to_c_retry(tree, result_var = nil)
77
+ code = "
78
+ {
59
79
  typeof(pframe) target_frame_;
60
- target_frame_ = (void*)FIX2LONG(plocals->call_frame);
80
+ target_frame_ = (void*)plocals->call_frame;
61
81
 
62
82
  if (target_frame_ == 0) {
63
83
  #{_raise("rb_eLocalJumpError","illegal retry")};
64
84
  }
65
85
 
66
86
  target_frame_->targetted = 1;
67
- longjmp(pframe->jmp,FASTRUBY_TAG_RETRY);"
68
- )
87
+ longjmp(pframe->jmp,FASTRUBY_TAG_RETRY);
88
+ }
89
+ "
90
+ if result_var
91
+ code
92
+ else
93
+ inline_block code
94
+ end
69
95
  end
70
96
 
71
- def to_c_redo(tree)
97
+ def to_c_redo(tree, result_var = nil)
72
98
  if @on_block
73
- inline_block "
74
- longjmp(pframe->jmp,FASTRUBY_TAG_REDO);
75
- return Qnil;
99
+ code = "
100
+ goto fastruby_local_redo;
76
101
  "
102
+
103
+ if result_var
104
+ code
105
+ else
106
+ inline_block code
107
+ end
77
108
  else
78
109
  _raise("rb_eLocalJumpError","illegal redo");
79
110
  end
80
111
  end
81
112
 
82
- def to_c_next(tree)
113
+ def to_c_next(tree, result_var = nil)
114
+ tmp_varname = "_acc_" + rand(10000000).to_s
83
115
  if @on_block
84
- inline_block "
85
- pframe->thread_data->accumulator = #{tree[1] ? to_c(tree[1]) : "Qnil"};
86
- longjmp(pframe->jmp,FASTRUBY_TAG_NEXT);
87
- return Qnil;
116
+ code = "
117
+ {
118
+ last_expression = Qnil;
119
+
120
+ #{
121
+ if tree[1]
122
+ to_c(tree[1],"last_expression")
123
+ end
124
+ }
125
+ pframe->thread_data->accumulator = last_expression;
126
+ goto fastruby_local_next;
127
+ }
88
128
  "
129
+ if result_var
130
+ code
131
+ else
132
+ inline_block code
133
+ end
89
134
  else
90
135
  _raise("rb_eLocalJumpError","illegal next");
91
136
  end