- Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathunlambda.py
More file actions
Latest commit
96 lines (83 loc) · 2.93 KB
/
Copy pathunlambda.py
File metadata and controls
96 lines (83 loc) · 2.93 KB
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
#! /usr/bin/python
importsys
currentchar=''
# "i" through "reprint" form the "apply" half of an eval/apply mutual
# recursion
i=lambdaa,c: (c,a)
k=lambdaa,c: (c, lambda_, c2: (c2, a))
s=lambdaa,c: (c, lambdaa2,c2: (c2, lambdaa3, c3:\
(descend, (((a,a3),(a2,a3)),c3))))
# you would think that the below definition of s would work, but it
# stumbles on "d".
#s = lambda a,c: (c, lambda a2,c2: (c2, lambda a3,c3: a(a3, lambda r1: a2(a3, lambda r2: r1(r2, c3)))))
v=lambda_,c: (c,v)
#c = lambda a,k: a(lambda a2, _: (k, a2), k)
c=lambdaa, k: (descend, ((a, lambdaa2, _: (k, a2)),k))
e=lambdaa,_: sys.exit(a!=i)
## d is a special form; it is never applied (provided we are careful
## never to invoke an argument directly---see e.g. def'n of s above.)
defd(a,c):
assertFalse, "This should never happen."
defreadchar(a, k):
globalcurrentchar
currentchar=sys.stdin.read(1)
ifnotcurrentchar: return (descend, ((a,v),k)) #a(v,k)
else: return (descend, ((a,i),k)) #a(i,k)
defprintchar(c):
defp(a, k):
sys.stdout.write(c)
return (k,a)
returnp
r=printchar('\n')
defcompchar(c):
defcomp(a, k):
ifc==currentchar: return (descend, ((a,i),k)) # a(i,k)
else: return (descend, ((a,v),k)) # a(v,k)
returncomp
defreprint(a, k):
pc=printchar(currentchar)
ifnotcurrentchar: return (descend, ((a,v),k)) #a(v,k)
else: return (descend, ((a,pc),k)) # a(pc, k)
takesarg= {'.':printchar, '?':compchar}
noarg= {'|':reprint, 's':s, 'k':k, 'c':c, 'e':e, 'i':i, 'v':v, 'r':r,
'd':d, '@':readchar}
### a pretty cowboy approach to parsing!
defbt(i):
tree, stack, ticks, tot= [], [], 0, 0
whiletot!=2*ticks+1:
cur=i(1).lower()
ifnotcur: raiseEOFError
tot+=1
ifcur=='#':
whilecurandcur!='\n': cur=i(1)
ifcurintakesarg:
stack.append(takesarg[cur](i(1)))
elifcurinnoarg: stack.append(noarg[cur])
elifcur=='`':
stack.append(cur)
ticks+=1
else: tot-=1
whilestack:
cur=stack.pop()
ifcur=='`':
l=tree.pop()
tree.append((l,tree.pop()))
else: tree.append(cur)
returntree[0]
### better known as "eval".
defdescend(tree_cont):
tree, cont=tree_cont
defdcheck(lval):
iflval==d:
returncont(lambdarv,k2: (descend, (tree[1], lambdalv:lv(rv,k2))))
else:
return (descend, (tree[1], lambdarv: lval(rv, cont)))
ifisinstance(tree, tuple): ### application of tree[0] to tree[1]
return (descend, (tree[0], dcheck))
else:
return (cont, tree)
if__name__=='__main__':
tree=bt((open(sys.argv[1]) iflen(sys.argv) ==2elsesys.stdin).read)
k, a=descend((tree, lambdax: sys.exit(x!=i)))
while1:
k, a=k(a)