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

Revision 1749, 2.2 kB (checked in by nishio, 7 years ago)

lang/unlambda/impl/in_python: brandnew version to support call/cc[c], currently supports [`.xi]

Line 
1""" unlambda interpreter
2
3# test
4>>> run("`.ai")
5a
6
7"""
8globals().clear()
9# Main loop
10#
11def run(s):
12    task = EvalTask(parse(s), FinalCont)
13    try:
14        while True:
15            task = task()
16    except StopIteration, e:
17        return
18
19# Continuation
20# __call__(Func) returns Task
21def FinalCont(f):
22    def FinalTask():
23        raise StopIteration
24    return FinalTask
25
26# Task
27#
28class Task(object): pass
29
30def EvalTask(node, cont):
31    def run():
32        return node.eval(cont)
33    return run
34
35# Node
36#
37class Node(object):
38    "parsed element"
39
40class I(Node):
41    "identity"
42    def eval(self, cont):
43        def I0(X, cont):
44            return cont.invoke(X)
45        return cont(I0)
46
47class Dot(Node):
48    "print char: `.aX => print 'a'"
49    def __init__(self, c):
50        self.c = c
51    def eval(self, cont):
52        def Dot0(X, cont):
53            import sys
54            sys.stdout.write(self.c)
55            return cont(X)
56        return cont(Dot0)
57   
58class Apply(Node):
59    "apply: `FG = F(G)"
60    def __init__(self, X, Y):
61        "take 2 not-evaluated node"
62        self.nX = X
63        self.nY = Y
64    def eval(self, cont):
65        nY = self.nY
66        def next(X):
67            def _App1(): # task
68                "evalated X and not-evaluated Y"
69
70#                if X.isDelay:
71#                     return self.cont.invoke(D1Function(self.nY))
72
73                def next(Y):
74                    def _App2(): # task
75                        return X(Y, cont)
76                    return _App2
77                return nY.eval(next)
78            return _App1
79        return EvalTask(self.nX, next)
80   
81def _parse(iter):
82    c = iter.next()
83    result = {
84        "i": lambda: I(),
85        ".": lambda: Dot(iter.next()),
86        "`": lambda: (lambda f=_parse(iter): Apply(f, _parse(iter)))(),
87
88        "r": lambda: R(),
89        "v": lambda: V(),
90        "d": lambda: "(delay)", # special form
91        "c": lambda: C(),
92        "s": lambda: S(),
93        "k": lambda: K(),
94    }.get(c, lambda: _parse(iter))()
95    return result
96
97def parse(s):
98    return _parse(list(s).__iter__())
99
100def _test():
101    import doctest
102    reload(doctest)
103    doctest.testmod()
104
105run("`.ai")
Note: See TracBrowser for help on using the browser.