fastruby 0.0.12 → 0.0.13
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +8 -0
- data/README +0 -1
- data/Rakefile +1 -1
- data/lib/fastruby/builder.rb +9 -2
- data/lib/fastruby/translator/modules/block.rb +92 -0
- data/lib/fastruby/translator/modules/call.rb +137 -0
- data/lib/fastruby/translator/modules/defn.rb +221 -0
- data/lib/fastruby/translator/modules/exceptions.rb +134 -0
- data/lib/fastruby/translator/modules/flow.rb +91 -0
- data/lib/fastruby/translator/modules/iter.rb +584 -0
- data/lib/fastruby/translator/modules/literal.rb +86 -0
- data/lib/fastruby/translator/modules/logical.rb +38 -0
- data/lib/fastruby/translator/modules/method_group.rb +174 -0
- data/lib/fastruby/translator/modules/nonlocal.rb +96 -0
- data/lib/fastruby/translator/modules/variable.rb +190 -0
- data/lib/fastruby/translator/translator.rb +1171 -0
- data/lib/fastruby/translator/translator_modules.rb +49 -0
- data/lib/fastruby.rb +1 -1
- data/spec/call/multiple_args_spec.rb +87 -0
- data/spec/defn/multiple_args_spec.rb +271 -0
- metadata +19 -7
- data/lib/fastruby/translator/call.rb +0 -2594
- data/lib/fastruby/translator/iter.rb +0 -2594
- data/lib/fastruby/translator.rb +0 -2594
@@ -0,0 +1,86 @@
|
|
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
|
+
module LiteralTranslator
|
23
|
+
register_translator_module self
|
24
|
+
|
25
|
+
def to_c_lit(tree)
|
26
|
+
literal_value tree[1]
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_c_nil(tree)
|
30
|
+
"Qnil"
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_c_str(tree)
|
34
|
+
literal_value tree[1]
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_c_hash(tree)
|
38
|
+
|
39
|
+
hash_aset_code = ""
|
40
|
+
(0..(tree.size-3)/2).each do |i|
|
41
|
+
strkey = to_c tree[1 + i * 2]
|
42
|
+
strvalue = to_c tree[2 + i * 2]
|
43
|
+
hash_aset_code << "rb_hash_aset(hash, #{strkey}, #{strvalue});"
|
44
|
+
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
|
+
end
|
59
|
+
|
60
|
+
def to_c_array(tree)
|
61
|
+
if tree.size > 1
|
62
|
+
strargs = tree[1..-1].map{|subtree| to_c subtree}.join(",")
|
63
|
+
"rb_ary_new3(#{tree.size-1}, #{strargs})"
|
64
|
+
else
|
65
|
+
"rb_ary_new3(0)"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def to_c_self(tree)
|
70
|
+
locals_accessor + "self"
|
71
|
+
end
|
72
|
+
|
73
|
+
def to_c_false(tree)
|
74
|
+
"Qfalse"
|
75
|
+
end
|
76
|
+
|
77
|
+
def to_c_true(tree)
|
78
|
+
"Qtrue"
|
79
|
+
end
|
80
|
+
|
81
|
+
def to_c_dot2(tree)
|
82
|
+
"rb_range_new(#{to_c tree[1]}, #{to_c tree[2]},0)"
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,38 @@
|
|
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
|
+
module LogicalOperatorTranslator
|
23
|
+
register_translator_module self
|
24
|
+
|
25
|
+
def to_c_and(tree)
|
26
|
+
"(RTEST(#{to_c tree[1]}) && RTEST(#{to_c tree[2]})) ? Qtrue : Qfalse"
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_c_or(tree)
|
30
|
+
"(RTEST(#{to_c tree[1]}) || RTEST(#{to_c tree[2]})) ? Qtrue : Qfalse"
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_c_not(tree)
|
34
|
+
"RTEST(#{to_c tree[1]}) ? Qfalse : Qtrue"
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,174 @@
|
|
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
|
+
module BlockTranslator
|
23
|
+
register_translator_module self
|
24
|
+
|
25
|
+
def to_c_class(tree)
|
26
|
+
str_class_name = get_class_name(tree[1])
|
27
|
+
container_tree = get_container_tree(tree[1])
|
28
|
+
|
29
|
+
if container_tree == s(:self)
|
30
|
+
method_group("
|
31
|
+
VALUE tmpklass = rb_define_class(
|
32
|
+
#{str_class_name.inspect},
|
33
|
+
#{tree[2] ? to_c(tree[2]) : "rb_cObject"}
|
34
|
+
);
|
35
|
+
", tree[3])
|
36
|
+
else
|
37
|
+
method_group("
|
38
|
+
VALUE container_klass = #{to_c(container_tree)};
|
39
|
+
VALUE tmpklass = rb_define_class_under(
|
40
|
+
container_klass,
|
41
|
+
#{str_class_name.inspect},
|
42
|
+
#{tree[2] ? to_c(tree[2]) : "rb_cObject"}
|
43
|
+
);
|
44
|
+
", tree[3])
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def to_c_module(tree)
|
49
|
+
str_class_name = get_class_name(tree[1])
|
50
|
+
container_tree = get_container_tree(tree[1])
|
51
|
+
|
52
|
+
if container_tree == s(:self)
|
53
|
+
method_group("
|
54
|
+
VALUE tmpklass = rb_define_module(#{str_class_name.inspect});
|
55
|
+
", tree[2])
|
56
|
+
else
|
57
|
+
method_group("
|
58
|
+
VALUE container_klass = #{to_c(container_tree)};
|
59
|
+
VALUE tmpklass = rb_define_module_under(container_klass,#{str_class_name.inspect});
|
60
|
+
", tree[2])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
def method_group(init_code, tree)
|
66
|
+
|
67
|
+
alt_locals = Set.new
|
68
|
+
alt_locals << :self
|
69
|
+
|
70
|
+
FastRuby::GetLocalsProcessor.get_locals(tree).each do |local|
|
71
|
+
alt_locals << local
|
72
|
+
end
|
73
|
+
|
74
|
+
fun = nil
|
75
|
+
|
76
|
+
locals_scope(alt_locals) do
|
77
|
+
fun = anonymous_function { |method_name| "static VALUE #{method_name}(VALUE self) {
|
78
|
+
|
79
|
+
#{@frame_struct} frame;
|
80
|
+
typeof(&frame) pframe = &frame;
|
81
|
+
#{@locals_struct} *plocals;
|
82
|
+
|
83
|
+
frame.parent_frame = 0;
|
84
|
+
frame.return_value = Qnil;
|
85
|
+
frame.rescue = 0;
|
86
|
+
frame.targetted = 0;
|
87
|
+
frame.thread_data = rb_current_thread_data();
|
88
|
+
|
89
|
+
int stack_chunk_instantiated = 0;
|
90
|
+
VALUE rb_previous_stack_chunk = Qnil;
|
91
|
+
VALUE rb_stack_chunk = frame.thread_data->rb_stack_chunk;
|
92
|
+
struct STACKCHUNK* stack_chunk = 0;
|
93
|
+
|
94
|
+
if (rb_stack_chunk != Qnil) {
|
95
|
+
Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
|
96
|
+
}
|
97
|
+
|
98
|
+
if (stack_chunk == 0 || (stack_chunk == 0 ? 0 : stack_chunk_frozen(stack_chunk)) ) {
|
99
|
+
rb_previous_stack_chunk = rb_stack_chunk;
|
100
|
+
rb_gc_register_address(&rb_stack_chunk);
|
101
|
+
stack_chunk_instantiated = 1;
|
102
|
+
|
103
|
+
rb_stack_chunk = rb_stack_chunk_create(Qnil);
|
104
|
+
frame.thread_data->rb_stack_chunk = rb_stack_chunk;
|
105
|
+
|
106
|
+
rb_ivar_set(rb_stack_chunk, #{intern_num :_parent_stack_chunk}, rb_previous_stack_chunk);
|
107
|
+
|
108
|
+
Data_Get_Struct(rb_stack_chunk,struct STACKCHUNK,stack_chunk);
|
109
|
+
}
|
110
|
+
|
111
|
+
int previous_stack_position = stack_chunk_get_current_position(stack_chunk);
|
112
|
+
|
113
|
+
plocals = (typeof(plocals))stack_chunk_alloc(stack_chunk ,sizeof(typeof(*plocals))/sizeof(void*));
|
114
|
+
|
115
|
+
frame.plocals = plocals;
|
116
|
+
plocals->active = Qtrue;
|
117
|
+
plocals->self = self;
|
118
|
+
plocals->targetted = Qfalse;
|
119
|
+
plocals->call_frame = LONG2FIX(0);
|
120
|
+
|
121
|
+
#{to_c tree};
|
122
|
+
|
123
|
+
stack_chunk_set_current_position(stack_chunk, previous_stack_position);
|
124
|
+
|
125
|
+
if (stack_chunk_instantiated) {
|
126
|
+
rb_gc_unregister_address(&rb_stack_chunk);
|
127
|
+
frame.thread_data->rb_stack_chunk = rb_previous_stack_chunk;
|
128
|
+
}
|
129
|
+
|
130
|
+
plocals->active = Qfalse;
|
131
|
+
return Qnil;
|
132
|
+
}
|
133
|
+
"
|
134
|
+
}
|
135
|
+
end
|
136
|
+
|
137
|
+
inline_block("
|
138
|
+
#{init_code}
|
139
|
+
|
140
|
+
rb_funcall(tmpklass, #{intern_num :__id__},0);
|
141
|
+
|
142
|
+
#{fun}(tmpklass);
|
143
|
+
return Qnil;
|
144
|
+
|
145
|
+
|
146
|
+
")
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
def get_class_name(argument)
|
151
|
+
if argument.instance_of? Symbol
|
152
|
+
argument.to_s
|
153
|
+
elsif argument.instance_of? FastRuby::FastRubySexp
|
154
|
+
if argument[0] == :colon3
|
155
|
+
get_class_name(argument[1])
|
156
|
+
elsif argument[0] == :colon2
|
157
|
+
get_class_name(argument[2])
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
def get_container_tree(argument)
|
163
|
+
if argument.instance_of? Symbol
|
164
|
+
s(:self)
|
165
|
+
elsif argument.instance_of? FastRuby::FastRubySexp
|
166
|
+
if argument[0] == :colon3
|
167
|
+
s(:const, :Object)
|
168
|
+
elsif argument[0] == :colon2
|
169
|
+
argument[1]
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,96 @@
|
|
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
|
+
module NonLocalTranslator
|
23
|
+
register_translator_module self
|
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);
|
30
|
+
return Qnil;
|
31
|
+
"
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_c_break(tree)
|
35
|
+
inline_block(
|
36
|
+
"
|
37
|
+
|
38
|
+
VALUE value = #{tree[1] ? to_c(tree[1]) : "Qnil"};
|
39
|
+
|
40
|
+
typeof(pframe) target_frame_;
|
41
|
+
target_frame_ = (void*)FIX2LONG(plocals->call_frame);
|
42
|
+
|
43
|
+
if (target_frame_ == 0) {
|
44
|
+
#{_raise("rb_eLocalJumpError","illegal break")};
|
45
|
+
}
|
46
|
+
|
47
|
+
plocals->call_frame = LONG2FIX(0);
|
48
|
+
|
49
|
+
target_frame_->return_value = value;
|
50
|
+
target_frame_->targetted = 1;
|
51
|
+
pframe->thread_data->exception = Qnil;
|
52
|
+
longjmp(pframe->jmp,FASTRUBY_TAG_BREAK);"
|
53
|
+
)
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_c_retry(tree)
|
57
|
+
inline_block(
|
58
|
+
"
|
59
|
+
typeof(pframe) target_frame_;
|
60
|
+
target_frame_ = (void*)FIX2LONG(plocals->call_frame);
|
61
|
+
|
62
|
+
if (target_frame_ == 0) {
|
63
|
+
#{_raise("rb_eLocalJumpError","illegal retry")};
|
64
|
+
}
|
65
|
+
|
66
|
+
target_frame_->targetted = 1;
|
67
|
+
longjmp(pframe->jmp,FASTRUBY_TAG_RETRY);"
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_c_redo(tree)
|
72
|
+
if @on_block
|
73
|
+
inline_block "
|
74
|
+
longjmp(pframe->jmp,FASTRUBY_TAG_REDO);
|
75
|
+
return Qnil;
|
76
|
+
"
|
77
|
+
else
|
78
|
+
_raise("rb_eLocalJumpError","illegal redo");
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_c_next(tree)
|
83
|
+
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;
|
88
|
+
"
|
89
|
+
else
|
90
|
+
_raise("rb_eLocalJumpError","illegal next");
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,190 @@
|
|
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
|
+
module VariabeTranslator
|
23
|
+
register_translator_module self
|
24
|
+
|
25
|
+
|
26
|
+
def to_c_cvar(tree)
|
27
|
+
"rb_cvar_get(CLASS_OF(plocals->self) != rb_cClass ? CLASS_OF(plocals->self) : plocals->self,#{intern_num tree[1]})"
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_c_cvasgn(tree)
|
31
|
+
"__rb_cvar_set(CLASS_OF(plocals->self) != rb_cClass ? CLASS_OF(plocals->self) : plocals->self,#{intern_num tree[1]},#{to_c tree[2]},Qfalse)"
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_c_gvar(tree)
|
35
|
+
if (tree[1] == :$!)
|
36
|
+
"pframe->thread_data->exception"
|
37
|
+
else
|
38
|
+
"rb_gvar_get((struct global_entry*)#{global_entry(tree[1])})"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_c_gasgn(tree)
|
43
|
+
"_rb_gvar_set((void*)#{global_entry(tree[1])}, #{to_c tree[2]})"
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_c_ivar(tree)
|
47
|
+
"rb_ivar_get(#{locals_accessor}self,#{intern_num tree[1]})"
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_c_iasgn(tree)
|
51
|
+
"_rb_ivar_set(#{locals_accessor}self,#{intern_num tree[1]},#{to_c tree[2]})"
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_c_const(tree)
|
55
|
+
"rb_const_get(CLASS_OF(plocals->self), #{intern_num(tree[1])})"
|
56
|
+
end
|
57
|
+
|
58
|
+
def to_c_cdecl(tree)
|
59
|
+
if tree[1].instance_of? Symbol
|
60
|
+
inline_block "
|
61
|
+
// set constant #{tree[1].to_s}
|
62
|
+
VALUE val = #{to_c tree[2]};
|
63
|
+
rb_const_set(rb_cObject, #{intern_num tree[1]}, val);
|
64
|
+
return val;
|
65
|
+
"
|
66
|
+
elsif tree[1].instance_of? FastRuby::FastRubySexp
|
67
|
+
|
68
|
+
if tree[1].node_type == :colon2
|
69
|
+
inline_block "
|
70
|
+
// set constant #{tree[1].to_s}
|
71
|
+
VALUE val = #{to_c tree[2]};
|
72
|
+
VALUE klass = #{to_c tree[1][1]};
|
73
|
+
rb_const_set(klass, #{intern_num tree[1][2]}, val);
|
74
|
+
return val;
|
75
|
+
"
|
76
|
+
elsif tree[1].node_type == :colon3
|
77
|
+
inline_block "
|
78
|
+
// set constant #{tree[1].to_s}
|
79
|
+
VALUE val = #{to_c tree[2]};
|
80
|
+
rb_const_set(rb_cObject, #{intern_num tree[1][1]}, val);
|
81
|
+
return val;
|
82
|
+
"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def to_c_colon3(tree)
|
88
|
+
"rb_const_get_from(rb_cObject, #{intern_num tree[1]})"
|
89
|
+
end
|
90
|
+
|
91
|
+
def to_c_colon2(tree)
|
92
|
+
inline_block "
|
93
|
+
VALUE klass = #{to_c tree[1]};
|
94
|
+
|
95
|
+
if (rb_is_const_id(#{intern_num tree[2]})) {
|
96
|
+
switch (TYPE(klass)) {
|
97
|
+
case T_CLASS:
|
98
|
+
case T_MODULE:
|
99
|
+
return rb_const_get_from(klass, #{intern_num tree[2]});
|
100
|
+
break;
|
101
|
+
default:
|
102
|
+
#{_raise("rb_eTypeError","not a class/module")};
|
103
|
+
break;
|
104
|
+
}
|
105
|
+
}
|
106
|
+
else {
|
107
|
+
return rb_funcall(klass, #{intern_num tree[2]}, 0, 0);
|
108
|
+
}
|
109
|
+
|
110
|
+
return Qnil;
|
111
|
+
"
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_c_lasgn(tree)
|
115
|
+
if options[:validate_lvar_types]
|
116
|
+
klass = @infer_lvar_map[tree[1]]
|
117
|
+
if klass
|
118
|
+
|
119
|
+
verify_type_function = proc { |name| "
|
120
|
+
static VALUE #{name}(VALUE arg, void* pframe ) {
|
121
|
+
if (CLASS_OF(arg)!=#{literal_value klass}) {
|
122
|
+
#{_raise(literal_value(FastRuby::TypeMismatchAssignmentException), "Illegal assignment at runtime (type mismatch)")};
|
123
|
+
}
|
124
|
+
return arg;
|
125
|
+
}
|
126
|
+
"
|
127
|
+
}
|
128
|
+
|
129
|
+
|
130
|
+
"_lvar_assing(&#{locals_accessor}#{tree[1]}, #{anonymous_function(&verify_type_function)}(#{to_c tree[2]},pframe))"
|
131
|
+
else
|
132
|
+
"_lvar_assing(&#{locals_accessor}#{tree[1]},#{to_c tree[2]})"
|
133
|
+
end
|
134
|
+
else
|
135
|
+
"_lvar_assing(&#{locals_accessor}#{tree[1]},#{to_c tree[2]})"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
def to_c_lvar(tree)
|
140
|
+
locals_accessor + tree[1].to_s
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
def to_c_defined(tree)
|
145
|
+
nt = tree[1].node_type
|
146
|
+
|
147
|
+
if nt == :self
|
148
|
+
'rb_str_new2("self")'
|
149
|
+
elsif nt == :true
|
150
|
+
'rb_str_new2("true")'
|
151
|
+
elsif nt == :false
|
152
|
+
'rb_str_new2("false")'
|
153
|
+
elsif nt == :nil
|
154
|
+
'rb_str_new2("nil")'
|
155
|
+
elsif nt == :lvar
|
156
|
+
'rb_str_new2("local-variable")'
|
157
|
+
elsif nt == :gvar
|
158
|
+
"rb_gvar_defined((struct global_entry*)#{global_entry(tree[1][1])}) ? #{literal_value "global-variable"} : Qnil"
|
159
|
+
elsif nt == :const
|
160
|
+
"rb_const_defined(rb_cObject, #{intern_num tree[1][1]}) ? #{literal_value "constant"} : Qnil"
|
161
|
+
elsif nt == :call
|
162
|
+
"rb_method_node(CLASS_OF(#{to_c tree[1][1]}), #{intern_num tree[1][2]}) ? #{literal_value "method"} : Qnil"
|
163
|
+
elsif nt == :yield
|
164
|
+
"rb_block_given_p() ? #{literal_value "yield"} : Qnil"
|
165
|
+
elsif nt == :ivar
|
166
|
+
"rb_ivar_defined(plocals->self,#{intern_num tree[1][1]}) ? #{literal_value "instance-variable"} : Qnil"
|
167
|
+
elsif nt == :attrset or
|
168
|
+
nt == :op_asgn1 or
|
169
|
+
nt == :op_asgn2 or
|
170
|
+
nt == :op_asgn_or or
|
171
|
+
nt == :op_asgn_and or
|
172
|
+
nt == :op_asgn_masgn or
|
173
|
+
nt == :masgn or
|
174
|
+
nt == :lasgn or
|
175
|
+
nt == :dasgn or
|
176
|
+
nt == :dasgn_curr or
|
177
|
+
nt == :gasgn or
|
178
|
+
nt == :iasgn or
|
179
|
+
nt == :cdecl or
|
180
|
+
nt == :cvdecl or
|
181
|
+
nt == :cvasgn
|
182
|
+
literal_value "assignment"
|
183
|
+
else
|
184
|
+
literal_value "expression"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
|
189
|
+
end
|
190
|
+
end
|