root/lang/unlambda/impl/in_python/unlambda.py @ 1751

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")
5a
6>>> run("``i.ai")
7a
8>>> run("`i`.ai")
9a
10>>> run("`d`.ai")
11>>> run("``d`.aii")
12a
13>>> run("`.b`i`.ai")
14ab
15>>> run("`.b`d`.ai")
16b
17>>> run("``.b`d`.aii")
18ba
19"""
20
21# Main loop
22#
23def 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
33def FinalCont(f):
34    def FinalTask():
35        raise StopIteration
36    return FinalTask
37
38# Task
39#
40class Task(object): pass
41
42def EvalTask(node, cont):
43    def run():
44        #print node
45        return node.eval(cont)
46    return run
47
48# Node
49#
50class Node(object):
51    "parsed element"
52
53class 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
62class 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   
75class 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
106class 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
114def _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
130def parse(s):
131    return _parse(list(s).__iter__())
132
133def _test():
134    import doctest
135    reload(doctest)
136    doctest.testmod()
137
Note: See TracBrowser for help on using the browser.