Skip to content

Instantly share code, notes, and snippets.

@falseresync
Last active February 19, 2023 11:14
Show Gist options
  • Save falseresync/0c6c974d915f8b5d001d7467098144c1 to your computer and use it in GitHub Desktop.
Save falseresync/0c6c974d915f8b5d001d7467098144c1 to your computer and use it in GitHub Desktop.
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()
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