|
Revision 1751, 3.0 kB
(checked in by nishio, 6 years ago)
|
|
lang/unlambda/impl/in_python: support [d], the delay special form
|
| Line | |
|---|
| 1 | """ unlambda interpreter
|
|---|
| 2 |
|
|---|
| 3 | # test
|
|---|
| 4 | >>> run("`.ai")
|
|---|
| 5 | a
|
|---|
| 6 | >>> run("``i.ai")
|
|---|
| 7 | a
|
|---|
| 8 | >>> run("`i`.ai")
|
|---|
| 9 | a
|
|---|
| 10 | >>> run("`d`.ai")
|
|---|
| 11 | >>> run("``d`.aii")
|
|---|
| 12 | a
|
|---|
| 13 | >>> run("`.b`i`.ai")
|
|---|
| 14 | ab
|
|---|
| 15 | >>> run("`.b`d`.ai")
|
|---|
| 16 | b
|
|---|
| 17 | >>> run("``.b`d`.aii")
|
|---|
| 18 | ba
|
|---|
| 19 | """
|
|---|
| 20 |
|
|---|
| 21 | # Main loop
|
|---|
| 22 | #
|
|---|
| 23 | def run(s):
|
|---|
| 24 | task = EvalTask(parse(s), FinalCont)
|
|---|
| 25 | try:
|
|---|
| 26 | while True:
|
|---|
| 27 | task = task()
|
|---|
| 28 | except StopIteration, e:
|
|---|
| 29 | return
|
|---|
| 30 |
|
|---|
| 31 | # Continuation
|
|---|
| 32 | # __call__(Func) returns Task
|
|---|
| 33 | def FinalCont(f):
|
|---|
| 34 | def FinalTask():
|
|---|
| 35 | raise StopIteration
|
|---|
| 36 | return FinalTask
|
|---|
| 37 |
|
|---|
| 38 | # Task
|
|---|
| 39 | #
|
|---|
| 40 | class Task(object): pass
|
|---|
| 41 |
|
|---|
| 42 | def EvalTask(node, cont):
|
|---|
| 43 | def run():
|
|---|
| 44 | #print node
|
|---|
| 45 | return node.eval(cont)
|
|---|
| 46 | return run
|
|---|
| 47 |
|
|---|
| 48 | # Node
|
|---|
| 49 | #
|
|---|
| 50 | class Node(object):
|
|---|
| 51 | "parsed element"
|
|---|
| 52 |
|
|---|
| 53 | class I(Node):
|
|---|
| 54 | "identity"
|
|---|
| 55 | def __str__(self):
|
|---|
| 56 | return "I"
|
|---|
| 57 | def eval(self, cont):
|
|---|
| 58 | def I0(X, cont):
|
|---|
| 59 | return cont(X)
|
|---|
| 60 | return cont(I0)
|
|---|
| 61 |
|
|---|
| 62 | class Dot(Node):
|
|---|
| 63 | "print char: `.aX => print 'a'"
|
|---|
| 64 | def __init__(self, c):
|
|---|
| 65 | self.c = c
|
|---|
| 66 | def __str__(self):
|
|---|
| 67 | return "(print %r)" % self.c
|
|---|
| 68 | def eval(self, cont):
|
|---|
| 69 | def Dot0(X, cont):
|
|---|
| 70 | import sys
|
|---|
| 71 | sys.stdout.write(self.c)
|
|---|
| 72 | return cont(X)
|
|---|
| 73 | return cont(Dot0)
|
|---|
| 74 |
|
|---|
| 75 | class Apply(Node):
|
|---|
| 76 | "apply: `FG = F(G)"
|
|---|
| 77 | def __init__(self, X, Y):
|
|---|
| 78 | "take 2 not-evaluated node"
|
|---|
| 79 | self.nX = X
|
|---|
| 80 | self.nY = Y
|
|---|
| 81 | def __str__(self):
|
|---|
| 82 | return "(apply %s %s)" % (self.nX, self.nY)
|
|---|
| 83 | def eval(self, cont):
|
|---|
| 84 | nY = self.nY
|
|---|
| 85 | def next(X):
|
|---|
| 86 | def _App1(): # task
|
|---|
| 87 | "evalated X and not-evaluated Y"
|
|---|
| 88 |
|
|---|
| 89 | if X.__class__ == D:
|
|---|
| 90 | def Promise0(Y, cont):
|
|---|
| 91 | def next(X):
|
|---|
| 92 | def Promise1(X, cont):
|
|---|
| 93 | return X(Y, cont)
|
|---|
| 94 | return cont(Promise1)
|
|---|
| 95 | return nY.eval(next)
|
|---|
| 96 | return cont(Promise0)
|
|---|
| 97 |
|
|---|
| 98 | def next(Y):
|
|---|
| 99 | def _App2(): # task
|
|---|
| 100 | return X(Y, cont)
|
|---|
| 101 | return _App2
|
|---|
| 102 | return nY.eval(next)
|
|---|
| 103 | return _App1
|
|---|
| 104 | return EvalTask(self.nX, next)
|
|---|
| 105 |
|
|---|
| 106 | class D(Node):
|
|---|
| 107 | def __str__(self):
|
|---|
| 108 | return "D"
|
|---|
| 109 | def eval(self, cont):
|
|---|
| 110 | return cont(self)
|
|---|
| 111 | def __call__(self, Y, cont):
|
|---|
| 112 | raise NotImplemented
|
|---|
| 113 |
|
|---|
| 114 | def _parse(iter):
|
|---|
| 115 | c = iter.next()
|
|---|
| 116 | result = {
|
|---|
| 117 | "i": lambda: I(),
|
|---|
| 118 | ".": lambda: Dot(iter.next()),
|
|---|
| 119 | "`": lambda: (lambda f=_parse(iter): Apply(f, _parse(iter)))(),
|
|---|
| 120 | "r": lambda: Dor("\n"),
|
|---|
| 121 | "d": lambda: D(), # special form
|
|---|
| 122 |
|
|---|
| 123 | "v": lambda: V(),
|
|---|
| 124 | "c": lambda: C(),
|
|---|
| 125 | "s": lambda: S(),
|
|---|
| 126 | "k": lambda: K(),
|
|---|
| 127 | }.get(c, lambda: _parse(iter))()
|
|---|
| 128 | return result
|
|---|
| 129 |
|
|---|
| 130 | def parse(s):
|
|---|
| 131 | return _parse(list(s).__iter__())
|
|---|
| 132 |
|
|---|
| 133 | def _test():
|
|---|
| 134 | import doctest
|
|---|
| 135 | reload(doctest)
|
|---|
| 136 | doctest.testmod()
|
|---|
| 137 |
|
|---|