module brainfuck
# Interpreter for Brainfuck source code.
-class BFInterpret
+class BFInterpreter
# Data cells
- var dr = new Array[Char]
+ var dr = new Array[Int]
# Data pointer
var dp = 0
# Instruction pointer
var ip = 0
# The program being interpreted
- var program: String
+ var program: Bytes
- # Contains the set of valid instructions, used in next
- var valid_instr: Set[Char]
+ # Create an interpreter for `program`.
+ init do
+ dr.add 0
+ end
- # Starts interpretation of file `filename`
- init(filename: String) do
- var ifs = new IFStream.open(filename.simplify_path)
- valid_instr = new HashSet[Char]
- valid_instr.add_all "><[].,+-".chars
- dr.add 0.ascii
- program = ifs.read_all
- start
+ # Create an interpreter for the file located at `path`.
+ init from_file(path: String) do
+ var ifs = new FileReader.open(path)
+ init(ifs.read_all_bytes)
end
# Starts the interpretation of the loaded program
loop
if ip >= program.length then break
eval
- next
- end
- end
-
- # Go to the next executable instruction
- fun next do
- ip += 1
- while ip < program.length and not valid_instr.has(program[ip]) do
ip += 1
end
end
+
# Evaluates the current instruction
fun eval do
var instr = program[ip]
- if instr == '.' then printn dr[dp]
- if instr == '[' then
- if dr[dp] == 0.ascii then
+ if instr == u'.' then printn dr[dp].code_point
+ if instr == u'[' then
+ if dr[dp] == 0 then
ip = find_matching_rbra
return
end
end
- if instr == ']' then
- if dr[dp] != 0.ascii then
+ if instr == u']' then
+ if dr[dp] != 0 then
ip = find_matching_lbra
return
end
end
- if instr == '>' then
+ if instr == u'>' then
dp += 1
- if dp >= dr.length then dr.add(0.ascii)
+ if dp >= dr.length then dr.add(0)
end
- if instr == '<' then
+ if instr == u'<' then
dp -= 1
if dp < 0 then abort
end
- if instr == '+' then
- dr[dp] = (dr[dp].ascii + 1).ascii
+ if instr == u'+' then
+ dr[dp] = dr[dp] + 1
end
- if instr == '-' then
- dr[dp] = (dr[dp].ascii - 1).ascii
+ if instr == u'-' then
+ dr[dp] = dr[dp] - 1
end
- if instr == ',' then
- dr[dp] = getc
+ if instr == u',' then
+ dr[dp] = getc.code_point
end
end
var lbracnt = 0
loop
if pos > program.length then abort
- if program[pos] == ']' then
+ if program[pos] == u']' then
if lbracnt > 0 then
lbracnt -= 1
else
break
end
end
- if program[pos] == '[' then lbracnt += 1
+ if program[pos] == u'[' then lbracnt += 1
pos += 1
end
return pos
var rbracnt = 0
loop
if pos < 0 then abort
- if program[pos] == '[' then
+ if program[pos] == u'[' then
if rbracnt > 0 then
rbracnt -= 1
else
break
end
end
- if program[pos] == ']' then rbracnt += 1
+ if program[pos] == u']' then rbracnt += 1
pos -= 1
end
return pos
end
end
-var i = new BFInterpret(args[0])
+new BFInterpreter.from_file(args[0]).start