执行Brainfuck程序。
参数1为代码。代码中,除+、-、<、>、[、]、,和.之外的字符都将被忽略。
参数2为输入。输入的内容将按字节而非Unicode码位读取。输入的内容末尾会被添加-1 (0xFF)作为EOF。
返回程序的输出。
输出“Hello, World!”。[1]
{{User:あめろ/Brainfuck|
+[-->-[>>+>-----<<]<--<---]>-.>>>+.>>..+++[.>]<<<<.+++.------.<<-.>>>>+.
}}
执行结果:Hello, World!
花了一夜肝出来的,水平不好。
{{User:あめろ/Brainfuck|1=
[由于内存单元初始是0,这对方括号里的代码(+-<>[],.)会被跳过,所以可以当作文档注释。
该程序实现了将输入的内容中的大写字母转换为对应小写字母,而其它字符不变。]
MEM: zero zero charIn
^ 0 0 0
>>(charIn),+[- 读取字符,当字符不是EOF时进入循环
将charIn减'A',并复制为两份:charCpy在下一段用,charOut在最终输出的时候用。
MEM: charOut charCpy charIn counter
0 0 ^ X 0
>(counter)++++++++[<-------->-]<- charIn减'A'的ASCII码65 (8 * 负8 减 1)
(charIn)[<+<+>>-] 复制charIn到charCpy和charOut中
判断是charCpy否小于等于26,若是,则isLT26非0。
MEM: charOut charCpy isLT26 temp doesDec
X X ^ 0 0 0
>(temp)+++++[<+++++>-]<+ isLT26 = 26 (LT: less than)
<(charCpy)[
>(isLT26)[>(temp)+>(doesDec)[-]+<<-]
>(temp)[<+>-] 上一行和此行:isLT26非0时,使doesDec为1
>(doesDec)[<<->>-] 若doesDec,则isLT26减1、doesDec减1
<<<(charCopy)- charCopy减1
]
如果是小写字母,输出对应大写字母;否则输出本身。
MEM: charOut counter isLT26
X ^ 0 B
>(isLT26)[ isLT26非0时
<(counter)++++[<++++++++>-] charOut加32 (4 * 8)
>(isLT26)[-] 将isLT26清零,以退出循环
]
<(counter)++++++++[<++++++++>-]<+ charOut加65 (8 * 8 加 1)
(charOut).[-] 输出并清零
MEM: zero zero charIn
^ 0 0 0
>>(charIn),+ 读取下一个字符
]
|2=ABcdEf123}}
去掉注释:
{{User:あめろ/Brainfuck|
>>,+[->++++++++[<-------->-]<-[<+<+>>-]>+++++[<+++++>-]<+<[>[>+>[-]+<<-]>[<+>-]>[<<->>-]<<<-]>[<++++[<++++++++>-]>[-]]<++++++++[<++++++++>-]<+.[-]>>,+]
|ABcdEf123}}
执行结果:abcdef123
--[[
-- Brainfuck解析器
--
-- 作者:amero
-- 协议:MIT License
--]]
local insert = table.insert
local push = insert
local remove = table.remove
local pop = remove
local Brainfuck = {}
function Brainfuck._main(commands, input)
-- 数据
local cells = setmetatable({}, {
__index = function(t, k) return 0 end,
})
local dp -- data pointer
local input_buffer
local output_buffer
-- 指令
local instructions
local bracket_pair_index
local ip -- instruction pointer
local commands_len
local command_funcs
instructions = {
['>'] = function()
dp = dp + 1
end,
['<'] = function()
dp = dp - 1
end,
['+'] = function()
cells[dp] = (cells[dp] + 1) % 256
end,
['-'] = function()
cells[dp] = (cells[dp] - 1) % 256
end,
['.'] = function()
insert(output_buffer, cells[dp])
end,
[','] = function()
cells[dp] = remove(input_buffer, 1)
end,
['['] = function()
if cells[dp] == 0 then
ip = bracket_pair_index[ip]
end
end,
[']'] = function()
if cells[dp] ~= 0 then
ip = bracket_pair_index[ip]
end
end,
}
-- 预处理代码。创建成对的括号索引;将字符串转换为函数序列
commands = string.gsub(commands, '[^><%+%-%.,%[%]]', '')
command_funcs = {}
bracket_pair_index = {}
do
local i = 1
local bracket_stack = {}
for char in string.gmatch(commands, '.') do
command_funcs[i] = instructions[char]
-- 寻找'['对应的']',并创建索引
if char == '[' then
push(bracket_stack, i)
elseif char == ']' then
assert(#bracket_stack > 0, '方括号不配对')
local left = pop(bracket_stack)
bracket_pair_index[left] = i
bracket_pair_index[i] = left
end
i = i + 1
end
assert(#bracket_stack == 0, '方括号不配对')
commands_len = i - 1
end
-- 运行
ip, dp = 1, 1
input_buffer = input and { string.byte(input, 1, #input) } or {}
insert(input_buffer, 0xFF) -- EOF
output_buffer = {}
while ip <= commands_len do
command_funcs[ip]()
ip = ip + 1
end
return string.char(unpack(output_buffer))
end
function Brainfuck.main(frame)
local parent = frame:getParent()
if parent and parent:getTitle() == 'User:あめろ/Brainfuck' then
frame = parent
end
local args = frame.args
return Brainfuck._main(args[1], args[2])
end
return Brainfuck