fastruby 0.0.12 → 0.0.13
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 +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
|