Advertisement
Guest User

brainfuck

a guest
May 24th, 2013
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --Brainf*ck interpreter (c) 2013 by victorious3
  2. --Usage: use brainfuck <filename> to run brainf*ck program
  3. --       add extra "-debug" for testing
  4.  
  5. local tArgs = {...}
  6.  
  7. local yieldTime = os.clock() --yield timer
  8. local function yield()
  9.   if os.clock() - yieldTime > 2 then
  10.     os.queueEvent("yield") --post fake "yield" event
  11.     os.pullEvent()
  12.     yieldTime=os.clock() --reset yield timer
  13.   end
  14. end
  15.  
  16. local function run(program, debug)
  17.  
  18.   local lenght = program:len() --Total program lenght
  19.   local pointers = {} --all memory cells
  20.   local pointer = 1 --currently selected memory cell
  21.   local counter = 1 --program counter
  22.   local jumpers = {} --jumpers for the "]" command
  23.   local jumper = 0 --current jumperlevel
  24.  
  25.   --fill pointers and jumpers with 0  
  26.   for i = 1, 30000 do
  27.     pointers[i] = 0
  28.     jumpers[i] = 0
  29.   end
  30.    
  31.   while counter ~= lenght + 1 do --while program not at the end
  32.     --current character in the program
  33.     local command = string.sub(program, counter, counter)
  34.     local isCommandValid = true
  35.                            
  36.     if command == "+" then
  37.       pointers[pointer] = pointers[pointer] + 1 --increment current cell
  38.     elseif command == "-" then
  39.       pointers[pointer] = pointers[pointer] - 1 --decrement current cell
  40.     elseif command == ">" then
  41.       if pointer < 30001 then --increment cell pointer
  42.         pointer = pointer + 1
  43.       else
  44.         pointer = 1
  45.       end
  46.     elseif command == "<" then
  47.       if pointer > 1 then --decrement cell pointer
  48.         pointer = pointer - 1
  49.       else
  50.         pointer = 30000
  51.       end
  52.     elseif command == "." then
  53.       write(string.char(pointers[pointer])) --ouput current cell as ASCII character
  54.     elseif command == "[" then
  55.       if pointers[pointer] ~= 0 then --if current cell ~= 0 then add new jumper at jumperlevel
  56.         jumper = jumper + 1
  57.         jumpers[jumper] = counter
  58.       else
  59.         local i = counter + 1
  60.         local j = 1
  61.         while i ~= lenght do
  62.           if string.sub(program, i, i) == "]" then
  63.             j = j - 1
  64.           elseif string.sub(program, i, i) == "[" then
  65.             j = j + 1
  66.           end
  67.                                        
  68.           if j == 0 then
  69.             counter = i --if current cell == n�B40 then go to the matching "]"
  70.             break
  71.           end
  72.          
  73.           i = i + 1
  74.         end
  75.       end
  76.     elseif command == "]" then    
  77.       if pointers[pointer] ~= 0 then
  78.         counter = jumpers[jumper] --if current cell ~= 0 then go to matching "[" (jumper)
  79.       else
  80.         jumper = jumper - 1
  81.       end
  82.     elseif command == "," then
  83.       local event, key = os.pullEvent("char") --wait for character input and store ASCII Code in current cell
  84.       pointers[pointer] = string.byte(key)  
  85.     else
  86.       isCommandValid = false
  87.     end
  88.  
  89.     if debug and isCommandValid then
  90.       os.pullEvent() --wait for os event
  91.       write("{"..command.." "..pointer..":"..pointers[pointer].."@"..counter.."} ") --write debug information
  92.     end
  93.    
  94.     counter = counter + 1 --increment program counter                                                                                                                                                                                                                                                                                                                
  95.     yield() --used to prevent "Too long without yielding" - error
  96.   end
  97. end
  98.  
  99. if tArgs[1] == nil then
  100.   error("Argument 1 must be a filename!")
  101. end
  102.  
  103. local file = fs.open(tArgs[1], "r") --open program file
  104. local debug = tArgs[2] == "-debug"
  105.  
  106. if file == nil then
  107.   error("Argument 1 is not a valid file!")
  108. end
  109.  
  110. local program = file.readAll() --read program file into a string
  111. file.close()
  112. term.clear()
  113. term.setCursorPos(1,1)
  114. run(program, debug) --run the program
  115. write("\n")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement