Skip to content

Instantly share code, notes, and snippets.

@inmatarian
Created October 7, 2016 01:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save inmatarian/ca66d29f6241a7bb11f593f48a134bf1 to your computer and use it in GitHub Desktop.
Save inmatarian/ca66d29f6241a7bb11f593f48a134bf1 to your computer and use it in GitHub Desktop.
brainfuck, recursive interpreter implementation, cuz why not.
function abs(x)
if x < 0 then
return -1
else
return 1
end
end
oper = {}
oper['+'] = function(prog, instr, data, ptr)
data[ptr] = (data[ptr] or 0) + 1
return step(prog, instr+1, data, ptr)
end
oper['-'] = function(prog, instr, data, ptr)
data[ptr] = (data[ptr] or 0) - 1
return step(prog, instr+1, data, ptr)
end
oper['>'] = function(prog, instr, data, ptr)
return step(prog, instr+1, data, ptr+1)
end
oper['<'] = function(prog, instr, data, ptr)
return step(prog, instr+1, data, ptr-1)
end
oper['.'] = function(prog, instr, data, ptr)
io.write(string.char(data[ptr] or 0))
return step(prog, instr+1, data, ptr)
end
oper[','] = function(prog, instr, data, ptr)
data[ptr] = string.byte(io.read(1))
return step(prog, instr+1, data, ptr)
end
oper['['] = function(prog, instr, data, ptr)
if (data[ptr] or 0) == 0 then
return seek(prog, instr+1, data, ptr, 1)
else
return step(prog, instr+1, data, ptr)
end
end
oper[']'] = function(prog, instr, data, ptr)
if (data[ptr] or 0) ~= 0 then
return seek(prog, instr-1, data, ptr, -1)
else
return step(prog, instr+1, data, ptr)
end
end
function seek(prog, instr, data, ptr, loop)
if loop == 0 then
return step(prog, instr, data, ptr)
elseif prog[instr] == '[' then
return seek(prog, instr+abs(loop), data, ptr, loop+1)
elseif prog[instr] == ']' then
return seek(prog, instr+abs(loop), data, ptr, loop-1)
else
return seek(prog, instr+abs(loop), data, ptr, loop)
end
end
function step(prog, instr, data, ptr)
if instr > #prog then
return data, ptr
else
local fn = oper[prog[instr]]
if fn then
return fn(prog, instr, data, ptr)
else
return step(prog, instr+1, data, ptr)
end
end
end
function run(filename, ...)
if filename == nil then return end
local str = io.open(filename):read('*a')
local prg = {}
str:gsub(".", function(c) table.insert(prg, c) end)
step(prg, 1, {}, 1)
return run(...)
end
run(...)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment