comparison graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/HashNodes.java @ 13514:0fbee3eb71f0

Ruby: import project.
author Chris Seaton <chris.seaton@oracle.com>
date Mon, 06 Jan 2014 17:12:09 +0000
parents
children f70c894ae874
comparison
equal deleted inserted replaced
13513:64a23ce736a0 13514:0fbee3eb71f0
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.util.*;
13
14 import com.oracle.truffle.api.*;
15 import com.oracle.truffle.api.dsl.*;
16 import com.oracle.truffle.api.frame.*;
17 import com.oracle.truffle.ruby.runtime.*;
18 import com.oracle.truffle.ruby.runtime.core.*;
19 import com.oracle.truffle.ruby.runtime.core.array.*;
20
21 @CoreClass(name = "Hash")
22 public abstract class HashNodes {
23
24 @CoreMethod(names = "[]", isModuleMethod = true, needsSelf = false, isSplatted = true)
25 public abstract static class ConstructNode extends CoreMethodNode {
26
27 public ConstructNode(RubyContext context, SourceSection sourceSection) {
28 super(context, sourceSection);
29 }
30
31 public ConstructNode(ConstructNode prev) {
32 super(prev);
33 }
34
35 @Specialization
36 public RubyHash construct(Object[] args) {
37 final RubyHash hash = new RubyHash(getContext().getCoreLibrary().getHashClass());
38
39 if (args.length == 1) {
40 final RubyArray array = (RubyArray) args[0];
41
42 for (int n = 0; n < array.size(); n++) {
43 final RubyArray keyValue = (RubyArray) array.get(n);
44 hash.put(keyValue.get(0), keyValue.get(1));
45 }
46 } else {
47 assert args.length % 2 == 0;
48
49 for (int n = 0; n < args.length; n += 2) {
50 hash.put(args[n], args[n + 1]);
51 }
52 }
53
54 return hash;
55 }
56
57 }
58
59 @CoreMethod(names = "[]", minArgs = 1, maxArgs = 1)
60 public abstract static class GetIndexNode extends CoreMethodNode {
61
62 public GetIndexNode(RubyContext context, SourceSection sourceSection) {
63 super(context, sourceSection);
64 }
65
66 public GetIndexNode(GetIndexNode prev) {
67 super(prev);
68 }
69
70 @Specialization
71 public Object construct(VirtualFrame frame, RubyHash hash, Object index) {
72 final Object value = hash.get(index);
73
74 if (value == null) {
75 if (hash.defaultBlock == null) {
76 return NilPlaceholder.INSTANCE;
77 } else {
78 return hash.defaultBlock.call(frame.pack(), hash, index);
79 }
80 } else {
81 return value;
82 }
83 }
84
85 }
86
87 @CoreMethod(names = "[]=", minArgs = 2, maxArgs = 2)
88 public abstract static class SetIndexNode extends CoreMethodNode {
89
90 public SetIndexNode(RubyContext context, SourceSection sourceSection) {
91 super(context, sourceSection);
92 }
93
94 public SetIndexNode(SetIndexNode prev) {
95 super(prev);
96 }
97
98 @Specialization
99 public Object construct(RubyHash hash, Object index, Object value) {
100 hash.put(index, value);
101 return value;
102 }
103
104 }
105
106 @CoreMethod(names = "delete", minArgs = 1, maxArgs = 1)
107 public abstract static class DeleteNode extends CoreMethodNode {
108
109 public DeleteNode(RubyContext context, SourceSection sourceSection) {
110 super(context, sourceSection);
111 }
112
113 public DeleteNode(DeleteNode prev) {
114 super(prev);
115 }
116
117 @Specialization
118 public Object delete(RubyHash hash, Object index) {
119 hash.checkFrozen();
120
121 final Object value = hash.getMap().remove(index);
122
123 if (value == null) {
124 return NilPlaceholder.INSTANCE;
125 } else {
126 return value;
127 }
128 }
129
130 }
131
132 @CoreMethod(names = "each", needsBlock = true, maxArgs = 0)
133 public abstract static class EachNode extends YieldingCoreMethodNode {
134
135 public EachNode(RubyContext context, SourceSection sourceSection) {
136 super(context, sourceSection);
137 }
138
139 public EachNode(EachNode prev) {
140 super(prev);
141 }
142
143 @Specialization
144 public NilPlaceholder each(VirtualFrame frame, RubyHash hash, RubyProc block) {
145 for (Map.Entry<Object, Object> entry : hash.storage.entrySet()) {
146 yield(frame, block, entry.getKey(), entry.getValue());
147 }
148
149 return NilPlaceholder.INSTANCE;
150 }
151
152 }
153
154 @CoreMethod(names = "empty?", maxArgs = 0)
155 public abstract static class EmptyNode extends CoreMethodNode {
156
157 public EmptyNode(RubyContext context, SourceSection sourceSection) {
158 super(context, sourceSection);
159 }
160
161 public EmptyNode(EmptyNode prev) {
162 super(prev);
163 }
164
165 @Specialization
166 public boolean empty(RubyHash hash) {
167 return hash.storage.isEmpty();
168 }
169
170 }
171
172 @CoreMethod(names = "initialize", needsBlock = true, maxArgs = 0)
173 public abstract static class InitializeNode extends CoreMethodNode {
174
175 public InitializeNode(RubyContext context, SourceSection sourceSection) {
176 super(context, sourceSection);
177 }
178
179 public InitializeNode(InitializeNode prev) {
180 super(prev);
181 }
182
183 @Specialization
184 public NilPlaceholder initialize(RubyHash hash, @SuppressWarnings("unused") UndefinedPlaceholder block) {
185 hash.initialize(null);
186 return NilPlaceholder.INSTANCE;
187 }
188
189 @Specialization
190 public NilPlaceholder initialize(RubyHash hash, RubyProc block) {
191 hash.initialize(block);
192 return NilPlaceholder.INSTANCE;
193 }
194
195 }
196
197 @CoreMethod(names = {"map", "collect"}, needsBlock = true, maxArgs = 0)
198 public abstract static class MapNode extends YieldingCoreMethodNode {
199
200 public MapNode(RubyContext context, SourceSection sourceSection) {
201 super(context, sourceSection);
202 }
203
204 public MapNode(MapNode prev) {
205 super(prev);
206 }
207
208 @Specialization
209 public RubyArray map(VirtualFrame frame, RubyHash hash, RubyProc block) {
210 final RubyArray result = new RubyArray(getContext().getCoreLibrary().getArrayClass());
211
212 for (Map.Entry<Object, Object> entry : hash.storage.entrySet()) {
213 result.push(yield(frame, block, entry.getKey(), entry.getValue()));
214 }
215
216 return result;
217 }
218
219 }
220
221 @CoreMethod(names = "key?", minArgs = 1, maxArgs = 1)
222 public abstract static class KeyNode extends CoreMethodNode {
223
224 public KeyNode(RubyContext context, SourceSection sourceSection) {
225 super(context, sourceSection);
226 }
227
228 public KeyNode(KeyNode prev) {
229 super(prev);
230 }
231
232 @Specialization
233 public boolean key(RubyHash hash, Object key) {
234 return hash.storage.containsKey(key);
235 }
236
237 }
238
239 @CoreMethod(names = "keys", maxArgs = 0)
240 public abstract static class KeysNode extends CoreMethodNode {
241
242 public KeysNode(RubyContext context, SourceSection sourceSection) {
243 super(context, sourceSection);
244 }
245
246 public KeysNode(KeysNode prev) {
247 super(prev);
248 }
249
250 @Specialization
251 public RubyArray keys(RubyHash hash) {
252 final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass());
253
254 for (Object key : hash.storage.keySet()) {
255 array.push(key);
256 }
257
258 return array;
259 }
260
261 }
262
263 @CoreMethod(names = "size", maxArgs = 0)
264 public abstract static class SizeNode extends CoreMethodNode {
265
266 public SizeNode(RubyContext context, SourceSection sourceSection) {
267 super(context, sourceSection);
268 }
269
270 public SizeNode(SizeNode prev) {
271 super(prev);
272 }
273
274 @Specialization
275 public int size(RubyHash hash) {
276 return hash.storage.size();
277 }
278
279 }
280
281 @CoreMethod(names = "values", maxArgs = 0)
282 public abstract static class ValuesNode extends CoreMethodNode {
283
284 public ValuesNode(RubyContext context, SourceSection sourceSection) {
285 super(context, sourceSection);
286 }
287
288 public ValuesNode(ValuesNode prev) {
289 super(prev);
290 }
291
292 @Specialization
293 public RubyArray values(RubyHash hash) {
294 final RubyArray array = new RubyArray(getContext().getCoreLibrary().getArrayClass());
295
296 for (Object value : hash.storage.values()) {
297 array.push(value);
298 }
299
300 return array;
301 }
302
303 }
304
305 }