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.
- data/CHANGELOG +17 -1
- data/Rakefile +1 -1
- data/ext/fastruby_base/fastruby_base.inl +81 -3
- data/lib/fastruby/fastruby_sexp.rb +21 -0
- data/lib/fastruby/getlocals.rb +2 -1
- data/lib/fastruby/object.rb +1 -1
- data/lib/fastruby/sexp_extension.rb +189 -0
- data/lib/fastruby/sexp_extension_edges.rb +210 -0
- data/lib/fastruby/translator/modules/block.rb +29 -22
- data/lib/fastruby/translator/modules/call.rb +211 -34
- data/lib/fastruby/translator/modules/defn.rb +64 -29
- data/lib/fastruby/translator/modules/exceptions.rb +1 -1
- data/lib/fastruby/translator/modules/flow.rb +93 -31
- data/lib/fastruby/translator/modules/iter.rb +277 -340
- data/lib/fastruby/translator/modules/literal.rb +97 -20
- data/lib/fastruby/translator/modules/logical.rb +40 -5
- data/lib/fastruby/translator/modules/method_group.rb +41 -19
- data/lib/fastruby/translator/modules/nonlocal.rb +74 -29
- data/lib/fastruby/translator/modules/variable.rb +151 -42
- data/lib/fastruby/translator/scope_mode_helper.rb +161 -0
- data/lib/fastruby/translator/translator.rb +389 -302
- data/lib/fastruby.rb +1 -1
- data/lib/fastruby.rb~ +36 -0
- data/spec/edges_helper.rb +91 -0
- data/spec/graph/base_spec.rb +35 -0
- data/spec/graph/path_spec.rb +48 -0
- data/spec/graph/vertex_spec.rb +58 -0
- data/spec/ruby/block/proc_as_block_spec.rb +214 -0
- data/spec/ruby/block/redo_spec.rb +133 -0
- data/spec/ruby/defn/single_function_spec.rb +50 -0
- data/spec/scope_mode/base_spec.rb +55 -0
- data/spec/scope_mode/block_spec.rb +105 -0
- data/spec/scope_mode/call_spec.rb +24 -0
- data/spec/scope_mode/exception_spec.rb +34 -0
- data/spec/scope_mode/flow_spec.rb +99 -0
- data/spec/scope_mode/optimization_spec.rb +130 -0
- data/spec/sexp2graph/base_spec.rb +36 -0
- data/spec/sexp2graph/exception_spec.rb +172 -0
- data/spec/sexp2graph/flow_spec.rb +67 -0
- data/spec/sexp2graph/logical_spec.rb +21 -0
- data/spec/sexp2graph/variable_spec.rb +26 -0
- metadata +110 -120
- data/lib/fastruby/self +0 -82
- data/lib/len +0 -280
- data/spec/block/proc_as_block_spec.rb +0 -111
- data/spec/block/redo_spec.rb +0 -67
- /data/spec/{base_spec.rb → ruby/base_spec.rb} +0 -0
- /data/spec/{block → ruby/block}/arguments_spec.rb +0 -0
- /data/spec/{block → ruby/block}/block_as_proc_spec.rb +0 -0
- /data/spec/{block → ruby/block}/break_spec.rb +0 -0
- /data/spec/{block → ruby/block}/callcc_spec.rb +0 -0
- /data/spec/{block → ruby/block}/lambda_spec.rb +0 -0
- /data/spec/{block → ruby/block}/next_spec.rb +0 -0
- /data/spec/{block → ruby/block}/proc_spec.rb +0 -0
- /data/spec/{block → ruby/block}/retry_spec.rb +0 -0
- /data/spec/{block_spec.rb → ruby/block_spec.rb} +0 -0
- /data/spec/{call → ruby/call}/base_call_spec.rb +0 -0
- /data/spec/{call → ruby/call}/multiple_args_spec.rb +0 -0
- /data/spec/{control_spec.rb → ruby/control_spec.rb} +0 -0
- /data/spec/{defn → ruby/defn}/default_args_spec.rb +0 -0
- /data/spec/{defn → ruby/defn}/multiple_args_spec.rb +0 -0
- /data/spec/{defn → ruby/defn}/replacement_spec.rb +0 -0
- /data/spec/{exception → ruby/exception}/base_spec.rb +0 -0
- /data/spec/{exception → ruby/exception}/ensure_spec.rb +0 -0
- /data/spec/{exception → ruby/exception}/exc_trap_spec.rb +0 -0
- /data/spec/{exception → ruby/exception}/internal_ex_spec.rb +0 -0
- /data/spec/{exception → ruby/exception}/syntaxis_spec.rb +0 -0
- /data/spec/{expression_spec.rb → ruby/expression_spec.rb} +0 -0
- /data/spec/{flow_control → ruby/flow_control}/case_spec.rb +0 -0
- /data/spec/{flow_control → ruby/flow_control}/for_spec.rb +0 -0
- /data/spec/{integrity_spec.rb → ruby/integrity_spec.rb} +0 -0
- /data/spec/{jump → ruby/jump}/next_spec.rb +0 -0
- /data/spec/{literal_spec.rb → ruby/literal_spec.rb} +0 -0
- /data/spec/{module_spec.rb → ruby/module_spec.rb} +0 -0
- /data/spec/{return_spec.rb → ruby/return_spec.rb} +0 -0
- /data/spec/{singleton_spec.rb → ruby/singleton_spec.rb} +0 -0
- /data/spec/{sugar_spec.rb → ruby/sugar_spec.rb} +0 -0
- /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 << "
|
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
|
-
|
63
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
39
|
+
superklass
|
34
40
|
);
|
35
|
-
", tree[3])
|
41
|
+
", tree[3], result_var)
|
36
42
|
else
|
37
43
|
method_group("
|
38
|
-
VALUE container_klass =
|
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
|
-
|
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 =
|
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 =
|
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 =
|
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
|
-
|
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
|
-
|
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
|
-
|
27
|
-
|
28
|
-
|
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
|
-
|
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
|
-
|
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*)
|
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 =
|
59
|
+
plocals->call_frame = 0;
|
48
60
|
|
49
|
-
target_frame_->return_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
|
-
|
58
|
-
|
76
|
+
def to_c_retry(tree, result_var = nil)
|
77
|
+
code = "
|
78
|
+
{
|
59
79
|
typeof(pframe) target_frame_;
|
60
|
-
target_frame_ = (void*)
|
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
|
-
|
74
|
-
|
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
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
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
|