-
Notifications
You must be signed in to change notification settings - Fork 0
/
compiler.go
97 lines (91 loc) · 1.83 KB
/
compiler.go
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
package bf
type Operator uint8
const (
opModifyValue Operator = iota
opModifyPointer
opOut
opIn
opJumpForward
opJumpBackward
)
type Instruction struct {
Operator
Operand int
}
type Program struct {
instructions []Instruction
stack []int
pointer int
opPointer int
}
func (p *Program) Compile(code string) {
jumpStack := make([]int, 1)
for i, c := range code {
var instruction Instruction
switch c {
case '+':
instruction = Instruction{
Operator: opModifyValue,
Operand: 1,
}
case '-':
instruction = Instruction{
Operator: opModifyValue,
Operand: -1,
}
case '<':
instruction = Instruction{
Operator: opModifyPointer,
Operand: -1,
}
case '>':
instruction = Instruction{
Operator: opModifyPointer,
Operand: 1,
}
case '[':
instruction = Instruction{
Operator: opJumpForward,
}
jumpStack = append(jumpStack, i)
case ']':
jumpTo := jumpStack[len(jumpStack)-1]
jumpStack = jumpStack[:len(jumpStack)-1]
instruction = Instruction{
Operator: opJumpBackward,
Operand: jumpTo,
}
p.instructions[jumpTo].Operand = i
case '.':
instruction = Instruction{
Operator: opOut,
}
}
p.instructions = append(p.instructions, instruction)
}
}
func (p *Program) Run() string {
output := ""
for p.opPointer < len(p.instructions) {
opPtr := p.opPointer
p.opPointer++
instruction := p.instructions[opPtr]
switch instruction.Operator {
case opModifyValue:
p.stack[p.pointer] += instruction.Operand
case opModifyPointer:
p.pointer += instruction.Operand
case opJumpForward:
if p.stack[p.pointer] == 0 {
p.opPointer = instruction.Operand
}
case opJumpBackward:
if p.stack[p.pointer] != 0 {
p.opPointer = instruction.Operand
}
case opOut:
output += string(p.stack[p.pointer])
}
}
return output
}