-
Notifications
You must be signed in to change notification settings - Fork 259
Expand file tree
/
Copy pathbf.jl
More file actions
112 lines (90 loc) · 2.42 KB
/
bf.jl
File metadata and controls
112 lines (90 loc) · 2.42 KB
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
# code from https://github.com/MikeInnes/BrainForth/blob/master/src/brainfuck.jl
using Sockets
mutable struct Tape
count::Int
pos::Int
tape::Vector{UInt8}
end
Tape() = Tape(0, 1, [0])
Base.getindex(t::Tape) = t.tape[t.pos]
Base.setindex!(t::Tape, v) = t.tape[t.pos] = v
function Base.show(io::IO, t::Tape)
print(io, "[$(t.count)] ")
for i = 1:length(t.tape)
print(io, t.tape[i], i == t.pos ? "* " : " ")
end
end
Base.:(==)(a::Tape, b::Tape) = a.tape == b.tape
function left!(t::Tape)
t.pos == length(t.tape) && t.tape[end] == 0 && pop!(t.tape)
t.pos == 1 ? pushfirst!(t.tape, 0) : (t.pos -= 1)
return
end
function right!(t::Tape)
t.pos == 1 && t.tape[1] == 0 && (popfirst!(t.tape); t.pos -= 1)
t.pos == length(t.tape) && push!(t.tape, 0)
t.pos += 1
return
end
clip(n) = n > 255 ? n - 256 : n < 0 ? n + 256 : n
inc!(t::Tape) = (t[] = clip(t[] + 1))
dec!(t::Tape) = (t[] = clip(t[] - 1))
function read!(t::Tape, io::IO)
t[] = read(io, UInt8)
end
function write!(t::Tape, io::IO)
write(io, t[])
end
# Gets ~370 MHz
function interpret(t::Tape, bf; input::IO = stdin, output::IO = stdout)
loops = Int[]
scan = 0
ip = 1
@inbounds while ip <= length(bf)
t.count += 1
op = bf[ip]
if op == '['
scan > 0 || t[] == 0 ? (scan += 1) :
push!(loops, ip)
elseif op == ']'
scan > 0 ? (scan -= 1) :
t[] == 0 ? pop!(loops) :
(ip = loops[end])
elseif scan == 0
op == '+' ? inc!(t) :
op == '-' ? dec!(t) :
op == '<' ? left!(t) :
op == '>' ? right!(t) :
op == ',' ? read!(t, input) :
op == '.' ? write!(t, output) :
op == '#' ? println(t) :
nothing
end
ip += 1
end
return t
end
interpret(t::Tape, bf::String; kws...) = interpret(t, collect(bf); kws...)
interpret(bf; kws...) = interpret(Tape(), bf; kws...)
function main(text)
interpret(text)
end
println("JIT warming up")
main(">++[<+++++++++++++>-]<[[>+>+<<-]>[<+>-]++++++++[>++++++++<-]>[-]<<>++++++++++[>++++++++++[>++++++++++[>++++++++++[>++++++++++[>++++++++++[>++++++++++[-]<-]<-]<-]<-]<-]<-]<-]++++++++++")
println("bench")
function notify(msg)
try
socket = connect("localhost", 9001)
write(socket, msg)
close(socket)
catch
# standalone usage
end
end
text = open(ARGS[1]) do file
read(file, String)
end
notify("Julia\t$(getpid())")
x = @timed main(text)
println("Elapsed: $(x[2]), Allocated: $(x[3]), GC Time: $(x[4])")
notify("stop")