forked from mame/quine-relay
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunlambda.rb
60 lines (58 loc) · 1.32 KB
/
unlambda.rb
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
tokens = []
File.read($*[0]).scan(/\.(?<out>.)|(?<insn>[r`ikscd])|#.*/) do
if $~[:out]
tokens << [:o, $~[:out]]
elsif $~[:insn]
case $~[:insn]
when ?r then tokens << [:o, ?\n]
when ?` then tokens << :a
else tokens << $~[:insn].to_sym
end
end
end
tokens.reverse!
stack = [nil, :S]
acc = nil
while stack
stack, cmd = stack
acc = if cmd == :S
stack = [stack, acc] if acc
insn, arg = tokens.pop
case insn
when :o then [:o, arg]
when :a then stack = [[stack, :S], :S]; nil
when nil then raise "EOF"
else [insn]
end
else
[:a, cmd, acc]
end
end
stack = [nil, :E, acc]
acc = nil
while stack
stack, cmd, cls = stack
acc = if cmd == :E
if acc && acc[0] == :d
[:d1, cls]
else
stack = [stack, :A, acc] if acc
cls[0] == :a ? (stack = [[stack, :E, cls[2]], :E, cls[1]]; nil) : cls
end
else
type, x, y = cls
case type
when :o then print x; acc
when :i then acc
when :k then [:k1, acc]
when :k1 then x
when :s then [:s1, acc]
when :s1 then [:s2, x, acc]
when :s2 then stack = [stack, :E, [:a, [:a, x, acc], [:a, y, acc]]]; nil
when :c then stack = [stack, :A, acc]; [:c1, stack[0]]
when :c1 then stack = x; acc
when :d then acc
when :d1 then stack = [stack, :E, [:a, x, acc]]; nil
end
end
end