-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbf.ym
91 lines (84 loc) · 2.32 KB
/
bf.ym
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
# TODO #5
# This would be a lot clearer if i had enums
struct Instruction(type I32, payload I32)
def :new(::type, ::payload) end
def :new(::type)
::payload = 0
end
def :new()
::type = 0
::payload = 0
end
end
def parse(input U8[]) Instruction[]
let i = 0
let instructions = Instruction[](input.size)
# TODO #14
# This should be dynamically sized...
let stack = I32[](512)
let stack_i = 0
input.each_with_index(def (chr U8, i I32)
let instruction = Instruction()
# TODO
# This could be simplified if I had switch-like stuff
if chr == ?> then instruction = Instruction(1)
else if chr == ?< then instruction = Instruction(2)
else if chr == ?+ then instruction = Instruction(3)
else if chr == ?- then instruction = Instruction(4)
else if chr == ?. then instruction = Instruction(5)
else if chr == ?, then instruction = Instruction(6)
else if chr == ?[
instruction = Instruction(7, -1)
stack[stack_i] = i
# TODO
# This could be simplified if I had fused `+=`
stack_i = stack_i + 1
else if chr == ?]
stack_i = stack_i - 1
let jump_target = stack[stack_i]
instruction = Instruction(8, jump_target)
instructions[jump_target]::payload = i
end
instructions[i] = instruction
i = i + 1
end)
return instructions
end
def main(argc I32, argv U8 ptr ptr) I32
# Hello world example function
let word U8[] = "++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++."
if argc > 1
let word_ptr U8 ptr = argv[1]
word = U8[](word_ptr, word_ptr.c_len)
end
let instructions = parse(word)
let pc I32 = 0
let ptr I32 = 0
let memory = U8[](65535)
while pc < instructions.size
let instr = instructions[pc]
if instr::type == 1
ptr = ptr + 1
else if instr::type == 2
ptr = ptr - 1
else if instr::type == 3
memory[ptr] = memory[ptr] + 1
else if instr::type == 4
memory[ptr] = memory[ptr] - 1
else if instr::type == 5
printf("%c".c_str.unsafe_ptr, memory[ptr])
else if instr::type == 7
if memory[ptr] == ?\0
pc = instr::payload
end
else if instr::type == 8
if memory[ptr] != ?\0
pc = instr::payload
end
else
return 2
end
pc = pc + 1
end
return 0
end