-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlazyk2hb.rb
104 lines (95 loc) · 1.8 KB
/
lazyk2hb.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
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
97
98
99
100
101
102
103
104
class LazyK2HonestB
def initialize(cpl, input=$<, output=$>)
@count = 0
@buf = []
@chars_per_line = cpl
@input = input
@output = output
end
def read_lazyk
expr = read1
while e = read1
expr = [expr, e]
end
expr
end
def read1
stack = []
cur = nil
while true
while true
begin
c = @input.readchar
rescue EOFError
c = nil
break
end
if c =~ /[`ski]/ || c.nil?
break
end
end
case c
when nil
if stack.empty? && cur.nil?
return nil
else
raise "unexpected EOF"
end
when "`"
stack << cur if cur
cur = []
when "s" then cur << :S
when "k" then cur << :K
when "i" then cur << [[:S, :K], :K]
end
while cur.length == 2
if stack.empty?
return cur
end
prev = stack.pop
prev << cur
cur = prev
end
end
nil
end
def print1(tk)
@count += tk.length
if @count >= @chars_per_line
@output.puts @buf.join
@buf.clear
@count = tk.length
end
@buf << tk
end
def flush()
@output.puts @buf.join
@buf.clear
@count = 0
end
def print_hb(expr)
stack = [expr]
until stack.empty?
e = stack.pop
case e
in :S then print1("スロー")
in :K then print1("クイック")
in :App then print1("\u2764")
in [e1, e2]
stack << :App
stack << e1
stack << e2
end
end
end
def run
print_hb(read_lazyk)
flush
end
end
if ARGV[0] == "-h" || ARGV[0] == "--help"
puts "usage: ruby lazyk2hb.rb prog.lazyk > prog.hb"
puts " or cat prog.lazyk | ruby lazyk2hb.rb > prog.hb"
else
LazyK2HonestB.new(39).run
end