[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