#! /usr/bin/python import sys currentchar = '' def k(a, c): def k2(_, c2): c2(a) c(k2) def s(a, k): def s2(a2, k2): def s3(a3, k3): a(a3, lambda r1: a2(a3, lambda r2: r1(r2, k3))) k2(s3) k(s2) def i(a, k): k(a) def v(_, k): k(v) def c(a, k): a(lambda a2, _: k(a2), k) def e(a, k): sys.exit(a != i) def readchar(a, k): global currentchar currentchar = sys.stdin.read(1) if not currentchar: a(v, k) #EOF else: a(i, k) def printchar(c): def p(a, k): sys.stdout.write(c) k(a) return p r = printchar('\n') def compchar(c): def comp(a, k): if c == currentchar: a(i, k) else: a(v, k) def reprint(a, k): if not currentchar: a(v, k) else: a(printchar(currentchar), k) # any time d actually gets invoked, its argument has already been evaluated. def d(a, k): k(a) takesarg = {'.':printchar, '?':compchar} noarg = {'|':reprint, 's':s, 'k':k, 'c':c, 'e':e, 'i':i, 'v':v, 'r':r, 'd':d} def bt(inp): cur, inp = inp[0], inp[1:] if cur == '#': while cur != '\n': cur, inp = inp[0], inp[1:] if cur == '`': l, inp = bt(inp) r, inp = bt(inp) return (l, r), inp elif cur in takesarg: arg, inp = inp[0], inp[1:] return takesarg[cur](arg), inp elif cur in noarg: return noarg[cur], inp else: return bt(inp) def descend(tree, cont): def maybedescend(lv, righthalf, cont2): if lv == d: cont2(lambda rval, k: descend(righthalf, lambda lval: lval(rval, k))) else: descend(righthalf, lambda rv: lv(rv, cont2)) if isinstance(tree, tuple): descend(tree[0], lambda lv: maybedescend(lv, tree[1], cont)) else: cont(tree) if __name__ == '__main__': sys.setrecursionlimit(10000) # enough to run modest unlambda programs... if len(sys.argv) == 2: txt = open(sys.argv[1]).read() else: txt = sys.stdin.read() tree = bt(txt)[0] descend(tree, lambda x: sys.exit(x != i))