Module:Sandbox/あめろ/Brainfuck
< Module:Sandbox | あめろ
跳到导航
跳到搜索
执行Brainfuck程序。
用法
参数1
为代码。代码中,除+
、-
、<
、>
、[
、]
、,
和.
之外的字符都将被忽略。
参数2
为输入。输入的内容将按字节而非Unicode码位读取。输入的内容末尾会被添加-1 (0xFF)
作为EOF。
返回程序的输出。
示例
Hello, World!
输出“Hello, World!”。[1]
{{User:あめろ/Brainfuck| +[-->-[>>+>-----<<]<--<---]>-.>>>+.>>..+++[.>]<<<<.+++.------.<<-.>>>>+. }}
执行结果:User:あめろ/Brainfuck
字母小写化
花了一夜肝出来的,水平不好。
{{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}}
执行结果:User:あめろ/Brainfuck
注释
--[[ -- 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