Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.ruby.nodes/src/com/oracle/truffle/ruby/nodes/core/HashNodes.java @ 13529:856c2c294f84
Merge.
author | Christian Humer <christian.humer@gmail.com> |
---|---|
date | Tue, 07 Jan 2014 18:53:04 +0100 |
parents | 0fbee3eb71f0 |
children | f70c894ae874 |
comparison
equal
deleted
inserted
replaced
13528:5a0c694ef735 | 13529:856c2c294f84 |
---|---|
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 } |