13514
|
1 /*
|
|
2 * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
|
|
3 * code is released under a tri EPL/GPL/LGPL license. You can use it,
|
|
4 * redistribute it and/or modify it under the terms of the:
|
|
5 *
|
|
6 * Eclipse Public License version 1.0
|
|
7 * GNU General Public License version 2
|
|
8 * GNU Lesser General Public License version 2.1
|
|
9 */
|
|
10 package com.oracle.truffle.ruby.nodes.core;
|
|
11
|
|
12 import java.math.*;
|
|
13
|
|
14 import com.oracle.truffle.api.*;
|
|
15 import com.oracle.truffle.api.dsl.*;
|
|
16 import com.oracle.truffle.ruby.runtime.*;
|
|
17 import com.oracle.truffle.ruby.runtime.core.*;
|
|
18 import com.oracle.truffle.ruby.runtime.core.array.*;
|
|
19
|
|
20 @CoreClass(name = "Float")
|
|
21 public abstract class FloatNodes {
|
|
22
|
|
23 @CoreMethod(names = "+@", maxArgs = 0)
|
|
24 public abstract static class PosNode extends CoreMethodNode {
|
|
25
|
|
26 public PosNode(RubyContext context, SourceSection sourceSection) {
|
|
27 super(context, sourceSection);
|
|
28 }
|
|
29
|
|
30 public PosNode(PosNode prev) {
|
|
31 super(prev);
|
|
32 }
|
|
33
|
|
34 @Specialization
|
|
35 public double pos(double value) {
|
|
36 return value;
|
|
37 }
|
|
38
|
|
39 }
|
|
40
|
|
41 @CoreMethod(names = "-@", maxArgs = 0)
|
|
42 public abstract static class NegNode extends CoreMethodNode {
|
|
43
|
|
44 public NegNode(RubyContext context, SourceSection sourceSection) {
|
|
45 super(context, sourceSection);
|
|
46 }
|
|
47
|
|
48 public NegNode(NegNode prev) {
|
|
49 super(prev);
|
|
50 }
|
|
51
|
|
52 @Specialization
|
|
53 public double neg(double value) {
|
|
54 return -value;
|
|
55 }
|
|
56
|
|
57 }
|
|
58
|
|
59 @CoreMethod(names = "+", minArgs = 1, maxArgs = 1)
|
|
60 public abstract static class AddNode extends CoreMethodNode {
|
|
61
|
|
62 public AddNode(RubyContext context, SourceSection sourceSection) {
|
|
63 super(context, sourceSection);
|
|
64 }
|
|
65
|
|
66 public AddNode(AddNode prev) {
|
|
67 super(prev);
|
|
68 }
|
|
69
|
|
70 @Specialization
|
|
71 public double add(double a, int b) {
|
|
72 return a + b;
|
|
73 }
|
|
74
|
|
75 @Specialization
|
|
76 public double add(double a, double b) {
|
|
77 return a + b;
|
|
78 }
|
|
79
|
|
80 @Specialization
|
|
81 public double add(double a, BigInteger b) {
|
|
82 return a + b.doubleValue();
|
|
83 }
|
|
84
|
|
85 }
|
|
86
|
|
87 @CoreMethod(names = "-", minArgs = 1, maxArgs = 1)
|
|
88 public abstract static class SubNode extends CoreMethodNode {
|
|
89
|
|
90 public SubNode(RubyContext context, SourceSection sourceSection) {
|
|
91 super(context, sourceSection);
|
|
92 }
|
|
93
|
|
94 public SubNode(SubNode prev) {
|
|
95 super(prev);
|
|
96 }
|
|
97
|
|
98 @Specialization
|
|
99 public double sub(double a, int b) {
|
|
100 return a - b;
|
|
101 }
|
|
102
|
|
103 @Specialization
|
|
104 public double sub(double a, double b) {
|
|
105 return a - b;
|
|
106 }
|
|
107
|
|
108 @Specialization
|
|
109 public double sub(double a, BigInteger b) {
|
|
110 return a - b.doubleValue();
|
|
111 }
|
|
112
|
|
113 }
|
|
114
|
|
115 @CoreMethod(names = "*", minArgs = 1, maxArgs = 1)
|
|
116 public abstract static class MulNode extends CoreMethodNode {
|
|
117
|
|
118 public MulNode(RubyContext context, SourceSection sourceSection) {
|
|
119 super(context, sourceSection);
|
|
120 }
|
|
121
|
|
122 public MulNode(MulNode prev) {
|
|
123 super(prev);
|
|
124 }
|
|
125
|
|
126 @Specialization
|
|
127 public double mul(double a, int b) {
|
|
128 return a * b;
|
|
129 }
|
|
130
|
|
131 @Specialization
|
|
132 public double mul(double a, double b) {
|
|
133 return a * b;
|
|
134 }
|
|
135
|
|
136 @Specialization
|
|
137 public double mul(double a, BigInteger b) {
|
|
138 return a * b.doubleValue();
|
|
139 }
|
|
140
|
|
141 }
|
|
142
|
|
143 @CoreMethod(names = "**", minArgs = 1, maxArgs = 1)
|
|
144 public abstract static class PowNode extends CoreMethodNode {
|
|
145
|
|
146 public PowNode(RubyContext context, SourceSection sourceSection) {
|
|
147 super(context, sourceSection);
|
|
148 }
|
|
149
|
|
150 public PowNode(PowNode prev) {
|
|
151 super(prev);
|
|
152 }
|
|
153
|
|
154 @Specialization
|
|
155 public double mul(double a, int b) {
|
|
156 return Math.pow(a, b);
|
|
157 }
|
|
158
|
|
159 @Specialization
|
|
160 public double mul(double a, double b) {
|
|
161 return Math.pow(a, b);
|
|
162 }
|
|
163
|
|
164 @Specialization
|
|
165 public double mul(double a, BigInteger b) {
|
|
166 return Math.pow(a, b.doubleValue());
|
|
167 }
|
|
168
|
|
169 }
|
|
170
|
|
171 @CoreMethod(names = "/", minArgs = 1, maxArgs = 1)
|
|
172 public abstract static class DivNode extends CoreMethodNode {
|
|
173
|
|
174 public DivNode(RubyContext context, SourceSection sourceSection) {
|
|
175 super(context, sourceSection);
|
|
176 }
|
|
177
|
|
178 public DivNode(DivNode prev) {
|
|
179 super(prev);
|
|
180 }
|
|
181
|
|
182 @Specialization
|
|
183 public double div(double a, int b) {
|
|
184 return a / b;
|
|
185 }
|
|
186
|
|
187 @Specialization
|
|
188 public double div(double a, double b) {
|
|
189 return a / b;
|
|
190 }
|
|
191
|
|
192 @Specialization
|
|
193 public double div(double a, BigInteger b) {
|
|
194 return a / b.doubleValue();
|
|
195 }
|
|
196
|
|
197 }
|
|
198
|
|
199 @CoreMethod(names = "%", minArgs = 1, maxArgs = 1)
|
|
200 public abstract static class ModNode extends CoreMethodNode {
|
|
201
|
|
202 public ModNode(RubyContext context, SourceSection sourceSection) {
|
|
203 super(context, sourceSection);
|
|
204 }
|
|
205
|
|
206 public ModNode(ModNode prev) {
|
|
207 super(prev);
|
|
208 }
|
|
209
|
|
210 @Specialization
|
|
211 public double mod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") int b) {
|
|
212 throw new UnsupportedOperationException();
|
|
213 }
|
|
214
|
|
215 @Specialization
|
|
216 public double mod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") double b) {
|
|
217 throw new UnsupportedOperationException();
|
|
218 }
|
|
219
|
|
220 @Specialization
|
|
221 public double mod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") BigInteger b) {
|
|
222 throw new UnsupportedOperationException();
|
|
223 }
|
|
224
|
|
225 }
|
|
226
|
|
227 @CoreMethod(names = "divmod", minArgs = 1, maxArgs = 1)
|
|
228 public abstract static class DivModNode extends CoreMethodNode {
|
|
229
|
|
230 public DivModNode(RubyContext context, SourceSection sourceSection) {
|
|
231 super(context, sourceSection);
|
|
232 }
|
|
233
|
|
234 public DivModNode(DivModNode prev) {
|
|
235 super(prev);
|
|
236 }
|
|
237
|
|
238 @Specialization
|
|
239 public RubyArray divMod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") int b) {
|
|
240 throw new UnsupportedOperationException();
|
|
241 }
|
|
242
|
|
243 @Specialization
|
|
244 public RubyArray divMod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") double b) {
|
|
245 throw new UnsupportedOperationException();
|
|
246 }
|
|
247
|
|
248 @Specialization
|
|
249 public RubyArray divMod(@SuppressWarnings("unused") double a, @SuppressWarnings("unused") BigInteger b) {
|
|
250 throw new UnsupportedOperationException();
|
|
251 }
|
|
252
|
|
253 }
|
|
254
|
|
255 @CoreMethod(names = "<", minArgs = 1, maxArgs = 1)
|
|
256 public abstract static class LessNode extends CoreMethodNode {
|
|
257
|
|
258 public LessNode(RubyContext context, SourceSection sourceSection) {
|
|
259 super(context, sourceSection);
|
|
260 }
|
|
261
|
|
262 public LessNode(LessNode prev) {
|
|
263 super(prev);
|
|
264 }
|
|
265
|
|
266 @Specialization
|
|
267 public boolean less(double a, int b) {
|
|
268 return a < b;
|
|
269 }
|
|
270
|
|
271 @Specialization
|
|
272 public boolean less(double a, double b) {
|
|
273 return a < b;
|
|
274 }
|
|
275
|
|
276 @Specialization
|
|
277 public boolean less(double a, BigInteger b) {
|
|
278 return BigInteger.valueOf((long) a).compareTo(b) < 0;
|
|
279 }
|
|
280 }
|
|
281
|
|
282 @CoreMethod(names = "<=", minArgs = 1, maxArgs = 1)
|
|
283 public abstract static class LessEqualNode extends CoreMethodNode {
|
|
284
|
|
285 public LessEqualNode(RubyContext context, SourceSection sourceSection) {
|
|
286 super(context, sourceSection);
|
|
287 }
|
|
288
|
|
289 public LessEqualNode(LessEqualNode prev) {
|
|
290 super(prev);
|
|
291 }
|
|
292
|
|
293 @Specialization
|
|
294 public boolean lessEqual(double a, int b) {
|
|
295 return a <= b;
|
|
296 }
|
|
297
|
|
298 @Specialization
|
|
299 public boolean lessEqual(double a, double b) {
|
|
300 return a <= b;
|
|
301 }
|
|
302
|
|
303 @Specialization
|
|
304 public boolean lessEqual(double a, BigInteger b) {
|
|
305 return BigInteger.valueOf((long) a).compareTo(b) <= 0;
|
|
306 }
|
|
307 }
|
|
308
|
|
309 @CoreMethod(names = "==", minArgs = 1, maxArgs = 1)
|
|
310 public abstract static class EqualNode extends CoreMethodNode {
|
|
311
|
|
312 public EqualNode(RubyContext context, SourceSection sourceSection) {
|
|
313 super(context, sourceSection);
|
|
314 }
|
|
315
|
|
316 public EqualNode(EqualNode prev) {
|
|
317 super(prev);
|
|
318 }
|
|
319
|
|
320 @Specialization
|
|
321 public boolean equal(double a, int b) {
|
|
322 return a == b;
|
|
323 }
|
|
324
|
|
325 @Specialization
|
|
326 public boolean equal(double a, double b) {
|
|
327 return a == b;
|
|
328 }
|
|
329
|
|
330 @Specialization
|
|
331 public boolean equal(double a, BigInteger b) {
|
|
332 return BigInteger.valueOf((long) a).compareTo(b) == 0;
|
|
333 }
|
|
334 }
|
|
335
|
|
336 @CoreMethod(names = "!=", minArgs = 1, maxArgs = 1)
|
|
337 public abstract static class NotEqualNode extends CoreMethodNode {
|
|
338
|
|
339 public NotEqualNode(RubyContext context, SourceSection sourceSection) {
|
|
340 super(context, sourceSection);
|
|
341 }
|
|
342
|
|
343 public NotEqualNode(NotEqualNode prev) {
|
|
344 super(prev);
|
|
345 }
|
|
346
|
|
347 @Specialization
|
|
348 public boolean notEqual(double a, int b) {
|
|
349 return a != b;
|
|
350 }
|
|
351
|
|
352 @Specialization
|
|
353 public boolean notEqual(double a, double b) {
|
|
354 return a != b;
|
|
355 }
|
|
356
|
|
357 @Specialization
|
|
358 public boolean notEqual(double a, BigInteger b) {
|
|
359 return BigInteger.valueOf((long) a).compareTo(b) != 0;
|
|
360 }
|
|
361 }
|
|
362
|
|
363 @CoreMethod(names = ">=", minArgs = 1, maxArgs = 1)
|
|
364 public abstract static class GreaterEqualNode extends CoreMethodNode {
|
|
365
|
|
366 public GreaterEqualNode(RubyContext context, SourceSection sourceSection) {
|
|
367 super(context, sourceSection);
|
|
368 }
|
|
369
|
|
370 public GreaterEqualNode(GreaterEqualNode prev) {
|
|
371 super(prev);
|
|
372 }
|
|
373
|
|
374 @Specialization
|
|
375 public boolean greaterEqual(double a, int b) {
|
|
376 return a >= b;
|
|
377 }
|
|
378
|
|
379 @Specialization
|
|
380 public boolean greaterEqual(double a, double b) {
|
|
381 return a >= b;
|
|
382 }
|
|
383
|
|
384 @Specialization
|
|
385 public boolean greaterEqual(double a, BigInteger b) {
|
|
386 return BigInteger.valueOf((long) a).compareTo(b) >= 0;
|
|
387 }
|
|
388 }
|
|
389
|
|
390 @CoreMethod(names = ">", minArgs = 1, maxArgs = 1)
|
|
391 public abstract static class GreaterNode extends CoreMethodNode {
|
|
392
|
|
393 public GreaterNode(RubyContext context, SourceSection sourceSection) {
|
|
394 super(context, sourceSection);
|
|
395 }
|
|
396
|
|
397 public GreaterNode(GreaterNode prev) {
|
|
398 super(prev);
|
|
399 }
|
|
400
|
|
401 @Specialization
|
|
402 public boolean equal(double a, int b) {
|
|
403 return a > b;
|
|
404 }
|
|
405
|
|
406 @Specialization
|
|
407 public boolean equal(double a, double b) {
|
|
408 return a > b;
|
|
409 }
|
|
410
|
|
411 @Specialization
|
|
412 public boolean equal(double a, BigInteger b) {
|
|
413 return BigInteger.valueOf((long) a).compareTo(b) > 0;
|
|
414 }
|
|
415 }
|
|
416
|
|
417 @CoreMethod(names = "abs", maxArgs = 0)
|
|
418 public abstract static class AbsNode extends CoreMethodNode {
|
|
419
|
|
420 public AbsNode(RubyContext context, SourceSection sourceSection) {
|
|
421 super(context, sourceSection);
|
|
422 }
|
|
423
|
|
424 public AbsNode(AbsNode prev) {
|
|
425 super(prev);
|
|
426 }
|
|
427
|
|
428 @Specialization
|
|
429 public double abs(double n) {
|
|
430 return Math.abs(n);
|
|
431 }
|
|
432
|
|
433 }
|
|
434
|
|
435 @CoreMethod(names = "inspect", maxArgs = 0)
|
|
436 public abstract static class InpsectNode extends CoreMethodNode {
|
|
437
|
|
438 public InpsectNode(RubyContext context, SourceSection sourceSection) {
|
|
439 super(context, sourceSection);
|
|
440 }
|
|
441
|
|
442 public InpsectNode(InpsectNode prev) {
|
|
443 super(prev);
|
|
444 }
|
|
445
|
|
446 @Specialization
|
|
447 public RubyString inspect(double n) {
|
|
448 return getContext().makeString(Double.toString(n));
|
|
449 }
|
|
450
|
|
451 }
|
|
452
|
|
453 @CoreMethod(names = "nonzero?", maxArgs = 0)
|
|
454 public abstract static class NonZeroNode extends CoreMethodNode {
|
|
455
|
|
456 public NonZeroNode(RubyContext context, SourceSection sourceSection) {
|
|
457 super(context, sourceSection);
|
|
458 }
|
|
459
|
|
460 public NonZeroNode(NonZeroNode prev) {
|
|
461 super(prev);
|
|
462 }
|
|
463
|
|
464 @Specialization
|
|
465 public Object nonZero(double value) {
|
|
466 if (value == 0) {
|
|
467 return false;
|
|
468 } else {
|
|
469 return value;
|
|
470 }
|
|
471 }
|
|
472
|
|
473 }
|
|
474
|
|
475 @CoreMethod(names = "to_s", maxArgs = 0)
|
|
476 public abstract static class ToSNode extends CoreMethodNode {
|
|
477
|
|
478 public ToSNode(RubyContext context, SourceSection sourceSection) {
|
|
479 super(context, sourceSection);
|
|
480 }
|
|
481
|
|
482 public ToSNode(ToSNode prev) {
|
|
483 super(prev);
|
|
484 }
|
|
485
|
|
486 @Specialization
|
|
487 public RubyString toS(double value) {
|
|
488 return getContext().makeString(Double.toString(value));
|
|
489 }
|
|
490
|
|
491 }
|
|
492
|
|
493 }
|