basic_robot/scripts/programming/brainfuck.lua

66 lines
2.2 KiB
Lua

-- BRAINFUCK interpreter by rnd, 2017
-- https://en.wikipedia.org/wiki/Brainfuck
if not ram then
prog = "+++.>++++++.<[->+<]>."
ramsize = 10
maxsteps = 100; step=0; -- for RUN state only
n = string.len(prog);ram = {};for i = 1, ramsize do ram[i]=0 end -- init ram
pointer = 1 -- ram pointer
instruction = 1 -- instruction pointer
self.spam(1)
RUNNING = 1; END = 2; RUN = 3;
state = RUNNING
get_ram = function() msg = "" for i = 1,ramsize do msg = msg .. ram[i] .. "," end return msg end
cmdset = {
[">"] = function() pointer = pointer + 1; if pointer > ramsize then pointer = 1 end end,
["<"] = function() pointer = pointer - 1; if pointer > ramsize then pointer = 1 end end,
["+"] = function() ram[pointer]=ram[pointer]+1 end,
["-"] = function() ram[pointer]=ram[pointer]-1 end,
["."] = function() say(ram[pointer]) end,
[","] = function() ram[pointer] = tonumber(read_text.forward("infotext") or "") or 0 end,
["["] = function()
if ram[pointer] == 0 then
local lvl = 0
for j = instruction, n, 1 do
if string.sub(prog,j,j) == "]" then lvl = lvl - 1 if lvl == 0 then
self.label("JMP " .. j ) instruction = j return
end end
if string.sub(prog,j,j) == "[" then lvl = lvl + 1 end
end
end
end,
["]"] = function()
if ram[pointer] ~= 0 then
local lvl = 0
for j = instruction, 1, -1 do
if string.sub(prog,j,j) == "]" then lvl = lvl - 1 end
if string.sub(prog,j,j) == "[" then lvl = lvl + 1 if lvl == 0 then
self.label("JMP " .. j ) instruction = j return
end end
end
end
end,
}
end
-- EXECUTION
if state == RUNNING then
c = string.sub(prog,instruction,instruction) or "";
if c and cmdset[c] then cmdset[c]() end
self.label("ins ptr " .. instruction .. ", ram ptr " .. pointer .. ": " .. ram[pointer] .. "\n" .. string.sub(prog, instruction).."\n"..get_ram())
instruction = instruction + 1; if instruction > n then state = END end
-- RUN THROUGH
elseif state == RUN then
while (step<maxsteps) do
step = step + 1
c = string.sub(prog,instruction,instruction) or "";
if c and cmdset[c] then cmdset[c]() end
instruction = instruction + 1; if instruction > n then self.label("ram : " .. get_ram()) step = maxsteps state = END end
end
end