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.
@@ -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