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

david at codespeak.net david at codespeak.net
Wed Apr 29 15:59:16 CEST 2009


Author: david
Date: Wed Apr 29 15:59:09 2009
New Revision: 64809

Added:
   pypy/branch/io-lang/pypy/lang/io/block.py
   pypy/branch/io-lang/pypy/lang/io/test/test_block.py
Modified:
   pypy/branch/io-lang/pypy/lang/io/model.py
   pypy/branch/io-lang/pypy/lang/io/object.py
   pypy/branch/io-lang/pypy/lang/io/objspace.py
   pypy/branch/io-lang/pypy/lang/io/test/test_method.py
Log:
Introduced  block prototype object, create new methods and blocks by cloning this and support call operation on blocks and methods

Added: pypy/branch/io-lang/pypy/lang/io/block.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-lang/pypy/lang/io/block.py	Wed Apr 29 15:59:09 2009
@@ -0,0 +1,8 @@
+from pypy.lang.io.register import register_method
+from pypy.lang.io.model import W_Block
+
+ at register_method('Block', 'call')
+def w_block_call(space, w_target, w_message, w_context):
+    return w_target.call(space, w_target, w_message, w_context)
+
+    
\ 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	Wed Apr 29 15:59:09 2009
@@ -87,16 +87,21 @@
             return w_result
   
 class W_Block(W_Object):
-    def __init__(self, space, arguments, body):
+    def __init__(self, space, arguments, body, activateable=True, protos=[]):
         self.arguments = arguments
         self.body = body
-        W_Object.__init__(self, space)
+        W_Object.__init__(self, space, protos)
+        self.activateable = activateable
         
     def apply(self, space, w_receiver, w_message, w_context):
         # TODO: move the call logic to a call method to use with blocks also
         # TODO: store if the block is activateable (a method) or not
         # TODO: create and populate call object
-
+        if self.activateable:
+            return self.call(space, w_receiver, w_message, w_context)
+        return self
+        
+    def call(self, space, w_receiver, w_message, w_context):
         w_locals = self.space.w_locals.clone()
         assert w_locals is not None
         args = list(self.arguments)
@@ -110,10 +115,21 @@
         for arg_name in args:
             w_locals.slots[arg_name] = space.w_nil
         
-        w_locals.protos = [w_receiver]
-        w_locals.slots['self'] = w_receiver
+        if self.activateable:
+            w_locals.protos = [w_receiver]
+            w_locals.slots['self'] = w_receiver
+        else:
+            w_locals.protos = [w_context]
+            w_locals.slots['self'] = w_context
+            
         return self.body.eval(space, w_locals, w_context)
+            
+    
+    def clone(self):
+        return W_Block(self.space, self.arguments, self.body, self.activateable, [self])
         
+    def clone_and_init(self, space, arguments, body, activateable):
+        return W_Block(space, arguments, body, activateable, [self])
         
 def parse_hex(string):
     if not string.startswith("0x"):

Modified: pypy/branch/io-lang/pypy/lang/io/object.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/object.py	(original)
+++ pypy/branch/io-lang/pypy/lang/io/object.py	Wed Apr 29 15:59:09 2009
@@ -14,8 +14,15 @@
     w_body = w_message.arguments[-1]
     w_arguments = w_message.arguments[:-1]
     names = [x.name for x in w_arguments]
-    return W_Block(space, names, w_body)
+    return space.w_block.clone_and_init(space, names, w_body, True)
 
+ at register_method('Object', 'block')
+def w_object_block(space, w_target, w_message, w_context):
+    w_body = w_message.arguments[-1]
+    w_arguments = w_message.arguments[:-1]
+    names = [x.name for x in w_arguments]
+    return space.w_block.clone_and_init(space, names, w_body, False)
+    
 @register_method('Object', 'clone')
 def w_object_clone(space, w_target, w_message, w_context):
     assert w_message.name == 'clone'

Modified: pypy/branch/io-lang/pypy/lang/io/objspace.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/objspace.py	(original)
+++ pypy/branch/io-lang/pypy/lang/io/objspace.py	Wed Apr 29 15:59:09 2009
@@ -1,9 +1,10 @@
 from pypy.rlib.objectmodel import instantiate
-from pypy.lang.io.model import W_Number, W_Object, W_CFunction
+from pypy.lang.io.model import W_Number, W_Object, W_CFunction, W_Block, W_Message
 from pypy.lang.io.register import cfunction_definitions
 
 import pypy.lang.io.number
 import pypy.lang.io.object
+import pypy.lang.io.block
 
 class ObjSpace(object):
     """docstring for ObjSpace"""
@@ -16,12 +17,15 @@
         self.w_true = W_Object(self, [self.w_object])
         self.w_false = W_Object(self, [self.w_object])
         self.w_nil = W_Object(self, [self.w_object])
+        self.w_block = W_Block(self, [], W_Message(self, 'nil', []), False, [self.w_object])
         
         self.w_core.protos.append(self.w_object)
         
         self.w_protos.protos.append(self.w_core)
         self.w_protos.slots['Core'] = self.w_core
         
+        self.init_w_block()
+        
         self.init_w_lobby()
         
         self.init_w_number()
@@ -32,9 +36,13 @@
     #     
     # def init_singletons(self):
     #     #true, false, nil, Message, Call, Normal, Break, Continue, Return
-        
+    def init_w_block(self):
+        for key, function in cfunction_definitions['Block'].items():
+            self.w_block.slots[key] = W_CFunction(self, function)
+            
     def init_w_core(self):
         self.w_core.slots['Locals'] = self.w_locals
+        self.w_core.slots['Block'] = self.w_block
         self.w_core.slots['Object'] = self.w_object
         self.w_core.slots['true'] = self.w_true
         self.w_core.slots['false'] = self.w_false

Added: pypy/branch/io-lang/pypy/lang/io/test/test_block.py
==============================================================================
--- (empty file)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_block.py	Wed Apr 29 15:59:09 2009
@@ -0,0 +1,41 @@
+from pypy.lang.io.parserhack import parse, interpret
+from pypy.lang.io.model import W_Block, W_Message
+import py.test
+
+def test_parse_block():
+    inp = "a := block(1)\na"
+    res,space = interpret(inp)
+    assert isinstance(res, W_Block)
+    assert res.body == W_Message(space, '1', [], None)
+    
+def test_call_block():
+    inp = "a := block(1)\na call"
+    res,space = interpret(inp)
+    assert res.value == 1
+    
+    
+def test_call_method_with_args():
+    inp = "a := method(x, x+1)\na(2)"
+    res,space = interpret(inp)
+    assert res.value == 3
+    
+def test_call_method_without_all_args():
+    inp = "a := method(x, y, z, 42)\na(2)"
+    res,space = interpret(inp)
+    assert res.value == 42
+    
+def test_unspecified_args_are_nil():
+    inp = "a := method(x, y, z, z)\na(2)"
+    res,space = interpret(inp)
+    assert res == space.w_nil
+    
+def test_superfluous_args_are_ignored():
+    inp = "a := method(x, y, z, z)\na(1,2,3,4,5,6,6,7)"
+    res,space = interpret(inp)
+    assert res.value == 3
+    
+    
+def test_block_proto_evals_to_nil():
+    inp = 'Block call'
+    res, space = interpret(inp)
+    assert res == space.w_nil
\ No newline at end of file

Modified: pypy/branch/io-lang/pypy/lang/io/test/test_method.py
==============================================================================
--- pypy/branch/io-lang/pypy/lang/io/test/test_method.py	(original)
+++ pypy/branch/io-lang/pypy/lang/io/test/test_method.py	Wed Apr 29 15:59:09 2009
@@ -1,4 +1,5 @@
 from pypy.lang.io.parserhack import parse, interpret
+from pypy.lang.io.model import W_Block
 import py.test
 # "W_Message(space,"method", [W_Message(space,"1", [],), ],)"
 def test_get_slot():
@@ -32,4 +33,16 @@
 def test_superfluous_args_are_ignored():
     inp = "a := method(x, y, z, z)\na(1,2,3,4,5,6,6,7)"
     res,space = interpret(inp)
-    assert res.value == 3
\ No newline at end of file
+    assert res.value == 3
+    
+def test_method_proto():
+    inp = 'a := method(f)'
+    res, space = interpret(inp)
+    method = space.w_lobby.slots['a']
+    assert method.protos == [space.w_block]
+    
+def test_block_proto():
+    inp = 'Block'
+    res,space = interpret(inp)
+    assert isinstance(res, W_Block)
+    assert res.protos == [space.w_object]
\ No newline at end of file



More information about the Pypy-commit mailing list