1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
|
from rpython.tool.pairtype import pairtype, pair, extendabletype
def test_binop():
### Binary operation example
class __extend__(pairtype(int, int)):
def add((x, y)):
return 'integer: %s+%s' % (x, y)
def sub((x, y)):
return 'integer: %s-%s' % (x, y)
class __extend__(pairtype(bool, bool)):
def add((x, y)):
return 'bool: %s+%s' % (x, y)
assert pair(3,4).add() == 'integer: 3+4'
assert pair(3,4).sub() == 'integer: 3-4'
assert pair(3,True).add() == 'integer: 3+True'
assert pair(3,True).sub() == 'integer: 3-True'
assert pair(False,4).add() == 'integer: False+4'
assert pair(False,4).sub() == 'integer: False-4'
assert pair(False,True).add() == 'bool: False+True'
assert pair(False,True).sub() == 'integer: False-True'
def test_somebuiltin():
### Operation on built-in types
class MiniPickler:
def __init__(self):
self.data = []
def emit(self, datum):
self.data.append(datum)
class __extend__(pairtype(MiniPickler, int)):
def write((pickler, x)):
pickler.emit('I%d' % x)
class __extend__(pairtype(MiniPickler, str)):
def write((pickler, x)):
pickler.emit('S%s' % x)
class __extend__(pairtype(MiniPickler, list)):
def write((pickler, x)):
for item in x:
pair(pickler, item).write()
pickler.emit('L%d' % len(x))
p = MiniPickler()
pair(p, [1, 2, ['hello', 3]]).write()
assert p.data == ['I1', 'I2', 'Shello', 'I3', 'L2', 'L3']
def test_some_multimethod():
### Another multimethod example
class Block:
def __init__(self, exit):
self.exit = exit
class Jump:
pass
class Switch:
pass
class C_Generator:
def __init__(self):
self.lines = []
class __extend__(pairtype(C_Generator, Block)):
def emit((gen, block), inputvars):
gen.lines.append("C code for block")
outputvars = inputvars + ['v4', 'v5']
pair(gen, block.exit).emit(outputvars)
class __extend__(pairtype(C_Generator, Jump)):
def emit((gen, jump), inputvars):
gen.lines.append("goto xyz")
class __extend__(pairtype(C_Generator, Switch)):
def emit((gen, jump), inputvars):
gen.lines.append("switch (%s) { ... }" % inputvars[-1])
g = C_Generator()
pair(g, Block(Switch())).emit(['v1', 'v2'])
assert g.lines == ["C code for block", "switch (v5) { ... }"]
class Lisp_Generator:
def __init__(self):
self.progn = []
class __extend__(pairtype(Lisp_Generator, Block)):
def emit((gen, block), inputvars):
gen.progn.append("(do 'something)")
g = Lisp_Generator()
pair(g, Block(Switch())).emit(['v1', 'v2'])
assert g.progn == ["(do 'something)"]
def test_multiple_extend():
class A:
__metaclass__ = extendabletype
class B:
__metaclass__ = extendabletype
class __extend__(A,B):
def f(self):
pass
assert hasattr(A, 'f')
assert hasattr(B, 'f')
|