blob: cd7d6fcdf63bad58bdf9a912ec41b9e0b3e2daf9 (
plain)
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
105
106
107
108
109
110
111
112
|
require "big"
require "random"
require "../util.cr"
struct AmongUs::Program < Flint::Program
def interpret : Nil
rand = Random.new
code = Parser.new(@source_io).parse
jumps = find_jumps(code)
code_ptr = 0
stack = [] of BigInt
acc1 = BigInt.new
acc2 = BigInt.new
color = code.find &.is_a?(Color)
while code_ptr < code.size
case code[code_ptr]
in Color::RED
color = Color::RED
in Color::BLUE
color = Color::BLUE
in Color::PURPLE
color = Color::PURPLE
in Color::GREEN
color = Color::GREEN
in Color::YELLOW
color = Color::YELLOW
in Color::CYAN
color = Color::CYAN
in Color::BLACK
color = Color::BLACK
in Color::WHITE
color = Color::WHITE
in Color::BROWN
color = Color::BROWN
in Color::LIME
color = Color::LIME
in Color::PINK
color = Color::PINK
in Color::ORANGE
color = Color::ORANGE
in Command::SUS
case color
when Color::RED
acc1 += 1
when Color::BLUE
stack << BigInt.new(acc1)
when Color::PURPLE
stack.pop unless stack.empty?
when Color::GREEN
print (stack.pop % 256).to_u8.chr unless stack.empty?
when Color::YELLOW
c = STDIN.read_char
stack << BigInt.new(c.ord) unless c.nil?
when Color::CYAN
r = rand.rand(acc1 + 1)
r.times do
break if stack.empty?
stack.pop
end
when Color::BLACK
print stack.pop
when Color::WHITE
acc1 -= 1
when Color::BROWN
acc1 = stack.pop
when Color::LIME
stack[-1] *= 2
when Color::PINK
acc1 = 0
when Color::ORANGE
acc1 += 10
when nil
raise Util::InterpreterError.new("Tried to use SUS command with no color.")
end
in Command::VENTED
acc2 += 10
in Command::SUSSY
acc2 -= 1
in Command::ELECTRICAL
acc2 = 0
in Command::WHO
code_ptr = jumps[code_ptr] if !stack.empty? && stack[-1] % 256 == acc2 % 256
in Command::WHERE
code_ptr = jumps[code_ptr] if !stack.empty? && stack[-1] % 256 != acc2 % 256
end
code_ptr += 1
end
end
private def find_jumps(code : Array(Instruction)) : Hash(Int32, Int32)
jumps = {} of Int32 => Int32
stack = [] of Int32
code.each_index do |i|
case code[i]
when Command::WHO
stack << i
when Command::WHERE
jumps[i] = stack.pop
jumps[jumps[i]] = i
end
end
return jumps
end
end
|