Last active
February 19, 2023 11:14
-
-
Save falseresync/0c6c974d915f8b5d001d7467098144c1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local function pointerAdd(state) | |
state.pointer = state.pointer + 1 | |
end | |
local function pointerSub(state) | |
state.pointer = state.pointer - 1 | |
end | |
local function dataAdd(state) | |
state.data[state.pointer] = (state.data[state.pointer] or 0) + 1 | |
end | |
local function dataSub(state) | |
state.data[state.pointer] = (state.data[state.pointer] or 0) - 1 | |
end | |
local function dataOut(state) | |
print(string.char(state.data[state.pointer])) | |
end | |
local function dataIn(state) | |
state.data[state.pointer] = io.read() | |
end | |
---@param program string | |
---@return table | |
local function analyze(program) | |
local tree = { | |
pointer = 1, | |
result = {} | |
} | |
for index = 1, #program do | |
if (index >= tree.pointer) then | |
local char = program:sub(index, index) | |
tree.pointer = tree.pointer + 1 | |
if char == "[" then | |
local subtree = analyze(program:sub(index + 1)) | |
table.insert(tree.result, subtree.result) | |
tree.pointer = tree.pointer + subtree.pointer - 1 | |
elseif char == "]" then | |
break | |
elseif char == ">" then table.insert(tree.result, pointerAdd) | |
elseif char == "<" then table.insert(tree.result, pointerSub) | |
elseif char == "+" then table.insert(tree.result, dataAdd) | |
elseif char == "-" then table.insert(tree.result, dataSub) | |
elseif char == "." then table.insert(tree.result, dataOut) | |
elseif char == "," then table.insert(tree.result, dataIn) | |
end | |
end | |
end | |
return tree | |
end | |
---@param state table | |
---@param tree table | function | |
local function execute(state, tree) | |
if #tree ~= nil then | |
for i = 1, #tree do | |
local nodeType = type(tree[i]) | |
if nodeType == "table" then | |
while (state.data[state.pointer] or 0) ~= 0 do | |
execute(state, tree[i]) | |
end | |
elseif nodeType == "function" then | |
tree[i](state) | |
end | |
end | |
end | |
end | |
function Main() | |
local INPUT = [[ | |
++ Cell c0 = 2 | |
> +++++ Cell c1 = 5 | |
[ Start your loops with your cell pointer on the loop counter (c1 in our case) | |
< + Add 1 to c0 | |
> - Subtract 1 from c1 | |
] End your loops with the cell pointer on the loop counter | |
At this point our program has added 5 to 2 leaving 7 in c0 and 0 in c1 | |
but we cannot output this value to the terminal since it is not ASCII encoded | |
To display the ASCII character "7" we must add 48 to the value 7 | |
We use a loop to compute 48 = 6 * 8 | |
++++ ++++ c1 = 8 and this will be our loop counter again | |
[ | |
< +++ +++ Add 6 to c0 | |
> - Subtract 1 from c1 | |
] | |
< . Print out c0 which has the value 55 which translates to "7"! | |
]] | |
local program = INPUT:gsub("[^><+-.,%[%]]", "") | |
local tree = analyze(program) | |
local state = { | |
pointer = 0, | |
data = {} | |
} | |
execute(state, tree.result) | |
end | |
Main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local function pointerAdd(state) | |
state.pointer = state.pointer + 1 | |
end | |
local function pointerSub(state) | |
state.pointer = state.pointer - 1 | |
end | |
local function dataAdd(state) | |
state.data[state.pointer] = (state.data[state.pointer] or 0) + 1 | |
end | |
local function dataSub(state) | |
state.data[state.pointer] = (state.data[state.pointer] or 0) - 1 | |
end | |
local function dataOut(state) | |
print(string.char(state.data[state.pointer])) | |
end | |
local function dataIn(state) | |
state.data[state.pointer] = io.read() | |
end | |
---@param program string | |
---@return table | |
local function analyze(program) | |
local tree = { | |
pointer = 1, | |
result = {} | |
} | |
for index = 1, #program do | |
if (index >= tree.pointer) then | |
local char = program:sub(index, index) | |
tree.pointer = tree.pointer + 1 | |
if char == "[" then | |
local subtree = analyze(program:sub(index + 1)) | |
table.insert(tree.result, subtree.result) | |
tree.pointer = tree.pointer + subtree.pointer - 1 | |
elseif char == "]" then | |
break | |
elseif char == ">" then table.insert(tree.result, pointerAdd) | |
elseif char == "<" then table.insert(tree.result, pointerSub) | |
elseif char == "+" then table.insert(tree.result, dataAdd) | |
elseif char == "-" then table.insert(tree.result, dataSub) | |
elseif char == "." then table.insert(tree.result, dataOut) | |
elseif char == "," then table.insert(tree.result, dataIn) | |
end | |
end | |
end | |
return tree | |
end | |
---@param state table | |
---@param tree table | function | |
local function execute(state, tree) | |
if #tree ~= nil then | |
for i = 1, #tree do | |
local nodeType = type(tree[i]) | |
if nodeType == "table" then | |
while (state.data[state.pointer] or 0) ~= 0 do | |
execute(state, tree[i]) | |
end | |
elseif nodeType == "function" then | |
tree[i](state) | |
end | |
end | |
end | |
end | |
function Main() | |
local program = io.input("brain.fuck"):read("*a"):gsub("[^><+-.,%[%]]", "") | |
local tree = analyze(program) | |
local state = { | |
pointer = 0, | |
data = {} | |
} | |
execute(state, tree.result) | |
end | |
Main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment