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 com.oracle.truffle.api.*;
|
|
13 import com.oracle.truffle.api.dsl.*;
|
|
14 import com.oracle.truffle.api.frame.*;
|
|
15 import com.oracle.truffle.ruby.nodes.call.*;
|
|
16 import com.oracle.truffle.ruby.runtime.*;
|
|
17 import com.oracle.truffle.ruby.runtime.objects.*;
|
|
18
|
|
19 @CoreClass(name = "Comparable")
|
|
20 public abstract class ComparableNodes {
|
|
21
|
|
22 public abstract static class ComparableCoreMethodNode extends CoreMethodNode {
|
|
23
|
|
24 @Child protected DispatchHeadNode compareNode;
|
|
25
|
|
26 public ComparableCoreMethodNode(RubyContext context, SourceSection sourceSection) {
|
|
27 super(context, sourceSection);
|
|
28 compareNode = adoptChild(new DispatchHeadNode(context, getSourceSection(), "<=>", false));
|
|
29 }
|
|
30
|
|
31 public ComparableCoreMethodNode(ComparableCoreMethodNode prev) {
|
|
32 super(prev);
|
|
33 compareNode = adoptChild(prev.compareNode);
|
|
34 }
|
|
35
|
|
36 public int compare(VirtualFrame frame, RubyBasicObject receiverObject, Object comparedTo) {
|
|
37 return (int) compareNode.dispatch(frame, receiverObject, null, comparedTo);
|
|
38 }
|
|
39
|
|
40 }
|
|
41
|
|
42 @CoreMethod(names = "<", isModuleMethod = true, minArgs = 1, maxArgs = 1)
|
|
43 public abstract static class LessNode extends ComparableCoreMethodNode {
|
|
44
|
|
45 public LessNode(RubyContext context, SourceSection sourceSection) {
|
|
46 super(context, sourceSection);
|
|
47 }
|
|
48
|
|
49 public LessNode(LessNode prev) {
|
|
50 super(prev);
|
|
51 }
|
|
52
|
|
53 @Specialization
|
|
54 public boolean less(VirtualFrame frame, RubyBasicObject self, Object comparedTo) {
|
|
55 return compare(frame, self, comparedTo) < 0;
|
|
56 }
|
|
57
|
|
58 }
|
|
59
|
|
60 @CoreMethod(names = "<=", isModuleMethod = true, minArgs = 1, maxArgs = 1)
|
|
61 public abstract static class LessEqualNode extends ComparableCoreMethodNode {
|
|
62
|
|
63 public LessEqualNode(RubyContext context, SourceSection sourceSection) {
|
|
64 super(context, sourceSection);
|
|
65 }
|
|
66
|
|
67 public LessEqualNode(LessEqualNode prev) {
|
|
68 super(prev);
|
|
69 }
|
|
70
|
|
71 @Specialization
|
|
72 public boolean lessEqual(VirtualFrame frame, RubyBasicObject self, Object comparedTo) {
|
|
73 return compare(frame, self, comparedTo) <= 0;
|
|
74 }
|
|
75
|
|
76 }
|
|
77
|
|
78 @CoreMethod(names = "==", isModuleMethod = true, minArgs = 1, maxArgs = 1)
|
|
79 public abstract static class EqualNode extends ComparableCoreMethodNode {
|
|
80
|
|
81 public EqualNode(RubyContext context, SourceSection sourceSection) {
|
|
82 super(context, sourceSection);
|
|
83 }
|
|
84
|
|
85 public EqualNode(EqualNode prev) {
|
|
86 super(prev);
|
|
87 }
|
|
88
|
|
89 @Specialization
|
|
90 public boolean equal(VirtualFrame frame, RubyBasicObject self, Object comparedTo) {
|
|
91 if (self == comparedTo) {
|
|
92 return true;
|
|
93 }
|
|
94
|
|
95 try {
|
|
96 return compare(frame, self, comparedTo) == 0;
|
|
97 } catch (Exception e) {
|
|
98 // Comparable#== catches and ignores all exceptions in <=>, returning false
|
|
99 return false;
|
|
100 }
|
|
101 }
|
|
102 }
|
|
103
|
|
104 @CoreMethod(names = ">=", isModuleMethod = true, minArgs = 1, maxArgs = 1)
|
|
105 public abstract static class GreaterEqualNode extends ComparableCoreMethodNode {
|
|
106
|
|
107 public GreaterEqualNode(RubyContext context, SourceSection sourceSection) {
|
|
108 super(context, sourceSection);
|
|
109 }
|
|
110
|
|
111 public GreaterEqualNode(GreaterEqualNode prev) {
|
|
112 super(prev);
|
|
113 }
|
|
114
|
|
115 @Specialization
|
|
116 public boolean greaterEqual(VirtualFrame frame, RubyBasicObject self, Object comparedTo) {
|
|
117 return compare(frame, self, comparedTo) >= 0;
|
|
118 }
|
|
119
|
|
120 }
|
|
121
|
|
122 @CoreMethod(names = ">", isModuleMethod = true, minArgs = 1, maxArgs = 1)
|
|
123 public abstract static class GreaterNode extends ComparableCoreMethodNode {
|
|
124
|
|
125 public GreaterNode(RubyContext context, SourceSection sourceSection) {
|
|
126 super(context, sourceSection);
|
|
127 }
|
|
128
|
|
129 public GreaterNode(GreaterNode prev) {
|
|
130 super(prev);
|
|
131 }
|
|
132
|
|
133 @Specialization
|
|
134 public boolean greater(VirtualFrame frame, RubyBasicObject self, Object comparedTo) {
|
|
135 return compare(frame, self, comparedTo) > 0;
|
|
136 }
|
|
137
|
|
138 }
|
|
139
|
|
140 @CoreMethod(names = "between?", isModuleMethod = true, minArgs = 2, maxArgs = 2)
|
|
141 public abstract static class BetweenNode extends ComparableCoreMethodNode {
|
|
142
|
|
143 public BetweenNode(RubyContext context, SourceSection sourceSection) {
|
|
144 super(context, sourceSection);
|
|
145 }
|
|
146
|
|
147 public BetweenNode(BetweenNode prev) {
|
|
148 super(prev);
|
|
149 }
|
|
150
|
|
151 @Specialization
|
|
152 public boolean between(VirtualFrame frame, RubyBasicObject self, Object min, Object max) {
|
|
153 return !(compare(frame, self, min) < 0 || compare(frame, self, max) > 0);
|
|
154 }
|
|
155
|
|
156 }
|
|
157
|
|
158 }
|