@@ -839,8 +839,9 @@ private RubyNode translateCPath(SourceSection sourceSection, org.jruby.ast.Colon
839
839
public RubyNode visitComplexNode (ComplexNode node ) {
840
840
final SourceSection sourceSection = translate (node .getPosition ());
841
841
842
- // TODO: implement Complex
843
- return node .getNumber ().accept (this );
842
+ return translateRationalComplex (sourceSection , "Complex" ,
843
+ new FixnumLiteralNode .IntegerFixnumLiteralNode (context , sourceSection , 0 ),
844
+ node .getNumber ().accept (this ));
844
845
}
845
846
846
847
@ Override
@@ -1007,7 +1008,7 @@ protected RubyNode translateMethodDefinition(SourceSection sourceSection, RubyNo
1007
1008
* In the top-level, methods are defined in the class of the main object. This is
1008
1009
* counter-intuitive - I would have expected them to be defined in the singleton class.
1009
1010
* Apparently this is a design decision to make top-level methods sort of global.
1010
- *
1011
+ *
1011
1012
* http://stackoverflow.com/questions/1761148/where-are-methods-defined-at-the-ruby-top-level
1012
1013
*/
1013
1014
@@ -1105,39 +1106,39 @@ public RubyNode visitFloatNode(org.jruby.ast.FloatNode node) {
1105
1106
public RubyNode visitForNode (org .jruby .ast .ForNode node ) {
1106
1107
/**
1107
1108
* A Ruby for-loop, such as:
1108
- *
1109
+ *
1109
1110
* <pre>
1110
1111
* for x in y
1111
1112
* z = x
1112
1113
* puts z
1113
1114
* end
1114
1115
* </pre>
1115
- *
1116
+ *
1116
1117
* naively desugars to:
1117
- *
1118
+ *
1118
1119
* <pre>
1119
1120
* y.each do |x|
1120
1121
* z = x
1121
1122
* puts z
1122
1123
* end
1123
1124
* </pre>
1124
- *
1125
+ *
1125
1126
* The main difference is that z is always going to be local to the scope outside the block,
1126
1127
* so it's a bit more like:
1127
- *
1128
+ *
1128
1129
* <pre>
1129
1130
* z = nil unless z is already defined
1130
1131
* y.each do |x|
1131
1132
* z = x
1132
1133
* puts x
1133
1134
* end
1134
1135
* </pre>
1135
- *
1136
+ *
1136
1137
* Which forces z to be defined in the correct scope. The parser already correctly calls z a
1137
1138
* local, but then that causes us a problem as if we're going to translate to a block we
1138
1139
* need a formal parameter - not a local variable. My solution to this is to add a
1139
1140
* temporary:
1140
- *
1141
+ *
1141
1142
* <pre>
1142
1143
* z = nil unless z is already defined
1143
1144
* y.each do |temp|
@@ -1146,25 +1147,25 @@ public RubyNode visitForNode(org.jruby.ast.ForNode node) {
1146
1147
* puts x
1147
1148
* end
1148
1149
* </pre>
1149
- *
1150
+ *
1150
1151
* We also need that temp because the expression assigned in the for could be index
1151
1152
* assignment, multiple assignment, or whatever:
1152
- *
1153
+ *
1153
1154
* <pre>
1154
1155
* for x[0] in y
1155
1156
* z = x[0]
1156
1157
* puts z
1157
1158
* end
1158
1159
* </pre>
1159
- *
1160
+ *
1160
1161
* http://blog.grayproductions.net/articles/the_evils_of_the_for_loop
1161
1162
* http://stackoverflow.com/questions/3294509/for-vs-each-in-ruby
1162
- *
1163
+ *
1163
1164
* The other complication is that normal locals should be defined in the enclosing scope,
1164
1165
* unlike a normal block. We do that by setting a flag on this translator object when we
1165
1166
* visit the new iter, translatingForStatement, which we recognise when visiting an iter
1166
1167
* node.
1167
- *
1168
+ *
1168
1169
* Finally, note that JRuby's terminology is strange here. Normally 'iter' is a different
1169
1170
* term for a block. Here, JRuby calls the object being iterated over the 'iter'.
1170
1171
*/
@@ -1229,7 +1230,7 @@ private static org.jruby.ast.Node setRHS(org.jruby.ast.Node node, org.jruby.ast.
1229
1230
1230
1231
private final Set <String > readOnlyGlobalVariables = new HashSet <String >();
1231
1232
private final Map <String , String > globalVariableAliases = new HashMap <String , String >();
1232
-
1233
+
1233
1234
private void initReadOnlyGlobalVariables () {
1234
1235
Set <String > s = readOnlyGlobalVariables ;
1235
1236
s .add ("$:" );
@@ -1244,7 +1245,7 @@ private void initReadOnlyGlobalVariables() {
1244
1245
s .add ("$-l" );
1245
1246
s .add ("$-p" );
1246
1247
}
1247
-
1248
+
1248
1249
private void initGlobalVariableAliases () {
1249
1250
Map <String , String > m = globalVariableAliases ;
1250
1251
m .put ("$-I" , "$LOAD_PATH" );
@@ -2032,7 +2033,7 @@ public RubyNode visitOpAsgnNode(org.jruby.ast.OpAsgnNode node) {
2032
2033
/*
2033
2034
* We're going to de-sugar a.foo += c into a.foo = a.foo + c. Note that we can't evaluate a
2034
2035
* more than once, so we put it into a temporary, and we're doing something more like:
2035
- *
2036
+ *
2036
2037
* temp = a; temp.foo = temp.foo + c
2037
2038
*/
2038
2039
@@ -2168,19 +2169,23 @@ public RubyNode visitPostExeNode(PostExeNode node) {
2168
2169
public RubyNode visitRationalNode (RationalNode node ) {
2169
2170
final SourceSection sourceSection = translate (node .getPosition ());
2170
2171
2171
- // Translate as Rubinius.privately { Rubinius.convert(a, b) }
2172
-
2173
2172
// TODO(CS): use IntFixnumLiteralNode where possible
2174
2173
2174
+ return translateRationalComplex (sourceSection , "Rational" ,
2175
+ new FixnumLiteralNode .LongFixnumLiteralNode (context , sourceSection , node .getNumerator ()),
2176
+ new FixnumLiteralNode .LongFixnumLiteralNode (context , sourceSection , node .getDenominator ()));
2177
+ }
2178
+
2179
+ private RubyNode translateRationalComplex (SourceSection sourceSection , String name , RubyNode a , RubyNode b ) {
2180
+ // Translate as Rubinius.privately { Rational.convert(a, b) }
2181
+
2175
2182
final LexicalScope lexicalScope = environment .getLexicalScope ();
2176
2183
final RubyNode moduleNode = new LexicalScopeNode (context , sourceSection , lexicalScope );
2177
2184
return new RubyCallNode (
2178
2185
context , sourceSection , "convert" ,
2179
- new ReadConstantNode (context , sourceSection , "Rational" , moduleNode , lexicalScope ),
2186
+ new ReadConstantNode (context , sourceSection , name , moduleNode , lexicalScope ),
2180
2187
null , false , true , false ,
2181
- new RubyNode []{
2182
- new FixnumLiteralNode .LongFixnumLiteralNode (context , sourceSection , node .getNumerator ()),
2183
- new FixnumLiteralNode .LongFixnumLiteralNode (context , sourceSection , node .getDenominator ())});
2188
+ new RubyNode []{a , b });
2184
2189
}
2185
2190
2186
2191
@ Override
0 commit comments