[pypy-svn] r65508 - in pypy/branch/io-lang/pypy/lang/io: . test

david at codespeak.net david at codespeak.net
Sat May 30 15:57:31 CEST 2009


Author: david
Date: Sat May 30 15:57:28 2009
New Revision: 65508

Modified:
   pypy/branch/io-lang/pypy/lang/io/map.py
   pypy/branch/io-lang/pypy/lang/io/model.py
   pypy/branch/io-lang/pypy/lang/io/test/test_map.py
Log:
Added Map type for key value based collections, extended all types by a hash method and impelemented some Map methods


Modified: pypy/branch/io-lang/pypy/lang/io/map.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/map.py	(original)
+++ pypy/branch/io-lang/pypy/lang/io/map.py	Sat May 30 15:57:28 2009
@@ -1,6 +1,10 @@
 from pypy.lang.io.register import register_method
 
 @register_method('Map', 'atPut', unwrap_spec=[object, object, object])
-def map_at_put(space, target, key, value):
-    target.items[key] = value
-    return target
\ No newline at end of file
+def map_at_put(space, w_target, w_key, w_value):
+    w_target.at_put(w_key, w_value)
+    return w_target
+    
+ at register_method('Map', 'at', unwrap_spec=[object, object])
+def map_at(space, w_target, w_key):
+    return w_target.at(w_key)
\ No newline at end of file

Modified: pypy/branch/io-lang/pypy/lang/io/model.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/model.py	(original)
+++ pypy/branch/io-lang/pypy/lang/io/model.py	Sat May 30 15:57:28 2009
@@ -11,7 +11,16 @@
 
     def __ne__(self, other):
         return not self == other
-
+    
+    def hash(self):
+        h = 0
+        for w_x in self.slots:
+            h += w_x.hash()
+        for x in self.protos:
+            h += hash(x)
+        
+        return h
+        
     def lookup(self, name, seen=None):
         if seen is None:
             seen = {}
@@ -49,6 +58,9 @@
         cloned = W_Number(self.space, self.value)
         cloned.protos = [self]
         return cloned
+        
+    def hash(self):
+        return hash(self.value)
 
 class W_List(W_Object):
     def __init__(self, space, protos = [], items = []):
@@ -72,6 +84,12 @@
         l = self.clone()
         l.items += items
         return l
+    
+    def hash(self):
+        h = 0
+        for x in self.items:
+            h += x.hash()
+        return h
         
 class W_Map(W_Object):
     """A key/value dictionary appropriate for holding large key/value collections."""
@@ -82,10 +100,30 @@
     def clone(self):
         return W_Map(self.space, [self], dict(self.items))
         
+    def hash(self):
+        h = 0
+        for key, val in self.items:
+            h += key + val.hash()
+        return h
+    
+    def at(self, w_key):
+        return self.items[w_key.hash()].value
+    
+    def at_put(self, w_key, w_value):
+        self.items[w_key.hash()] = MapEntry(w_key, w_value)
+        
+class MapEntry(object):
+    def __init__(self, w_key, w_value):
+        self.key = w_key
+        self.value = w_value
+    
+        
 class W_ImmutableSequence(W_Object):
     def __init__(self, space, string):
         self.value = string
-    
+        
+    def hash(self):
+        return hash(self.value)
 
 class W_CFunction(W_Object):
     def __init__(self, space, function):
@@ -95,6 +133,9 @@
     def apply(self, space, w_receiver, w_message, w_context):
         return self.function(space, w_receiver, w_message, w_context)
     
+    def hash(self):
+        return hash(self.function)
+        
 class W_Message(W_Object):
     def __init__(self, space, name, arguments, next = None):
         self.name = name
@@ -106,7 +147,12 @@
     def __repr__(self):
         return "Message(%r, %r, %r)" % (self.name, self.arguments, self.next)
 
-    
+    def hash(self):
+        h = hash(self.name)
+        for x in self.arguments:
+            h += x.hash()
+        return h
+        
     def eval(self, space, w_receiver, w_context):
         if self.name == ';':
             # xxx is this correct?
@@ -168,6 +214,13 @@
     def clone_and_init(self, space, arguments, body, activateable):
         return W_Block(space, arguments, body, activateable, [self])
         
+    def hash(self):
+        h = self.body.hash()
+        for x in self.arguments:
+            h += x.hash()
+        return h
+        
+        
 def parse_hex(string):
     if not string.startswith("0x"):
         raise ValueError

Modified: pypy/branch/io-lang/pypy/lang/io/test/test_map.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_map.py	(original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_map.py	Sat May 30 15:57:28 2009
@@ -18,7 +18,17 @@
 def test_at_put():
     inp = 'Map clone atPut("foo", "bar")'
     res, space = interpret(inp)
-    keys = [(key.value) for key in res.items.keys()]
+    keys = [(entry.key.value) for entry in res.items.values()]
     assert keys == ['foo']
-    values = [(val.value) for val in res.items.values()]
-    assert values == ['bar']
\ No newline at end of file
+    values = [(entry.value.value) for entry in res.items.values()]
+    assert values == ['bar']
+    
+def test_at():
+    inp = 'Map clone atPut("foo", "bar") atPut("lorem", "ipsum") at("foo")'
+    res, space = interpret(inp)
+    assert res.value == 'bar'
+    
+def test_key_hashing():
+    inp = 'Map clone atPut(1, "bar") atPut(nil, "ipsum") atPut("foo", 123) at(nil)'
+    res, space = interpret(inp)
+    assert res.value == 'ipsum'
\ No newline at end of file



More information about the Pypy-commit mailing list