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