Advertisement
Greygraphics

Brainfuck Interpreter

Dec 7th, 2016
293
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.67 KB | None | 0 0
  1. --  An interpreter to run the Brainfuck language in lua
  2. --  The size of the memory array is in this example 1024 (1 - 1025)
  3.  
  4. local _args = {...}
  5.  
  6. local _nSize = 1024
  7. local _nMaxVal = 255
  8.  
  9. local _nVars = {}
  10. local _nPtr = 1
  11.  
  12. local _nChar = 1
  13. local _sScript
  14. local _nEntries = {}
  15.  
  16. local _usage = [[
  17. Brainfuck - Usage                              
  18.                                                
  19.   'bfq <filename>'                             
  20.   'bfq :<usage|info|help|test|learn>'          
  21. ]]
  22. local _info = [[
  23. Brainfuck - Info                               
  24.                                                
  25.   Brainfuck is an esoteric programming language
  26.   created in 1993 by Urban Mueller, and notable
  27.   for its extreme minimalism.                  
  28.                                                
  29.   The language consists of only eight simple   
  30.   commands and an instruction pointer.         
  31.                                                
  32.   While it is fully Turing-complete, it is not 
  33.   intended for practical use, but to challenge 
  34.   and amuse programmers.                       
  35.                                                
  36.   https://en.wikipedia.org/wiki/Brainfuck      
  37.   8th of December 2016                         
  38.   ]]
  39.  local _help = [[
  40. Brainfuck - Help                               
  41.                                                
  42.   :usage - How to use this program             
  43.   :info  - Information about Brainfuck         
  44.   :help  - This message                        
  45.   :test  - Runs a small program                
  46.   :learn - Explains how to use Brainfuck       
  47. ]]
  48. local _test = "Brainfuck - Test\n\n  Program output:"
  49.  local _learn = [[ 
  50. Brainfuck - Learn                              
  51.                                                
  52.   There are eight commands:                    
  53.     < - Decrease the pointer                   
  54.     > - Increase the pointer                   
  55.     + - Increase the current cell value        
  56.     - - Decrease the current cell value        
  57.     [ - Declare a loop                         
  58.     ] - Declare the end of a lopp              
  59.     . - Display the current cell value in ASCII
  60.     , - Read the user's input into the cell    
  61.                                                
  62.  A loop gets executed when the current cell has
  63.  a value greater than zero. Cells overflow and
  64.   underflow. The pointer does so too.          
  65.   Cell range: 0-255                            
  66.   Pointer range: 1-1025                        
  67. ]]
  68. local _notFound = [[
  69. Brainfuck - Error                              
  70.                                                
  71.   Command/File not found                       
  72.   Try ':help' instead                          
  73. ]]
  74.  
  75. --  Several cleaning/ready functions (mostly for aestetic reasons)
  76. local function _printf(_sInput)
  77.     term.write(_sInput)
  78. end
  79.  
  80. local function _readyAll()
  81.     for i = 1,_nSize do
  82.         _nVars[i] = 0
  83.     end
  84.     _nPtr = 1
  85. end
  86.  
  87. --  The six functions for memory manipulation/output
  88. --  < > - + ,
  89. local function _decPtr()
  90.     _nPtr = _nPtr-1
  91.     if _nPtr < 1 then
  92.         _nPtr = _nSize
  93.     end
  94. end
  95.  
  96. local function _nncPtr()
  97.     _nPtr = _nPtr+1
  98.     if _nPtr > _nSize then
  99.         _nPtr = 1
  100.     end
  101. end
  102.  
  103. local function _decVal()
  104.     _nVars[_nPtr] = _nVars[_nPtr] - 1
  105.     if _nVars[_nPtr] < 0 then
  106.         _nVars[_nPtr] = _nMaxVal
  107.     end
  108. end
  109.  
  110. local function _nncVal()
  111.     _nVars[_nPtr] = _nVars[_nPtr] + 1
  112.     if _nVars[_nPtr] > _nMaxVal then
  113.         _nVars[_nPtr] = 0
  114.     end
  115. end
  116.  
  117. local function _getChar()
  118.     local _sInput = read()
  119.     if string.len(_sInput)  < 1 then
  120.         _nVars[_nPtr] = 0
  121.     else
  122.         _nVars[_nPtr] = (string.byte(string.sub(_sInput,1,1)) > _nMaxVal and 0)or string.byte(string.sub(_sInput,1,1))
  123.     end
  124. end
  125.  
  126. local function _putChar()
  127.     _printf(string.char(_nVars[_nPtr]))
  128. end
  129.  
  130. --  The remaining functions for the loop
  131. --  [ ]
  132. local function _jmpLoop()
  133.     local _nCount = 0
  134.     while _nChar < string.len(_sScript) do
  135.         _sChar = string.sub(_sScript,_nChar,_nChar)
  136.         if _sChar == "[" then
  137.             _nCount = _nCount + 1
  138.         elseif _sChar == "]" then
  139.             _nCount = _nCount -1
  140.         else
  141.            
  142.         end
  143.         _nChar = _nChar +1
  144.     end
  145. end
  146.  
  147. --  The interpreter
  148. local function _doString(_sInput)
  149.     _sScript = _sInput
  150.     _readyAll()
  151.     repeat
  152.         c = string.sub(_sScript,_nChar,_nChar)
  153.         if c == nil then
  154.         elseif c=="<" then
  155.             _decPtr()
  156.         elseif c==">" then
  157.             _nncPtr()
  158.         elseif c=="-" then
  159.             _decVal()
  160.         elseif c=="+" then
  161.             _nncVal()
  162.         elseif c=="." then
  163.             _putChar()
  164.         elseif c=="," then
  165.             _getChar()
  166.         elseif c=="[" then
  167.             if _nVars[_nPtr] > 0 then
  168.                 _nEntries[#_nEntries + 1] = _nChar
  169.             else
  170.                 _jmpLoop()
  171.             end
  172.         elseif c=="]" then
  173.             if _nVars[_nPtr] > 0 then
  174.                 _nChar = _nEntries[#_nEntries]
  175.             else
  176.             end
  177.         end
  178.        
  179.         _nChar = _nChar+1
  180.     until _nChar > string.len(_sScript)
  181.     print("")
  182. end
  183.  
  184. --  The frontend
  185. local function _commands()
  186.     if _args[1] == ":usage" then
  187.         print(_usage)
  188.     elseif _args[1] == ":info" then
  189.         print(_info)
  190.     elseif _args[1] == ":help" then
  191.         print(_help)
  192.     elseif _args[1] == ":test" then
  193.         print(_test)
  194.         _doString("+++++[->+++++<]>+++++++..<++++++[->++++++<]>+++++.<+++++[->+++++<]>++++.<++++++++[->--------<]>------.<+++++++++[->+++++++++<]>++++++++.<+++[->---<]>-.<>++++++.<+++++++++[->---------<]>----.<+++++++++[->+++++++++<]>++.<+++[->---<]>-----.<>.<++++++++[->--------<]>-----.<+++++++++[->+++++++++<]>+++.<+++[->---<]>---.<>+.<+++[->+++<]>+.<+++++++++[->---------<]>--.<++++++++[->++++++++<]>+++++++++++++.<>--------.<+++[->+++<]>+++++.<>.<++++[->----<]>--.<>++++++.<>--.<+++++++[->-------<]>--------.<+++[->---<]>---.<+++++++++[->+++++++++<]>+++.<+++[->---<]>---.<>---.<++++++++[->--------<]>-----.<++++++++[->++++++++<]>+++++++++.<>+++++.<>++++++.<+++[->---<]>------.<+++[->+++<]>++++.<>--.<>++.<+++[->---<]>----.<+++[->+++<]>++++++.<+++[->---<]>------.<+++[->+++<]>++++.<+++++++++[->---------<]>-.<+++++++++[->+++++++++<]>++++++.<>--------.<>+++.<>-------.<>++++++++.<+++++++++[->---------<]>-.<++++[->----<]>-------.<")
  195.     elseif _args[1] == ":learn" then
  196.         print(_learn)
  197.     else
  198.         print(_notFound)
  199.     end
  200. end
  201.  
  202. local function _run()
  203.     if fs.exists(_args[1]) then
  204.         _fFile = fs.open(_args[1],"r")
  205.         _sFile = _fFile.readAll()
  206.         _fFile.close()
  207.         _doString(_sFile)
  208.     else
  209.         print(_notFound)
  210.     end
  211. end
  212.  
  213. local function _main()
  214.     shell.run("clear")
  215.     if #_args < 1 then
  216.         print(_usage)
  217.         return
  218.     end
  219.     if string.sub(_args[1],1,1) == ":" then
  220.         _commands()
  221.     else
  222.         _run()
  223.     end
  224. end
  225.  
  226. _main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement